<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                ## 第?25?章?Emacs 入門 **目錄** [](ch25.html#id3104570) [基礎知識](ch25s02.html) [緩沖區](ch25s02.html#id3103963) [信息欄](ch25s02.html#id3104594) [按鍵描述](ch25s02.html#id3104810) [回顯區](ch25s02.html#id3105196) [](ch25s03.html) [內部命令](ch25s03.html#id3105241) [Emacs 命令行](ch25s03.html#id3105421) [Emacs 終端](ch25s03.html#id3105508) [Emacs 文件管理器](ch25s03.html#id3105578) [區塊選擇](ch25s03.html#emacs-select) [中止執行](ch25s03.html#id3105829) [基本配置](ch25s04.html) [幫助系統](ch25s05.html) [基本操作](ch25s06.html) [數字參數](ch25s07.html) [基礎編輯](ch25s08.html) [定位](ch25s08.html#id3107742) [刪除](ch25s08.html#id3108035) [復制](ch25s08.html#id3108335) [粘貼](ch25s08.html#id3108389) [撤消](ch25s08.html#id3108462) [重做](ch25s08.html#id3108555) [](ch25s09.html) [區塊編輯](ch25s09.html#emacs-region) [搜索和替換](ch25s09.html#id3108932) [其它](ch25s09.html#id3109245) [窗格和緩沖區管理](ch25s10.html) [多窗格](ch25s10.html#id3109383) [多緩沖區](ch25s10.html#id3109505) [寄存器管理](ch25s11.html) [光標位置和窗口狀態](ch25s11.html#id3109638) [文本和數字](ch25s11.html#id3109722) [書簽管理](ch25s12.html) [Shell 模式](ch25s13.html) [宏](ch25s14.html) [定義與運行](ch25s14.html#id3110094) [宏隊列](ch25s14.html#id3110151) [文件管理](ch25s15.html) [定位、查看](ch25s15.html#id3110561) [標記](ch25s15.html#id3110745) [操作](ch25s15.html#id3110911) [服務器模式](ch25s16.html) [大綱模式](ch25s17.html) [定制結構標識](ch25s17.html#id3111333) [配置](ch25s17.html#id3111467) [操作列表](ch25s17.html#id3111604) [在 Emacs 中使用 sdcv](ch25s18.html) [Windows 下字體設置](ch25s19.html) [版本](ch25s20.html) ## 基礎知識 引起我們痛苦的東西我們就會去愛它,以使自己覺得這份痛苦是值得的 Emacs 是一個架構在編輯器上的集成環境,除了最基本的編輯功能,還可以完成文件管理、終端模擬、瀏覽網頁、收發郵件、編譯程序等工作。 Emacs 使用 Elisp 語言進行配置和擴展,它本身也可以作為 Elisp 解釋器使用。 Emacs 的界面主要由三部分構成:信息欄、回顯區(echo)、緩沖區(buffer) ### 緩沖區 緩沖區(buffer) 類似于常規編輯器的文字編輯區。Emacs 并不直接對文件進行修改,而是讀取文件的內容并顯示在緩沖區中,在收到保存的指令后才將修改寫入文件。 緩沖區名稱通常為它所讀取文件的文件名。 ### 信息欄 在緩沖區之下為狀態欄,像這樣的 ![](https://box.kancloud.cn/2016-08-07_57a6a935374bf.jpg) 簡單說明一下: ``` -U(UNIX)**- emacs.xml 15% (28,32) Git:master (DocBook-XML Outl)----二 9月 30 11:57-------------------- ``` > [![1](https://box.kancloud.cn/2015-10-12_561bcb76795ae.png)](ch25s02.html#emacs11) 點擊拖動這里可以狀態欄位置 > [![2](https://box.kancloud.cn/2015-10-12_561bcb768596e.png)](ch25s02.html#emacs12) 文件編碼 U 代表 UTF-8; c 代表 chinese-gbk > [![3](https://box.kancloud.cn/2015-10-12_561bcb94ee26f.png)](ch25s02.html#emacs13) 換行符類型 有 UNIX、DOS 和 MacOS 三種 > [![4](https://box.kancloud.cn/2015-10-12_561bcb9508b82.png)](ch25s02.html#emacs14) 文件狀態 %代表只讀 -代表可寫 *代表未保存 > [![5](https://box.kancloud.cn/2015-10-12_561bcb95133e7.png)](ch25s02.html#emacs22) 當前工作路徑 > [![6](https://box.kancloud.cn/2016-01-06_568cdb4f32753.png)](ch25s02.html#emacs15) 當前編輯的文件 > [![7](https://box.kancloud.cn/2016-01-06_568cdb4f41fcc.png)](ch25s02.html#emacs16) 光標在當前文件中的位置 > [![8](https://box.kancloud.cn/2016-01-06_568cdb4f5948a.png)](ch25s02.html#emacs17) 光標所在的行、列 > [![9](https://box.kancloud.cn/2016-01-06_568cdb4f68749.png)](ch25s02.html#emacs18) 版本控制系統 > [![10](https://box.kancloud.cn/2016-01-06_568cdb4f83cf0.png)](ch25s02.html#emacs19) 主模式 > [![11](https://box.kancloud.cn/2016-01-06_568cdb4f902e3.png)](ch25s02.html#emacs20) 輔模式 > [![12](https://box.kancloud.cn/2016-01-06_568cdb4f9f9e9.png)](ch25s02.html#emacs21) 日期時間 標題欄也可以顯示一部分信息,并且可以自由定義。 ### 按鍵描述 Emacs 的功能鍵,通常為組合鍵。例如 **表?25.1.?Emacs 按鍵描述** | Emacs 描述 | 實際熱鍵 | 功能 | | --- | --- | --- | | C-f | Ctrl+f | 光標前進一格 | | C-b | Ctrl+b | 光標后退一格 | | C-d | Ctrl+d | 刪除一個字符 | | C-a | Ctrl+a | 回到行首 | Emacs 對按鍵的描述方式中, _-_ 之前的一個字符為修飾鍵,表示按住該鍵,再按 _-_ 后面的鍵。 例如: `C-a` 表示按住 Ctrl 再按 a 鍵。 Emacs 對其它一些特殊按鍵的描述 | | | | --- | --- | | `C-` | 按住 Ctrl鍵 | | `M-` | 按住 Meta鍵。在 PC 上,Meta鍵 通常對應 Alt 鍵 | | `C-M-` | 同時按住 Ctrl鍵 和 Meta鍵 | | `S-` | Shift鍵 | | `s-` | Linux 下對應 WIN 鍵 | | `RET` | 回車鍵 | | `TAB` | Tab鍵 | | `ESC` | Esc鍵 | | `SPC` | 空格鍵 | | `DEL` | 退格鍵 | | `Delete` | 刪除鍵 | > 注意:在 Emacs 中,`ESC` 等價于 `M-`,也就是說,按一次 `ESC` 鍵,與按住 `Meta` 鍵的作用是相同的。 > 類似 `C-M-r` 的按鍵,可以使用 `ESC C-r`(按一次 `ESC`,再按 `C-r`)這種更容易的方式 在后面的部分中,將統一使用 Emacs 對按鍵的描述方式。 Emacs 十分強大,上面的組合鍵,遠不能涵蓋 Emacs 的功能于萬一。除基本的編輯功能鍵外,其它功能多使用 _按鍵序列_: 連續的按下多組快捷鍵 例如: `C-x C-c` 表示先按下 `C-x` ,再按下 `C-c` 。也就是 `Ctrl+x` 后,再 `Ctrl+c` (退出 Emacs) 接下來 `C-h t` ,進入 《Emacs 快捷指南》 ### 回顯區 `C-x h` (先按 Ctrl+x 再按 h) 后,您會發現狀態欄和編輯器底部之間的區域出現 Mark set 字樣。同時,整個緩沖區的內容都被選中。 它是一個迷你緩沖區(minibuffer),叫作回顯區(echo area),提示您正在進行的操作,比如 Mark set(設定標記) 如果一個按鍵序列沒有完成,卻停止了輸入。大約兩秒后,回顯區會顯示已輸入部分,以免您忘記。不要以為是 Emacs 反應遲鈍 ### 內部命令 `C-h k` 后,回顯區提示 ``` Describe key (or click or menu item): ``` 接著 `C-x h` ,您會發現,緩沖區被水平分割為兩個。另一個名為 _*help*_ 緩沖區中顯示的內容為 ``` C-x h runs the command mark-whole-buffer which is an interactive compiled Lisp function in `simple.el'. It is bound to C-x h, <menu-bar> <edit> <mark-whole-buffer>. (mark-whole-buffer) Put point at beginning and mark at end of buffer. You probably should not use this function in Lisp programs; it is usually a mistake for a Lisp function to use any subroutine that uses or sets the mark. [back] ``` 第一行說明了 `C-x h` 運行的命令為 **mark-whole-buffer** 第二行說明了該命令由 `simple.el` 這個擴展提供,綁定到 `C-x h` 、 菜單欄-編輯-標記全部緩沖區 、 和命令 **mark-whole-buffer** 第三行介紹了這個命令的行為: 在文檔末尾設置一個標記,并把_光標點_[[45](ch25s03.html#ftn.emacs-point)]移動到文檔起始。 > 注意:_Emacs 使用命令進行處理,快捷鍵只是一種發送命令的方法!_ 一般情況下,我們用不到這么詳細的說明,而且英文看起來也比較吃力。您可以使用 `C-h c` 以簡潔模式查看說明。 只在回顯區顯示鍵位和它執行的命令: ``` C-x h runs the command mark-whole-buffer ``` 通常這就足夠了。 如果您知道一個命令,而不知道它綁定到什么鍵上,您可以使用 `C-h w` ,也就是命令 **Where-is** ### Emacs 命令行 由于 Emacs 太過強大,內部命令恒河沙數,根本不可能有同樣數量的快捷鍵位來綁定它們! 對于沒有綁定的命令,可以使用命令執行! `M-x` (Alt+x) 開啟命令行,回顯區顯示為 M-x ,然后輸入 newline 這個命令默認綁定在回車鍵,所以它和回車鍵的作用一樣為 換行 C-h w newline 結果是: newline is on RET > 提示:命令行中,可以使用 `TAB` 補全,使用 `M-p` 上翻, `M-n` 下翻 在后面的部分中,統一使用 `M-x command` 來表示 內部命令 **command** ;內部命令以 "(command)" 的形式寫到配置文件中 ### Emacs 終端 `M-x shell` 激活 Emacs 終端。可以在 Emacs 終端中使用外部命令。 需要注意的是,Emacs 終端是啞終端,某些類型的輸出不能夠正確顯示。 在 Emacs 終端中使用 `exit` 命令退出。 `M-!` (Alt+Shift+1)臨時執行一條外部命令,并輸出在名為 _*Shell Command Output*_ 的緩沖區中 **(M-x shell-command)** `C-u M-!` (Ctrl+u Alt+Shift+1)臨時執行一條外部命令,并輸出到光標位置。 ### Emacs 文件管理器 `C-x d` 進入 Dired 列表模式 `C-x C-d` 獲取文件列表(簡潔) `C-x C-f`打開文件,輸入路徑為打開目錄 詳細介紹見 [“文件管理”一節](ch25s15.html "文件管理") ### 區塊選擇 很多時候,我們需要選中緩沖區中的某一部分內容。和大多數程序一樣,您可以在被選擇區塊的起始點按下左鍵,移動鼠標,在結束點釋放左鍵,這部分區塊便被選中。 這種方式效率并不高,而且一些場合并沒有鼠標支持,例如控制臺或者遠程登錄。 事實上,Emacs 進行區塊選擇的方法,是設置一個標記,標記到光標點[[45](ch25s03.html#ftn.emacs-point)]之間的部分將被選中。 標記的位置為 **M-x set-mark-command** 時,光標點[[45](ch25s03.html#ftn.emacs-point)]所處的位置。 M-x set-mark-command 是設置標記的內部命令,默認綁定在 `C-SPC` 鍵上。 如果使用輸入法,這個鍵位多半是切換輸入法的快捷鍵。鍵盤指令會先被輸入法攔截下來,而無法發送到 Emacs。 當然也可以使用 `M-@` 來設定標記。不過 `M-@` 原綁定為 **M-x mark-word** ,雖然差不太多,但有時并不好用;況且對于一個常用的命令來講, `M-@` 鍵位的難度太高了 Emacs 的鍵位中,幾乎沒有默認綁定在 WIN 鍵上的命令,不妨利用一下 在 Emacs 的用戶配置文件 `~/.emacs` 中添加如下內容: ``` ;; WIN+Space 設置標記 (global-set-key (kbd "s-SPC") 'set-mark-command) ``` 在某些類型的終端中,WIN鍵 不起作用,建議使用命令。或者綁定到 `C-t` [[46](ch25s03.html#ftn.id3105776)] ``` ;; (在注釋里說明原命令和綁定,是一個良好的習慣) ;; C-t 設置標記 (global-set-key (kbd "C-t") 'set-mark-command) ``` > 重要:重啟 Emacs,或者在 ~/.emacs 文件的緩沖區中執行命令 `M-x eval-buffer` ,便可以使配置文件立即生效 ### 中止執行 如果想放棄一個命令,可以使用 `C-g` **(M-x keyboard-quit)**打斷。 建議您使用快捷鍵 C-g ,因為在需要中止執行的情況下, M-x 通常是無法使用的 `ESC ESC ESC` **(M-x keyboard-escape-quit)**可以從一些交互命令中退出。 例如從 "詢問替換 M-x query-replace" 中退出。 當 C-g 不能搞定,您可以嘗試連按三次 ESC * * * > [[45](ch25s03.html#emacs-point)] 光標點假定光標為插入式(豎線),位置在覆蓋式光標(方塊)的左側。 > 事實上,Emacs 中的相關判定以光標點為準!方塊形光標只是為了減少視覺疲勞 > [[46](ch25s03.html#id3105776)] 這是一個讓人頭痛不已的地方。因為無論綁到哪,似乎都不太方便: > 使用 WIN鍵 倒是挺好,但是在字符界面下,WIN鍵 通常不起作用;同樣,C-; 這樣使用標點的組合鍵在字符界面下也不行; > C-m、C-i 是兩個不錯的組合,但是 Emacs 認為 C-m 和 RET、C-i 和 TAB 是一個鍵,這樣綁定,你的回車或者 TAB 就成了設置標記; > 最后,C-t 這個鍵默認綁定的命令幾乎沒什么用,只是這個鍵位不是很好按,但這樣也有好處──無論你用左手或者右手來按 t鍵,距離都差不多 ## 基本配置 您已經知道了,Emacs 的配置文件為 `~/.emacs` 。配置文件中,以 ; 起始到行末的部分為注釋。 讓我們些簡單配置一下: **例?25.1.?emacs 配置 `~/.emacs`** ``` ;;======================================== ;;添加 Emacs 搜索目錄 可以將自定的擴展放該目錄 ;;======================================== ;(add-to-list 'load-path "~/..emacs") ;如果有其它配置文件,使此命令讀取 ;(load "addon.el") ;;======================================== ;; 外觀設置 ;;======================================== ;;禁用工具欄 (tool-bar-mode nil) ;;禁用菜單欄,F10 開啟關閉菜單 (menu-bar-mode nil) ;;禁用滾動欄,用鼠標滾輪代替 ;;(scroll-bar-mode nil) ;;禁用啟動畫面 (setq inhibit-startup-message t) ;;======================================== ;; 鍵綁定 ;;======================================== ;; C-t 設置標記 ;; (global-set-key (kbd "C-t") 'set-mark-command) ;; C-x b => CRM bufer list (global-set-key "\C-xb" 'electric-buffer-list) ;;---------- redo (global-set-key ( kbd "C-.") 'redo) ;;======================================== ;;關閉當前緩沖區 Alt+4 ;; C-x 0 (global-set-key (kbd "M-4") 'delete-window) ;;關閉其它緩沖區 Alt+1 ;; C-x 1 (global-set-key (kbd "M-1") 'delete-other-windows) ;;水平分割緩沖區 Alt+2 ;; C-x 2 (global-set-key (kbd "M-2") 'split-window-vertically) ;;垂直分割緩沖區 Alt+3 ;; C-x 3 (global-set-key (kbd "M-3") 'split-window-horizontally) ;;切換到其它緩沖區 Alt+0 ;; C-x o (global-set-key (kbd "M-0") 'other-window) ;;F10 顯示/隱藏菜單欄 ;; M-x menu-bar-open ;;(global-set-key (kbd "F10") 'menu-bar-mode) ;;WIN+s 進入 Shell ;; M-x shell ;(global-set-key (kbd "s-s") 'shell) ;;(define-key ctl-x-map "\M-s" 'shell) ;;======================================== ;; 緩沖區 ;;======================================== ;;設定行距 (setq default-line-spacing 0) ;;頁寬 (setq default-fill-column 90) ;;缺省模式 text-mode (setq default-major-mode 'text-mode) ;;設置刪除紀錄 (setq kill-ring-max 200) ;;以空行結束 (setq require-final-newline t) ;;語法加亮 (global-font-lock-mode t) ;;高亮顯示區域選擇 (transient-mark-mode t) ;;頁面平滑滾動, scroll-margin 5 靠近屏幕邊沿3行時開始滾動,可以很好的看到上下文。 (setq scroll-margin 5 scroll-conservatively 10000) ;高亮顯示成對括號,但不來回彈跳 (show-paren-mode t) (setq show-paren-style 'parentheses) ;;鼠標指針規避光標 ;(mouse-avoidance-mode 'animate) ;;粘貼于光標處,而不是鼠標指針處 (setq mouse-yank-at-point t) ;;======================================== ;; 回顯區 ;;======================================== ;;閃屏報警 (setq visible-bell t) ;;使用 y or n 提問 (fset 'yes-or-no-p 'y-or-n-p) ;;鎖定行高 (setq resize-mini-windows nil) ;;遞歸 minibuffer (setq enable-recursive-minibuffers t) ;; 當使用 M-x COMMAND 后,過 1 秒鐘顯示該 COMMAND 綁定的鍵。 ;;(setq suggest-key-bindings 1) ;; ;;======================================== ;; 狀態欄 ;;======================================== ;;顯示時間 (display-time) ;;時間格式 (setq display-time-24hr-format t) (setq display-time-day-and-date t) (setq display-time-interval 10) ;;顯示列號 (setq column-number-mode t) ;;標題欄顯示 %f 緩沖區完整路徑 %p 頁面百分數 %l 行號 (setq frame-title-format "%f") ;;======================================== ;; 編輯器設定 ;;======================================== ;;不生成臨時文件 ;;(setq-default make-backup-files nil) ;;只渲染當前屏幕語法高亮,加快顯示速度 (setq font-lock-maximum-decoration t) ;;將錯誤信息顯示在回顯區 ;(condition-case err ; (progn ; (require 'xxx) ) ; (error ; (message "Can't load xxx-mode %s" (cdr err)))) ;;使用X剪貼板 (setq x-select-enable-clipboard t) ;;;;;;;; 使用空格縮進 ;;;;;;;; ;; indent-tabs-mode t 使用 TAB 作格式化字符 nil 使用空格作格式化字符 (setq indent-tabs-mode nil) (setq tab-always-indent nil) (setq tab-width 4) ;;======================================== ;; 顏色設置 ;;======================================== ;; 指針顏色 (set-cursor-color "black") ;; 鼠標顏色 (set-mouse-color "black") ;; 背景和字體顏色 (set-foreground-color "gainsboro") (set-background-color "grey30") (set-border-color "black") ;; 語法高亮顯示,區域選擇,二次選擇 ;;前景和背景色 (set-face-foreground 'highlight "white") (set-face-background 'highlight "blue") (set-face-foreground 'region "cyan") (set-face-background 'region "blue") (set-face-foreground 'secondary-selection "skyblue") (set-face-background 'secondary-selection "darkblue") ;;日歷配色 ;(setq calendar-load-hook ;'(lambda () ;(set-face-foreground 'diary-face "skyblue") ;(set-face-background 'holiday-face "slate blue") ;(set-face-foreground 'holiday-face "white"))) ;;======================================== ;; 字體設置 ;;======================================== (set-default-font "Monospace-10") (if window-system (set-fontset-font (frame-parameter nil 'font) 'unicode '("Microsoft YaHei" . "unicode-bmp")) ) ;;======================================== ;; 必備擴展 ;;======================================== ;;---------- color-theme ;(require 'color-theme) ;(color-theme-gray30) ;;========== ibuffer (require 'ibuffer) (global-set-key ( kbd "C-x C-b ")' ibuffer) ;;========== outline (setq outline-minor-mode-prefix [(control o)]) ;;---------- Docbook ;(require 'docbook-xml-mode) ;(add-hook 'docbook-xml-mode-hook ; (function (lambda () ; (setq outline-regexp "<!\\-\\-\\*+") ; (outline-minor-mode) ; (hide-body) ; ))) ;;開啟服務器模式 ;(server-start) ;;org-mode (setq org-hide-leading-stars t) (define-key global-map "\C-ca" 'org-agenda) (setq org-log-done 'time) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;; F5 運行當前文件 ;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;(defun run-current-file () ; "Execute or compile the current file. ;For example, if the current buffer is the file x.pl, ;then it'll call “perl x.pl” in a shell. ;The file can be php, perl, python, bash, java. ;File suffix is used to determine what program to run." ;(interactive) ; (let (ext-map file-name file-ext prog-name cmd-str) ;; get the file name ;; get the program name ;; run it ; (setq ext-map ; '( ; ("php" . "php") ; ("pl" . "perl") ; ("py" . "python") ; ("sh" . "bash") ; ("java" . "javac") ; ) ; ) ; (setq file-name (buffer-file-name)) ; (setq file-ext (file-name-extension file-name)) ; (setq prog-name (cdr (assoc file-ext ext-map))) ; (setq cmd-str (concat prog-name " " file-name)) ;; (compile cmd-str))) ; (shell-command cmd-str))) ; ;(global-set-key (kbd "<f5>") 'run-current-file) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;; 以下為實現 redo 的代碼 ;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (provide 'redo) (defvar redo-version "1.02" "Version number for the Redo package.") (defvar last-buffer-undo-list nil "The head of buffer-undo-list at the last time an undo or redo was done.") (make-variable-buffer-local 'last-buffer-undo-list) (make-variable-buffer-local 'pending-undo-list) ;; Emacs 20 variable (defvar undo-in-progress) (defun redo (&optional count) "Redo the the most recent undo. Prefix arg COUNT means redo the COUNT most recent undos. If you have modified the buffer since the last redo or undo, then you cannot redo any undos before then." (interactive "*p") (if (eq buffer-undo-list t) (error "No undo information in this buffer")) (if (eq last-buffer-undo-list nil) (error "No undos to redo")) (or (eq last-buffer-undo-list buffer-undo-list) ;; skip one undo boundary and all point setting commands up ;; until the next undo boundary and try again. (let ((p buffer-undo-list)) (and (null (car-safe p)) (setq p (cdr-safe p))) (while (and p (integerp (car-safe p))) (setq p (cdr-safe p))) (eq last-buffer-undo-list p)) (error "Buffer modified since last undo/redo, cannot redo")) (and (or (eq buffer-undo-list pending-undo-list) (eq (cdr buffer-undo-list) pending-undo-list)) (error "No further undos to redo in this buffer")) (or (eq (selected-window) (minibuffer-window)) (message "Redo...")) (let ((modified (buffer-modified-p)) (undo-in-progress t) (recent-save (recent-auto-save-p)) (old-undo-list buffer-undo-list) (p (cdr buffer-undo-list)) (records-between 0)) ;; count the number of undo records between the head of the ;; undo chain and the pointer to the next change. Note that ;; by `record' we mean clumps of change records, not the ;; boundary records. The number of records will always be a ;; multiple of 2, because an undo moves the pending pointer ;; forward one record and prepend a record to the head of the ;; chain. Thus the separation always increases by two. When ;; we decrease it we will decrease it by a multiple of 2 ;; also. (while p (cond ((eq p pending-undo-list) (setq p nil)) ((null (car p)) (setq records-between (1+ records-between)) (setq p (cdr p))) (t (setq p (cdr p))))) ;; we're off by one if pending pointer is nil, because there ;; was no boundary record in front of it to count. (and (null pending-undo-list) (setq records-between (1+ records-between))) ;; don't allow the user to redo more undos than exist. ;; only half the records between the list head and the pending ;; pointer are undos that are a part of this command chain. (setq count (min (/ records-between 2) count) p (primitive-undo (1+ count) buffer-undo-list)) (if (eq p old-undo-list) nil ;; nothing happened ;; set buffer-undo-list to the new undo list. if has been ;; shortened by `count' records. (setq buffer-undo-list p) ;; primitive-undo returns a list without a leading undo ;; boundary. add one. (undo-boundary) ;; now move the pending pointer backward in the undo list ;; to reflect the redo. sure would be nice if this list ;; were doubly linked, but no... so we have to run down the ;; list from the head and stop at the right place. (let ((n (- records-between count))) (setq p (cdr old-undo-list)) (while (and p (> n 0)) (if (null (car p)) (setq n (1- n))) (setq p (cdr p))) (setq pending-undo-list p))) (and modified (not (buffer-modified-p)) (delete-auto-save-file-if-necessary recent-save)) (or (eq (selected-window) (minibuffer-window)) (message "Redo!")) (setq last-buffer-undo-list buffer-undo-list))) (defun undo (&optional arg) "Undo some previous changes. Repeat this command to undo more changes. A numeric argument serves as a repeat count." (interactive "*p") (let ((modified (buffer-modified-p)) (recent-save (recent-auto-save-p))) (or (eq (selected-window) (minibuffer-window)) (message "Undo...")) (or (eq last-buffer-undo-list buffer-undo-list) ;; skip one undo boundary and all point setting commands up ;; until the next undo boundary and try again. (let ((p buffer-undo-list)) (and (null (car-safe p)) (setq p (cdr-safe p))) (while (and p (integerp (car-safe p))) (setq p (cdr-safe p))) (eq last-buffer-undo-list p)) (progn (undo-start) (undo-more 1))) (undo-more (or arg 1)) ;; Don't specify a position in the undo record for the undo command. ;; Instead, undoing this should move point to where the change is. ;; ;;;; The old code for this was mad! It deleted all set-point ;;;; references to the position from the whole undo list, ;;;; instead of just the cells from the beginning to the next ;;;; undo boundary. This does what I think the other code ;;;; meant to do. (let ((list buffer-undo-list) (prev nil)) (while (and list (not (null (car list)))) (if (integerp (car list)) (if prev (setcdr prev (cdr list)) ;; impossible now, but maybe not in the future (setq buffer-undo-list (cdr list)))) (setq prev list list (cdr list)))) (and modified (not (buffer-modified-p)) (delete-auto-save-file-if-necessary recent-save))) (or (eq (selected-window) (minibuffer-window)) (message "Undo!")) (setq last-buffer-undo-list buffer-undo-list)) ``` ## 幫助系統 使用 Emacs 的過程中,您隨時可以獲取幫助 M-x help-with-tutorial `C-h t` Emacs快捷指南 M-x info-emacs-manual `C-h r` Emacs使用手冊 M-x info `C-h i` 在線幫助 其它 **表?25.2.?Emacs幫助系統** | | | | --- | --- | | C-h a | M-x apropos-command | 搜索命令 | | C-h f | M-x describe-function | 函數說明 | | C-h v | M-x describe-variable | 變量說明 | | C-h k | M-x describe-key | 鍵綁定說明 | | C-h c | M-x describe-key-briefly | 鍵綁定說明 | | C-h w | M-x where-is | 查找鍵綁定 | * 使用幫助時,可能會分割出其它窗格。 `C-x 1` 關閉其它窗格 詳見 [“窗格和緩沖區管理”一節](ch25s10.html "窗格和緩沖區管理") ## 基本操作 針對文件及編輯器的一些操作,絕大多數軟件中,這類操作都安排在 _文件_ 菜單里面。 **表?25.3.?Emacs 基本操作** | | | | --- | --- | | C-x C-c | M-x save-buffers-kill-emacs | 保存退出 | | C-x C-z | M-x iconify-or-deiconify-frame | 掛起(最小化) | | C-x C-f | M-x find-file | 打開文件、目錄 | | C-x C-r | M-x find-file-read-only | 以只讀模式打開 | | C-x i | M-x insert-file | 插入文件 | | C-x C-s | M-x save-buffer | 保存 | | C-x s | M-x save-some-buffers | 詢問,保存所有未保存的緩沖區 | | C-x C-w | M-x write-file | 另存為文件 | | C-x RET r | M-x revert-buffer-with-coding-system | 以指定編碼讀取文件 | | C-x RET f | M-x set-buffer-file-coding-system | 以指定編碼保存文件 | | | M-x revert-buffer | 恢復到原始狀態 | ## 數字參數 Emacs 中可以使用 Ctrl+u 向命令傳遞參數。例如用數字作為參數,指定命令運行的次數 `C-u (#) command` **M-x universal-argument** (通用參數) 例如: ``` C-u 10 C-f 向前10個字符 C-u 10 M-x forward-char ``` `M-(#) (command)` **negative-argument** (負參數) `M-[1-9] 快速參數` **digit-argument** (數字參數) ## 基礎編輯 幾乎所有編輯器都具有的基礎功能。 使用 Readline 控件的程序,例如 bash ;以及其它使用 Emacs風格 鍵綁定的程序,也使用基本相同的功能鍵。如果熟悉 bash 的快捷鍵,這些綁定您一定駕輕就熟 > 注意:這里只是一個列表,更詳細的介紹,請參閱《Emacs 快捷指南》 C-h t ### 定位 **表?25.4.?Emacs 定位** | | 向前 | 向后 | 向下 | 向上 | | --- | --- | | 卷屏 | C-v | M-v | | 字符 | C-f | C-b | C-n | C-p | | 單詞 | M-f | M-b | | 行 | C-a | C-e | 移動到行首或行尾,不能跨行 | | 句 | M-a | M-e | | 段落 | M-{ | M-} | | 緩沖區 | M-&lt; | M-&gt; | 移動到緩沖區起始或結束 | | 行號 | M-g g | M-g M-g | M-x goto-line | 按行號跳轉 | | 字符位置 | M-x goto-char | 按字符跳轉 | 其它: `C-M-l` **(M-x reposition-window)** 將當前行卷至頁面中部 `C-l` **(M-x recenter)** 刷新頁面,將將當前行卷至頁面中部 (使用數字參數指定行) `M-r M-x` **(move-to-window-line)** 移動光標至頁面中間的行 (使用數字參數指定行) ### 刪除 **表?25.5.?Emacs 刪除** | | 向前 | 向后 | | --- | --- | | 字符 | C-d | M-x delete-char | DEL | M-x delete-backward-char | | 單詞 | M-d | M-x kill-word | C-Delete / M-DEL | M-x backward-kill-word | | 行 | 光標至行末 | C-k | M-x kill-line | | 整行 | C-S-backspace | M-x kill-whole-line | | 按表達式刪除 | C-M-k | M-x kill-sexp | | 區塊 | C-w | M-x kill-region | | 空白 | 刪除連續空格 | M-x delete-horizontal-space | > 注意:上表中 DEL 實際按鍵為 Backspace ,PC 中只有 Delete 鍵,而沒有 DEL 鍵,Emacs 把 Backspace 映射為 DELbackspace 實際按鍵也為 Backspace類似的,Emacs 把 PC 的 Enter 鍵映射為 RET ; 而 RET 實際為 C-m 可能您注意到了,Emacs 進行刪除時有兩種處理方法, delete 和 kill kill 比較類似于 剪切 ,剪切掉的內容被依次放入 剪切隊列 kill-ring ,可以召回。 delete 就是 刪除 了,刪除掉的內容并不能召回。但是可以通過 M-x undo 撤消刪除。 ### 復制 `M-w` **(M-x kill-ring-save)** 將內容放入 剪切隊列 kill-ring `C-w` 剪切 ### 粘貼 `C-y` **(M-x yank)** 從 剪切隊列 kill-ring 中召回最后一次放入的內容 `M-y` **(M-x yank-pop)** 從 剪切隊列 kill-ring 中按后進先出的順序,依次召回 * 這個命令只能在 M-x yank 或者 M-x yank-pop 之后使用。也就是說,只能 C-y 后 M-y , M-y 可以連續多次。 ### 撤消 `C-/` **(M-x undo)** 撤消之前的修改 `C-_` **(M-x undo)** `C-x u` **(M-x advertised-undo)** advertised-unde 是 undo 命令的一個別名 * 為了減少 undo 的次數,每插入20個字符,視為一個 undo 的單位。 ### 重做 安裝 redo.el 擴展,并在配置文件中添加如下內容 ``` ;;---------- redo ;; 讀取擴展 (require 'redo) ;; 設置 Redo 的鍵綁定 (global-set-key ( kbd "C-.") 'redo) ``` ### 區塊編輯 如何選中區塊,可以參考[“區塊選擇”一節](ch25s03.html#emacs-select "區塊選擇") 需要補充的是,完成區塊選擇時,實際定義了兩種區塊 : ``` ---XXXXXxxx xxxXXXXXxxx xxxXXXXXxxx xxxXXXXX--- ``` _---_代表沒有被選中的區域 _連續區塊_為標記和光標點之間連續的區塊;字符 X 和 x 均為連續區塊 _矩形區塊_為標記和光標點之間矩形的區塊;大寫字符 X 為矩形區塊 **表?25.6.?Emacs 區塊編輯** | | | | --- | --- | | 連續區塊 | | C-SPC | M-x set-mark-command | 在光標點處設置標記 | | C-@ | 同上 | 建議使用 C-t | | M-@ | M-x mark-word | 在單詞結尾處設置標記 | | M-h | M-x mark-paragraph | 選中段落 | | | M-x mark-end-of-sentence | 在句末設置標記 | | C-x h | M-x mark-whole-buffer | 整個緩沖區 | | C-x C-x | M-x exchange-point-and-mark | 交換標記和光標點 | | C-w | M-x kill-region | 剪切區塊 | | M-w | M-x kill-ring-save | 復制區塊 | | C-y | M-x yank | 粘貼區塊 | | M-y | M-x yank-pop | 隊列粘貼 | | 矩形區塊 | | C-x r k | M-x kill-rectangle | 刪除矩形區塊 | | C-x r y | M-x yank-rectangle | 粘貼上一次刪除的矩形區塊 | | C-x r t | M-x string-rectangle | 用指定字符填充 | | C-x r o | M-x open-rectangle | 用空格插入 | | C-x r c | M-x clear-rectangle | 用空格填充 | | C-x r r | M-x copy-rectangle-to-register | 拷貝到寄存器中 | ### 搜索和替換 Emacs中,默認使用 增量搜索 :在搜索對話模式中輸入關鍵詞的同時,Emacs 就開始進行搜索,隨著關鍵字的輸入,不斷的縮小搜索范圍 而傳統的非增量搜索,則是關鍵詞輸入后,再進行搜索。 **表?25.7.?Emacs 搜索** | | | | --- | --- | | 增量搜索 | | C-s | M-x isearch-forward | 向前增量搜索 | | C-r | M-x isearch-backward | 向后增量搜索 | | C-M-s | M-x isearch-forward-regexp | 正則表達式向前增量搜索 | | C-M-r | M-x isearch-backward-regexp | 正則表達式向后增量搜索 | | 詢問替換 | | M-% | M-x query-replace | 詢問替換 | | C-M-% | M-x query-replace-regexp | 正則表達式詢問替換 | | 搜索 | | | M-x search-forward | 向前搜索 | | | M-x search-backward | 向后搜索 | | | M-x search-forward-regexp | 正則表達式向前搜索 | | | M-x search-backward-regexp | 正則表達式向后搜索 | | 替換 | | | M-x replace-string | 替換 | | | M-x replace-regexp | 正則表達式替換 | * 增量搜索時,關鍵詞會被一直保留。可以直接進行下一次搜索 * 下一次增量搜索,如果之前進行了其它操作,則需要連續兩次命令(快捷鍵),才能召回關鍵詞。 * `C-g` 取消搜索,回到搜索前的位置 * `RET` 結束搜索,停在當前位置 * 可以選中區塊后,在區塊內進行替換 ### 其它 _插入控制字符_ 使用 `C-q` ,可以在緩沖區插入一個控制字符。例如: `C-q C-m = ^M` 文本換位 **表?25.8.?Emacs 其它** | | | | --- | --- | | 字符 | C-t | M-x transpose-chars | | 單詞 | M-t | M-x transpose-words | | 行 | C-x C-t | M-x transpose-lines | _將 TAB 字符轉換為空格_ 選中需要轉換的區域, **M-x untabify** _對齊文本塊_ 選中需要對齊的區域, **M-x indent-region** ## 窗格和緩沖區管理 ### 多窗格 **表?25.9.?Emacs 窗格** | | | | --- | --- | | C-x 2 | M-x split-window-vertically | 分隔出兩個垂直窗格,水平分隔線 | | C-x 3 | M-x split-window-horizontally | 分隔出兩個水平窗格,垂直分隔線 | | C-x 1 | M-x delete-other-window | 只保留當前窗格 | | ESC ESC ESC | M-x keyboard-escape-quit | 只保留當前窗格 | | C-x 0 | M-x delete-window | 關閉當前窗格 | | C-x o | M-x other-window | 在下一個窗格中激活光標 | | C-M-v | M-x scroll-other-window | 向下卷動下一個窗格,使用負參數可以向上卷動 | * _下一個窗格_: 垂直分隔,則先左后右;水平分隔,則先上后下。如果窗格還有子窗格,則先遍歷其子窗格后,再遍歷其它窗格,以此遞歸。 ### 多緩沖區 Emacs 中,打開新的緩沖區,原有緩沖區并不會關閉 **表?25.10.?Emacs 緩沖區** | | | | --- | --- | | C-x C-b | M-x list-buffers | 查看緩沖區列表 | | C-x b | M-x switch-to-buffer | 切換到其它緩沖區 | | C-x k | M-x kill-buffer | 關閉當前緩沖區 | * 切換到其它緩沖區時,默認上一次使用的緩沖區(可以用 TAB 補全) * 使用多窗格時,緩沖區操作只對當前窗格有效 * 建議使用 ibuffer.el 這個擴展。 Emacs 自帶,在配置文件中添加如下語句 ``` ;;========== ibuffer (require 'ibuffer) (global-set-key ( kbd "C-x C-b ")' ibuffer) ``` * 另一個緩沖區列表的擴展(Emacs 自帶) ``` ;;CRM bufer list (global-set-key "\C-x\C-b" 'electric-buffer-list) ``` ## 寄存器管理 寄存器用于存貯內容,在需要時取出,插入緩沖區。 Emacs 的寄存器使用_單個字符_命名,可以存貯兩種內容 : ### 光標位置和窗口狀態 **表?25.11.?Emacs 寄存器** | | | | --- | --- | | C-x r SPC (寄存器名) | M-x point-to-register | 存貯光標位置 | | C-x r w (寄存器名) | M-x window-configuration-to-register | 保存當前窗口狀態 | | C-x r f (寄存器名) | M-x frame-configuration-to-register | 保存所有窗口狀態 | | C-x r j (寄存器名) | M-x jump-to-register | 光標跳轉 | | C-x j (寄存器名) | 略…… | 同上 | ### 文本和數字 **表?25.12.?Emacs 寄存器2** | | | | --- | --- | | C-x r s (寄存器名) | M-x copy-to-register | 將連續區塊拷貝到寄存器中 | | C-x r r (寄存器名) | M-x copy-rectangle-to-register | 將矩形區塊拷貝到寄存器中 | | C-u (數字) C-x r n (寄存器名) | M-x number-to-register | 將數字拷貝到寄存器中 | | C-x r i (寄存器名) | M-x insert-register | 在緩沖區中插入寄存器內容 | * **M-x view-register** 查看寄存器內容 * **M-x list-registers** 查看寄存器列表 * 寄存器中的矩形區塊,以矩形區塊的方式插入到緩沖區中。 見 [“區塊編輯”一節](ch25s09.html#emacs-region "區塊編輯") * 也可以將文件插入到寄存器中 (set-register ?寄存器名稱 '(file . 文件名)) ,示例 ``` M-x lisp-interaction-mode 進入交互模式,輸入如下 Lisp 代碼: (set-register ?e '(file . "~/.emacs"))(光標)移動此外, C-j 求值。 M-x list-registers 查看寄存器列表,多了寄存器 e : Register e contains the file "~/.emacs". ``` ## 書簽管理 Emacs 可以在當前位置創建一個書簽,以便能夠快速的返回。 與存儲光標位置的寄存器略有不同 * 書簽可以使用單詞來命名,而不限于一個字符。起一個容易記住的名字 * 退出 Emacs 后,書簽不會消失,下次還可以使用 **表?25.13.?Emacs 書簽** | | | | --- | --- | | C-x r m (name) | M-x bookmark-set | 設置書簽 | | C-x r b (name) | M-x bookmark-jump | 跳轉到書簽 | | C-x r l | M-x bookmark-bmenu-list | 書簽列表 | | | M-x bookmark-delete | 刪除書簽 | | | M-x bookmark-load | 讀取存儲書簽文件 | * 書簽默認存儲在 `~/.emacs.bmk` 文件中 * 在配置文件中,可以設置書簽存儲的文件 ``` ;; 書簽文件的路徑及文件名 (setq bookmark-default-file "~/.emacs.d/.emacs.bmk") ;; 同步更新書簽文件 ;; 或者退出時保存 (setq bookmark-save-flag 1) ``` ## Shell 模式 `M-x shell`進入 Shell 模式,可以完成一些簡單的工作。不過有些情況下,輸出會有一些問題 事實上,這是 Emacs 自帶的終端。它與 bash 和 sh 的兼容比較好,而 fish 之類比較現代的 Shell,在 Emacs 終端里的效果則很差 需要注意的是, readline-bash 的綁定 C-p C-n ,在 Emacs 終端需要使用 M-p M-n 。其它的鍵綁定,也以 Emacs 為準 ## 宏 記錄一系列操作,在需要的時候運行 例如給一個單詞加 " ,可以分解為以下操作: ``` M-b 移動到詞首 " M-f 移動到詞尾 " ``` 這種重復的操作往往需要經常執行,手動未免太沒有效率。我們可以把這些操作制作成宏,然后運行這個宏 當然,這只是最簡單的宏。結合正則表達式進行匹配,以宏進行操作,可以完成許多復雜的操作 ### 定義與運行 **表?25.14.?Emacs 宏** | | | | --- | --- | | 開始錄制 | C-x ( (M-x kmacro-start-macro) | F3 (M-x kmacro-start-macro-or-insert-counter) | | 結束錄制 | C-x ) (M-x kmacro-end-macro) | F4 (M-x kmacro-end-or-call-macro) | | 播放 | C-x e (M-x kmacro-end-and-call-macro) | ### 宏隊列 與 剪切隊列 類似,Emacs 中也有 宏隊列 的概念: 當一個新的宏被定義,原有的宏并不消失,只是在宏隊列中的位置被擠到后面。 `C-x C-k`進入宏隊列,以下的操作可以在宏隊列中連續進行 **表?25.15.?Emacs 宏隊列** | | | | --- | --- | | 基本操作 | | C-n | M-x kmacro-cycle-ring-next | 下翻 | | C-p | M-x kmacro-cycle-ring-previous | 上翻 | | C-d | M-x kmacro-delete-ring-head | 刪除當前宏 | | C-k | M-x kmacro-end-or-call-macro-repeat | 運行當前宏 | | 命名與保存 | | n (name) | M-x kmacro-name-last-macro | 命名 | | b | M-x kmacro-bind-to-key | 綁定 | | | M-x insert-kbd-macro | 在緩沖區中插入宏定義 | | 宏編輯器 | | C-e | M-x kmacro-edit-macro | 編輯 | | e | M-x edit-kbd-macro | 編輯指定名稱的宏 | | l | M-x kmacro-edit-lossage | | 詢問執行 | | q | M-x kbd-macro-query | 在播放宏時,將進行詢問確認 | | 計數器 | | C-i | M-x kmacro-insert-counter | 將宏計數器的數值插入緩沖區 | | C-c | M-x kmacro-set-counter | 為宏計數器設置一個數值 | | C-a | M-x kmacro-add-counter | 給宏計數器添加一個前綴參數 | | C-f | M-x kmacro-set-format | 給宏計數器指定一個將要插入的特殊值 | * 保存為文件,使用 **M-x load-file** 加載 * 保存到配置文件中,啟動時加載 ## 文件管理 ## 文件管理 `C-x d` **(M-x dired)** 進入 Dired 列表模式 `C-x C-d` **(M-x list-directory)** 獲取文件列表(簡潔) `C-x C-f` **(M-x find-file)** 打開文件,沒有文件名則打開目錄 ### 定位、查看 **表?25.16.?Emacs 文件管理** | | 向下 | 向上 | | --- | --- | | 文件 | n | p | | C-n | C-p | | SPC | DEL | 上一級 | | 目錄 | &gt; | &lt; | ^ | | 已標記 | M-} | M-{ | | | | | --- | --- | | g | 刷新 | | s | 切換名稱/日期排序方式 | | i | 在當前窗口插入一個子目錄 | | v | 查看當前文件 | | y | 查看當前文件類型 | | = | 比較 | ### 標記 | | | | --- | --- | | 普通標記 | m | 標記(顯示為字符 * ) | | t | 反向標記 | | u | 取消標記 | | U | 取消所有標記 | | * / | 標記文件夾 | | * * | 標記所有可執行文件 | | * @ | 標記所有符號連接 | | * c | 改變標記的符號 | | % m | 根據正則表達式標記文件 | | % g | 根據正則表達式標記文件內容 | | 刪除標記 | d | 標記為刪除(顯示為字符 D ) | | ~ | 將備份文件標記為刪除 | | # | 將存盤文件標記為刪除 | | & d | 根據正則表達式標記刪除 | | x | 執行刪除 | ### 操作 | | | | --- | --- | | RET | 在新緩沖區打開文件 | | o | 在另一個窗格打開 | | C-o | 在另一個窗格后臺打開 | | C-x C-f | 新建文件 | | + | 新建目錄 | | C-x C-q | 將文件列表設為只讀 | | 可以結合 _*_ 標記批量進行 | D | 刪除文件 | | C | 拷貝 | | R | 重命名/移動 | | O | 改變用戶 | | G | 改變群組 | | M | 改變權限 | | S | 符號鏈接 | | H | 硬鏈接 | | Z | 壓縮 | | T | touch | | w | 復制文件名 | | k | 刪除行(刷新后恢復) | ## 服務器模式 由于各種原因,Emacs 啟動比較耗時。可以啟動一個 Emacs 的守護進程 ``` emacs --daemon ``` 然后通過 emacsclient 來連接服務器 ``` emacsclient -t --alternate-editor jed file ``` * _-t_ 在當前控制臺打開 emacs 窗口 * _--alternate-editor jed_ 如果不能連接到 emacs 服務器,則使用 jed 編輯器 也可以使用 Emacs 服務器模式,`M-x server-start` 或者在配置文件中添加 _(server-start)_ 啟用 Emacs 服務器,使用 emacs-client 連接。 ## 大綱模式 Emacs 的大綱模式(Outline mode),是一個十分有用的模式。如果工程規模比較大,你應該用大綱來組織它。 大綱模式通常作為輔模式使用,**M-x outline-minor-mode**啟用。 大綱模式可以根據代碼的語法對結構進行識別,但是這種自動模式工作的不是很好,而且不夠靈活 另一種工作方式是查找特定的字串,來組織文檔的結構。這種工作方式是可控制的,不過需要手動加入這些作為結構標識的字串。似乎有點麻煩,但是對于嚴謹的構思來說,你是需要列一個提綱的 大綱模式默認以行首的 `*` 作為結構標識,每多一個 `*` 就是下一級分支。 大綱模式默認的鍵綁定太過復雜,在配置文件中添加以下語句,將所有大綱模式操作的前綴鍵改為 Ctrl+o ``` (setq outline-minor-mode-prefix [(control o)]) ``` 試著在文檔中隨便加入幾個這樣的標識 ``` *主干一 **分支一 **分支二 *主干二 ``` 進行一些簡單的操作 | | | | --- | --- | | C-o C-a | 全部顯示 | | C-o C-t | 顯示主干 | | C-o C-q | 全部隱藏 | | C-o C-i | 顯示下一級分支 | | C-o C-k | 顯示分支 | | C-o C-e | 顯示節點 | | C-o C-d | 隱藏分支 | ### 定制結構標識 為了不影響代碼的功能,通常要把結構標識放到注釋中,這樣作有可能會帶來不便,例如在 XML 環境中就要像這樣使用: ``` <!-- *結構標識 --> ``` 這樣會給你的工作制造出一些混亂,并且大綱模式是以行為單位進行識別的,也就是說`&lt;!--`屬于上一個分支 好在大綱模式可以通過正則表達式來定義結構標識,你可以把結構標識定義為下面這種形式 ``` <!--*結構標識--> ``` 通過設置`outline-regexp`定制標識: ``` setq outline-regexp "<!\\-\\-\\*+ ``` > [![1](https://box.kancloud.cn/2015-10-12_561bcb76795ae.png)](ch25s17.html#emacs-outline31) Elisp 語法中,`\` 有特殊意義,所以脫字符要用`\\`表示 > [![2](https://box.kancloud.cn/2015-10-12_561bcb768596e.png)](ch25s17.html#emacs-outline32) 正則表達式中 `-` 有特殊意義,所以前面要加脫字符 > [![3](https://box.kancloud.cn/2015-10-12_561bcb94ee26f.png)](ch25s17.html#emacs-outline33) `*+` 表示一個或多個`*` ### 配置 完整的配置: **例?25.2.?emacs 大綱模式** ``` (setq outline-minor-mode-prefix [(control o)]) (require 'docbook-xml-mode) (add-hook 'docbook-xml-mode-hook (function (lambda () (setq outline-regexp "<!\\-\\-\\*+") (outline-minor-mode) (hide-body) ))) ``` > [![1](https://box.kancloud.cn/2015-10-12_561bcb76795ae.png)](ch25s17.html#emacs-outline10) 更改大綱模式前綴鍵 > [![1](https://box.kancloud.cn/2015-10-12_561bcb76795ae.png)](ch25s17.html#emacs-outline10) 加載 docbook-xml-mode > [![3](https://box.kancloud.cn/2015-10-12_561bcb94ee26f.png)](ch25s17.html#emacs-outline11) 添加 docbook-xml-mode 鉤子,運行下面代碼[[47](ch25s17.html#ftn.id3111556)] > [![4](https://box.kancloud.cn/2015-10-12_561bcb9508b82.png)](ch25s17.html#emacs-outline12) 將`&lt;!--*`識別為標識 > [![5](https://box.kancloud.cn/2015-10-12_561bcb95133e7.png)](ch25s17.html#emacs-outline13) 啟動大綱模式作為輔模式 > [![6](https://box.kancloud.cn/2016-01-06_568cdb4f32753.png)](ch25s17.html#emacs-outline14) 隱藏所有內容,只顯示主干 ### 操作列表 _顯示、隱藏_ | | 全部顯示 | 顯示分支 | 隱藏 | | --- | --- | --- | --- | | 全局 | show-all | C-o C-a | hide-body | C-o C-t | hide-sublevels | C-o C-q![1](https://box.kancloud.cn/2015-10-12_561bcb76795ae.png) | | 分支 | show-subtree | C-o C-s | hide-leaves | C-o C-l | hide-subtree | C-o C-d | | show-branches | C-o C-k | | show-children | C-o C-i | | 節點 | show-entry | C-o C-e | hide-entry | C-o C-c | | 其它分支 | hide-other | C-o C-o | > [![1](https://box.kancloud.cn/2015-10-12_561bcb76795ae.png)](ch25s17.html#emacs-out81) 可以帶數字參數,如`M-2 C-o C-q`顯示第2層子結構 _移動_ | | 向前 | 向后 | | --- | --- | --- | | 全局 | outline-next-visible-heading | C-o C-n | outline-previous-visible-heading | C-o C-p | | 同級 | outline-forward-same-level | C-o C-f | outline-backward-same-level | C-o C-b | | 返回上一級 | outline-up-heading | C-o C-u | * * * > [[47](ch25s17.html#id3111556)] `docbook-xml-mode.el`中定義 docbook-xml-mode-hook,模式啟動時運行鉤子代碼 ## 在 Emacs 中使用 sdcv 在 Emacs 配置文件中加入以下代碼 ``` (global-set-key (kbd "C-c d") 'kid-sdcv-to-buffer) (defun kid-sdcv-to-buffer () (interactive) (let ((word (if mark-active (buffer-substring-no-properties (region-beginning) (region-end)) (current-word nil t)))) (setq word (read-string (format "Search the dictionary for (default %s): " word) nil nil word)) (set-buffer (get-buffer-create "*sdcv*")) (buffer-disable-undo) (erase-buffer) (let ((process (start-process-shell-command "sdcv" "*sdcv*" "sdcv" "-n" word))) (set-process-sentinel process (lambda (process signal) (when (memq (process-status process) '(exit signal)) (unless (string= (buffer-name) "*sdcv*") (setq kid-sdcv-window-configuration (current-window-configuration)) (switch-to-buffer-other-window "*sdcv*") (local-set-key (kbd "d") 'kid-sdcv-to-buffer) (local-set-key (kbd "q") (lambda () (interactive) (bury-buffer) (unless (null (cdr (window-list))) ; only one window (delete-window))))) (goto-char (point-min)))))))) ``` > [![1](https://box.kancloud.cn/2015-10-12_561bcb76795ae.png)](ch25s18.html#emacs-sdcv-1) 如果選中區域則查詢區域內容,否則查詢當前光標所在單詞。查詢結果顯示在一個叫做 *sdcv* 的緩沖區 > [![2](https://box.kancloud.cn/2015-10-12_561bcb768596e.png)](ch25s18.html#emacs-sdcv-2) 在 *sdcv* 里面按 q,將它隱藏到緩沖區列表的結尾 > [![3](https://box.kancloud.cn/2015-10-12_561bcb94ee26f.png)](ch25s18.html#emacs-sdcv-3) 在 *sdcv* 里面按 d 查詢當前單詞 ## Windows 下字體設置 ``` (set-default-font "Verdana-10") (if window-system (set-fontset-font (frame-parameter nil 'font) 'unicode '("simsun" . "unicode-bmp")) ) ``` > [![1](https://box.kancloud.cn/2015-10-12_561bcb76795ae.png)](ch25s19.html#emacs31) 英文字體 > [![2](https://box.kancloud.cn/2015-10-12_561bcb768596e.png)](ch25s19.html#emacs32) 中文字體 ## 版本 在 Linxu 系統中,Emacs 的最新版本通常為 emacs-snapshot、emacs-cvs Emacs for Windows 請到[這里](http://ourcomments.org/cgi-bin/emacsw32-dl-latest.pl)下載,推薦“patched”版本
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看