mirror of
https://github.com/beyondx/Notes.git
synced 2026-11-04 06:23:49 +08:00
Add New Notes
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-01-07T15:21:50+08:00
|
||||
|
||||
====== Auto-installing packages in Emacs with ELPA and el-get ======
|
||||
Created Saturday 07 January 2012
|
||||
|
||||
http://www.facebook.com/notes/xmms2/auto-installing-packages-in-emacs-with-elpa-and-el-get/10150401940759307
|
||||
|
||||
由 XMMS2 于 2011年8月12日16:05 发布
|
||||
|
||||
Those who live in emacs all know the pain of __manually installing__ extra modes and extensions, especially on different hosts. **System packages** sometimes help, but they differ on every OS (Debian packages, MacPorts, etc.), don’t always exist, and need to be installed manually.
|
||||
|
||||
A better alternative is to__ use emacs itself__ to manage, install and update all the required extra code. The __ELPA project__ provides a way to install packages from different repositories, while __el-get__ can help you declare recipes to install and update code from ELPA, or even Github or Emacswiki.
|
||||
|
||||
First, let’s setup some code that tries to load ELPA and el-get, and installs them if they are not present.
|
||||
|
||||
; derived from ELPA installation
|
||||
; http://tromey.com/elpa/install.html
|
||||
(defun eval-url (url)
|
||||
(let ((buffer (url-retrieve-synchronously url)))
|
||||
(save-excursion
|
||||
(set-buffer buffer)
|
||||
(goto-char (point-min))
|
||||
(re-search-forward "^$" nil 'move)
|
||||
(eval-region (point) (point-max))
|
||||
(kill-buffer (current-buffer)))))
|
||||
|
||||
;; Load ELPA
|
||||
(add-to-list 'load-path "~/.emacs.d/elpa")
|
||||
|
||||
(defun install-elpa ()
|
||||
(__eval-url __"http://tromey.com/elpa/package-install.el"))
|
||||
|
||||
(if (__require 'package nil t)__
|
||||
(progn
|
||||
;; Emacs 24+ includes ELPA, but requires some extra setup
|
||||
;; to use the (better) tromey repo
|
||||
(if (>= emacs-major-version 24)
|
||||
(setq package-archives
|
||||
(cons '("tromey" . "http://tromey.com/elpa/")
|
||||
package-archives)))
|
||||
(package-initialize))
|
||||
(install-elpa))
|
||||
|
||||
;; Load el-get
|
||||
(add-to-list 'load-path "~/.emacs.d/el-get/el-get")
|
||||
|
||||
(defun install-el-get ()
|
||||
(eval-url
|
||||
"https://github.com/dimitri/el-get/raw/master/el-get-install.el"))
|
||||
|
||||
(unless (__require 'el-get nil t__)
|
||||
(install-el-get))
|
||||
|
||||
|
||||
Note that when using** emacs 24, package.el is distributed with emacs** but it points to the GNU package repository; the code above adds tromey’s more complete ELPA repository to the sources.
|
||||
|
||||
Unfortunately, the ELPA installer script **appends a snippet of code to the end of the ~/.emacs** file to **auto-load package.el on startup**. To avoid any problem, it is best to __manually remove__ that code any only keep the load-or-install code above.
|
||||
|
||||
Now that ELPA and el-get are setup, we can **declare all the packages we want installed**. They will be installed after the first time emacs is started, and simply **loaded and initialized** in the future.
|
||||
|
||||
; extra recipes for packages __unknown to el-get__ (yet)
|
||||
(setq el-get-sources
|
||||
'((:name css-mode :type __elpa__)
|
||||
(:name js2-mode-mooz
|
||||
:type git
|
||||
:url "git://github.com/mooz/js2-mode.git"
|
||||
:load "js2-mode.el"
|
||||
:compile ("js2-mode.el")
|
||||
:features js2-mode)))
|
||||
|
||||
; list all packages you want installed
|
||||
(setq my-el-get-packages
|
||||
(append
|
||||
'(css-mode egg gist js2-mode-mooz)
|
||||
(mapcar 'el-get-source-name el-get-sources)))
|
||||
|
||||
(el-get 'sync** my-el-get-packages**)
|
||||
|
||||
|
||||
The el-get 'sync call does all the magic, based on all the packages **past in argument** (as my-el-get-packages). Any packages for which el-get __has a recipe__ can be installed.
|
||||
|
||||
The el-get-sources variable allows to __declare extra custom recipes__ for code to install. In the example above, css-mode is simply pulled from the ELPA repository, while js2-mode-mooz is fetched directly from Github.
|
||||
|
||||
Replicating this code in all your ~/.emacs files is a very easy and convenient way to bootstrap the same emacs environment on multiple hosts.
|
||||
113
Zim/Utils/emacs/el-get/GNU_Emacs的终极扩展管理工具_—_el-get.txt
Normal file
113
Zim/Utils/emacs/el-get/GNU_Emacs的终极扩展管理工具_—_el-get.txt
Normal file
@@ -0,0 +1,113 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-01-07T15:45:05+08:00
|
||||
|
||||
====== GNU Emacs的终极扩展管理工具 — el-get ======
|
||||
Created Saturday 07 January 2012
|
||||
http://emacser.com/el-get.htm
|
||||
|
||||
作者: Nick Qi
|
||||
|
||||
Let’s el-get together
|
||||
|
||||
通常我们在配置GNU Emacs的时候,都会安装一些第三方的lisp扩展来让GNU Emacs用起来更顺手,但是这些第三方lisp扩展的安装、升级和配置的方法各异,通常我们需要使用多种完全不同管理方式的lisp扩展(http直接下载,__发行版包管理器__下载,__版本控制器__下载等)。这样我们升级或者迁移的时候就可能会遇到各种麻烦。
|
||||
|
||||
GNU Emacs一直以来都缺少一个统一的第三方lisp扩展管理器,GNU XEmacs与GNU Emacs的一个区别就是它有一个统一的第三方包管理工具。这其中的原因主要是因为GNU Emacs是GNU Project的一个重要代表,它要求随它发行的所有lisp都__要作者签名用GPL授权给FSF__,但是并不是所有的作者都支持GPL,而且这个过程给第三方贡献增加了不少阻碍。所以当时就有一批开发者开发了GNU XEmacs。所以GNU Emacs一直到现在也没有引入官方的扩展管理工具(指的是当前的稳定版本,ELPA已经被合并到当前的开发分支了)。
|
||||
|
||||
===== 当前第三方包管理方法 =====
|
||||
|
||||
* emacswiki有auto-install.el之类的管理工具
|
||||
* linux发行版的包管理(如debian的lisp包)
|
||||
* tromey写的package.el
|
||||
* 手工使用git之类的版本控制工具来管理lisp扩展
|
||||
* 直接下载
|
||||
|
||||
当前这些方法的不足之处
|
||||
|
||||
* elpa可以管理当前大多数第三方扩展,但是仍然有很多不在里面
|
||||
* 手工管理,升级太麻烦,迁移也不方便
|
||||
* linux发行版的包管理,通常你用不了最新的扩展,而且迁移也挺麻烦
|
||||
* 开发分支的ELPA,不要认为GNU Emacs会放弃原来的授权方式,要进入官方ELPA估计和现在没有什么区别,仍然有很多作者不会把自己的代码交给FSF。不过也会有第三方ELPA。
|
||||
|
||||
===== el-get华丽登场 =====
|
||||
|
||||
=== el-get简介 ===
|
||||
|
||||
* el-get能够透明的管理各种来源的第三方扩展(不管你是通过linux发行版获取,还是直接下载还是通过git等版本控制器获取的)
|
||||
* el-get能够安装,升级和移除它管理的第三方扩展
|
||||
* el-get支持安装后的__初始化__操作,支持hook操作
|
||||
* el-get支持扩展包man和info的安装,安装好后,你可以直接C-h i查看info
|
||||
* el-get的__源描述文件__(recipe)超级简单,可以轻松添加自己的扩展源
|
||||
* el-get支持异步和同步安装和初始化
|
||||
* el-get__支持ELPA__中的所有package安装,ELPA是它的一种安装方法。。。
|
||||
|
||||
===== 安装el-get =====
|
||||
|
||||
el-get的作者参考和ELPA的package.el的做法,使得el-get的安装非常简单:
|
||||
|
||||
;; So the idea is that you copy/paste this code into your *scratch* buffer,
|
||||
;; hit C-j, and you have a working el-get.
|
||||
(url-retrieve
|
||||
"https://github.com/dimitri/el-get/raw/master/el-get-install.el"
|
||||
(lambda (s)
|
||||
(end-of-buffer)
|
||||
(eval-print-last-sexp)))
|
||||
|
||||
复制上面的代码到scratch中,移动光标到最后一行结尾,按下C-j然后就可坐等安装完成了。
|
||||
|
||||
===== 使用el-get =====
|
||||
|
||||
el-get的作者是debian developer,所以el-get有深深的apt-get烙印。其实我还觉得el-get很有gentoo portage的影子,直接描述扩展包地址,然后直接下载安装。
|
||||
|
||||
==== 安装扩展 ====
|
||||
|
||||
接下来就是最激动人心的时刻了,让我们先用magit、package和auto-complete来演示el-get的几个功能。
|
||||
|
||||
对于el-get本身,你需要给它手动指定load-path,因为启动的时候需要__先载入它的功能__,然后才能通过它来安装和管理其他lisp扩展。
|
||||
|
||||
当然在你刚安装玩el-get还没有重启GNU Emacs之前,你是可以直接使用它的功能的。
|
||||
|
||||
(setq el-get-sources
|
||||
'(el-get
|
||||
package
|
||||
auto-complete
|
||||
(:name magit
|
||||
__:after__ (lambda () (global-set-key (kbd "C-x C-z") 'magit-status))))
|
||||
)
|
||||
(el-get 'sync)
|
||||
|
||||
复制上面的代码到scratchbuffer,光标移动到buffer最后,键入C-j执行lisp代码。这样el-get、package、auto-complete和magit就被安装到~/.emacs.d/el-get目录下了。而且magit包在安装好后__还执行了__一个按键绑定操作,同样你也可以在任何需要配置的扩展后面__使用定制函数__。
|
||||
|
||||
===== 初始化扩展 =====
|
||||
|
||||
el-get还可以帮助你方便的初始化GNU Emacs扩展,在每个source描诉的__:after__后面可以放上自己的**初始化函数**,就像上面的magit那样。
|
||||
|
||||
通常(el-get)是异步执行的,所以如果你的扩展之间有依赖关系,它的初始化过程可能就会失败,所以为了方便大家写扩展包的初始化函数,作者给(el-get)增加了两种同步
|
||||
方式:
|
||||
|
||||
* (el-get ’sync) 完全同步,初始化的顺序严格按照el-get-sources中的顺序完成
|
||||
* (el-get ‘wait) 初始化过程异步,可以多个source同时初始化,但会等待整个初始化完成
|
||||
|
||||
===== 交互式命令接口 =====
|
||||
|
||||
* el-get-cd 用dired切换到指定package的文件夹
|
||||
* el-get-install 根据用户设定的el-get-sources变量中的package来指定安装其中一个
|
||||
* el-get-update 升级指定的package
|
||||
* el-get-update-all 升级el-get-sources中的所有package,慎用
|
||||
* el-get-remove 删除已经安装而且在el-get-sources中的某个package
|
||||
* 加上C-u前缀的时候,el-get-install和el-get-remove是可以操作仓库中的所有package
|
||||
|
||||
===== 定制和贡献 =====
|
||||
|
||||
* el-get支持本地扩展包仓库,参考el-get-recipe-path变量
|
||||
* 参考package描述文件的文档,对仓库中的package进行定制,可以改变来源、构建命令、 初始化函数。。。
|
||||
* 参考el-get-methods的文档,给el-get增加更多的安装来源支持
|
||||
* 贡献package描述文件(package recipe),添加你喜欢的package
|
||||
* 使用并报告bug,或者要求增加新的特性
|
||||
* 让更多的人用上el-get
|
||||
|
||||
===== 资源和链接 =====
|
||||
|
||||
* el-get github地址: https://github.com/dimitri/el-get
|
||||
* el-get 作者blog: http://tapoueh.org/news.dim.html
|
||||
* 我的el-get分支: https://github.com/vmlinz/el-get
|
||||
44
Zim/Utils/emacs/el-get/blog.txt
Normal file
44
Zim/Utils/emacs/el-get/blog.txt
Normal file
@@ -0,0 +1,44 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-01-07T15:41:21+08:00
|
||||
|
||||
====== blog ======
|
||||
Created Saturday 07 January 2012
|
||||
|
||||
http://tapoueh.org/emacs/el-get.html
|
||||
|
||||
Of course, my emacs setup is managed in a private git repository. Some people on #emacs are using git submodules (or was it straight import) for managing external repositories in there, but all I can say is that I frown on this idea. I want __an easy canonical list of packages I depend on to run emacs__, and I want this documentation to be usable as-is. Enters el-get!
|
||||
|
||||
(setq el-get-sources
|
||||
'((:name bbdb
|
||||
:type git
|
||||
:url "git://github.com/barak/BBDB.git"
|
||||
:load-path ("./lisp" "./bits")
|
||||
:info "texinfo"
|
||||
:build ("./configure" "make"))
|
||||
|
||||
(:name magit
|
||||
:type git
|
||||
:url "http://github.com/philjackson/magit.git"
|
||||
:info "."
|
||||
:build ("./autogen.sh" "./configure" "make"))
|
||||
|
||||
(:name vkill
|
||||
:type http
|
||||
:url "http://www.splode.com/~friedman/software/emacs-lisp/src/vkill.el"
|
||||
:features vkill)
|
||||
|
||||
(:name yasnippet
|
||||
:type git-svn
|
||||
:url "http://yasnippet.googlecode.com/svn/trunk/"))
|
||||
|
||||
(setq my-packages
|
||||
(append
|
||||
'(el-get escreen switch-window mailq cssh auto-complete)
|
||||
(mapcar 'el-get-source-name el-get-sources)))
|
||||
|
||||
(el-get 'sync my-packages)
|
||||
|
||||
So now you have a pretty good documentation of the packages__ you want installed__, where to get them, and how to install them. For the advanced methods (such as elpa or apt-get), you basically just need the package name. When relying on a bare git repository, you need to give some more information, such as the URL to clone and the build steps if any. Then also what features to require and maybe where to find the texinfo documentation of the package, for automatic inclusion into your local Info menu.
|
||||
|
||||
The good news is that not only you now have a solid readable description of all that in a central place, but this very description is all (el-get) needs to do its magic. This command will check that each and every package is installed on your system (in__ el-get-dir__) and if that's not the case, it will actually install it. Then, it will init the packages: that means caring about the load-path, the Info-directory-list (and dir texinfo menu building) the loading of the emacs-lisp files, and finally it will require the features.
|
||||
396
Zim/Utils/emacs/el-get/doc.txt
Normal file
396
Zim/Utils/emacs/el-get/doc.txt
Normal file
@@ -0,0 +1,396 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-01-07T15:54:55+08:00
|
||||
|
||||
====== doc ======
|
||||
Created Saturday 07 January 2012
|
||||
摘自源代码目录中的README文档
|
||||
|
||||
= el-get
|
||||
|
||||
Short Story: el-get allows you to install and manage +elisp+ code for
|
||||
Emacs. It supports lots of __differents types of sources __and is able to
|
||||
'install' them, 'update' them and 'remove' them, but more importantly it
|
||||
will __'init'__ them for you.
|
||||
|
||||
That means it will** +require+** the 'features' you need,** +load+** the
|
||||
necessary files, set the 'Info' paths so that **+C-h i+** shows the new
|
||||
documentation you now depend on, and finally call your own
|
||||
**+:post-init+ **function for you to setup the extension. Or call it a
|
||||
package.
|
||||
|
||||
== Status and Version Numbers
|
||||
|
||||
Current** +el-get+** status is stable, ready for daily use and packed with extra
|
||||
features that make life easier. There are some more things we could do, as
|
||||
always, but they will be about smoothing things further.
|
||||
|
||||
=== Latest released version
|
||||
|
||||
+el-get+ version 2.1 is available, with a boatload of features, including
|
||||
autoloads support, byte-compiling in an external "clean room" Emacs
|
||||
instance, custom support, **lazy initialisation support** (defering all init
|
||||
functions to __+eval-after-load+__), and multi repositories +ELPA+ support.
|
||||
|
||||
=== Version numbering
|
||||
|
||||
Version String are now inspired by how Emacs itself numbers its versions.
|
||||
First is the major version number, then a dot, then the minor version
|
||||
number. The minor version number is 0 when still developping the next major
|
||||
version. So 3.0 is a developer release while 3.1 will be the next stable
|
||||
release.
|
||||
|
||||
Please note that this versioning policy has been picked while backing
|
||||
1.2~dev, so 1.0 was a "stable" release in fact. Ah, history.
|
||||
|
||||
== How to Install it?
|
||||
|
||||
Here's the 'lazy installer':
|
||||
|
||||
--------------------------------------
|
||||
;; So the idea is that you copy/paste this code into your *scratch* buffer,
|
||||
;; hit C-j, and you have a working el-get.
|
||||
(url-retrieve
|
||||
"https://raw.github.com/dimitri/el-get/master/el-get-install.el"
|
||||
(lambda (s)
|
||||
(end-of-buffer)
|
||||
(eval-print-last-sexp)))
|
||||
--------------------------------------
|
||||
|
||||
You have to type +C-j+ with** the cursor at the end of the last line, but**
|
||||
**still on the line**. 'C-j runs the command eval-print-last-sexp', so it will
|
||||
evaluate the code you're looking at, and that will +git clone el-get+ at the
|
||||
'right place'.
|
||||
|
||||
Note that you can add this elisp code into your __emacs init file__ directly, as
|
||||
the installer code will detect if +el-get+ is already installed. Notice
|
||||
that doing so directly will require internet access to start emacs. You can
|
||||
avoid this with the following snippet instead:
|
||||
|
||||
--------------------------------------
|
||||
(add-to-list 'load-path "~/.emacs.d/el-get/el-get")
|
||||
|
||||
(unless __(require 'el-get nil t)__
|
||||
(url-retrieve
|
||||
"https://raw.github.com/dimitri/el-get/master/el-get-install.el"
|
||||
(lambda (s)
|
||||
(end-of-buffer)
|
||||
(eval-print-last-sexp))))
|
||||
--------------------------------------
|
||||
|
||||
See next section for details about how to** setup you emacs** so that it's able
|
||||
to benefit from +el-get+ automatically.
|
||||
|
||||
== How to install the developer version (master branch)?
|
||||
|
||||
The 'lazy installer' uses the default +el-get-install.el+ file which targets
|
||||
the +2.stable+ branch. To install el-get directly on the +master+ branch,
|
||||
summon the +el-get-master-branch+ variable into existence:
|
||||
|
||||
--------------------------------------
|
||||
;; So the idea is that you copy/paste this code into your *scratch* buffer,
|
||||
;; hit C-j, and you have a working developper edition of el-get.
|
||||
(url-retrieve
|
||||
"https://raw.github.com/dimitri/el-get/master/el-get-install.el"
|
||||
(lambda (s)
|
||||
(let (el-get-master-branch)
|
||||
(end-of-buffer)
|
||||
(eval-print-last-sexp))))
|
||||
--------------------------------------
|
||||
|
||||
== Basic usage
|
||||
|
||||
Now that +el-get+ is installed, simply use **+M-x el-get-install+** and pick
|
||||
whatever package you need. __ Arrange to__ have +el-get+ part of your setup, so
|
||||
that at next emacs startup the installed packages are **initialized**. Here's
|
||||
how to:
|
||||
通过el-get-install命令安装的package,需要在el-get的配置文件中添加一些设置,这样
|
||||
emacs下次启动时,el-get才会__自动地配置__它们。
|
||||
--------------------------------------
|
||||
(add-to-list 'load-path "~/.emacs.d/el-get/el-get")
|
||||
|
||||
(unless (require 'el-get nil t)
|
||||
(url-retrieve
|
||||
"https://raw.github.com/dimitri/el-get/master/el-get-install.el"
|
||||
(lambda (s)
|
||||
(end-of-buffer)
|
||||
(eval-print-last-sexp))))
|
||||
|
||||
(el-get 'sync)
|
||||
--------------------------------------
|
||||
|
||||
That's the basic setup.
|
||||
|
||||
== Advanced setup with local recipes
|
||||
|
||||
Of course, my emacs setup is managed in a private git repository. Some
|
||||
people on +#emacs+ are using +git submodules+ (or was it straight import)
|
||||
for managing external repositories in there, but all I can say is that I
|
||||
frown on this idea. I want an easy canonical list of packages I depend on to
|
||||
run emacs, and I want this documentation to be usable as-is. Enters el-get!
|
||||
|
||||
--------------------------------------
|
||||
(add-to-list 'load-path "~/.emacs.d/el-get/el-get")
|
||||
(require 'el-get)
|
||||
|
||||
;; local sources
|
||||
(setq __el-get-sources__
|
||||
'((:name magit
|
||||
:after (lambda () (global-set-key (kbd "C-x C-z") 'magit-status)))
|
||||
|
||||
(:name asciidoc
|
||||
:type elpa
|
||||
:after (lambda ()
|
||||
(autoload 'doc-mode "doc-mode" nil t)
|
||||
(add-to-list 'auto-mode-alist '("\\.adoc$" . doc-mode))
|
||||
(add-hook 'doc-mode-hook '(lambda ()
|
||||
(turn-on-auto-fill)
|
||||
(require 'asciidoc)))))
|
||||
|
||||
(:name lisppaste :type elpa)
|
||||
(:name dictionary-el :type apt-get)
|
||||
(:name emacs-goodies-el :type apt-get)))
|
||||
|
||||
(setq __my-packages__
|
||||
(append
|
||||
'(cssh el-get switch-window vkill google-maps nxhtml xcscope yasnippet)
|
||||
(mapcar 'el-get-source-name el-get-sources)))
|
||||
|
||||
__(el-get 'sync my-packages)__
|
||||
--------------------------------------
|
||||
|
||||
So now you have a pretty good documentation of the packages you want
|
||||
installed, where to get them, and how to install them. For the advanced
|
||||
methods (such as elpa or apt-get), you basically just need the package
|
||||
name. When relying on a bare git repository, you need to give some more
|
||||
information, such as the URL to clone and the build steps if any. Then also
|
||||
what features to require and maybe where to find the texinfo documentation
|
||||
of the package, for automatic inclusion into your local Info menu.
|
||||
|
||||
The good news is that not only you now have a solid readable description of
|
||||
all that in a central place, but this very description is all (el-get) needs
|
||||
to do its magic. This command will check that each and every package is
|
||||
installed on your system (in __el-get-dir__) and if that's not the case, it will
|
||||
actually install it. Then, it will__ init the packages__: that means caring
|
||||
about the load-path, the Info-directory-list (and dir texinfo menu building)
|
||||
the loading of the emacs-lisp files, and finally it will require the
|
||||
features.
|
||||
|
||||
== How to use it?
|
||||
|
||||
You see that +el-get-sources+ example up there? It __finishes with a single__
|
||||
__+(el-get)+ call__. That's it. It will 'install' new +sources+ on the list and
|
||||
only 'init' already installed ones.
|
||||
|
||||
The status of each package is tracked into +~/.emacs.d/el-get/__.status.el__+
|
||||
(by default) and can get the values +required+, +installed+ or +removed+.
|
||||
|
||||
=== Sync or async?
|
||||
|
||||
Most often you want +el-get-install+ and +el-get-build+ to stay out of the
|
||||
way and be 'asynchronous', so that you can continue using Emacs while your
|
||||
new package is getting ready. But imagine you're starting up Emacs after a
|
||||
+git pull+ on the other computer (after a commute, say), and there's some
|
||||
newer packages for this instance to consider installing.
|
||||
|
||||
Now you want a synchronous install, right?
|
||||
|
||||
So, by default +(el-get)+ is asynchronous, but you can ask for it to be
|
||||
sync, or to still be asynchronous but to wait until it finished before to
|
||||
give control back:
|
||||
|
||||
(el-get 'sync)
|
||||
(el-get 'wait)
|
||||
|
||||
You even get a progress report!
|
||||
|
||||
=== Sources
|
||||
|
||||
See the documentation of the +el-get-sources+ variable for details. __Please__
|
||||
__note that +el-get-sources+ is another source location for recipes, adding to__
|
||||
__your +el-get-recipe-path+.__
|
||||
|
||||
Note that you can also give a mix of +packages+ symbols, +inline recipes+
|
||||
and +source lists+ to +el-get+ as arguments, and completely __bypass__ the
|
||||
+el-get-sources+ variable.
|
||||
|
||||
(el-get 'sync 'package 'name 'list-of-packages-names-or-symbol)
|
||||
|
||||
It is still __recommended__ to +(setq el-get-sources '(list of packages))+ then
|
||||
use +(el-get 'sync)+, so that commands such as +el-get-update+ know which
|
||||
packages to update.
|
||||
|
||||
=== Recipes
|
||||
|
||||
Some sources are contributed to +el-get+ directly, so that you only have to
|
||||
put in the +el-get-sources+ the name of the package you want to
|
||||
install.
|
||||
|
||||
Should you need some __local specific setup__, you can do that by providing a
|
||||
partial sources **missing the +:type+ property**: your local properties will get
|
||||
merged into the recipes one.
|
||||
|
||||
Also, the variable __+el-get-recipe-path+__ allows you to maintain local recipes
|
||||
in case you either dislike the default one or are crafting some new one not
|
||||
commited to the main repository yet. But please do consider sending them
|
||||
over!
|
||||
|
||||
We do not intend to provide recipes for advanced types such as +apt-get+ and
|
||||
+elpa+ because there's so little to win here, and maintaining a package list
|
||||
would take too much time.
|
||||
|
||||
=== Package setup
|
||||
|
||||
The package setup can either go into the __+:after+__ function, or in a file
|
||||
named __+init-package.el+ in +el-get-user-package-directory+__. Any such named
|
||||
file will get automatically loaded by +el-get+ at +init+ time, if it exists.
|
||||
|
||||
=== Build Commands
|
||||
|
||||
__Avoid using +make install+__, which will usually move files into a
|
||||
"system location." In our case, you probably just want your package
|
||||
+foo+ to be all installed into +~/.emacs.d/el-get/foo+, right? So, no
|
||||
+make install+.
|
||||
|
||||
=== Byte Compiling
|
||||
|
||||
+el-get+ will 'byte compile' the elisp for the package when its source
|
||||
definition includes a +:compile+ property set to the list of files to byte
|
||||
compile (or to a single file), or all the +.el+ files found in the package
|
||||
when there's no +:build+ command.
|
||||
|
||||
=== Hooks
|
||||
|
||||
+el-get+ offers a variety of specific hooks (read the source), and two
|
||||
general purposes hooks facilities: +el-get-post-install-hooks+ and
|
||||
+el-get-post-update-hooks+, called with the package name as argument.
|
||||
|
||||
=== Some more commands?
|
||||
|
||||
Yes, ok.
|
||||
|
||||
M-x el-get-list-packages::
|
||||
|
||||
Opens a buffer listing all known packages (those for which you have a
|
||||
recipe). The listing includes the package name, its status (one of
|
||||
"available", "installed", "removed" or "required") and the package
|
||||
description. The description is a free form text and has not been
|
||||
provided for all recipes. Please also note that
|
||||
+el-get-emacswiki-refresh+ will create recipes omitting the description
|
||||
as of now.
|
||||
|
||||
M-x el-get-describe::
|
||||
|
||||
Prompt for a package name, with completion, then open an +*Help*+ window
|
||||
with details about the selected package. Those include current status,
|
||||
website, description, installation method, full recipe, and buttons to
|
||||
easily install, update or remove the package.
|
||||
|
||||
M-x el-get-install::
|
||||
+
|
||||
Will prompt for a package name, with completion, then install it. It will
|
||||
only propose packages that are not already +installed+. Any package that
|
||||
you have a recipe for is a candidate.
|
||||
+
|
||||
Please note that when installing a package that is not in your
|
||||
+el-get-sources+ or your +el-get+ call means that it will not be initialized
|
||||
for you automatically at emacs startup. You get a +WARNING+ message when
|
||||
that's the case.
|
||||
|
||||
M-x el-get-cd::
|
||||
|
||||
Will prompt for an +installed+ package name, with completion, then open
|
||||
its directory with dired.
|
||||
|
||||
M-x el-get-update::
|
||||
|
||||
Will prompt for an installed package name, with completion, then update
|
||||
it. This will run the +build+ commands and +init+ the package again.
|
||||
|
||||
M-x el-get-self-update::
|
||||
|
||||
Update only one package, +el-get+ itself.
|
||||
|
||||
M-x el-get-update-all::
|
||||
|
||||
Will update all packages used in +el-get-sources+. Beware that using
|
||||
this function can lead to hours of settings review: more often than not
|
||||
updating a package requires some adjustments to your setup. Updating
|
||||
all of them at once will require reviewing almost all your setup.
|
||||
|
||||
M-x el-get-remove::
|
||||
|
||||
Will prompt for an +installed+ package name, with completion, then
|
||||
remove it. Depending on the +type+ of the package, this often means
|
||||
simply deleting the directory where the source package lies. Sometime we
|
||||
have to use external tools instead (+apt-get+, e.g.). No effort is made
|
||||
to unload the features.
|
||||
|
||||
M-x el-get-find-recipe-file::
|
||||
|
||||
Will prompt for the name of a package, with completion, then +find-file+
|
||||
its +recipe+ file.
|
||||
|
||||
M-x el-get-make-recipes::
|
||||
|
||||
Will prompt for an existing directory where to output all your 'new'
|
||||
recipe files: one file for each entry in +el-get-sources+ that is not
|
||||
just a +symbol+ and that is not found anywhere in +el-get-recipe-path+.
|
||||
|
||||
M-x el-get-emacswiki-refresh::
|
||||
|
||||
Will launch a subprocess that connects to EmacsWiki and fetch from there
|
||||
the list of elisp scripts hosted. Then produce a recipe file per
|
||||
script, and store that in the given directory, which default to
|
||||
+~/.emacs.d/el-get/el-get/recipes/emacswiki/+ if you didn't change
|
||||
+el-get-dir+.
|
||||
|
||||
=== Useful functions
|
||||
|
||||
el-get-package-types-alist (statuses &rest types)::
|
||||
|
||||
Return an alist of package names that are of given types. Only consider
|
||||
packages whose status is `member' of STATUSES, which defaults to
|
||||
installed, required and removed.
|
||||
|
||||
ELISP> (el-get-package-types-alist "installed" 'cvs 'emacswiki)
|
||||
((emacs-w3m . cvs)
|
||||
(rect-mark . emacswiki)
|
||||
(icomplete+ . emacswiki)
|
||||
(php-mode-improved . emacswiki)
|
||||
(rainbow-delimiters . emacswiki)
|
||||
(goto-last-change . emacswiki)
|
||||
(emacs-goodies-el . cvs))
|
||||
|
||||
el-get-extra-packages (&rest packages)::
|
||||
|
||||
Return installed or required packages that are not in given package
|
||||
list.
|
||||
|
||||
ELISP> (el-get-extra-packages dim-packages)
|
||||
((verbiste "installed")
|
||||
(package "installed"))
|
||||
|
||||
== Extending it
|
||||
|
||||
Please see the documentation for the +el-get-methods+ and provide a patch!
|
||||
|
||||
Adding +bzr+ support for example was only about writing 2 functions, mostly
|
||||
using copy paste. Here's the patch: https://github.com/dimitri/el-get/commit/63e9018102bdeb7b6d9136db231adcd983087217#L0R437
|
||||
|
||||
== Upgrade Notes
|
||||
|
||||
=== Upgrading to 3.1
|
||||
|
||||
A change has been included so that +el-get-sources+ is now __only another__
|
||||
__source for recipes__, and +(el-get '...)+ will now only install and initialize
|
||||
known "required" and "installed" packages.
|
||||
|
||||
The documentation has been updated to detail the new setup.
|
||||
|
||||
If you have packages that have been installed in the past but you no longer
|
||||
want in your setup, here's how to get them out of the way:
|
||||
|
||||
M-: (el-get-save-package-status "package-name-here" "removed")
|
||||
|
||||
Please review documentation section 'Advanced setup with local recipes'.
|
||||
143
Zim/Utils/emacs/el-get/emacsWiki.txt
Normal file
143
Zim/Utils/emacs/el-get/emacsWiki.txt
Normal file
@@ -0,0 +1,143 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-01-07T15:04:30+08:00
|
||||
|
||||
====== emacsWiki ======
|
||||
Created Saturday 07 January 2012
|
||||
http://www.emacswiki.org/emacs/el-get#toc3
|
||||
|
||||
===== Contenus =====
|
||||
|
||||
Emacs Lisp get (Fetch, Install, Update, etc)
|
||||
Why el-get?
|
||||
How is el-get different from ELPA?
|
||||
Why have both?
|
||||
Social Packaging
|
||||
el-get and emacswiki
|
||||
emacs-kicker
|
||||
|
||||
===== Emacs Lisp get (Fetch, Install, Update, etc) =====
|
||||
El-get is tool that allows downloading **external scripts/extensions **for Emacs, __install __them for you, knows how to __update__ them and __init__ them, care about **load-path** and **Info-directory-list**, **byte-compile** what should be, manages **autoloads**, etc.
|
||||
JohnWiegley once said “el-get seems like it’s the Great Unifier of Emacs package systems and package repositories”
|
||||
Think apt-get for Emacs, and check out el-get.
|
||||
|
||||
===== Why el-get? =====
|
||||
Of course, my emacs setup is managed in a private git repository. Some people on #emacs are using git submodules (or was it straight import) for managing external repositories in there, but all I can say is that I frown on this idea. I want an easy **canonical list of packages **I depend on to run Emacs, and I want this documentation to be usable as-is. Enters el-get!
|
||||
|
||||
The following is an example of how to use it in your __.emacs__, you could also consider starting from the **emacs-kicker**.
|
||||
|
||||
(add-to-list 'load-path "~/.emacs.d/el-get/el-get")
|
||||
|
||||
(unless (__require 'el-get nil t__)
|
||||
(url-retrieve
|
||||
"https://github.com/dimitri/el-get/raw/master/el-get-install.el"
|
||||
(lambda (s)
|
||||
(end-of-buffer)
|
||||
(eval-print-last-sexp))))
|
||||
|
||||
;; now either el-get is `require'd __already__, or have been `load'ed by the
|
||||
;; el-get installer.
|
||||
(setq
|
||||
** el-get-sources**
|
||||
'(el-get ; el-get is self-hosting
|
||||
escreen ; screen for emacs, C-\ C-h
|
||||
php-mode-improved ; if you're into php...
|
||||
switch-window ; takes over C-x o
|
||||
auto-complete ; complete as you type with overlays
|
||||
zencoding-mode ; http://www.emacswiki.org/emacs/ZenCoding
|
||||
|
||||
(:name buffer-move ; have to add your own keys
|
||||
:after (lambda ()
|
||||
(global-set-key (kbd "<C-S-up>") 'buf-move-up)
|
||||
(global-set-key (kbd "<C-S-down>") 'buf-move-down)
|
||||
(global-set-key (kbd "<C-S-left>") 'buf-move-left)
|
||||
(global-set-key (kbd "<C-S-right>") 'buf-move-right)))
|
||||
|
||||
(:name smex ; a better (ido like) M-x
|
||||
:after (lambda ()
|
||||
(setq smex-save-file "~/.emacs.d/.smex-items")
|
||||
(global-set-key (kbd "M-x") 'smex)
|
||||
(global-set-key (kbd "M-X") 'smex-major-mode-commands)))
|
||||
|
||||
(:name magit ; __git__ meet emacs, and a binding
|
||||
:after (lambda ()
|
||||
(global-set-key (kbd "C-x C-z") 'magit-status)))
|
||||
|
||||
(:name goto-last-change ; move pointer back to last change
|
||||
:after (lambda ()
|
||||
;; when using AZERTY keyboard, consider C-x C-_
|
||||
(global-set-key (kbd "C-x C-/") 'goto-last-change)))))
|
||||
|
||||
(unless (string-match "**apple-darwin**" system-configuration)
|
||||
(loop for p in '(color-theme ; nice looking emacs
|
||||
color-theme-tango ; check out color-theme-solarized
|
||||
)
|
||||
do (add-to-list 'el-get-sources p)))
|
||||
|
||||
;;
|
||||
;; Some recipes require __extra tools__ to be installed
|
||||
;;
|
||||
;; Note: el-get-install requires **git**, so we know we have at least that.
|
||||
;;
|
||||
(when (el-get-executable-find "cvs")
|
||||
(add-to-list 'el-get-sources 'emacs-goodies-el)) ; the debian addons for emacs
|
||||
|
||||
(when (el-get-executable-find "svn")
|
||||
(loop for p in '(psvn ; M-x svn-status
|
||||
yasnippet ; powerful snippet mode
|
||||
)
|
||||
do (add-to-list 'el-get-sources p)))
|
||||
|
||||
;; install new packages and init already installed packages
|
||||
(el-get 'sync)
|
||||
|
||||
So now you have a pretty good documentation of the packages__ you want installed__, **where** to get them, and **how** to install them. For the advanced methods (such as **ELPA or apt-get**), you basically just need the package name. When relying on a bare git repository, you need to give some more information, such as the **URL** to clone and the build steps if any. Then also what** features** to require and maybe where to find the **texinfo **documentation of the package, for automatic inclusion into your local Info menu.
|
||||
|
||||
The good news is that not only you now have a solid readable description of __all that in a central place__, but this very description is all (el-get) needs to do its magic. This command will check that each and every package is installed on your system (in el-get-dir) and if that’s not the case, it will actually install it. Then, it will__ init __the packages: that means caring about the** load-path**, the Info-directory-list (and dir texinfo menu building) the loading of the **EmacsLisp files**, and finally it will **require** the features.
|
||||
|
||||
===== How is el-get different from ELPA? =====
|
||||
ELPA is the** Emacs Lisp Package Archive** and is also known as__ package.el__, to be included in Emacs 24. This allows emacs list extension authors to package their work. That means they have to follow some guidelines and format their contribution, then propose it for upload.
|
||||
|
||||
This requires licence checks (good) and for the new official ELPA mirror it even requires dead-tree papers exchange and contracts and copyright assignments, I believe.
|
||||
|
||||
===== Why have both? =====
|
||||
While ELPA is a great thing to have, it’s so easy to find some high quality Emacs extension out there that are not part of the offer. Either authors are not interrested into uploading to ELPA, or they don’t know how to properly package for it (it’s only simple for single file extensions, see).
|
||||
|
||||
So el-get is a pragmatic answer here. It’s there because it so happens that I don’t depend only on emacs extensions that are available with Emacs itself, in my distribution site-lisp and in ELPA. I need some more, and I don’t need it to be complex to find it, fetch it, init it and use it.
|
||||
|
||||
Of course I could try and package any extension I find I need and submit it to ELPA, but really, to do that nicely I’d need to contact the extension author (upstream) for him to accept my patch, and then consider a fork.
|
||||
|
||||
===== Social Packaging =====
|
||||
With el-get I propose distributed packaging if you will. Let’s have a look at __two recipes(菜单)__ here. First, the el-get one itself:
|
||||
|
||||
(:name el-get
|
||||
:type git
|
||||
:url "git://github.com/dimitri/el-get.git"
|
||||
:features el-get
|
||||
:compile "el-get.el")
|
||||
|
||||
Then a much more complex one, the bbdb one:
|
||||
|
||||
(:name bbdb
|
||||
:type git
|
||||
:url "git://github.com/barak/BBDB.git"
|
||||
:load-path ("./lisp" "./bits")
|
||||
:build ("./configure" "make autoloads" "make")
|
||||
:build/darwin ("./configure --with-emacs=/Applications/Emacs.app/Contents/MacOS/Emacs" "make autoloads" "make")
|
||||
:features bbdb
|
||||
:after (lambda () (bbdb-initialize))
|
||||
:info "texinfo")
|
||||
|
||||
The idea is that it’s __much simpler __to just come up with a recipe like this than to patch existing code and upload it to ELPA. And anybody can share their recipes very easily, with or without proposing them to me, even if I very much like to add some more in the official el-get list.
|
||||
|
||||
As a user, you don’t even need to twiddle with recipes, mostly, because we **already have them** for you. What you do instead is __list them in el-get-sources__.
|
||||
|
||||
===== el-get and emacswiki =====
|
||||
Just run **M-x el-get-emacswiki-refresh** and you will have a local cache of recipes for all scripts available in EmacsWiki. Now you can M-x el-get-install any of them, it’s a single command away.
|
||||
|
||||
===== emacs-kicker =====
|
||||
Following up on the very popular **emacs-starter-kit**, I’m now proposing the emacs-kicker. It’s about a very simple __.emacs__ file using el-get. It comes with an arbitrary selection of packages that make your life easier, and with some medium advanced settings. The idea is to, well, kick start you.
|
||||
https://github.com/dimitri/emacs-kicker
|
||||
|
||||
If you want to try it without installing it it’s very easy to do so. Just clone the git repository then start an Emacs that will use this. For example that could be, using the excellent Emacs For MacOSX:
|
||||
$ /Applications/Emacs.app/Contents/MacOS/Emacs -Q -l init.el
|
||||
203
Zim/Utils/emacs/el-get/配置.txt
Normal file
203
Zim/Utils/emacs/el-get/配置.txt
Normal file
@@ -0,0 +1,203 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-01-07T16:25:55+08:00
|
||||
|
||||
====== 配置 ======
|
||||
Created Saturday 07 January 2012
|
||||
|
||||
**El Get Sources**: Show Value
|
||||
State: HIDDEN, invoke "Show" in the previous line to show.
|
||||
|
||||
Each entry is a PLIST where the following properties are
|
||||
supported.
|
||||
|
||||
If your property list is missing the :type property, then it's
|
||||
__merged__ with the recipe one, so that you can** override **any
|
||||
definition provided by `el-get' recipes locally.
|
||||
|
||||
:name
|
||||
|
||||
The name of the package. It can be different from the name of
|
||||
the directory where the package is stored (after a `git
|
||||
clone' for example, in which case a symlink will be created.
|
||||
|
||||
:depends
|
||||
|
||||
A single package name, or a list of package names, on which
|
||||
the package depends. All of a packages dependencies will be
|
||||
installed before the package is installed.
|
||||
|
||||
:pkgname
|
||||
|
||||
The name of the package for the __underlying package management__
|
||||
__system__ (`apt-get', `fink' or `**pacman**', also supported by
|
||||
`emacsmirror'), which can be different from the Emacs package
|
||||
name.
|
||||
|
||||
:type
|
||||
|
||||
The type of the package, currently el-get offers support for
|
||||
`apt-get', `elpa', `git', `emacsmirror', `git-svn', `bzr' `svn',
|
||||
`cvs', `darcs', `fink', `ftp', `emacswiki', `http-tar', __`pacman'__,
|
||||
`hg' and `http'. You can easily support your own types here,
|
||||
see the variable `el-get-methods'.
|
||||
|
||||
:branch
|
||||
|
||||
Which branch to fetch when using `git'. Also supported in
|
||||
the installer in `el-get-install'.
|
||||
|
||||
:url
|
||||
|
||||
Where to fetch the package, only meaningful for `git' and `http' types.
|
||||
|
||||
:build
|
||||
|
||||
Your build recipe, a list.
|
||||
|
||||
A recipe R whose `car' is not a string will be replaced
|
||||
by (eval R).
|
||||
|
||||
Then, each element of the recipe will be interpreted as
|
||||
a command:
|
||||
|
||||
* If the element is a string, it will be interpreted directly
|
||||
by the shell.
|
||||
|
||||
* Otherwise, if it is a list, any list sub-elements will be
|
||||
recursively "flattened" (see `el-get-flatten'). The
|
||||
resulting strings will be interpreted as individual shell
|
||||
arguments, appropriately quoted.
|
||||
|
||||
:build/system-type
|
||||
|
||||
Your specific build recipe for a given `system-type' gets
|
||||
there and looks like :build.
|
||||
|
||||
:load-path
|
||||
|
||||
A directory or a list of directories you want `el-get' to add
|
||||
to your **`load-path'**. Those directories are__ relative to__ where
|
||||
the package gets installed.
|
||||
|
||||
:compile
|
||||
|
||||
Allow to restrict what to byte-compile: by default, `el-get'
|
||||
will compile __all elisp files in the :load-path directories__,
|
||||
unless a :build command exists for the package source. Given
|
||||
a :compile property, `el-get' will only byte-compile those
|
||||
**given files**, directories or __filename-regexpes__ in the property
|
||||
value. This property can be a `listp' or a `stringp' if you
|
||||
want to compile only one of those.
|
||||
|
||||
:info
|
||||
|
||||
This string allows you to setup a __directory__ where to find a
|
||||
'package.info' file, or a path/to/whatever.info file. It will
|
||||
even run `ginstall-info' for you to create the `dir' entry so
|
||||
that C-h i will be able to list the newly installed
|
||||
documentation. Note that you might need to kill (C-x k) your
|
||||
info buffer then C-h i again to be able to see the new menu
|
||||
entry.
|
||||
|
||||
:load
|
||||
|
||||
List of files to load, or a single file to load after having
|
||||
installed the source but __before__ `require'ing its features.
|
||||
|
||||
:features
|
||||
|
||||
List of features el-get will __`require'__ for you.
|
||||
|
||||
:autoloads
|
||||
|
||||
Control whether el-get should generate autoloads for this
|
||||
package. Setting this to nil prevents el-get from generating
|
||||
autoloads for the package. __Default is t__. Setting this to a
|
||||
string or a list of string will load the named autoload
|
||||
files.
|
||||
|
||||
:library
|
||||
|
||||
When **using :after but not using :features, **:library allows to
|
||||
set the library against which to register the :after function
|
||||
against `eval-after-load'. It defaults to either :pkgname
|
||||
or :package, in this order. See also `el-get-eval-after-load'.
|
||||
|
||||
:options
|
||||
|
||||
Currently used by http-tar and cvs support.
|
||||
|
||||
When using http-tar, it allows you to give the tar options
|
||||
you want to use. Typically would be "xzf", but you might
|
||||
want to choose "xjf" for handling .tar.bz files e.g.
|
||||
|
||||
When using CVS, when it's set to "login", `el-get' will
|
||||
first issue a `cvs login' against the server, asking you
|
||||
interactively (in the minibuffer) any password you might to
|
||||
enter, and only then it will run the `cvs checkout' command.
|
||||
|
||||
:module
|
||||
|
||||
Currently only used by the `cvs' support, allow you to
|
||||
configure the module you want to checkout in the given URL.
|
||||
|
||||
:repo
|
||||
|
||||
Only used by the `elpa' support, a cons cell with the
|
||||
form (NAME . URL), as in `package-archives'. If the package
|
||||
source only specifies a URL, the URL will be used for NAME as
|
||||
well.
|
||||
|
||||
:prepare
|
||||
|
||||
Intended for use __from recipes__, it will run once both the
|
||||
**`Info-directory-list' and the**__ `load-path' __**variables have been**
|
||||
** taken care of**, but before any further action from
|
||||
`el-get-init'.
|
||||
|
||||
:before
|
||||
|
||||
A pre-init function to run once__ before__** `el-get-init' calls**
|
||||
** `load' and `require'. ** It gets to run with `load-path'
|
||||
already set, and after :prepare has been called. It's__ not__
|
||||
__ intended__ for use from recipes.
|
||||
|
||||
:post-init
|
||||
|
||||
Intended for use from recipes. This function is registered
|
||||
for __`eval-after-load'__ against the recipe library by
|
||||
`el-get-init' once the **:load and :features** have been setup.
|
||||
|
||||
:after
|
||||
|
||||
A function to register for `eval-after-load' against the
|
||||
recipe library, after :post-init, and __after per-package__
|
||||
__ user-init-file (see `el-get-user-package-directory'). __ That's not
|
||||
intended for recipe use.
|
||||
|
||||
:lazy
|
||||
|
||||
Default to nil. Allows to override `el-get-is-lazy' per
|
||||
package.
|
||||
|
||||
:localname
|
||||
|
||||
Currently only used by both `http' and `ftp' supports, allows
|
||||
to specify the target name of the downloaded file.
|
||||
|
||||
This option is useful if the package should be retrieved using
|
||||
a presentation interface (such as as web SCM tool).
|
||||
|
||||
For example, destination should be set to "package.el" if
|
||||
the package url has the following scheme:
|
||||
|
||||
"http://www.example.com/show-as-text?file=path/package.el"
|
||||
|
||||
:website
|
||||
|
||||
The website of the project.
|
||||
|
||||
:description
|
||||
|
||||
A short description of the project.
|
||||
Reference in New Issue
Block a user