概述
我是一名電氣工程師,從10年開始使用emacs练对,到現(xiàn)在已經(jīng)5年多余舶,它已經(jīng)成為了電腦上必不可少的應(yīng)用之一。說它是操作系統(tǒng)可能會(huì)有點(diǎn)夸張锹淌,不如說是一個(gè)整合的工作站會(huì)更加好點(diǎn)匿值。
我的工作和電氣自動(dòng)化相關(guān),偶爾會(huì)處理一些嵌入式或單片機(jī)的代碼赂摆,或編寫一些批處理的文件挟憔,所以使用的范圍并非和編程太相關(guān),說白了就是一個(gè)非程序員的應(yīng)用烟号。而且這個(gè)行業(yè)的很多軟件還是運(yùn)行在windows下绊谭,在mac或者linux下就歇菜了,所以這里的內(nèi)容主要還是針對(duì)windows下的平臺(tái)汪拥。
前期教訓(xùn)或經(jīng)驗(yàn)
由于剛開始玩的時(shí)候沒有太多正確的方法达传,而且emacs的學(xué)習(xí)曲線較其他的要陡峭,所以走了很多彎路。以下總結(jié)了一些自己的經(jīng)驗(yàn):
- 盡量使用terminal下的emacs宪赶。當(dāng)初什么都不會(huì)宗弯,直接下載了一個(gè)windows下的emacs版本,結(jié)果遇到了3個(gè)很惱火的地方:配置中文顯示麻煩搂妻,而且org mode下的表格中英文字母混排時(shí)蒙保,顯示效果很差;ansi term根本無法起作用欲主;路徑還是沿用windows的風(fēng)格邓厕,很多時(shí)候無法和一些cygwin的工具配合。后來就直接轉(zhuǎn)到cygwin扁瓢,中英文顯示都很在正確详恼,也不需要配置中文,而且可以和terminal配合引几。
- 使用conemu单雾。用cygwin下的mintty感覺還是不好,就使用conemu來啟動(dòng)了她紫。但默認(rèn)的配色方案不多,也足夠用屿储。
- 使用zsh贿讹。如果想深入了解gnu/linux的系統(tǒng),最好還是裝zsh够掠,配合oh my zsh真的很好民褂。當(dāng)然有人對(duì)這個(gè)傻瓜包感到不滿,但對(duì)于我這種非程序員來說就足夠了疯潭。emacs的確是有一個(gè)eshell赊堪,但還是過于簡(jiǎn)單,所以就用multi term開一個(gè)zsh竖哩,這樣使用能夠和emacs配合的天衣無縫哭廉。
- 使用package。一開始沒注意相叁,很多時(shí)候擴(kuò)展都是使用git pull來更新遵绰,累死了,也不好管理增淹。所以還是使用包管理會(huì)好很多椿访。
- 需要有折騰的精神。曾經(jīng)看過一個(gè)幻燈片虑润,上面一個(gè)老外說到emacs不是目的成玫,而是一個(gè)過程。如果需要開箱即用的配置,固然有prelude或者spacemacs之類的哭当,但這樣就少了折騰的份了猪腕。
- 放棄LaTeX。個(gè)人感覺它還是太老荣病,很多不兼容的包和不統(tǒng)一的語(yǔ)法令人發(fā)狂码撰。如果要折騰,還是用conTeXt為好个盆。
- 越新的插件越好脖岛。在剛開始玩的時(shí)候,ido, helm這些補(bǔ)全都不滿意颊亮,直到最近使用ivy才覺得補(bǔ)全就應(yīng)該是這樣子柴梆。
- 不過于迷信插件。要滿足自己實(shí)際的需求终惑,如果有些比較簡(jiǎn)單功能绍在,能夠自己寫,或者是抄別人的代碼稍微tweak一下就能實(shí)現(xiàn)的雹有,就盡量不用插件偿渡。當(dāng)然很多例子也是東抄西抄,然后自己改改就用了霸奕。在編寫一些小功能的時(shí)候溜宽,發(fā)覺用得最多的是
shell-command
這條命令,配合一些命令行的工具质帅,就可以量身定做一些實(shí)用的功能适揉。
常用插件
- swiper: 用于查找字符,覺得比helm好用煤惩。
- projectile: 項(xiàng)目管理的插件嫉嘀,很好用,能夠隨意跳轉(zhuǎn)到項(xiàng)目中的文件和文件夾魄揉。
- orgmode: 在emacs里面90%都是使用這個(gè)功能剪侮,就不多說了,筆記洛退,待辦事務(wù)票彪,打草稿等。
- workgroup2: 用于保存虛擬桌面的插件不狮,很好用降铸,但貌似很久都沒更新了。
- multi-term: 直接在emacs運(yùn)行多個(gè)終端摇零。
- avy: 用于跳轉(zhuǎn)到文件中任意的位置推掸。
- olivetti: 用于專心寫作的模式,文字全部居中。
- hydra: 開頭還是不怎么喜歡這種輔助功能的插件谅畅,但隨著快捷件越來越多登渣,
- slime: 學(xué)習(xí)lisp的利器。
orgmode文件
關(guān)于這個(gè)萬能的模式說得太多了毡泻,有兩點(diǎn)想說說胜茧。一是我將所有的東西都塞在不多的2,3個(gè)文件中仇味,這樣的做法可能看上去很怪呻顽,但看了lifehacker的一篇文章后就決定這樣做了。有個(gè)老外也是使用純文本來管理他自己的筆記和文件丹墨,但后來發(fā)現(xiàn)要管理的東西太多廊遍,他干脆放棄了管理,僅僅用幾個(gè)文件就搞好了贩挣。開頭我也使用deft插件來管理文件喉前,但發(fā)覺太多的碎片文件要管理,現(xiàn)在也是使用少數(shù)的文件王财,如果需要查找卵迂,用emacs的標(biāo)記功能,加上swiper來查找就OK了绒净。
二是使用orgmode的literate programming见咒,也即所謂的文學(xué)編程。在以前沒有接觸這個(gè)功能之前疯溺,emacs的配置文件,ledger文件哎垦,計(jì)算機(jī)編程語(yǔ)言例程搞到到處都是囱嫩,很難管理,使用這個(gè)功能就能夠?qū)⒋蟛糠值奈募性谝黄稹?/p>
打開二進(jìn)制文件
emacs打開文件的方法漏设,默認(rèn)都是針對(duì)純文本性質(zhì)的文件墨闲,如果要打開一些二進(jìn)制的文件就無力了,所以打開二進(jìn)制文件的功能就非常實(shí)用郑口,可以將emacs作為文件管理器來用鸳碧。這個(gè)在xah lee的網(wǎng)站上說過,例子是針對(duì)windows犬性,linux和mac的瞻离。學(xué)藝不精,當(dāng)時(shí)就拿過來就用乒裆,后來才知道原來每個(gè)系統(tǒng)都有一個(gè)相關(guān)的命令套利,可以用文件默認(rèn)的程序來打開。因?yàn)槭褂玫氖莄ygwin,直接用cygstart
就可以了肉迫。稍微修改一下代碼验辞,捆綁在C-c C-o就可以了。
(defun rw-open-in-external-app ()
"Open the current file or dired marked files in external app.
The app is chosen from your OS's preference."
(interactive)
(let* (
(ξfile-list
(if (string-equal major-mode "dired-mode")
(dired-get-marked-files)
(list (buffer-file-name))))
(ξdo-it-p (if (<= (length ξfile-list) 5)
t
(y-or-n-p "Open more than 5 files? "))))
(when ξdo-it-p
(mapc (lambda (fPath) (shell-command (format "cygstart \"%s\"" fPath))) ξfile-list))))
(define-key global-map (kbd "C-c C-o") 'rw-open-in-external-app)
事實(shí)上上面這個(gè)函數(shù)用得不多喊衫。因?yàn)榻?jīng)常使用的projectile跌造,但只有一個(gè)projectile-find-file的功能,所以將這個(gè)函數(shù)也稍微修改族购,同樣也是增加cygstart
這條命令壳贪,就可以在projectile上實(shí)現(xiàn)打開二進(jìn)制文件的功能了。
(defun projectile-open-file-externally (&optional arg)
"Jump to a project's file using completion.
With a prefix ARG invalidates the cache first."
(interactive "P")
(projectile-maybe-invalidate-cache arg)
(let ((file (projectile-completing-read "Find file: "
(projectile-current-project-files))))
(shell-command (format "cygstart \"%s\""(expand-file-name file (projectile-project-root))))
(run-hooks 'projectile-find-file-hook)))
查英文字典
查找過一些比較舊的方法联四,就是在計(jì)算機(jī)上安裝一個(gè)字典撑碴,然后再用emacs作為前端去查找單詞。Xah Lee的方法是直接查在線字典朝墩,但我還想查找的同時(shí)醉拓,在另一個(gè)windwow顯示查找的結(jié)果。以前使用w3m收苏,但最新的emacs帶有內(nèi)部的eww文本瀏覽器亿卤,所以也改用這種方式,稍微tweak一下鹿霸,綁定在f5功能鍵上排吴,就可以查merriam-webster的在線字典了。
;; merriam-webster dictionary
(defvar webster-url "http://www.m-w.com/cgi-bin/dictionary?book=Dictionary&va=")
(defun merriam (word)
(interactive "slook up a word in merriam-webster: ")
(let (start (point))
;;
(cond ((string= (format "%s" (current-buffer)) "*eww*")
(eww-browse-url (concat webster-url word)))
;;
((bufferp (get-buffer "*eww*"))
(progn (view-buffer-other-window (get-buffer "*eww*"))
(eww-browse-url (concat webster-url word))))
;;
(t
(progn (view-buffer-other-window (get-buffer "*scratch*"))
(eww-browse-url (concat webster-url word)))))))
(global-set-key (kbd "<f5>") 'merriam)
total commander的模仿
emacs的一個(gè)特性就是懦鼠,如果你看到其他編輯器或程序有好用的地方纺裁,那么總會(huì)有相應(yīng)的插件或者也可以自己寫一些簡(jiǎn)單點(diǎn)的函數(shù)來實(shí)現(xiàn)蒙谓,也就是它的模仿能力特別強(qiáng)。
以前使用過稱為神器的total commander,覺得此類雙面板的資源管理器很好用丛肢。當(dāng)然emacs有一個(gè)sunrise commander的插件撩满,但查看它的使用习蓬,太復(fù)雜了旺隙。想照搬該插件里面的移動(dòng)及復(fù)制功能,又看不出所以然來馅笙。其實(shí)我在TC上99%用的功能就無非是將左邊面板的文件伦乔,移動(dòng)或者復(fù)制到左邊的面板,還有就是將左右兩邊的面板互換一下董习。查看了一下elisp手冊(cè)烈和,移動(dòng)或復(fù)制功能實(shí)現(xiàn)如下。邏輯無非就是先跳轉(zhuǎn)到目標(biāo)面板皿淋,將它的路徑復(fù)制下來斥杜,然后跳回到源面板虱颗,再將所有標(biāo)記的文件用cp
或mv
命令復(fù)制或移動(dòng)到目標(biāo)路徑中,再更新一下顯示就OK了蔗喂。寫得比較隨意忘渔,沒有dired-mode的判斷,progn
也顯得多余缰儿,但實(shí)用就行了畦粮。
;; total commander function
(defun total-commander-copy-files ()
"total commander copy method. Copy the marked files to the next panel."
(interactive)
(progn (switch-window)
(let ((target-directory (expand-file-name default-directory)))
(progn (switch-window)
(mapc (lambda (marked-file)
(shell-command (concat (format "cp -r \"%s\""
(file-name-nondirectory marked-file))
" "
target-directory)))
(dired-get-marked-files))
(switch-window)
(revert-buffer)))))
當(dāng)然兩個(gè)面板的互換的實(shí)現(xiàn)功能在網(wǎng)上早就有了,我將它捆綁在f9的功能鍵上面乖阵。但我想光標(biāo)停在互換后新的面板上宣赔,所以在代碼的最后加了(switch-window)
這一句。
;; transpose buffers
(defun transpose-buffers (arg)
(interactive "p")
(let ((selector (if (>= arg 0) 'next-window 'previous-window)))
(while (/= arg 0)
(let ((this-win (window-buffer))
(next-win (window-buffer (funcall selector))))
(set-window-buffer (selected-window) next-win)
(set-window-buffer (funcall selector) this-win)
(select-window (funcall selector)))
(setq arg (if (plusp arg) (1- arg) (1+ arg))))
(switch-window)))
(global-set-key [f9] 'transpose-buffers)
快速截屏及編輯
在編寫筆記時(shí)瞪浸,需要一種快速插入截屏方法儒将,在網(wǎng)上也曾經(jīng)說過這樣一種方法,但它是基于linux下的scrot
命令的对蒲,而且我想在截屏之后馬上對(duì)其進(jìn)行編輯钩蚊,所以稍微修改了如下的代碼。截屏使用irfanview的命令蹈矮,然后編輯使用picpick的命令砰逻,注意路徑都是使用windows的路徑方式。捆綁在快捷鍵C-c r
上泛鸟。
;; screenshot
(defun cut ()
"Take a screenshot into a unique-named file in the current buffer file
directory and insert a link to this file."
(interactive)
(setq filename
(concat (make-temp-name "img-") ".png"))
;; (shell-command (format "boxcutter f:/cy/home/thinkT420/Notiz/img/\"%s\"" filename))
(shell-command (concat "i_view32 /capture=4 /convert=" "\"f:\\cy\\home\\thinkT420\\Notiz\\img" (format "\\%s\"" filename)))
(insert (concat "[[./img/" filename "]]"))
(shell-command (format "picpick f:/cy/home/thinkT420/Notiz/img/\"%s\"" filename))
)
(define-key org-mode-map (kbd "C-c r") 'cut)
簡(jiǎn)單的pdf文件合并
在工作中90%的時(shí)候都需要合并pdf文件蝠咆,自動(dòng)使用了emacs作為文件管理工具,就不想再打開工具去合并北滥。有一個(gè)pdftk
的命令行工具刚操,可以對(duì)pdf進(jìn)行多種的操作。
;; pdf method
(defun pdf-merge ()
"Merge the marked files into a pdf file."
(interactive)
(setq filename
(concat (make-temp-name "c-") ".pdf"))
(shell-command (format "pdftk %s cat output %s"
(list-to-string (dired-get-marked-files))
filename))
(revert-buffer))
(defun list-to-string (l)
"Return a STRING which is the concatenation of the elements of L."
(if (not l)
nil
(if (stringp (car l))
(concat (file-name-nondirectory (car l)) " " (list-to-string (cdr l)))
(list-to-string (cdr l)))))
簡(jiǎn)單的壓縮及解壓
同理再芋,壓縮和解壓在工作中很常見菊霜,但emacs自帶的壓縮功能并不是我想要的。所以使用7z的命令行工具祝闻,對(duì)文件進(jìn)行解壓或者壓縮占卧,也是綁定在hydra的功能鍵上遗菠。但缺點(diǎn)是我收到的文件很多還是rar的壓縮方式联喘,用emacs解壓時(shí)出錯(cuò),非要打開GUI解壓才行辙纬』碓猓或者是這個(gè)功能還沒有摸清楚其正確使用方法吧。
;; compress and uncompress files with 7z
(defun 7z-unzip ()
"Uncompress the marked files to a directory. The directory name is same as the zip file name without suffix."
(interactive)
(mapc (lambda (marked-file)
(shell-command (format "7z e -o\"%s\" \"%s\""
(file-name-base marked-file)
(file-name-nondirectory marked-file))))
(dired-get-marked-files))
(revert-buffer))
(defun 7z-zip ()
"Compress the marked files to a zip files. The zip file name is random."
(interactive)
(setq filename
(concat (buffer-name) ".zip"))
(mapc (lambda (marked-file)
(shell-command (format "7z a \"%s\" \"%s\""
(file-name-nondirectory filename)
(file-name-nondirectory marked-file))))
(dired-get-marked-files))
(revert-buffer))
關(guān)機(jī)贺拣,重啟及睡眠
再次是懶人的道理蓖谢,使用MS的psshutdown命令行功能捂蕴,在emacs上直接實(shí)現(xiàn)這三個(gè)功能,也懶得去記一些命令行和快捷鍵闪幽,也不想動(dòng)鼠標(biāo)啥辨。然后將他們捆綁在hydra上的三個(gè)功能鍵上。
每月花費(fèi)結(jié)算
很多文章都提到了ledger來進(jìn)行個(gè)人的財(cái)務(wù)結(jié)算盯腌,但windows版本的ledger太舊了溉知。后來找到一個(gè)克隆版的hledger,windows版本更新也快腕够。使用文學(xué)編程的方式级乍,在orgmode文件中增加如下代碼,就可以直接將當(dāng)月的花費(fèi)記錄下來帚湘。
#+BEGIN_SRC sh :dir ~/note
hledger balance -p "2016/06" --file finance.ledger
#+END_SRC
編寫簡(jiǎn)單的幻燈片
利用pandoc玫荣,reveal.js編寫一些簡(jiǎn)單,非正式的幻燈片大诸,快捷簡(jiǎn)單捅厂。后來發(fā)現(xiàn)有個(gè)ox-reveal的插件,但沒有用底挫。
;; create the revealjs slideshow file
(defun org-revealjs-compile ()
(interactive)
(compile (concat "pandoc -s -i -t revealjs --self-contained" " " (file-name-nondirectory (buffer-file-name)) " " "-o" " "(file-name-sans-extension (file-name-nondirectory (buffer-file-name))) ".html" " " "-V theme=league")))
文件加密
網(wǎng)上推薦的方式是使用GNU GPG的方法恒傻,但過于復(fù)雜,而在一次不小心的操作中在加密的文字上再加密建邓,之后無法恢復(fù)盈厘。其實(shí)只需要簡(jiǎn)單的ccrypt這個(gè)簡(jiǎn)單的工具,他本身也捆綁了elisp的插件官边,簡(jiǎn)單好用沸手。
hydra
有些鍵的組合實(shí)在太難記,所以都捆綁在hydra上注簿,這個(gè)插件還是挺好用的契吉。
沒有用emacs做的事
- 郵件:試過用mutt實(shí)現(xiàn)過,但本身對(duì)郵件操作不太重視诡渴,后來也沒有用了捐晶。
- 多標(biāo)簽:因?yàn)槭窃赾ygwin下使用emacs,而且本身對(duì)標(biāo)簽的使用不感冒妄辩,開得多反而會(huì)混亂惑灵。
- 查看圖片,pdf眼耀,聽音樂:在emacs里面實(shí)現(xiàn)了英支,但太geek,作用也不大哮伟,所以后來也沒用干花。
- 編寫正式的幻燈片:考慮到大家多數(shù)還是用MS ppt妄帘,用LaTeX等寫的方式?jīng)]有人會(huì)改,也放棄了池凄。