Emacs Lisp向后搜索

时间:2010-11-02 04:33:04

标签: search 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))

问题

基本上,它起作用,只是搜索包含名称总是失败,例如: 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."*/

我在搜索后退时遇到了什么问题?

(代码中还有另一个(至少一个)错误,如果向后搜索成功,我不应该添加(长度包含名称),但是现在我对如何使其成功更感兴趣,首先)

2 个答案:

答案 0 :(得分:2)

好的,我明白了。不知何故,我有一个想法,搜索后退(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 :(得分: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-/