weidagang2046的專欄

          物格而后知致
          隨筆 - 8, 文章 - 409, 評論 - 101, 引用 - 0
          數據加載中……

          在Emacs下用C/C++編程

          版權說明和參考文獻

          按照慣例,我寫的文章在最開始處放版權說明和參考文獻。

          參考文獻:

          • hhuu @ newsmth 的《Emacs的日常生活》
          • emacs 的文檔
          • emacs 相關插件的文檔

          版權說明:

          轉載請注明轉自 曹樂的個人主頁 www.caole.net,請保證全文轉載,尤其不可省略這一部分。

          用emacs寫程序也有5個年頭了,深切地體會到Emacs的強大。程序員有三種,一種是用vi的,一種是用emacs的,還有一種是其他。或許有些夸張,但也頗能體現出emacs在程序員中的地位。

          emacs最大的問題在于入門門檻較高。它看起來和多數人想象中的IDE相差甚遠,很多人看到emacs的第一眼就覺得它是個記事本(還是個非常難用的記事本),稍微好些的往往覺得emacs也就是個ultraEditor而已,真是暴殄天物了。

          我是個懶人,不喜歡記太多的快捷鍵,相信很多人和我一樣。所以從我后面的敘述可以看出來,除了常用的命令都是快捷鍵外,其他命令多數都是用M-x執行或者用鼠標點菜單。這僅僅是個人風格問題,先說明一下。

          我的基本編程環境是:

          • Debian GNU/Linux sid 操作系統
          • Gnome 2.10.0 桌面環境
          • GUN Emacs 23.0.0.1 for debian
          • 使用 Gnu tool chains(gcc,make,gdb等等)

          后面的敘述都基于上述環境。另外,本文主要針對C/C++程序開發,對其他語言有些也適用,從難度上說,本文主要針對入門者。

          本文肯定會有很多錯誤, 請指正 ,謝謝。

          基本流程

          寫C++程序基本上是這么幾個步驟:

          1. 編輯代碼
          2. 編寫Makefile
          3. 編譯代碼,修改編譯錯誤
          4. 調試代碼,修改邏輯錯誤

          當然,往往還需要閱讀別人的代碼。

          根據上述步驟,本文主要針對以下幾個方面:

          • 配置Emacs,建立便利的代碼編輯環境和Makefile編寫環境。
          • 在Emacs中編譯代碼,并修改編譯錯誤。
          • 在Emacs中配合GDB調試程序。
          • 利用cscope和ecb在emacs中閱讀代碼。

          基本環境設置

          編輯環境配置

          要寫C++程序,當然要用到cc-mode插件。CC-Mode原本是支持C語言的,但現在也能支持很多語言,比如C++,Java,Objective-C,CORBA,AWK,Pike等等。CC-Mode是gnu-emacs的標準插件。如果您要求不高,那么默認的配置或許就能滿足。CC-Mode的各種行為都可以自由地定制,您可以參考這里的文檔: CC-Mode參考文檔

          這里是我的.emacs文件中關于CC-Mode配置的部分,僅供參考:

          				;;;; CC-mode配置  http://cc-mode.sourceforge.net/
          (require 'cc-mode)
          (c-set-offset 'inline-open 0)
          (c-set-offset 'friend '-)
          (c-set-offset 'substatement-open 0)
          
          		
          				;;;;我的C/C++語言編輯策略
          
          (defun my-c-mode-common-hook()
            (setq tab-width 4 indent-tabs-mode nil)
            ;;; hungry-delete and auto-newline
            (c-toggle-auto-hungry-state 1)
            ;;按鍵定義
            (define-key c-mode-base-map [(control \`)] 'hs-toggle-hiding)
            (define-key c-mode-base-map [(return)] 'newline-and-indent)
            (define-key c-mode-base-map [(f7)] 'compile)
            (define-key c-mode-base-map [(meta \`)] 'c-indent-command)
          ;;  (define-key c-mode-base-map [(tab)] 'hippie-expand)
            (define-key c-mode-base-map [(tab)] 'my-indent-or-complete)
            (define-key c-mode-base-map [(meta ?/)] 'semantic-ia-complete-symbol-menu)
          
          		

          注意一下,上面最后兩行是代碼自動補齊的快捷鍵。后面我會提到代碼自動補齊。

          				  ;;預處理設置
            (setq c-macro-shrink-window-flag t)
            (setq c-macro-preprocessor "cpp")
            (setq c-macro-cppflags " ")
            (setq c-macro-prompt-flag t)
            (setq hs-minor-mode t)
            (setq abbrev-mode t)
          )
          (add-hook 'c-mode-common-hook 'my-c-mode-common-hook)
          
          ;;;;我的C++語言編輯策略
          (defun my-c++-mode-hook()
            (setq tab-width 4 indent-tabs-mode nil)
            (c-set-style "stroustrup")
          ;;  (define-key c++-mode-map [f3] 'replace-regexp)
          )
          
          		

          自動補齊

          自動補齊通常用的都是hippie-expand,我也用了很長時間。不過有時候會覺得這個自動補齊“傻”了一點,常會補齊出一些毫不相干的東西,因為hippie-expand是根據你敲過的詞和kill-ring等進行判斷的,并不對程序語法進行分析。

          所以你還需要安裝一個代碼分析工具,然后把它加進hippie-expand的擴展策略里去。我們可以用semantic。實際上,hippie-expand+semantic是我所發現的最好的選擇了,如果您有更好的,請您也告訴我一聲:)

          Semantic是 CEDET 中的一個工具,CEDET是Collection of Emacs Development Environment Tools的縮寫,它包含了好幾個工具,都挺不錯的。可惜我只會用其中兩個。

          您可以在.emacs中對Semantic進行配置,下面是我的.emacs相關的配置,僅供參考:

          導入cedet:

          				(load-file "~/lib/emacs-lisp/cedet-1.0pre3/common/cedet.el")
          
          		

          配置Semantic的檢索范圍:

          				(setq semanticdb-project-roots 
          	  (list
                  (expand-file-name "/")))
          
          		

          自定義自動補齊命令,這部分是抄hhuu的,如果在單詞中間就補齊,否則就是tab。

          				(defun my-indent-or-complete ()
             (interactive)
             (if (looking-at "\\>")
           	  (hippie-expand nil)
           	  (indent-for-tab-command))
           )
          
          (global-set-key [(control tab)] 'my-indent-or-complete)
          
          		

          hippie的自動補齊策略,優先調用了senator的分析結果:

          				(autoload 'senator-try-expand-semantic "senator")
          
          (setq hippie-expand-try-functions-list
           	  '(
          		senator-try-expand-semantic
          		try-expand-dabbrev
          		try-expand-dabbrev-visible
          		try-expand-dabbrev-all-buffers
          		try-expand-dabbrev-from-kill
          		try-expand-list
          		try-expand-list-all-buffers
          		try-expand-line
                  try-expand-line-all-buffers
                  try-complete-file-name-partially
                  try-complete-file-name
                  try-expand-whole-kill
                  )
          )
          
          		

          注意一下我前面CC-Mode配置中有這么兩行:

          				  (define-key c-mode-base-map [(tab)] 'my-indent-or-complete)
            (define-key c-mode-base-map [(meta ?/)] 'semantic-ia-complete-symbol-menu)
          
          		

          這樣,我們在CC-Mode中就可以調用自定義的hippie補全了,快捷鍵是Tab。

          另外,我還把快捷鍵“Alt + / ”綁定到了semantic-ia-complete-symbol-menu命令上,這是semantic的命令,它會根據分析結果彈出補齊的菜單,效果如圖顯示:

          CEDET中還有一個不錯的工具是speedbar,你可以用它在多個文件中快速切換。在我的.emacs配置文件里,我把speedbar關聯到了F5上:

          				(global-set-key [(f5)] 'speedbar)
          
          		
          這樣用F5就可以調出speedbar,效果如下:

          不過說實話,我自己很少用到speedbar,我通常都是用dired配合bookmark使用:)

          編譯和調試程序

          按上面的配置,寫完程序和Makefile文件后,在Emacs源代碼窗口中按F7就可以進行編譯。因為在my-c-mode-common-hook()函數里,有這么一行:

          				 (define-key c-mode-base-map [(f7)] 'compile)
          
          		

          默認情況下,emacs的compile命令是調用make -k,我把它改成了make。你也可以把它改成其他的,比如gcc之類的。改下面的“make”就行了。

          				'(compile-command "make")
          
          		

          Emacs會劃分一個窗格顯示編譯的消息,在編譯結束后,emacs會自動將編譯器的輸出和程序關聯起來,告訴你第幾行的程序有問題。直接在出錯的行號上按Enter,就可以跳轉到相應文件的相應行。其實我通常都是用鼠標中鍵去點出錯行號:)

          搞定了編譯錯誤后,接著要和邏輯錯誤斗爭了。其實對簡單的程序來說,把中間結果打印到終端是最簡單好用的調試辦法:)不過稍微復雜點的程序就會暈菜了,這時我們就需要拿gdb跟蹤程序流程了。

          你用下面的命令就可以啟動gdb了。

          				M-x gdb
          
          		

          通常我喜歡進入gdb-many-windows模式,這樣就會把一個Frame劃分為5個窗格,同時顯示:gdb命令窗口,當前局部變量,程序文本,調用棧和斷點。

          gdb的命令就不在這里說了,它的文檔幾乎到處都是。emacs把gdb的命令和快捷鍵做了綁定,對于常用的命令,還是輸入快捷鍵比較方便。比如,C-c C-n是Next line,C-c C-s是step in,其實用的最多的快捷鍵也就是這兩個。

          下面是我的gdb效果圖:

          閱讀代碼

          在emacs下讀代碼通常有三種工具,最簡單的是etags,最復雜的是ecb(emacs code browser),位于中間的是cscope。

          etags和ctags一樣,只不過前者是用于emacs的,后者是用于vi的。我個人覺得etags功能稍稍顯得不夠用一點,當然,也可能是我用的不好:) 歡迎大牛指導。

          使用tags之前要先對源代碼分析建立tags文件,在代碼所在目錄中運行:etags -R 即可。

          我常用的就這幾個命令和快捷鍵:

          				M-x visit-tags-table <RET> FILE <RET>   選擇tags文件
          M-. [TAG] <RET>                         訪問標簽
          M-*                                     返回
          C-u M-.                                 尋找標簽的下一個定義
          
          		

          ecb據說功能強大,但是太復雜了,我懶得折騰它。誰搞定了教教我吧:) 下面是一張ecb的效果圖。

          cscope是我感覺比較合適的一個工具。它其實是一個獨立的軟件,完全可以脫離vi和emacs使用。但是結合emacs的強大功能,cscope就顯得更加方便了。GNU Emacs默認自帶cscope的支持。在使用之前,cscope也需要對代碼進行索引。在emacs中可以這樣做:

          				C-c s a             設定初始化的目錄,一般是你代碼的根目錄
          C-s s I             對目錄中的相關文件建立列表并進行索引
          
          		

          建完索引之后,你就可以用cscope在代碼里游蕩了。常用的一些命令如下:

          				C-c s s             序找符號
          C-c s g             尋找全局的定義
          C-c s c             看看指定函數被哪些函數所調用
          C-c s C             看看指定函數調用了哪些函數
          C-c s e             尋找正則表達式
          C-c s f             尋找文件
          C-c s i             看看指定的文件被哪些文件include
          
          		

          上面這些快捷鍵其實我自己也常常記不全,沒關系,抬頭看看上面的菜單欄,有一欄就是Cscope,這些命令里頭都有:)

          貼一個cscope的效果圖吧:

          寫完了。希望這篇文章對您能有一些用處。有問題或建議可以和 聯系。

          posted on 2006-07-28 23:23 weidagang2046 閱讀(885) 評論(0)  編輯  收藏 所屬分類: Linux

          主站蜘蛛池模板: 调兵山市| 贞丰县| 临颍县| 凤城市| 家居| 萨嘎县| 定南县| 舞阳县| 武宣县| 历史| 安泽县| 兴化市| 冕宁县| 平果县| 凤庆县| 兰考县| 大安市| 新民市| 江达县| 岳阳市| 平遥县| 永年县| 东兰县| 新巴尔虎左旗| 甘洛县| 济南市| 石阡县| 盘锦市| 修武县| 岐山县| 广宗县| 三门县| 开江县| 银川市| 江阴市| 宝应县| 桦甸市| 乾安县| 新沂市| 五河县| 满洲里市|