[Emacs] 小技巧: 高亮/修改所有同名符號


(此篇面向初級用戶,寫的比較啰嗦,請中高級用戶見諒。

其實這篇的草稿是9月初寫的,躺在草稿箱里面3個月了,最近工作和生活都比較忙,沒時間來整理格式 :-( )

** hi-lock-mode

Emacs自帶hi-lock-mode (hi-lock.el),里面提供了一下幾個很有用的命令:

  • highlight-phrase (M-s h p)
  • highlight-regexp (M-s h r)
  • highlight-lines-matching-regexp (M-s h l)

使用時直接輸入上面命令或快捷鍵即可,不用先打開 hi-lock-mode ,Emacs會自動打開。

使用時Emacs會先問你要高亮什么內容,如果你不想手工輸入的話,得事先拷貝好內容再在這里粘貼。

然后Emacs會問你使用那種風格(face)來顯示高亮,除了hi-lock.el提供的 hi-yellow, hi-pink, hi-green 等顏色之外,你也可以使用Emacs里面其它的face。

要去除高亮,用 M-x unhighlight-regexp (M-s h u),它會自動提供當前已有條目(剛才通過上 述三個命令輸入的內容)供你選擇。

** highlight-symbol

http://nschum.de/src/emacs/highlight-symbol/

這個第三方庫其實是對hi-lock-mode的封裝,使得用戶用起來更方便:

  • highlight-symbol-at-point: 因為大多數時候我們只關注當前焦點所在的符號,所以可以省略輸入高亮內容那一步,顏色也不用用戶輸入了,它會自己隨機挑一個,這個命令正是這樣工作的;

  • 可以方便地跳轉到當前符號的上一次/下一此出現位置(highlight-symbol-prev, highlight-symbol-next)

  • 還可以限定只在當前函數里面查找(highlight-symbol-next-in-defun, highlight-symbol-prev-in-defun)

這就跟vim用戶很喜歡的*和#鍵功能差不多了,我綁定的快捷鍵也是沿用了這兩個符號:

(require 'highlight-symbol) ;;Use autoload' oridle-require' if you like

(global-set-key (kbd "M-s j") 'highlight-symbol-at-point) 
(global-set-key (kbd "<C-double-mouse-1") 'highlight-symbol-at-point) (global-set-key (kbd "M-s *") 'highlight-symbol-next)
(global-set-key (kbd "M-s #") 'highlight-symbol-prev) (global-set-key (kbd "C-*") 'highlight-symbol-next)
(global-set-key (kbd "C-#") 'highlight-symbol-prev)

后兩個(C-*, C-#)是為了應付連續按的場景的,單次按鍵比多次要方便一點。不過這兩個組合鍵在term(console, gnome-terminal, putty等)下面是沒法用的(我比較少有在term下用emacs,如果用得比較多,倒是可以考慮綁定到M-*和M-# 上)。

** idle-highlight

https://github.com/nonsequitur/idle-highlight-mode

很多朋友很喜歡能夠自動高亮當前焦點所在的符號,當焦點移開之后又自動取消高 亮, idle-highlight.el 就是干這個的。

idle-highlight.el放到load-path內,然后在dotemacs里面加入:

(autoload 'idle-highlight-mode "idle-highlight" "highlight the word the point is on" t)

使用時只要M-x idle-highlight-mode RET 就可以了。

如果想打開文件時自動開啟該功能 如果要自動對所有文件都打開該功能,在dotemacs里面加入:

 

(add-hook 'find-file-hook 'idle-highlight-mode)

 

如果只對某些主模式打開,則加入:

(add-hook 'emacs-lisp-mode-hook 'idle-highlight-mode) 
(add-hook 'python-mode-hook 'idle-highlight-mode) 
(add-hook 'js-mode-hook 'idle-highlight-mode)

Emacs 24里面將所有編程語言的major mode做了變更,都變成繼承自prog-mode了,這種情況下只 需要這樣就可以對所有編程語言添加此功能(而其它文本編輯不受影響):

(add-hook 'prog-mode-hook 'idle-highlight-mode)

** semantic-idle-local-symbol-highlight-mode

CEDET里面提供了一個 semantic-idle-local-symbol-highlight-mode ,跟idle-highlight功能類 似,但依賴於CEDET的語法解析功能。我不怎么用CEDET,所以不能給出評價。有興趣的可以看看Emacs中文網的這篇 [用CEDET瀏覽和編輯C++代碼] 里面的 [相應說明]。

** iedit

https://github.com/victorhge/iedit/

http://www.emacswiki.org/emacs/Iedit

修改代碼的時候嘗嘗需要對函數名、變量名進行修改,這就需要對同一符號的多次出現 (occurrence)進行批量替換(這個活兒在重構里面叫做rename method 或者rename field

iedit.el可以部分實現這個目標。之所以說"部分"是因為它只是個編輯功能,只能應付單一文件的 情況,做不到基於工程或者語法來修改所有調用到的地方。

iedit.el提供的iedit-mode是個臨時模式,使用方法如下:

1. 加載iedit.el,將iedit.el放到site-lisp目錄下,然后

  a). 動態加載: M-x load-library RET iedit.el RET

  b). Emacs啟動時加載: 在dotemacs里面加入:

(autoload 'iedit-mode "iedit" 
  "Edit multiple regions with the same content simultaneously." t)
2. 需要修改某個符號(函數名、變量名)時,將光標移動到該符號上,然后 M-x iedit-mode RET (或者按C-; 這是缺省配置的快捷鍵)即可進入批量修 改模式,使用該符號的所有地方會被高亮。通過編輯修改該符號的名稱,所做改動會即時反饋到所有高亮的地方。

3. 修改完成后,重新輸入 M-x iedit-mode RET 退出此模式。

如前所說,iedit比較簡單,沒有語法分析能力,所以如果你一個文件里有兩個類用了同名的變 量,它也區分不了,解決辦法是結合Emacs Narrowing來實現: Emacs narrowing功能使得我們可以只編輯一個文件的一部分,而其它部分並不在可編輯范圍內。所以實現上述目標的方法是:

1. 選擇(mark)要修改的函數(C-M-h)或者類;

2. 輸入 M-x narrow-to-region (或者 C-x n n), 如果你是第一次使用這個功能,Emacs 會問你是否要啟用該功能(因為這個功能會導致初學者暈頭,所以為防止誤入,缺省被禁用了);

3. 好了,Emacs現在只顯示你選中的那一塊代碼了,你現在做全buffer的替換,並不會影響文件的其它部分:用上面的 M-x iedit-mode RET 來做替換吧;

4. 修改完成,再用C-; 退出iedit-mode

5. 用 M-x widen RET (或者 C-x n w) 回到編輯整個文件的模式

 

參考: - emacs-fu: interactive replacement

** 其它補充

* auto-highlight-symbol-mode

https://github.com/mitsuo-saito/auto-highlight-symbol-mode/wiki/

這是寫這篇文章時翻到的一個擴展,看說明它用一個el文件把上述幾個功能都包含了,並不需要三個文件:

  • automatic highlighting current symbol like eclipse IDE.
  • cycle through highlighted locations.
  • can specify the range to highlight.
  • can edit the highlighted symbols at a time.

我還沒有試過,有興趣的朋友自己試試吧。

 * occur: 列出所有包含某個符號的行

M-x list-matching-lines RET (缺省綁定到了M-s o) 然后輸入要查找的符號即可。Emacs會在一個新的窗口列出結 果,可以用 M-g n和M-g p 跳轉到下一次、上一次出現的地方。(注: 此命令有個比較簡短的別名: occur ),

如果想將當前符號作為輸入,免去每次輸入的麻煩,可以用下面這個函數:

(require 'thingatpt)

(defun occur-at-point (nlines)
 (interactive "P")
 (occur (format "%s" (thing-at-point 'symbol)) nlines))

(define-key search-map "O" 'occur-at-point)

要深入研究一下occur的話: http://emacswiki.org/emacs/OccurMode


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM