source insight是windows環境下用於代碼開發和閱讀的利器,功能強大,對於大規模代碼的維護和開發幾乎不可或缺(這裏 php
指它提供的功能,相似的商業工具還有不少)。使用emacs替代source insight緣由有:a,si是商業軟件,使用須要付費,雖然能夠從網上 css
找到破解版本;b,對於unix/linux愛好者或者須要同時工做於unix和windows環境下的開發人員,emacs是通用工具;emacs其它的強大 html
功能暫且不表。 linux
下面是基於windows xp平臺的安裝方法,其中大部分步驟和unix環境下的同樣,只有cscope的有所不一樣。 c++
1)準備工做 shell
首先,你得下載一下一些工具(擴展),emacs,cscope,ecb,cedet是必須的,session,doxymacs不是必要的,可是裝上會 windows
更方便。下載這些東西的網址連接以下:(固然,下面這些東西均可以從google找到下載連接,下面提供的網址都是google出來的,若是 瀏覽器
下面提供的連接不可用了,你們能夠本身google一把) bash
i)emacs: session
http://www.gnu.org/software/emacs/
從gnu的ftp網站上下載windows版本,最新的版本是emacs-22.1。下面的設置都是在這個版本上進行的。
ii)cscope:cscope的主頁
http://cscope.sourceforge.net/
,其中有一個download的連接,從那裏能夠下載到編譯好的壓縮包。
win32版本的下載地址:
http://iamphet.nm.ru/cscope/index.html
,壓縮包中有兩個編譯好的exe文件:cscope.exe, sort.exe
iii)ecb:主頁地址
,download頁面中還有一個Xemcas的安裝程序setup.exe,能夠試試,我沒有使用這個。
sourceforg下載地址
http://sourceforge.net/project/showfiles.php?group_id=17484
iv)cedet:主頁
,下載release壓縮包1.0pre4.tar.gz,這個包中已經包含了semantic,ede,eieio,
speedbar,所以下載了這個大包後不用分別下載這些擴展插件。
v)session:sf下載地址
http://sourceforge.net/project/showfiles.php?group_id=46019
vi)doxymacs:地址
http://doxymacs.sourceforge.net/
,
下載
http://sourceforge.net/project/s ... p;release_id=514962
vii)下載windows下的bash工具,主要是用到其中的find工具,用來手工生成cscope.files。若是安裝了cygwin則不用安裝這個了。
地址:
http://folk.uio.no/andreass/unix_tools.html
2)安裝
安裝emacs:這個很簡單,只要將壓縮包解開,放到你想放的位置就能夠用了,若是要在windows的開始菜單中添加菜單項,點擊bin目錄下
的addpm運行,就會在菜單中加入gnu菜單項。
安裝cscope:a,解壓平臺不相關的那個tar.gz包,將/contrib/xscope/xscope.el拷貝到emacs-22.1/site-lisp目錄下(emacs-22.1是
你安裝emacs的目錄);b,解壓win32版本的cscope,將cscope.ext sort.exe拷貝到emacs-22.1/bin目錄下(這個路徑不是必要的,由於
cscope在windows下要用起來還得費點勁,4)點會講到)
安裝ecb:解壓,將解壓後的ecb目錄拷貝到site-lisp目錄下。
安裝cedet:解壓,將解壓後的cedet目錄拷貝到site-lisp目錄下。
安裝session:解壓,將解壓後的session目錄拷貝到site-lisp目錄下。
安裝doxymacs:解壓,將解壓後的doxymacs目錄拷貝到site-lisp目錄下。
安裝win32bash:點擊user.exe安裝文件一步步點到最後就好了。
到此安裝工做完成。
3)配置.emacs啓動文件
顯示指定擴展插件的加載地址(這一步好像不是必要的,只列出一個地址,其它相似)
(add-to-list 'load-path "e:/emacs/site-lisp/ecb-2.31"
加載相應插件:
(require 'xcscope) ;;加載xcscope
(require 'cedet) ;;加載cedet
(require 'ecb) ;;加載ecb
(require 'session) ;;加載session
(add-hook 'after-init-hook 'session-initialize) ;; 啓動時初始化session
(require 'doxymacs) ;; 啓動doxymacs
在配置文件中加入這些語句後,保存重啓emacs,重啓後查看一下Message窗口中的加載信息,能夠看到各個插件加載成功。
在.emacs中加入一些方便的設置就可使用了,完整的配置文件附在後面。(這些配置都是從google上處處搜刮來的,其中王垠博士的
網頁上有不少emacs設置的好東西能夠參考,還有一些英文網站上貼出的配置文件中也有不少好東西,你們能夠根據本身的習慣寫本身的
配置)
4)問題及解決
安裝進行到這裏,大部分功能都沒有問題了,存在的問題有:
i)cscope的建立文件列表和建立代碼符號索引兩個命令不可用,按下C-c s L和C-c s I後minibuffer中顯示cscope-indexer找不到。在
cscope的安裝包中確實有一個cscope-indexer的文件,咱們安裝時沒有將它拷貝到emacs的安裝路徑中去,可是即便將它拷貝到bin目錄下
也仍是不能工做,用文本編輯器打開cscope-indexer會發現它實際上是個shell腳本文件,從腳本中能夠看到,它首先經過find,grep等工具
生成一個cscope.files的文件,而後調用cscope使用cscope.files做爲輸入生成cscope.out的索引文件。
所以,只要能生成一個文件列表的文件就可使用win32版本的cscope.exe來生成cscope.out文件。到此,咱們可使用win32bash中的find
工具生成一個源代碼文件列表了(與unix下同樣:find /my-project-source -name "*.[chs]" -print > cscope.files,不知windows下
是否有相似find這樣功能的命令,xp下的find好像不能用通配符,若是有這樣的東西就能夠不安裝win32bash)。
生成了cscope.files源碼文件列表後就可使用它像si同樣在代碼間穿梭了:
C-c s a設定代碼根目錄,cscope.files必須放在這個設定目錄下,不然cscope找不到;在第一次使用以下幾條命令時cscope會自動生成
cscope.out,也能夠在windows的cmd中調用cscope.exe -b -i cscope.files -f cscope.out生成cscope.out。
C-c s g查找函數(或變量)定義;
C-c s c查看調用者;
C-c s C查看函數中調用的子函數;
ii)semantic中設置的項目根目錄好像不起做用,在進行tag查找時semantic只查了當前目錄中的代碼文件,若是引用的是其它目錄中的函數
或變量,查找相應定義時就找不到。這個問題還不知道緣由,多是設置的問題,semantic的設置項太多了。遇到相同問題的朋友請解答一下。
到此,si中經常使用的幾個動做實現了。
還有個si中相似功能的實現:跳到函數定義後如何在跳回剛纔的調用函數的地方。
在王垠的網頁中找到了一個實現
;;;臨時記號
(global-set-key [(control ?\.)] 'ska-point-to-register)
(global-set-key [(control ?\,)] 'ska-jump-to-register)
(defun ska-point-to-register()
"Store cursorposition _fast_ in a register.
Use ska-jump-to-register to jump back to the stored
position."
(interactive)
(setq zmacs-region-stays t)
(point-to-register
)
(defun ska-jump-to-register()
"Switches between current cursorposition and position
that was stored with ska-point-to-register."
(interactive)
(setq zmacs-region-stays t)
(let ((tmp (point-marker)))
(jump-to-register
(set-register 8 tmp)))
這樣就能夠在函數間跳來跳去,
結合cscope的pop-mark,就能夠跳來跳去了,這樣基本能夠知足大多數狀況下的使用。
還有一些有用擴展:
http://docs.huihoo.com/homepage/shredderyin/emacs_elisp.html
ecb,cedet(semantic)提供了不少功能,不過因爲太多了,須要慢慢摸索,目前使用cscope已經基本上實現了si上的幾個經常使用功能,
ecb + semantic能夠實現像si中的函數/變量上下文顯示功能,可是因爲4)ii)中提到的問題,這個顯示上下文功能有時候不起做用。
附:一個雜七雜八的配置文件
;;basic setting =============================================
(setq display-time-24hr-format t)
(display-time)
(column-number-mode t)
(transient-mark-mode t)
(tool-bar-mode -1)
(setq visible-bell t)
(setq inhibit-startup-message t)
(setq mouse-yank-at-point t)
(setq default-fill-column 60)
;(setq-default indent-tabs-mode nil)
;(setq default-tab-width
;(setq tab-stop-list ()
; (loop for x downfrom 40 to 1 do
; (setq tab-stop-list (cons (* x 4) tab-stop-list))))
(global-set-key [f3] 'repeat-complex-command)
(global-set-key [f4] 'other-window)
;; 跳轉到 Emacs 的另外一個buffer窗口
;; 能夠從外面粘貼東西
(setq x-select-enable-clipboard t)
;; 屏蔽C-SPC的set mark功能 , 目前沒必要要,SCIM輸入法不能用
(global-set-key (kbd "C-SPC"
'nil)
(global-set-key (kbd "M-"
'set-mark-command)
;;這樣 我就不用按 C-@ 來 setmark 了, C-@ 很很差按。
(setq sentence-end "\\([。!?]\\|……\\|[.?!][]\"')}]*\\($\\|[ \t]\\)\\)[ \t\n]*"
(setq sentence-end-double-space nil)
(setq enable-recursive-minibuffers t)
(setq scroll-margin 3
scroll-conservatively 10000)
(setq default-major-mode 'text-mode)
(show-paren-mode t)
(setq show-paren-style 'parentheses)
(mouse-avoidance-mode 'animate)
(setq frame-title-format "emacs@%b"
(auto-image-file-mode)
;;shadow password
(add-hook 'comint-output-filter-functions
'comint-watch-for-password-prompt)
;; global font lock
(global-font-lock-mode 1)
(put 'set-goal-column 'disabled nil)
(put 'narrow-to-region 'disabled nil)
(put 'upcase-region 'disabled nil)
(put 'downcase-region 'disabled nil)
(put 'LaTeX-hide-environment 'disabled nil)
;;version control
(setq version-control t)
(setq kept-new-versions 3)
(setq delete-old-versions t)
(setq kept-old-versions 2)
(setq dired-kept-versions 1)
(mapcar
(function (lambda (setting)
(setq auto-mode-alist
(cons setting auto-mode-alist))))
'(("\\.xml$". sgml-mode)
("\\\.bash" . sh-mode)
("\\.rdf$". sgml-mode)
("\\.session" . emacs-lisp-mode)
("\\.l$" . c-mode)
("\\.css$" . css-mode)
("\\.cfm$" . html-mode)
("gnus" . emacs-lisp-mode)
("\\.idl$" . idl-mode)))
(setq dired-recursive-copies 'top)
(setq dired-recursive-deletes 'top)
;; frame customize
;(setq default-frame-alist
; '((top . 200) (left . 400)
; (width . 160) (height . 70)
; (cursor-color . "green"
; (cursor-type . box)
; (foreground-color . "grey"
; (background-color . "black"
))
;(font . "-*-Courier-namorl-r-*-*-13-*-*-*-c-*-iso8859-1"
))
;(setq initial-frame-alist '((top . 30) (left . 10)))
;(condition-case err
; (progn
; (require 'xxx))
; (error
; (message "Can't load xxx-mode %s" (cdr err))))
; chinese environment
(set-terminal-coding-system 'chinese-iso-8bit)
(set-keyboard-coding-system 'chinese-iso-8bit)
(setq locale-coding-system 'chinese-iso-8bit)
;;display number
(require 'setnu)
(global-set-key [f11] 'setnu-mode)
(setq-default kill-whole-line t);;刪除整行時,順便把產生的空格行也刪除掉。
;(w32-send-sys-command #xf030);;窗口最大化
(setq track-eol t)
;; 當光標在行尾上下移動的時候,始終保持在行尾。
;;保存文件時在最後使用換行
(setq require-final-newline t)
(setq suggest-key-bindings 1)
;;;;設置移動窗口命令
;(global-set-key [M-down] 'windmove-down)
; (global-set-key [M-up] 'windmove-up)
; (global-set-key [M-right] 'windmove-right)
;(global-set-key [M-left] 'windmove-left)
(require 'ibuffer)
(global-set-key (kbd "C-x C-b"
'ibuffer)
(require 'browse-kill-ring)
(global-set-key [(control c)(k)] 'browse-kill-ring)
(browse-kill-ring-default-keybindings)
(require 'ido)
(ido-mode t)
;;ido綁定鍵
;;{{{ ido: fast switch buffers
(add-hook 'ido-define-mode-map-hook 'ido-my-keys)
(defun ido-my-keys ()
"Set up the keymap for `ido'."
;; common keys
(define-key ido-mode-map "\C-e" 'ido-edit-input)
(define-key ido-mode-map "\t" 'ido-complete) ;; complete partial
(define-key ido-mode-map "\C-j" 'ido-select-text)
(define-key ido-mode-map "\C-m" 'ido-exit-minibuffer)
(define-key ido-mode-map "?" 'ido-completion-help) ;; list completions
(define-key ido-mode-map [(control ? )] 'ido-restrict-to-matches)
(define-key ido-mode-map [(control ?@)] 'ido-restrict-to-matches)
;; cycle through matches
(define-key ido-mode-map "\C-r" 'ido-prev-match)
(define-key ido-mode-map "\C-s" 'ido-next-match)
(define-key ido-mode-map [right] 'ido-next-match)
(define-key ido-mode-map [left] 'ido-prev-match)
;; toggles
(define-key ido-mode-map "\C-t" 'ido-toggle-regexp) ;; same as in isearch
(define-key ido-mode-map "\C-p" 'ido-toggle-prefix)
(define-key ido-mode-map "\C-c" 'ido-toggle-case)
(define-key ido-mode-map "\C-a" 'ido-toggle-ignore)
;; keys used in file and dir environment
(when (memq ido-cur-item '(file dir))
(define-key ido-mode-map "\C-b" 'ido-enter-switch-buffer)
(define-key ido-mode-map "\C-d" 'ido-enter-dired)
(define-key ido-mode-map "\C-f" 'ido-fallback-command)
;; cycle among directories
;; use [left] and [right] for matching files
(define-key ido-mode-map [down] 'ido-next-match-dir)
(define-key ido-mode-map [up] 'ido-prev-match-dir)
;; backspace functions
(define-key ido-mode-map [backspace] 'ido-delete-backward-updir)
(define-key ido-mode-map "\d" 'ido-delete-backward-updir)
(define-key ido-mode-map [(meta backspace)] 'ido-delete-backward-word-updir)
(define-key ido-mode-map [(control backspace)] 'ido-up-directory)
;; I can't understand this
(define-key ido-mode-map [(meta ?d)] 'ido-wide-find-dir)
(define-key ido-mode-map [(meta ?f)] 'ido-wide-find-file)
(define-key ido-mode-map [(meta ?k)] 'ido-forget-work-directory)
(define-key ido-mode-map [(meta ?m)] 'ido-make-directory)
(define-key ido-mode-map [(meta down)] 'ido-next-work-directory)
(define-key ido-mode-map [(meta up)] 'ido-prev-work-directory)
(define-key ido-mode-map [(meta left)] 'ido-prev-work-file)
(define-key ido-mode-map [(meta right)] 'ido-next-work-file)
;; search in the directories
;; use C-_ to undo this
(define-key ido-mode-map [(meta ?s)] 'ido-merge-work-directories)
(define-key ido-mode-map [(control ?_)] 'ido-undo-merge-work-directory)
)
(when (eq ido-cur-item 'file)
(define-key ido-mode-map "\C-k" 'ido-delete-file-at-head)
(define-key ido-mode-map "\C-l" 'ido-toggle-literal)
(define-key ido-mode-map "\C-o" 'ido-copy-current-word)
(define-key ido-mode-map "\C-v" 'ido-toggle-vc)
(define-key ido-mode-map "\C-w" 'ido-copy-current-file-name)
)
(when (eq ido-cur-item 'buffer)
(define-key ido-mode-map "\C-b" 'ido-fallback-command)
(define-key ido-mode-map "\C-f" 'ido-enter-find-file)
(define-key ido-mode-map "\C-k" 'ido-kill-buffer-at-head)
))
;;(ido-mode t)
;;}}}
;;使用這個,你就能夠方便的在最近編輯的 buffer 之間切換了。切換的時候會出現一個小窗口顯示附近的buffer,就像翻頁同樣.
;;默認的鍵是 C-f6 爲 swbuff-switch-to-next-buffer。 C-S-F6爲 swbuff-switch-to-previous-buffer
(require 'swbuff)
(global-set-key (kbd ""
'swbuff-switch-to-previous-buffer)
(global-set-key (kbd "") 'swbuff-switch-to-next-buffer)
(setq swbuff-exclude-buffer-regexps
'("^ " "\\*.*\\*"))
(setq swbuff-status-window-layout 'scroll)
(setq swbuff-clear-delay 1)
(setq swbuff-separator "|")
(setq swbuff-window-min-text-height 1)
(require 'tabbar)
(tabbar-mode)
(global-set-key (kbd "") 'tabbar-backward-group)
(global-set-key (kbd "") 'tabbar-forward-group)
(global-set-key (kbd "") 'tabbar-backward)
(global-set-key (kbd "") 'tabbar-forward)
;;;表格
(autoload 'table-insert "table" "WYGIWYS table editor")
;;;將語法加量文件輸出爲彩色HTML文件
;;(load "htmlize")
;;;將emacs作爲圖片瀏覽器
(load "thumbs")
;;;設置c-o,這樣在一行中的任何位置就能夠直接新建一行了。至關於先c-e再enter
(global-set-key (kbd "C-o")
'(lambda ()
(interactive)
(end-of-line 1)
(newline-and-indent)))
(load "color-theme")
(color-theme-dark-blue2)
;;programming setting =================================================================
(require 'xcscope) ;;加載xcscope
(require 'cedet) ;;加載cedet
(require 'ecb) ;;加載ecb
(require 'session) ;;加載session
(add-hook 'after-init-hook 'session-initialize) ;; 啓動時初始化session
(require 'doxymacs) ;; 啓動doxymacs
(add-hook 'c-mode-common-hook 'doxymacs-mode) ;; 啓動doxymacs-mode
(add-hook 'c++-mode-common-hook 'doxymacs-mode) ;; 啓動doxymacs-mode
(desktop-load-default) ;;讀取默認desktop設置
(desktop-read) ;;讀取當前目錄保存的desktop設置
;(set-face-background 'default "LightCyan3") ;;設置背景色爲 淺青色3
;(set-face-font 'default "-outline-新宋體-normal-r-normal-normal-*-*-96-96-c-*-iso8859-1") ;;設置字體爲新宋體 ( Only for windows )
;(global-set-key [f12] 'ecb-activate) ;;定義F12鍵爲激活ecb
(global-set-key [C-f12] 'ecb-deactivate) ;;定義Ctrl+F12爲中止ecb
(global-set-key [C-f11] 'delete-other-windows) ;;設置F11爲刪除其它窗口
(global-set-key [(meta return)] 'semantic-ia-complete-symbol-menu) ;;設置Alt+Enter爲自動補全菜單
(global-set-key [(control ?\;)] 'ecb-goto-window-edit-last) ;;切換到編輯窗口
(global-set-key [(control ?\')] 'ecb-goto-window-methods) ;;切換到函數窗口
(global-set-key [(control ?\=)] 'cscope-find-global-definition-no-prompting) ;;搜索定義
(global-set-key [(control ?\/)] 'cscope-find-called-functions)
(global-set-key [(control ?\,)] 'cscope-pop-mark) ;; 跳出轉向
(enable-visual-studio-bookmarks) ;; 啓動VS書籤子程序
(setq semanticdb-project-roots (list "g:/ob41")) ;; 設置cemanticdb的掃描根目錄
(add-hook 'c-mode-common-hook ( lambda() ( c-set-style "k&r" ) ) ) ;;設置C語言默認格式
(add-hook 'c++-mode-common-hook ( lambda() ( c-set-style "k&r" ) ) ) ;;設置C++語言默認格式
;;;臨時記號
(global-set-key [(control ?\.)] 'ska-point-to-register)
(global-set-key [(meta ?\,)] 'ska-jump-to-register)
(defun ska-point-to-register()
"Store cursorposition _fast_ in a register.
Use ska-jump-to-register to jump back to the stored
position."
(interactive)
(setq zmacs-region-stays t)
(point-to-register
)
(defun ska-jump-to-register()
"Switches between current cursorposition and position
that was stored with ska-point-to-register."
(interactive)
(setq zmacs-region-stays t)
(let ((tmp (point-marker)))
(jump-to-register
(set-register 8 tmp)))
(setq speedbar-show-unknown-files t);;能夠顯示全部目錄以及文件
(setq dframe-update-speed nil);;不自動刷新,手動 g 刷新
(setq speedbar-update-flag nil)
(setq speedbar-use-images nil);;不使用 image 的方式
(setq speedbar-verbosity-level 0)
(setq ecb-tip-of-the-day nil)
(custom-set-variables
;; custom-set-variables was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
'(ecb-auto-expand-tag-tree (quote all))
'(ecb-gzip-setup (quote cons))
'(ecb-layout-window-sizes (quote (("left8" (0.21844660194174756 . 0.288135593220339) (0.21844660194174756 . 0.23728813559322035) (0.21844660194174756 . 0.288135593220339) (0.21844660194174756 . 0.169491525423728
))))
'(ecb-options-version "2.32")
'(ecb-tar-setup (quote cons))
'(ecb-type-tag-expansion (quote ((default . all-specifiers) (c-mode . all-specifiers))))
'(ecb-wget-setup (quote cons))
'(global-semantic-decoration-mode t nil (semantic-decorate-mode))
'(global-semantic-highlight-edits-mode t nil (semantic-util-modes))
'(global-semantic-idle-completions-mode t nil (semantic-idle))
'(global-semantic-show-parser-state-mode t nil (semantic-util-modes))
'(global-semantic-show-unmatched-syntax-mode t nil (semantic-util-modes))
'(global-semantic-stickyfunc-mode t nil (semantic-util-modes))
'(imenu-auto-rescan nil)
'(semantic-edits-verbose-flag t)
'(semantic-imenu-auto-rebuild-directory-indexes t)
'(semantic-imenu-index-directory t)
'(semantic-imenu-summary-function (quote semantic-format-tag-abbreviate))
'(semantic-which-function-use-color t)
'(semanticdb-default-save-directory "g:/ob41")
'(semanticdb-find-default-throttle (quote (file local project unloaded system recursive omniscience)))
'(semanticdb-project-roots (quote ("g:/ob41"))))
(custom-set-faces
;; custom-set-faces was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
)
;(require 'recentf)
;(recentf-mode 1)
;(defun recentf-open-files-compl ()
; (interactive)
; (let* ((all-files recentf-list)
; (tocpl (mapcar (function
; (lambda (x) (cons (file-name-nondirectory x) x))) all-files))
; (prompt (append '("File name: ") tocpl))
; (fname (completing-read (car prompt) (cdr prompt) nil nil)))
; (find-file (cdr (assoc-ignore-representation fname tocpl)))))
;(global-set-key [(control x)(control r)] 'recentf-open-files-compl)
(setq semantic-load-turn-everything-on t)
;(add-hook 'semantic-init-hooks 'semantic-idle-completions-mode)
(autoload 'senator-try-