Emacs Lisp поиск назад - PullRequest
       20

Emacs Lisp поиск назад

3 голосов
/ 02 ноября 2010

Преамбула

Используя библиотеку 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))

Проблема

По сути, это работает, за исключением того, что поиск имени для включения всегда завершается неудачей, например:

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 ]

2 голосов
/ 02 ноября 2010

ОК, я понял.Каким-то образом я понял, что третий аргумент 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 голос
/ 07 ноября 2010

Команда, которая встроена в 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-/.

...