Emacs and Lisp wiki
Table of Contents
- 1. 我的emacs学习笔记
[3/4]
- 1.1. 每次多个执行shell-command或者async-shell-command都会问是否需要重新开一个buffer shell command
- 1.2. DONE 自己把一些emacs文档制作成为mobi格式方便kindle阅读。
- 1.3. DONE 对emacs的kill-ring的理解
- 1.4. DONE 使用org-mode来管理GTD blog org mode
- 1.5. emacs下关的一些学习资料
- 1.6. emacs中判断系统的版本
- 1.7. eshell
[0/1]
eshell - 1.8. C/C++ IDE ide C C
- 1.9. 闹钟 alarm
- 1.10. 使用过tramp编辑远程文件后eshell的问题
- 1.11. 重新安装helm helm
- 1.12. 在emacs中使用zsh
- 1.13. company-mode自动补全
- 1.14. emacsclient
- 1.15. cua-mode
- 1.16. TODO cscope cscope
- 2. 我的lisp学习笔记
- 3. 我的emacs习惯
- 4. config irony-mode
- 5. config ycmd
- 6. elpy for python
- 7. 使用emacs加密文件
- 8. use of markdown-mode
- 9. ssh-terminal in emacs
- 10. hex-mode
- 11. tramp
- 12. find and grep
- 13. DONE lexical and dynamic scoping box's blog 词法作用域和动态作用域
- 14. org tangle
- 15. org exec code block
- 16. org exports
- 17. theme
- 18. elisp check if string is empty
- 19. emacs python parser
- 20. 使用workgroup来完善我的工作流
- 21. 使用ditaa
- 22. emacs对齐
- 23. 正则表达式
- 24. 使用emacs来查看python代码
- 25. replace-regexp中输入换行newline
- 26. 结合helm-ag来进行multi-edit
- 27. ibuffer
- 28. 写一个判断是否有
universal-argument
的函数 - 29. 读写文件
- 30. convert string to list object
- 31. artist mode
- 32. org-mode代码块
- 33. ivy和helm的写法
- 34. emacs把行号添加到文件中
- 35. org-mode publish时太慢的解决办法
- 36. bookmark plus
- 37. elisp函数根据有没有按
C-u
来走不同的流程 - 38. 启动加速
- 39. 我的
cc-mode
- 40. use exwm
- 41. 在elisp函数中使用
C-u
- 42. cscope和gtags不包括某些目录
- 43. 为org-mode自动添加目录
- 44. org-mode tangle整个head
- 45. 直接查看info文件
- 46. 在elisp中模拟按键的输入
- 47. emacs中的长table导出pdf的问题
- 48. org-mode中以root用户执行命令
- 49. eshell中定义alias
- 50. 在emacs中执行shell脚本
1 我的emacs学习笔记 [3/4]
1.1 每次多个执行shell-command或者async-shell-command都会问是否需要重新开一个buffer shell command
其实就是没次默认开的都是\verb+*Async Shell Command*+这个buffer-name。 我自己这样写,每次生成peng-async-shell-command-output-和一个随机数的 buffer。避免每次都问我。见下:
不完美的
- 每次使用完后,这些buffer貌似都没有被关闭,还是有可能重复。应该还有 其它解决办法的。
(defun peng-async-shell-command (COM) "Run the shell command asynchronize Don't ask me whether to create a new buffer just because the default buffer is used. For this reason, I create a random output buffer rather than the default one every time I launch a shell command. The COM is what you want to excute. It MUST be a string." (save-window-excursion (save-excursion (let ((RANDOM-NUM (message "%s" (random 10000)))) (async-shell-command COM (get-buffer-create (concat "peng-async-shell-command-output-" RANDOM-NUM))) ))))
1.2 DONE 自己把一些emacs文档制作成为mobi格式方便kindle阅读。
State "DONE" from "TODO"
使用别人写的脚本texi2mobi。调用了makeinfo,dbtoepub,kindlegen.
参考的这里,https://kanru.info/blog/archives/2010/11/18/convert-texinfo-to-mobi/
Convert Texinfo to MOBI
Thu, 18 Nov 2010 18:36:26 +0800
GNU software often comes with a large set of documents in texinfo format, which can be typesetted to a real book. For example the Gnus Manual has over 500 pages, full of fun and humor. Having a mobi version on my Kindle would be quite handy.
Gnus Manual on Kindle This work involves two parts, first is to convert texinfo to docbook, second is to convert docbook to mobi. In fact the second part could be applied on all docbooks.
Convert Texinfo to DocBook
Texinfo has native support of converting texi file to docbook format:
makeinfo –docbook gnus.texi
will output gnus.xml.
If the texi includes some other texis the the makeinfo command somehow doesn't strip the @setfilename macro from the included file, so cluttered output. Use the following sed script to fix it:
sed -i -e 's#<para><setfilename>.*</setfilename></para>##' gnus.xml
Convert DocBook to MOBI
Since DocBook 1.74, they included a ruby script dbtoepub to convert xml file to epub format. Then we can use kindlegen or calibre to convert epub to mobi.
However the docbook xsl produces nested navPoints and <dl> formated TOC. Both aren't handled very well by Kindle.
So I created a customized layer above the docbook.xsl for mobi creation. This mobi.xsl will flatten the navPoints and use <ul> formated TOC. The output mobi looked very nice on my Kindle.
All in one script
Download the texi2mobi.tar.gz, which contains the script and the style sheet used to create mobi friendly epub.
To use this script you have to install makeinfo, dbtoepub and kindlegen. I use kindlegen here because it creates better mobi at present.
apt-get install texinfo
apt-get install dbtoepub
kindlegen could be downloaded form Amazon.
Untar the tarball then use
texi2mobi.sh TEXINFO-FILE
Create your mobi version! Have fun ☺
使用an-introduction-to-programming-in-emacs-lisp做实验。安装好之后,刚 开始出现一点bug,用makeinfo制作不出来xml。然后我修改了一下texi中的源码 的前面设置部分,感觉应该是注释掉其中一些图片起作用了。然后makeinfo步骤 就没有问题了。然后直接使用其提供的脚本就能进行转换了。
流程是:makeinfo转换成xml。dbtoepub转换程epub。kindlegen转换成mobi。
制作过程中发现,使用makeinfo失败的时候,把texi文件开头的setfilename 一行注释掉就行了。makeinfo能成功,则脚本就基本不会出现问题。
1.3 DONE 对emacs的kill-ring的理解
- State "DONE" from ""
就是kill-ring和kill-ring-yank-pointer两个symbol拉。symbol其实就是指针的 结构体。有指向函数的指针,有指向变量的指针,还有指向变量名字,变量 properties的指针。这两个symbol都是指向变量的指针这在起作用。
1.4 DONE 使用org-mode来管理GTD blog org mode
State "DONE" from "TODO"
昨天一天配置以后,基本实现了用org-mode来管理GTD的想法。使用 org-capture随时抓取想法。用org-agenda查看所有想法和代办事项。配合org-capture使用,可以随时记录我的想法,待做的项目了。把\C-c c 绑定到org-capture上。定义一些org-capture-template。可以快速抓取我 自己的想法到指定的文件中。
(define-key global-map (kbd "C-c c") 'org-capture) (setq org-capture-templates '(("n" "News" entry (file+datetree (concat GTD "inbox.org")) "* TODO %?\n %T") ("t" "Tasks" entry (file+datetree (concat GTD "task.org")) "* TODO %?\n %T") ("r" "Notes" entry (file+datetree (concat GTD "note.org")) "* TODO %?\n %T") ("p" "Project" entry (file+headline (concat GTD "project.org") "Projects") "* %?\n") ("a" "Account" table-line (file+headline (concat GTD "account.org.gpg") "Web accounts") "|") ("k" "test" entry (file+datetree "/tmp/test.org" "Tasks") "* TODO %? \n %T") ))
使用org-agenda来管理我GTD目录下所有的文档。设置变量 org-agenda-files为GTD目录。可以使得该目录下所有的org文档对 org-agenda都可见。把org-refile-targets也设置为这个目录。就可以该目 录下自由refile。非常方便。
(setq org-agenda-files '("~/gtd/")) (setq org-refile-targets (quote ((nil :maxlevel . 9) (org-agenda-files :maxlevel . 9))))
在设置这些变量的时候,绑定到org-mode-hook有时候不起作用。我认为是 在emacs刚启动没有打开org文件的时候。这个hook没有被调用。如果绑定在 这个hook上。变量没有被设置。这时候org-agenda就没用了。最后测试出来。 我把这些变量设置绑定到了org-load-hook上面了。同时设置了 org-todo-keywords这个变量。可以自定义事件不同的状态。
(defun peng-org-load () (setq org-directory "~/gtd/") (setq org-agenda-files '("~/gtd/")) (setq org-todo-keywords '((sequence "TODO(t!)" "NEXT(n)" "WAITTING(w)" "SOMEDAY(s)" "|" "DONE(d@/!)" "ABORT(a@/!)"))) ) (add-hook 'org-load-hook 'peng-org-load)
1.5 emacs下关的一些学习资料
看tuhdo的emacs mini manual,里面有写 关于gtags+semantic , 目前最快的方法
国外的先不算 什么 planet emacs blog 等去处确实不错
个人总结学习 emacs 的去处, google 这种通用搜索的就不说了. 大家还有不错的欢迎分享.
国内的质量确实不高, 不过对英文水平要求低:
- emacs@smth 虽然更新不多, 这里出现过不少国内 emacs 圈里厉害的角色, 包括 yas 和 ace-jump 作者等
- 以前有个 emacser.com , 有蛮久没更新了, 个人看老的文章质量也一般般, 不过比百度随便搜出来的好点.
国外(或者准确的说英文圈)
- emacswiki
- planet emacsen: emacs blog 3. reddit 的 emacs tag
个别单枪匹马但是至少最近更新还多的; 通常也会出现在上面的 2 和 3 里,
. 台湾的李杀(人家主要用英文) http://ergoemacs.org/emacs/ . endlessparentheses http://www.endlessparentheses.com . Sacha Chua 貌似是东南亚的小美女 http://sachachua.com/blog
1.6 emacs中判断系统的版本
;; check OS type (cond ((string-equal system-type "windows-nt") ; Microsoft Windows (progn (message "Microsoft Windows") ) ) ((string-equal system-type "darwin") ; Mac OS X (progn (message "Mac OS X") ) ) ((string-equal system-type "gnu/linux") ; linux (progn (message "Linux") ) ) )
1.7 eshell [0/1]
eshell
1.7.1 进入之前进入过的文件夹
`cd ='可以查看历史文件夹。
然后使用`cd -number'就能进入对应的目录。
使用`cd =REGEXP'可以使用正则表达式。
1.7.2 不使用eshell中用lisp编译的命令
使用lisp编译的版本效率实在太低。在info中看到可以使用*ls来调用系统原始的合令。其它也一样。 eshell#Built-ins
1.7.3 使用jobs控制eemacs中的子进程
使用jobs可以查看emacs中的所有子进程。kill可以子进程。kill不仅可以接进程id,还可以接`project object'。
其中的`project object'可以通过`C-c M-i'查看然后返回。调用的是`eshell-insert-process'函数。我就是使用这个方法干掉了一个tramp的子进程。
1.7.4 一些有用的快捷键
keybinding | description |
---|---|
C-c M-b | 插入buffer名称 |
C-c M-i | 插入子进程名称 |
C-c M-v | 插入环境变量名 |
C-c M-v | 若一些程序不能正确处理带缓冲的输入,则按这个键序列切换? |
1.7.5 在eshell中使用 **
代替 *
eshell在只使用一个 *
的时候会触发自动补全。最后发现使用 **
可以达到原来一个 *
的效果。
最后发现不是这个原因 :可能是company-mode的原因。
1.7.6 Eshell中执行bash脚本
比如执行下面的代码:
for i in `ls`;do echo $i;done
现在我的解决办法是使用`multi-term'开一个`term'在里面执行。
需要了解一下`eshell'中的变量这些才可以。
1.7.7 TODO 一些期待改进的功能 [0/7]
[ ]
grep可以显示颜色[ ]
*
不再自动触发补全。这个是因为`company-mode'[ ]
循环还不是很会
$ for file in *.org { echo "Upcasing: $file" mv $file $file(:U) } I told you the modifiers from the previous section would come in handy. I find it interesting to note that *.org gives this for loop a list to iterate over, but if there is more than one argument, a list is created, as in: $ for i in 1 2 3 4 {echo $i} Passing more than one list flattens them into one list, so the following works as you expect: $ for file in emacs* zsh* { ... }
[ ]
eshell中的`predicate'和`modifier'这些比较有用。可以看下[ ]
company-mode有时有用,有时又没有[ ]
命令补全<TAB>不是很好。不想直接因输入目录名就进入目录。不想补全目录。[ ]
使用`helm-esh-pcomplete'还有一点问题:在`~'下`ls'然后`TAB'后直接输入是不行的。必须先输入前几个字母才行。还希望大小写不敏感。
1.8 C/C++ IDE ide C C
1.8.1 使用ecb
可以更加方便地浏览代码。在`init.el'中将(require 'init-ecb)打开就可以使用。我使用过的函数大概是`ecb-expand-method-nodes'和`ecb-expand-directory-*'和`ecb-toggle-layout'这些。还没有对其进行仔细地配置,以后用到再说。
1.8.2 TODO cedet
emacs24中应该是已经集成了。还没有使用到。
1.9 闹钟 alarm
在mac中,使用的是`terminal-notifier'做为输出。
我修改了一下`alarm.el',如下:
;;; alarm.el --- ;; ;; Filename: alarm.el ;; ;; Description: 从网上下载的。我修改了一下。在mac上需要安装`terminal-notifier'来产生alarm ;; ;; Author: pengpengxp ;; Email: pengpengxppri@gmail.com ;; Created: 二 3 17 20:43:28 2015 (+0800) ;; Version: ;; Last-Updated: ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;; Code: (defvar peng-alarm-clock-timer nil "Keep timer so that the user can cancel the alarm.") (defun peng-alarm-clock-message (text) "The actual alarm action. Argument TEXT alarm message." (shell-command (format "terminal-notifier -sound default -message \"%s\" " text))) ;; (defun peng-alarm-clock () ;; "Set an alarm. ;; The time format is the same accepted by `run-at-time'. For ;; example \"11:30am\"." ;; (interactive) ;; (let ((time (read-string "Time(example, 11:30am): ")) ;; (text (read-string "Message: "))) ;; (setq peng-alarm-clock-timer (run-at-time time nil 'peng-alarm-clock-message text)))) (defun peng-alarm-clock () "Set an alarm. The time format is the same accepted by `run-at-time'. For example \"11:30am\"." (interactive) (let ((time (read-from-minibuffer "Time(example, 11:30am): " (time-stamp-string "%02H:%02M%#p"))) (text (read-string "Message: "))) (setq peng-alarm-clock-timer (run-at-time time nil 'peng-alarm-clock-message text)))) (defun peng-alarm-clock-cancel () "Cancel the alarm clock." (interactive) (cancel-timer peng-alarm-clock-timer)) (provide 'alarm) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; alarm.el ends here
只是做了最简单的功能。先凑合着使用吧。
1.10 使用过tramp编辑远程文件后eshell的问题
使用过tramp编辑远程文件以后,eshell每次切换目录时候都自动登陆,然后就一直等待或是手动`C-g'。其实可以在`~/.emacs.d/eshell/lastdir'中将以`/ssh'和`/scp'这些开头的目录删掉就可以了。这些都是默认被记录下来了。
还有没有更好一点的办法?
1.11 重新安装helm helm
需要在helm-master中使用make来编译一下才行。这里需要用到`cask'。到现在不知道是干什么的。
中途在`cl-lib'的错。没弄懂。
1.12 在emacs中使用zsh
可以通过使用`sudo chsh -u pengpengxp -s /bin/zsh'设置默认shell为zsh。
在emacs中可以通过multi-term来使用zsh。
但是在emacs中zsh的提示符会默认有`4m'这些乱七八糟的字符。可以这样解决:
(setq system-uses-terminfo nil)
然后进入Emacs.app中的`/Contents/Resources/etc/e/'目录。按照里面的`README'执行`tic -o ../ ./xterm-color.ti'。
就OK啦。
1.13 company-mode自动补全
1.13.1 基本内容
company-mode可以有许多的backends。可以查看`company-backends'。
backends可以单独调用,比如可以在输入了`/'后调用`company-files'就可以进行补全文件名了。
`company-backends'是按照顺序调用的。原始的值为:
(company-bbdb company-nxml company-semantic company-clang company-xcode company-cmake (company-dabbrev-code company-gtags company-etags company-keywords) company-oddmuse company-files company-eclim company-dabbrev
补全不合适时,可以使用`company-other-backend'来调用下一个`backend'。
backend可以分组。上面原始的就有一个分组,中间的那个:
(company-dabbrev-code company-gtags company-etags company-keywords)
可以自己定义分组来用。
1.13.2 TODO 不同的mode使用不同的backend
1.14 emacsclient
默认是开启GUI,使用`-nw'参数就可以在当前的tty下访问了。
mac下的emacsclient是系统默认的emacs22的。我的emacs24不能使用。不过从源码安装emacs后,会在Emacs.app中的`Contents/MacOS/bin'下生成对应的emacsclient。拷贝出来使用它就行啦 :-)
1.15 cua-mode
cua-mode下可以用以下命令进行列操作:
直接输入字符 | 在每行前(或后)都插入这个字符 |
[M-a] | 将rect中的文字左对齐 |
[M-b] | 用空格(tabs或者spaces)替换所有rect中的字符 |
[M-c] | 去掉所有行左侧的空格 |
[M-f] | 用单个字符替换所有rect中的字符(提示输入一个字符) |
[M-i] | 对每行中第一个找到的数字进行加1操作(自动把0x开头的当作十六进制数字) |
[M-k] | 剪切rect |
[M-l] | 把rect中的内容全部转换为小写 |
[M-m] | 拷贝rect |
[M-n] | 用一串自增的数字替换rect中的每一行(这个功能可以用来给每行编号) |
[M-o] | rect的内容右移,选中的rect用空格填充 |
[M-r] | 用字符串替换符满足正则表达式的字符串 |
[M-R] | 上下反转 |
[M-s] | 把rect中的每一行替换为一个字符串(提示输入) |
[M-t] | 把rect整个替换为一个字符串(提示输入) |
[M-u] | 把rect中的内容全部转换为大写 |
[M-|] | 对rect执行一个shell命令 |
1.16 TODO cscope cscope
cscope是一个独立的程序,也可以在emacs中使用。安装过程不说了。下载放入加载就行了。
emacs中加入对应的.el文件后,有一个cscope-indexer的程序需要从源文件中取出来放到`PATH'中并设置为可执行。这是为cscope制做index用的。
说下怎么使用:
默认是的快捷键都是绑定到 C-c s 的前缀上面,如果嫌麻烦的话可以自己更改 快捷键绑定。这是默认的用于查找的键绑定: C-c s s Find symbol. C-c s d Find global definition. C-c s g Find global definition (alternate binding). C-c s G Find global definition without prompting. C-c s c Find functions calling a function. C-c s C Find called functions (list functions called from a function). C-c s t Find text string. C-c s e Find egrep pattern. C-c s f Find a file. C-c s i Find files #including a file. 下面是在搜索到的结果之间切换用的快捷键: C-c s b Display *cscope* buffer. C-c s B Auto display *cscope* buffer toggle. C-c s n Next symbol. C-c s N Next file. C-c s p Previous symbol. C-c s P Previous file. C-c s u Pop mark. 更详细的使用说明请参见 xcscope.el 文件头部的注释。
如果只在一个目录下用,貌似可以直接使用,如果不行,使用`C-c s I'重新做下索引。这时就会调用`cscope-indexer'这个脚本。之前需要配置好。
一般就"C-c s s"就行了。然后`C-c s B'可以设置每次查询的时候调出`cscope-buffer'不。如果不调出。就自动跳转到查询到的第一个中去。如果些时没有到位,可以使用`C-c s n'查看下一个。最后查到了以后使用`C-c s u'可以跳转到之前的位置。
现在只是配置了C语言的cscope。怎么设置elisp这些呢?
可以在shell中这样使用:
首先使用下面的命令做一个`cscope.files'文件出来:
find -type f -name "*.el" > cscope.files
然后使用`cscope -b'更新一下数据库就行了。
emacs中还没有找到方法。
2 我的lisp学习笔记
2.1 DONE scheme中的define scheme
State "DONE" from "TODO"
(define peng (lambda (amount) ...))
这是定义了一个symbol,其中的函数指针指向了lambda构造的那个函数的开头。
(define (peng) (...))
这是定义了一个无参函数。
这两个是有区别的。
2.2 写一个自动转换org到pdf的脚本。这里 可以看看。我是想批量转换我的org文件。 notperfect
emacs的batch-mode可以看看。
想把需要同步的文档自动转换为pdf。可以直接在emacs中实现罗。查看elisp。用elisp来写一个。
最后得到了一个这样的函数,可以暂时在emacs中使用着:
(defun peng-dired-org-to-pdf () "convert the marked org files to pdf in dired-mode. otherwise,you need to input a directory name. this function will try to convert all of the org files in the directory you just type to pdf automatically" (interactive) (let ((files (if (eq major-mode 'dired-mode) (dired-get-marked-files) (let ((default-directory (read-directory-name "dir: "))) (mapcar #'expand-file-name (file-expand-wildcards "*.org")))))) ;; (message "%s" files) (mapc (lambda (f) (with-current-buffer (find-file-noselect f) (org-latex-export-to-pdf))) files) ))
2.3 copy-keymap
想要保存一个keymap不能简单的使用setq:
(setq save-map some-map)
这样只能是一个symbol,类似于C中的指针,some-map改变了,save-map也会 变。应该使用copy-keymap:
(setq save-map (copy-keymap some-map))
2.4 其它笔记
据说lisp的宏在本质上是一个由编译器自动为你动行的代码生成器。
一个简单的common lisp宏的例子:
(defmacro backwards (argu) (reverse argu)) (backwards ("xiepeng" t format))
这样就定义了反过来的format了。
3 我的emacs习惯
3.1 插件
名称 | 状态 | 备注 |
---|---|---|
2048-game | 已安装 | |
ace-jump-buffer | 已安装 | |
ace-jump-helm-line | 已安装 | |
ace-jump-mode | 已安装 | |
ace-jump-zap | 已安装 | |
ace-pinyin | 已安装 | |
ace-window | 已安装 | |
alert | 已安装 | |
applescript-mode | 已安装 | |
async | 已安装 | |
bibtex-utils | 已安装 | |
command-log-mode | 已安装 | |
darkroom | 已安装 | |
dash | 已安装 | |
f | 已安装 | |
flx | 已安装 | |
gntp | 已安装 | |
helm | 已安装 | |
helm-ag | 已安装 | |
helm-bibtex | 已安装 | |
helm-bibtexkey | 已安装 | |
helm-c-yasnippet | 已安装 | |
helm-swoop | 已安装 | |
icicles | 已安装 | |
ido-better-flex | 已安装 | |
ido-ubiquitous | 已安装 | |
ido-vertical-mode | 已安装 | |
idomenu | 已安装 | |
list-utils | 已安装 | |
log4e | 已安装 | |
makey | 已安装 | |
mark-tools | 已安装 | |
markdown-mode | 已安装 | |
markdown-mode+ | 已安装 | |
noflet | 已安装 | |
org | 已安装 | |
org-mac-iCal | 已安装 | |
org-mac-link | 已安装 | |
org-pomodoro | 已安装 | |
org-screenshot | 已安装 | |
org-tree-slide | 已安装 | |
ox-html5slide | 已安装 | |
ox-ioslide | 已安装 | |
parsebib | 已安装 | |
pcache | 已安装 | |
persistent-soft | 已安装 | |
rw-ispell | 已安装 | |
s | 已安装 | |
shadchen | 已安装 | |
showkey | 已安装 | |
smex | 已安装 | |
swiper | 已安装 | |
swiper-helm | 已安装 | |
yasnippet | 已安装 | |
ebib | 待安装 | 据说是一个emacs中的参考文献管理器 |
eyebrowse | 待安装 | 可以控制windows,等我换了大屏以后吧 |
workgroup2 | 待安装 | 和eyebrowse可能差不多。 |
4 config irony-mode
- down source code;
- put it into your load-path
- (require 'irony)
M-x irony-install-server.1
cmake -DCMAKE_INSTALL_PREFIX\=/Users/pengpengxp/.emacs.d/irony/ /Users/pengpengxp/.emacs.d/site-lisp/irony-mode-master/server && cmake --build . --use-stderr --config Release --target install
manual run will make a bin/irony-server at ~/.emacs.d/site-lisp/, make a directory ~/.emacs.d/irony and then move the bin directory in it so that irony can user it:
mkdir ~/.emacs.d/irony/ mv ~/.emacs.d/site-lisp/bin ~/.emacs.d/irony/
wirte a .clang_complete file at the root path of your project. These are all argument compiler use when compiling the projectExample .clang_complete file:
-DDEBUG -include ../config.h -I../common -I/usr/include/c++/4.5.3/ -I/usr/include/c++/4.5.3/x86_64-slackware-linux/
- And then, it work.
5 config ycmd
- git clone XXX
- git submodule update –init –recursive
- ./build.py –all
- download emacs-ycmd and load it.
configure it:
(set-variable 'ycmd-server-command '("python" "/Users/pengpengxp/github/ycmd/ycmd")) (set-variable 'ycmd-global-config "/Users/pengpengxp/github/ycmd/ycmd/completers/cpp/clang_completer.py") (require 'company-ycmd) (company-ycmd-setup)
5.1 config ycm for my own project:
- need to write .ycm_extra_conf.py files to tell ycm where the include file and compile flags.
use ycm-generator is a easy way to generate the .ycm_extra_conf.py file.
./config_gen.py -x c++ ~/src/ASP-Engine/core/src
- and then, Ycm can see the include files.
set `ycmd-global-config' for a global config
(set-variable 'ycmd-global-config "/Users/pengpengxp/src/ASP-Engine/.ycm_extra_conf.py")
5.2 编译ycmd时可能出错
第一次编译时,需要更新到最新,然后把git子模块也更新到最新。
git pull git submodule update --init --recusive
然后直接执行 ./build.py --all
就可以了。这个过程中,编译脚本需要
去下载最新版本的clang。需要等一段时间。
后面发现,如果第二次编译,可能失败,出现错误:
Error: could not load cache
这种情况下,需要把 cpp
目录中的 CMakeCache.txt
文件删掉。这时再
重试就可以了。
最后就是漫长的等待。
./build.py --clang-completer
会下载clang编译器到 clang_archives
目录。同时编译 C-family
的补全。
不过下载clang编译器真的时太慢啦。我是去云主机上使用wget下载的。
wget http://releases.llvm.org/4.0.1/clang+llvm-4.0.1-x86_64-apple-darwin.tar.xz
下载好后,直接放到ycmd的 clang_archives
目录下。然后直接
./build.py --clang-completer
就可以编出来对 c-family
语言的补全。
5.3 ycmd介绍
它本来是vim上的插件 YouCompleteMe
。现在整成了一个通用的。
可以补全很多语言: C,C++,C#,python,js,go
等。
它可以是基于语义的和不基于语言的。根据不同的语言,把两种的结果都汇
总后一起返回。 C-family
的基于语言补全功能需要 libclang
,它是
编译器clang的libary,一般也叫llvm。
使用libclang的时候,它需要知道编译时提供的编译参数。这样libclang才
能分析代码,ycmd才能提供 c-family
基于语言的补全。有两种方式可以
得到编译选项:
- 编译数据库(compilation database):这是最简单的一个方式,有些编
译系统如cmake,它在编译时会自动生成编译数据库。以下几种方式都可以:
- If using CMake, add -DCMAKE_EXPORT_COMPILE_COMMANDS=ON when configuring (or add set( CMAKE_EXPORT_COMPILE_COMMANDS ON ) to CMakeLists.txt) and copy or symlink the generated database to the root of your project.
- If using Ninja, check out the compdb tool (-t compdb) in its docs.
- If using GNU make, check out Bear.
For other build systems, check out .ycm_extra_conf.py below.这后面还有这样一段:
If no .ycm_extra_conf.py is found, and no ycm_global_ycm_extra_conf is configured, YouCompleteMe automatically tries to load a compilation database if one is found. YCM looks for a file named compile_commands.json in the directory of the opened file or in any directory above it in the hierarchy (recursively); when the file is found, it is loaded. YouCompleteMe performs the following lookups when extracting flags for a particular file: * If the database contains an entry for the file, the flags for that file are used. * If the file is a header file and a source file with the same root exists in the database, the flags for the source file are used. For example, if the file is /home/Test/project/src/lib/ something.h and the database contains an entry for /home/Test/ project/src/lib/something.cc, then the flags for /home/Test/ project/src/lib/something.cc are used. * Otherwise, if any flags have been returned from the directory containing the requested file, those flags are used. This heuristic is intended to provide potentially working flags for newly created files. Finally, YCM converts any relative paths in the extracted flags to absolute paths. This ensures that compilation can be performed from any Vim working directory.
- 手动提供编译选项
5.4 build.py选项
使用 ./build.py --help
查看一下:
(python3) ~/github/ycmd/ [master] ./build.py --help usage: build.py [-h] [--clang-completer] [--system-libclang] [--omnisharp-completer] [--gocode-completer] [--racer-completer] [--system-boost] [--msvc {12,14,15}] [--tern-completer] [--all] [--enable-coverage] [--enable-debug] [--build-dir BUILD_DIR] optional arguments: -h, --help show this help message and exit --clang-completer Build C-family semantic completion engine. --system-libclang Use system libclang instead of downloading one from llvm.org. NOT RECOMMENDED OR SUPPORTED! --omnisharp-completer Build C# semantic completion engine. --gocode-completer Build Go semantic completion engine. --racer-completer Build rust semantic completion engine. --system-boost Use the system boost instead of bundled one. NOT RECOMMENDED OR SUPPORTED! --msvc {12,14,15} Choose the Microsoft Visual Studio version (default: 15). --tern-completer Enable tern javascript completer --all Enable all supported completers --enable-coverage For developers: Enable gcov coverage for the c++ module --enable-debug For developers: build ycm_core library with debug symbols --build-dir BUILD_DIR For developers: perform the build in the specified directory, and do not delete the build output. This is useful for incremental builds, and required for coverage data
--clang-completer
可以编译c-family
语言的补全。它会下载它需 要的libclang到clang_archives
目录。如果你学得下载速度太慢,也 可自己下载放进去--omnisharp-completer
对C#
--gocode-completer
对go
- …
5.5 emacs-ycmd
在emacs中使用,可以直接使用 emacs-ycmd
这个插件。
6 elpy for python
直接使用官网教程,先使用pip把需要的第三方工具安装好,然后使用package 来安装就OK了。
我的个人配置如下:
(setq peng-python-map (make-sparse-keymap)) (define-key peng-python-map (kbd "RET") 'elpy-shell-send-current-statement) (define-key peng-python-map (kbd "s") 'elpy-rgrep-symbol) (define-key peng-python-map (kbd "d") 'elpy-goto-definition) (define-key peng-python-map (kbd "a") 'elpy-set-project-root) (define-key peng-python-map (kbd "f") 'elpy-find-file) (define-key peng-python-map (kbd "t") 'pop-tag-mark) (defun peng-python-mode () (define-key evil-normal-state-local-map (kbd "SPC z") 'peng-run-current-script) (autopair-on) (smart-tab-mode-off) (peng-local-set-key (kbd "C-c C-v") 'peng-run-current-script) ;; (company-mode) (elpy-enable) (define-key evil-normal-state-local-map (kbd "SPC c") peng-python-map) (define-key evil-normal-state-local-map (kbd "SPC m") peng-python-map) (peng-local-set-key (kbd "<C-right>") 'elpy-nav-forward-indent) (peng-local-set-key (kbd "<C-left>") 'elpy-nav-backward-indent) (peng-local-set-key (kbd "<C-down>") 'elpy-nav-forward-block) (peng-local-set-key (kbd "<C-up>") 'elpy-nav-backward-block)) (add-hook 'python-mode-hook 'peng-python-mode) ;; (setq elpy-project-ignored-directories '(".bzr" "CVS" ".git" ".hg" ".svn" ".tox" "build" "dist" ".cask")) (provide 'init-python)
7 使用emacs加密文件
修改好文件后,使用 `epa-encrypt-file'就可以加密。默认加密完成后,会 生成.gpg结尾的加密文件。原始文件还是非加密状态。如果文件本身就是 以.gpg结尾,则不会再新建文件,本文件已被加密。
还可以加密一个区域,现在不太需要。
8 use of markdown-mode
markdown #1 ### 使用 ###
现在用 Emacs 写博文真是一种享受。会 Emacs 的人会发现,下面提到的多数 快捷键和 Emacs 的基础快捷键相关,我只列出常用的:
在 Emacs 中预览结果 C-c C-c. 使用该功能的前提是系统中有将 Markdown 文本转化为 HTML 的 Markdown 命令。如何配置?请看这篇博文。
- C-c C-c m 转化为 HTML,在另一个 buffer 中预览 HTML 文件,个人觉得 没太大意义
- C-c C-c p 转化为 HTML,在浏览器中预览
- C-c C-c e 转化为 HTML,保存为文件
- C-c C-c v 转化为 HTML,保存为文件,并在浏览器中预览
超链接 Hyperlinks C-c C-a
- C-c C-a l 插入[]()形式的链接,C-c C-a L 插入 [LinkText][Label] 形 式的链接。在这种形式下,如果光标附近有文字或是 Active Region,会自 动被选择当作 LinkText。后一种形式会提示你在 Minibuffer 中输入 LinkText,LinkLabel 和可选的 LinkTitle。 图片 Images C-a C-i
C-c C-i i 和 C-c C-i I,两者的区别和超链接的类似。
样式 Styles C-a C-s
C-c C-s e 插入斜体字(e 表示 emphasis) C-c C-s s 插入粗体字(s 表示 strong) C-c C-s c 插入代码,比如开头的快捷键框框就是它的效果
标题 Headings C-c C-t
我最常用的 C-c C-t n ,n 从 1 - 6, 表示各级标题。比如 C-c C-t 3 得到 ### Heading ###
- C-c C-t h 根据前面的标题自动选择标题级别。C-c C-t H 类似,不同的是 它尝试得到带下划线的标题 一些零散的快捷键
- C-c - 插入水平线
- C-c C-o 如果该点是一个链接(Hyperlink),就会在浏览器中打开它的 URL, 如果该点是维基百科链接(wikilink),就会在另一个 Buffer 中打开
- C-c C-j 如果该点坐在的位置是一个 Hyperlink,按下此快捷键就会在 Link Text 和 Link URL 之间跳转。同样也适用于脚注(footnote)等其它类 似目标
- C-c C– 和 C-c C-= Promotion 和 Demotion(抱歉,想不到合适的中文翻 译)。例如,在 ### ### 附近按下 C-c C– 会使它变成 ## ##,按下 C-c C-= 会使它变成 #### ####。前者让 Heading 升级,后者让 Heading 降级
- C-c C-k 将该点的目标 kill 掉,并将其内容送到 kill ring 中,适用于 以下的目标:inline code, headings, horizonal rules, links, images, email address 等
C-c C-n,C-c C-p,C-c C-f,C-c C-b,C-c C-u 在 Heading 之间移动,自己去试试吧 M-{,M-},C-M-a,C-M-e,C-M-h 快速跳转,和 Emacs 基础快捷键操作一样 结束
9 ssh-terminal in emacs
It turns out, there is what you want:
(setq rlogin-program "ssh")
(setq rlogin-process-connection-type t)
and then M-x rlogin RET <myhost> RET will do that.
But I think this is useless.
10 hex-mode
`hexl-insert-hex-char'可以按照16进制来修改文件。输入37就对应修改为了
7
。
11 tramp
11.1 tramp multi-hop 在远程通过sudo编辑文件
;;; 使tramp可以使用`/sudo:root@host:/etc'这样的形式来在远程使用`sudo' ;;; 编辑文件,甚至可以使用`cd'直接进去。场景是不能通过root用户远程登陆, ;;; 但是又需要使用root的权限来编辑文件。 (add-to-list 'tramp-default-proxies-alist '(nil "\\`root\\'" "/ssh:%h:")) (add-to-list 'tramp-default-proxies-alist '((regexp-quote (system-name)) nil nil)) ;;; 本机中使用`localhost'这个HOST来使用sudo,设置在本机时的user和proxy ;;; 都是默认值nil (add-to-list 'tramp-default-proxies-alist '((regexp-quote "localhost") nil nil))
(HOST USER PROXY)
11.2 host down后emacs可能会 waiting for prompts from remote shell
删除 ~/.emacs.d/tramp
文件就可以了。这个文件应该是cache的一些认证
信息。remote host down后,这个信息如果还在,可能还会尝试连接。这时
关闭emacs都不行。使用`tramp-cleanup-all-buffers'也不行。
另外,我还接照网上的说法,这样设置了一下:
(setq tramp-shell-prompt-pattern "\\(?:^\\| \\)[^]#$%>\n]*#?[]#$%>].* *\\(\\[[0-9;]*[a-zA-Z] *\\)*")
12 find and grep
- in file or buffer: helm-occur, swiper
- dir in local:helm-do-ag, rgrep, find-grep-dired, find-grep
- dir in remote:rgrep, find-grep-dired, find-grep
13 DONE lexical and dynamic scoping box's blog 词法作用域和动态作用域
- State "DONE" from "PLAN"
动态作用域:
(setq b 17) (defun my-print-b () (print b)) (setq b 1717) (let ((b 8)) (my-print-b))
词法作用域:
;; -*- lexical-binding: t -*- (setq a 17) (defun my-print-a () (print a)) (setq a 1717) (let ((a 8)) (my-print-a))
Notice that the value of a is not specified within my-print-a, making it what some call a “free variable” (also known as nonlocal variables as in “a is nonlocal to my-print-a”). What will be the result of running the code above? Will it print 1717? Or is it going to be 8? With dynamic scoping, it prints 8. With lexical scoping, it prints 1717. With dynamic scoping, what the name a in my-print-a refers to is determined by when my-print-a is called. With lexical scoping, it is determined by where my-print-a is defined.
词法作用域:函数在什么地方被定义是关键。 动态作用域:函数在什么时候被调用是关键。
词法闭包就是闭包。Emacs 23及以前都是动态作用的。Emacs 24及以后的版本 才加入了词法作用域。
14 org tangle
org可以文学编程,使用 :tangle
来导出src块。org-mode中这样写,然后
调用`org-babel-tangle'就可以在本地生成一个名为main.sh的文件,里面的
内容即为块中的代码:
#+BEGIN_SRC sh :tangle main.sh date #+END_SRC
使用`org-babel-tangle'导出时,对应的目录可能不存在。需要新建,可以这 样来导出:
#+BEGIN_SRC sh :tangle (prog1 "/tmp/temp/dd.sh" (make-directory "temp" "/tmp")) date #+END_SRC
15 org exec code block
默认result中不会有脚本向STDOUT输出的内容。加入 :result output
info:org#Results of evaluation
#+BEGIN_SRC python :results output print('test output') #+END_SRC
16 org exports
下面这样,生成html的时候才会把结果导出出来。
print 'xiepeng'
17 theme
18 elisp check if string is empty
(= 0 (length ""))
19 emacs python parser
orgnode.py
源码在这里:
# Copyright (c) 2010 Charles Cave # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, copy, # modify, merge, publish, distribute, sublicense, and/or sell copies # of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. # Program written by Charles Cave (charlesweb@optusnet.com.au) # February - March 2009 # Version 2 - June 2009 # Added support for all tags, TODO priority and checking existence of a tag # More information at # http://members.optusnet.com.au/~charles57/GTD """ The Orgnode module consists of the Orgnode class for representing a headline and associated text from an org-mode file, and routines for constructing data structures of these classes. """ import re, sys import datetime def makelist(filename): """ Read an org-mode file and return a list of Orgnode objects created from this file. """ ctr = 0 try: f = open(filename, 'r') except IOError: print "Unable to open file [%s] " % filename print "Program terminating." sys.exit(1) todos = dict() # populated from #+SEQ_TODO line todos['TODO'] = '' # default values todos['DONE'] = '' # default values level = 0 heading = "" bodytext = "" tag1 = "" # The first tag enclosed in :: alltags = [] # list of all tags in headline sched_date = '' deadline_date = '' nodelist = [] propdict = dict() for line in f: ctr += 1 hdng = re.search('^(\*+)\s(.*?)\s*$', line) if hdng: if heading: # we are processing a heading line thisNode = Orgnode(level, heading, bodytext, tag1, alltags) if sched_date: thisNode.setScheduled(sched_date) sched_date = "" if deadline_date: thisNode.setDeadline(deadline_date) deadline_date = '' thisNode.setProperties(propdict) nodelist.append( thisNode ) propdict = dict() level = hdng.group(1) heading = hdng.group(2) bodytext = "" tag1 = "" alltags = [] # list of all tags in headline tagsrch = re.search('(.*?)\s*:(.*?):(.*?)$',heading) if tagsrch: heading = tagsrch.group(1) tag1 = tagsrch.group(2) alltags.append(tag1) tag2 = tagsrch.group(3) if tag2: for t in tag2.split(':'): if t != '': alltags.append(t) else: # we are processing a non-heading line if line[:10] == '#+SEQ_TODO': kwlist = re.findall('([A-Z]+)\(', line) for kw in kwlist: todos[kw] = "" if line[:1] != '#': bodytext = bodytext + line if re.search(':PROPERTIES:', line): continue if re.search(':END:', line): continue prop_srch = re.search('^\s*:(.*?):\s*(.*?)\s*$', line) if prop_srch: propdict[prop_srch.group(1)] = prop_srch.group(2) continue sd_re = re.search('SCHEDULED:\s+<([0-9]+)\-([0-9]+)\-([0-9]+)', line) if sd_re: sched_date = datetime.date(int(sd_re.group(1)), int(sd_re.group(2)), int(sd_re.group(3)) ) dd_re = re.search('DEADLINE:\s*<(\d+)\-(\d+)\-(\d+)', line) if dd_re: deadline_date = datetime.date(int(dd_re.group(1)), int(dd_re.group(2)), int(dd_re.group(3)) ) # write out last node thisNode = Orgnode(level, heading, bodytext, tag1, alltags) thisNode.setProperties(propdict) if sched_date: thisNode.setScheduled(sched_date) if deadline_date: thisNode.setDeadline(deadline_date) nodelist.append( thisNode ) # using the list of TODO keywords found in the file # process the headings searching for TODO keywords for n in nodelist: h = n.Heading() todoSrch = re.search('([A-Z]+)\s(.*?)$', h) if todoSrch: if todos.has_key( todoSrch.group(1) ): n.setHeading( todoSrch.group(2) ) n.setTodo ( todoSrch.group(1) ) prtysrch = re.search('^\[\#(A|B|C)\] (.*?)$', n.Heading()) if prtysrch: n.setPriority(prtysrch.group(1)) n.setHeading(prtysrch.group(2)) return nodelist ###################### class Orgnode(object): """ Orgnode class represents a headline, tags and text associated with the headline. """ def __init__(self, level, headline, body, tag, alltags): """ Create an Orgnode object given the parameters of level (as the raw asterisks), headline text (including the TODO tag), and first tag. The makelist routine postprocesses the list to identify TODO tags and updates headline and todo fields. """ self.level = len(level) self.headline = headline self.body = body self.tag = tag # The first tag in the list self.tags = dict() # All tags in the headline self.todo = "" self.prty = "" # empty of A, B or C self.scheduled = "" # Scheduled date self.deadline = "" # Deadline date self.properties = dict() for t in alltags: self.tags[t] = '' # Look for priority in headline and transfer to prty field def Heading(self): """ Return the Heading text of the node without the TODO tag """ return self.headline def setHeading(self, newhdng): """ Change the heading to the supplied string """ self.headline = newhdng def Body(self): """ Returns all lines of text of the body of this node except the Property Drawer """ return self.body def Level(self): """ Returns an integer corresponding to the level of the node. Top level (one asterisk) has a level of 1. """ return self.level def Priority(self): """ Returns the priority of this headline: 'A', 'B', 'C' or empty string if priority has not been set. """ return self.prty def setPriority(self, newprty): """ Change the value of the priority of this headline. Values values are '', 'A', 'B', 'C' """ self.prty = newprty def Tag(self): """ Returns the value of the first tag. For example, :HOME:COMPUTER: would return HOME """ return self.tag def Tags(self): """ Returns a list of all tags For example, :HOME:COMPUTER: would return ['HOME', 'COMPUTER'] """ return self.tags.keys() def hasTag(self, srch): """ Returns True if the supplied tag is present in this headline For example, hasTag('COMPUTER') on headling containing :HOME:COMPUTER: would return True. """ return self.tags.has_key(srch) def setTag(self, newtag): """ Change the value of the first tag to the supplied string """ self.tag = newtag def setTags(self, taglist): """ Store all the tags found in the headline. The first tag will also be stored as if the setTag method was called. """ for t in taglist: self.tags[t] = '' def Todo(self): """ Return the value of the TODO tag """ return self.todo def setTodo(self, value): """ Set the value of the TODO tag to the supplied string """ self.todo = value def setProperties(self, dictval): """ Sets all properties using the supplied dictionary of name/value pairs """ self.properties = dictval def Property(self, keyval): """ Returns the value of the requested property or null if the property does not exist. """ return self.properties.get(keyval, "") def setScheduled(self, dateval): """ Set the scheduled date using the supplied date object """ self.scheduled = dateval def Scheduled(self): """ Return the scheduled date object or null if nonexistent """ return self.scheduled def setDeadline(self, dateval): """ Set the deadline (due) date using the supplied date object """ self.deadline = dateval def Deadline(self): """ Return the deadline date object or null if nonexistent """ return self.deadline def __repr__(self): """ Print the level, heading text and tag of a node and the body text as used to construct the node. """ # This method is not completed yet. n = '' for i in range(0, self.level): n = n + '*' n = n + ' ' + self.todo + ' ' if self.prty: n = n + '[#' + self.prty + '] ' n = n + self.headline n = "%-60s " % n # hack - tags will start in column 62 closecolon = '' for t in self.tags.keys(): n = n + ':' + t closecolon = ':' n = n + closecolon # Need to output Scheduled Date, Deadline Date, property tags The # following will output the text used to construct the object n = n + "\n" + self.body return n
下面这个例子把test.org中的所有headline弄出来。
#!/usr/local/bin/python from orgnode import * import sys nodelist = makelist('/tmp/test.org') print "\n--------- PROJECT LIST ----------------" for node in nodelist: s = node print '*'*node.level,' ', node.headline
20 使用workgroup来完善我的工作流
- 使用workgroup2,每一个workgroup就干一件事情。它比bookmark的优势在
于:
- 可以记忆windows的布局。
- 可以记录多个文件,就像它的名字,完全就是不同的工作流。
- 每个workgroup中随便整。每次打开关闭都会记当前已打开的buffer。重启 后也会都打开。
有一个随便跳的workgroup: main。如果有时因打的workgroup太多导致打 开文件太多,可以切换到这个workgroup,清除所有文件buffer。然后再切 换到对应的workgroup就只有该wg相关的buffer存在了。还有一个专门的函 数来跳到
main
这个workgroup。peng-switch-to-main-workgroup
。(defun peng-switch-to-main-workgroup () (interactive) (wg-switch-to-workgroup (aref (wg-find-workgroup-by :name "main") 2)))
21 使用ditaa
在Mac上使用brew来安装ditaa:
brew install ditaa
下面是一个例子:
#+begin_src ditaa :file /tmp/some_filename.png :cmdline -r -s 0.8 -e utf-8 up1 up2 up3 up4 Input Traffic ^ ^ ^ ^ | | | | | | | | | | | v v v v v +-----+--+--+--+--+--+--+--+-------------------------+--+------------------+ | | | | | | | | | 1G/s | | 10G/s | | ++-+ ++-+ ++-+ ++-+ eth[0~3] ++-+ eth6 | | ^ ^ ^ ^ | | | | | | | | | | | | | | +---------------+---------------+ | | | | | | | | | | | | | +----------->+ | | | | | | | 你好 你好 | | | | | +----------------->+ | | | | | | bridge-eth6 | | | | +----------------------->+ | | | | | | | | +----------------------------->+ | | | +-+-------+-------+-------+-----+ | | | | | | | | ++-+ ++-+ ++-+ ++-+ | | | | | | | | | | ... | | +--+ +--+ +--+ +--+ | | vm1 vm2 vm3 vm5 | +--------------------------------------------------------------------------+ #+end_src
22 emacs对齐
[ ]
Emacs: Align Text By Xah Lee. Date: 2011-11-02. Last updated: 2017-11-05. Alt+x align-regexp to align text. For example, suppose you have: tom = 5 jenny = 8 mary = 7 and you want to align them by the equal sign. Just select the text, then Alt+x align-regexp then give “=”. Then you get: tom = 5 jenny = 8 mary = 7 The following is more advanced use of align and sort commands. Problem You have this list: California 423,970 km² Taiwan 36,008 km² Japan 377,944 km² Germany 357,021 km² Iraq 438,317 km² Iran 1,648,195 km² Korea (North+South) 219,140 km² Mexico 1,964,375 km² change it to this form: Taiwan 36,008 km² Korea (North+South) 219,140 km² Japan 377,944 km² Germany 357,021 km² California 423,970 km² Iraq 438,317 km² Iran 1,648,195 km² Mexico 1,964,375 km² Solution Jon Snader and “jm”, provided the following solution. align-regexp First, we align the text. Select the text first, then press 【Ctrl+u 】 then call align-regexp, with the regexp .* \([0-9,]+\).* then choose -1 for group, 1 for spacing, and n for repeat. Here's what it means. align-regexp lets you align a region by a regex in complex ways. * The regex .* \([0-9,]+\).* matches a whole line (you can add ^ at the beginning and $ at end if you like, but is not necessary). The pattern \([0-9,]+\) captures our numbers part. * The prompt “Parenthesis group to modify (justify if negative):”, we answer “-1”, because we want the first matched pattern to be used for alignment, and we want it to be justified to the right (meaning, align to the right of text captured by our pattern). * The query “Amount of spacing (or column if negative): ”, we use 1. * In “Repeat throughout line?” we answer “n”. * 【Ctrl+u】 is necessary for “align-regex” to promp you for various parameters (though, “align-regex”'s doc string does not mention it). The result is this: California 423,970 km² Taiwan 36,008 km² Japan 377,944 km² Germany 357,021 km² Iraq 438,317 km² Iran 1,648,195 km² Korea (North+South) 219,140 km² Mexico 1,964,375 km² sort-regexp-fields, sort-columns To sort it, there are 2 methods. One is using sort-regexp-fields, with this regex ^.*\([0-9 ,]\{9\}\) km²$. Another method is simply use sort-columns. This command sort lines by using a vertical column of text as sort key. The column is specified by the position of mark and cursor. So, place the cursor at the upper right, mark it, then move to lower left of our number, like this: California 423,970 km²▮ Taiwan 36,008 km² Japan 377,944 km² Germany 357,021 km² Iraq 438,317 km² Iran 1,648,195 km² Korea (North+South) 219,140 km² Mexico ▮1,964,375 km² Then call sort-columns. We got our desired result: Taiwan 36,008 km² Korea (North+South) 219,140 km² Japan 377,944 km² Germany 357,021 km² California 423,970 km² Iraq 438,317 km² Iran 1,648,195 km² Mexico 1,964,375 km² All these commands: {align-regexp, sort-regexp-fields, sort-columns} will be quite useful when you need it. (Big thanks to Jon Snader and “jm” for the excellent solutions.)
- 这里有一篇中文的
_f_: ls-git _F_: ido-fasd-find-file _r_: edit-current-file-as-root _g_: grep _o_: swiper _O_: swiper-all _j_: git-grep _i_: ivy-imenu-anywhere _S_: evil-write-all _s_: lusty-sudo-explorer _q_: hydra-zoom/body
可以这样来对齐:
C-u align-regex \(\s-*\)...: 1 10 y
对齐后效果如下:
_f_: ls-git _F_: ido-fasd-find-file _r_: edit-current-file-as-root _g_: grep _o_: swiper _O_: swiper-all _j_: git-grep _i_: ivy-imenu-anywhere _S_: evil-write-all _s_: lusty-sudo-explorer _q_: hydra-zoom/body
一般就是找到匹配的正则,然后第一个选 -1
,然后第二个选 1
我感觉
是一个tab。重不重看情况就好了。
23 正则表达式
emacs中的正则和其它我觉得没有太大区别。唯一不同是 \
在emacs的
string中有特殊的含义。所以使用string来表示emacs中的正则时,在需要使
用 \
来转义的地方,要使用两个。比如string中的这样: \\$
才是转义
了 $
。这就导致emacs的正则看起来是充满了 \
。
24 使用emacs来查看python代码
24.1 elpy
优先使用elpy,感觉它可以“理解”python代码。也很精确。
24.2 基于tag
使用ctags等工具制做好tags后来使用。tag相对来说要精确一些。
ctags指定文件列表制做tag:
find -type f -name "*.py" > tags.files ctags -e -L tags.files # 下面这个可以不要test目录 gfind -type f -name "*.py" -not -path "./tests/*"
24.3 cscope
cscope可以后于tag来使用。它的搜索范围要大些。
cscope指定文件列表制做database:
find -type f -name "*.py" > cscope.files
cscope -b -k
24.4 ag
`projectile-ag'来全局搜,效果很不错。
25 replace-regexp中输入换行newline
需要使用 C-q C-j
。
C-q for quoted-insert, C-j is a newline.
26 结合helm-ag来进行multi-edit
先使用helm-ag搜出来东西。然后 `C-c C-e' 进入helm-edit-mode。把需要的 修改改好后,使用 `C-c C-c' 确定提交。
Keymap
`helm-ag-map' and `helm-do-ag-map' are inherited by helm-map
Key | Action |
---|---|
C-c o | Open other window |
C-l | Search in parent directory |
C-c C-e | Switch to edit mode |
C-x C-s | Save ag results to buffer(Ask save buffer name if prefix key is specified) |
C-c C-f | Enable helm-follow-mode |
C-c >, right | Move to next file |
C-c <, left | Move to previous file |
C-c ? | Show help message |
Edit mode keymap
Key | Action |
---|---|
C-c C-c | Commit changes |
C-c C-k | Abort |
C-c C-d | Mark delete line |
C-c C-u | Unmark |
27 ibuffer
ibuffer可以这样设置来分组:
;;; set ibuffer display as group (setq ibuffer-saved-filter-groups (quote (("default" ("dired" (mode . dired-mode)) ;; ("perl" (mode . cperl-mode)) ("python" (mode . python-mode)) ;; ("erc" (mode . erc-mode)) ("emacs" (or (name . "^\\*scratch\\*$") (name . "^\\*Messages\\*$") (mode . emacs-lisp-mode) )) ("w3m" (or (mode . w3m-mode) )) ("planner" (or (name . "^Calendar$") (name . "^diary$") (name . "^inbox.org$") (name . "^Tips.org$") (name . "^note.org$") (name . "^daily.org$") (name . "^test.org$") (mode . muse-mode) )) ("org" (mode . org-mode)) ;; ("gnus" (or ;; (mode . message-mode) ;; (mode . bbdb-mode) ;; (mode . mail-mode) ;; (mode . gnus-group-mode) ;; (mode . gnus-summary-mode) ;; (mode . gnus-article-mode) ;; (name . "^\\.bbdb$") ;; (name . "^\\.newsrc-dribble"))) )))) (add-hook 'ibuffer-mode-hook (lambda () (ibuffer-switch-to-saved-filter-groups "default")))
设置显示大小为human readable:
;; Use human readable Size column instead of original one (define-ibuffer-column size-h (:name "Size" :inline t) (cond ((> (buffer-size) 1000000) (format "%7.1fM" (/ (buffer-size) 1000000.0))) ((> (buffer-size) 100000) (format "%7.0fk" (/ (buffer-size) 1000.0))) ((> (buffer-size) 1000) (format "%7.1fk" (/ (buffer-size) 1000.0))) (t (format "%8d" (buffer-size))))) ;; Modify the default ibuffer-formats (setq ibuffer-formats '((mark modified read-only " " (name 18 18 :left :elide) " " (size-h 9 -1 :right) " " (mode 16 16 :left :elide) " " filename-and-process)))
28 写一个判断是否有 universal-argument
的函数
(defun my-test (x) "print argument received" (interactive "P") (message "%s" x) ;; value of x is from universal argument, or nil if universal-argument isn't called )
29 读写文件
;;; Read File Content into a String (defun get-string-from-file (filePath) "Return filePath's file content." (with-temp-buffer (insert-file-contents filePath) (buffer-string))) ;; thanks to “Pascal J Bourguignon” and “TheFlyingDutchman 〔zzbba…@aol.com〕”. 2010-09-02 ;;; Read File Content as List of Lines (defun read-lines (filePath) "Return a list of lines of a file at filePath." (with-temp-buffer (insert-file-contents filePath) (split-string (buffer-string) "\n" t))) ;;; save variable `ivy-views' to file, it will overide the file (with-temp-file "/tmp/elisp.el" (insert (format "%s" ivy-views)))
30 convert string to list object
使用`read'可以完成,它可以从buffer、string等很多中读取出list object:
Read one Lisp expression as text from STREAM, return as Lisp object. If STREAM is nil, use the value of `standard-input' (which see). STREAM or the value of `standard-input' may be: a buffer (read from point and advance it) a marker (read from where it points and advance it) a function (call it with no arguments for each character, call it with a char as argument to push a char back) a string (takes text from string, starting at the beginning) t (read text line using minibuffer and use it, or read from standard input in batch mode).
;;; read from string (read "(xie peng ni hoa)") ;;; read from file (with-temp-buffer (insert-file-contents "/tmp/elisp.el") (goto-char (point-min)) (read (current-buffer)))
31 artist mode
使用 artist-select-op-text-see-thru
可以来画assicc字体。 M-x
调
用后,还需要按下回车。然后输入字母吧。
32 org-mode代码块
按键绑定
`C-c C-v p' or `C-c C-v C-p' `org-babel-previous-src-block' `C-c C-v n' or `C-c C-v C-n' `org-babel-next-src-block' `C-c C-v e' or `C-c C-v C-e' `org-babel-execute-maybe' `C-c C-v o' or `C-c C-v C-o' `org-babel-open-src-block-result' `C-c C-v v' or `C-c C-v C-v' `org-babel-expand-src-block' `C-c C-v u' or `C-c C-v C-u' `org-babel-goto-src-block-head' `C-c C-v g' or `C-c C-v C-g' `org-babel-goto-named-src-block' `C-c C-v r' or `C-c C-v C-r' `org-babel-goto-named-result' `C-c C-v b' or `C-c C-v C-b' `org-babel-execute-buffer' `C-c C-v s' or `C-c C-v C-s' `org-babel-execute-subtree' `C-c C-v d' or `C-c C-v C-d' `org-babel-demarcate-block' `C-c C-v t' or `C-c C-v C-t' `org-babel-tangle' `C-c C-v f' or `C-c C-v C-f' `org-babel-tangle-file' `C-c C-v c' or `C-c C-v C-c' `org-babel-check-src-block' `C-c C-v j' or `C-c C-v C-j' `org-babel-insert-header-arg' `C-c C-v l' or `C-c C-v C-l' `org-babel-load-in-session' `C-c C-v i' or `C-c C-v C-i' `org-babel-lob-ingest' `C-c C-v I' or `C-c C-v C-I' `org-babel-view-src-block-info' `C-c C-v z' or `C-c C-v C-z' `org-babel-switch-to-session-with-code' `C-c C-v a' or `C-c C-v C-a' `org-babel-sha1-hash' `C-c C-v h' or `C-c C-v C-h' `org-babel-describe-bindings' `C-c C-v x' or `C-c C-v C-x' `org-babel-do-key-sequence-in-edit-buffer'
org-babel-goto-named-src-block
可以跳到一个nameed的block,下面 这样写,直接输入xiepeng
就可以跳过去:#+NAME: xiepeng #+BEGIN_SRC python :results output :exports both :tangle /tmp/test_from_org_tangle.py print 'xiepeng' #+END_SRC
org-babel-insert-header-arg
这个来添加:results
这种选项(开 关)很方便org-babel-view-src-block-info
可以查看当前block的开关信息。
33 ivy和helm的写法
(ivy-read "Pick:" (mapcar #'number-to-string (number-sequence 1 10)))
对应helm的代码:
(helm :sources (helm-build-sync-source "one-to-ten" :candidates (mapcar #'number-to-string (number-sequence 1 10)) :fuzzy-match t) :buffer "*helm one-to-ten*")
或者这样:
(helm-comp-read "Pick:" (mapcar #'number-to-string (number-sequence 1 10)))
34 emacs把行号添加到文件中
选中后使用 C-x r N(rectangle-number-lines))
就可以啦。
35 org-mode publish时太慢的解决办法
我的静态blog是使用org的publish功能直接导出的。当文件较多的时候,完成 导出一次需要消耗太多时间。有时甚至都不能导出了。这个blog上,先查看下 导出的时候什么操作在占cpu:
(progn (profiler-start 'cpu) (org-publish "blog") (profiler-report))
然后发现,大多数时间花在版本控制上了:
Turns out, most of its total run time was spent in functions relating to version control (starting with vc-). Some package in my configuration set up vc-find-file-hook as part of find-file-hook. This means that every time org-publish opens a file, Emacs will look for the containing git repository and query its status. This takes forever! Worse yet, I don't even use vc-git at all. All my git interaction is done through magit.
结果是在 find-file-hook
中有 vc-find-file-hook
这个钩子,每次打
开文件都要使用去查一下git库的status。而这个作者和我都没有使用
vc-git
,而是使用 magit
来完成和git的交互。所以直接把这个钩子从
find-file-hook
中删掉。
(remove-hook 'find-file-hooks 'vc-find-file-hook)
36 bookmark plus
这个玩意可以把w3m的页面也当成bookmark。但是它还是做不到给w3m的书签分 类。
37 elisp函数根据有没有按 C-u
来走不同的流程
(defun peng-test (arg) (interactive "P") (if arg (message "yes") (message "no")))
38 启动加速
编译所有 site-lisp
目录下的 .el
:
C-u 0 M-x byte-recompile-directory will compile all the .el files in the directory and in all subdirectories below. The C-u 0 part is to make it not ask about every .el file that does not have a .elc counterpart.
39 我的 cc-mode
查看代码主要使用
counsel-gtags, cscope, counsel-rg
。
现在换成了 cquery(server)
和 lsp-mode(client)
的组合啦。
40 use exwm
1. Add following lines to your .emacs: (require 'exwm) (require 'exwm-config) (exwm-config-default) 2. Link or copy xinitrc (from exwm source directory) to ~/.xinitrc. 3. Start EXWM from a console (e.g. tty1) with xinit -- vt01
Ctrl + Alt + F1
stop X server:
sudo service lightdm stop sudo killall /usr/bin/X
start exwm:
xinit -- -vt01
41 在elisp函数中使用 C-u
下面这段代码可以就和使用 C-u
来调用 counsel-gtags-update-tags
实
现同样的功能:
(defun peng-test () (interactive) (let (current-prefix-arg) (setq current-prefix-arg '(4)) (call-interactively 'counsel-gtags-update-tags) ))
42 cscope和gtags不包括某些目录
cscope和gtags都支持指定文件。选项不同而已。先用find找出来。然后指定 就可以了。
find -name '*.[hc]'|grep -v '^./hal'|grep -v '^./third_party'|grep -v '^./linux/' > cscope.files cscope -b -q -i cscope.files cat cscope.files|gtags -f -
43 为org-mode自动添加目录
使用 toc-org
这个库,安装好后,加入下面的配置就可以了:
(if (require 'toc-org nil t) (add-hook 'org-mode-hook 'toc-org-enable) (warn "toc-org not found"))
这样,打上 :TOC:
标签的head每次保存的时候都会自动生成份目录了,也可以手动调用 toc-org-insert-toc
。所
以在需要添加目录的地方,可以搞一个这样的head:
* 目录 :TOC:
默认情况下是生成的和 github
兼容的目录,类似于这样:
[[#heading-name]]
这时在org-mode中直接跳,如果没有对应的 custom_id
的属性是跳不过去的。
toc_2_org
:可以设置为org中可以跳过去的link,2表示只生成前两级目录。
生成的link类似这样:
[[*heading-name]]
44 org-mode tangle整个head
可以加一个 header-args
,值就是对应写 tangle=的值: =:tangle
xxx.c :mkdirp yes :main no
:
* test :PROPERTIES: :header-args: :tangle /tmp/nihaotangle/main.c :mkdirp yes :main no :END: #+BEGIN_SRC C printf("xieng"); #+END_SRC #+BEGIN_SRC C printf("hi"); #+END_SRC
45 直接查看info文件
C-u M-x info
就可以了。
46 在elisp中模拟按键的输入
(call-interactively 'compile)
47 emacs中的长table导出pdf的问题
如果一个table太宽了,导出成pdf时会超出页面。把它搞成longtable就可以 解决了。这样可以设置每一列的长度。
功能 | 命令 | 说明 |
---|---|---|
进入config mode | configure terminal | |
进入interface mode | interface <interface-number> | |
配置端口的链路类型为Hybrid类型 | switchport mode hybrid | 缺省情况下,端口的链路类型为Access类型 |
允许指定的VLAN通过当前Hybrid端口 | switchport add vlan <vid> [tag | untaged] | 缺省情况下,所有Hybrid端口只允许VLAN1通过 |
不允许指定的VLAN通过当前Hybrid端口 | switchport remove vlan <vid> [tag | untaged] | |
把Hybrid端口加入default VLAN并设置pvid为输入vid | switchport default-vlan <vid> | 缺省情况下,Hybrid端口的缺省VLAN为VLAN 1 |
把Hybrid端口从default VLAN中移除并设置pvid为1 | no switchport default-vlan | 缺省情况下,Hybrid端口的缺省VLAN为VLAN 1 |
48 org-mode中以root用户执行命令
直接在org-mode中可以执行block中的命令,然而有些时候我需要使用root用 来执行,可以这样写:
#+BEGIN_SRC sh :dir /sudo:: apt-get update #+END_SRC
49 eshell中定义alias
直接写入 eshell-aliases-file
文件就可以了,比如当前我的是这些:
alias ll ls -al alias gbr git branch alias gst git status alias gck git checkout
50 在emacs中执行shell脚本
Elisp: Call Shell Command By Xah Lee. Date: 2018-09-04. Last updated: 2018-09-05. * shell-command → call a shell command, wait for it to finish. * shell-command-to-string → call a shell command and get its output ; call a shell command (shell-command "touch new.txt") ; call a shell command and get its output (shell-command-to-string "ls") Call a shell command, but don't wait for it to finish before continuing, use start-process or start-process-shell-command ;; open files in Linux desktop (mapc (lambda (x) (let ((process-connection-type nil)) (start-process "" nil "xdg-open" x)) ) filePathList)