2010-11-02 106 views
3

序言的Emacs Lisp搜索落後

使用VTK庫與C++,往往我必須寫這樣的事:

vtkInteractorStyleRubberBandZoom *isrbz = vtkInteractorStyleRubberBandZoom::New(); 

此外,每次我需要用一個新的VTK類在我的程序中,我必須去源文件的某個地方,並添加#include「vtkInteractorStyleRubberBandZoom.h」

我該如何自動化它,所以我必須輸入每個令人難以忍受的長類名稱而不是三個?

我試着爲它寫一個Emacs小模式。現在有可能已有的解決方案(YaSnippet?),但我認爲自己寫這個解決方案也是一個很好的練習。

代碼

;vtk-mode.el 
;add to .emacs: 
;(load "vtk-mode") 
;(global-set-key [(control =)] 'expand-vtk) 

(defun expand-vtk() 
    (interactive) 
    (setq now (point)) 
    (setq vtkstart (search-backward "vtk")) 
    (setq vtkend (- (search-forward " ") 1)) 
    (setq vtkname (buffer-substring vtkstart vtkend)) 

    ;check for #include "vtkBlah.h" 
    (setq includename (format "#include \"%s.h\"\n" vtkname)) 
    (search-backward includename nil (append-include-vtk includename)) 
    (goto-char (+ now (length includename))) 

    (insert (format "= %s::New();" vtkname))) 

(defun append-include-vtk (incname) 
    (goto-char 0) 
    (insert incname)) 

問題

基本上,它的工作原理,只是尋找一個有名字總是失敗,E。 g .:

vtkSomething *smth /*press C-= here, it looks backward for 
#include "vtkSomething.h", can't find it and 
calls append-include-vtk, adding it to the beginning 
of the file, then comes back here and expands this line into: */ 

vtkSomething *smth = vtkSomething::New(); 

//and let's add another instance of vtkSomething... 
vtkSomething *smth2 /*press C-= again, it looks backward for 
#include "vtkSomething", and fails, despite the fact 
that it was added by the previous command. So it adds it again."*/ 

我在做什麼錯在這裏與搜索後退?

(代碼中存在另一個(至少一個)錯誤,如果向後搜索成功,我不應該添加(length includename),但現在我更關心如何使它成功,首先)

回答

2

好的,我明白了。不知何故,我有一個想法,即search-backward(noerror)的第三個參數是回調,事實並非如此。因此每次都會對其進行評估,而不僅僅是搜索失敗。它應該是這樣,而不是:

(defun expand-vtk() 
    (interactive) 
    (setq now (point)) 
    (setq vtkstart (search-backward "vtk")) 
    (setq vtkend (- (search-forward " ") 1)) 
    (setq vtkname (buffer-substring vtkstart vtkend)) 

    ;check for #include "vtkBlah.h" 
    (setq includename (format "#include \"%s.h\"\n" vtkname)) 
    (if (search-backward includename nil t) 
     (goto-char now) 
     (progn (append-include-vtk includename) 
      (goto-char (+ now (length includename))))) 

    (insert (format "= %s::New();" vtkname))) 

(defun append-include-vtk (incname) 
    (goto-char 0) 
    (insert incname)) 
1

它內建到Emacs,將幫助您避免打字難以忍受的漫長的類名的命令是dabbrev-expand(綁定到M-/):

(dabbrev-expand ARG) 

Expand previous word "dynamically". 

Expands to the most recent, preceding word for which this is a prefix. 
If no suitable preceding word is found, words following point are 
considered. If still no suitable word is found, then look in the 
buffers accepted by the function pointed out by variable 
`dabbrev-friend-buffer-function'. 

已經輸入vtkInteractorStyleRubberBandZoom一次,下次你需要它時,你只需鍵入vtkI M-/

+0

謝謝。我知道這一點,並儘可能使用它。然而,在這種特殊情況下,它並不總是有用,因爲圖書館有很多很長的類名,它們共享很多很長的通用前綴。例如,有大約12個以「vtkInteractorStyle ...」開頭的類,如果我需要在同一個源上使用多個類,我仍然需要鍵入「vtkInteractorStyleX ...」和「vtkInteractorStyleY ...」 「 – Headcrab 2010-11-10 20:58:18