2014-01-09 3 views
0

В моем .emacs файл У меня есть следующие функции:Поиск лексема вперед

; Search for token forward and backward 
    (defun search-token-forward() 
     "Search forward for the ucode token at the point." 
     (interactive) ; Makes the function available as a command 
     (let (target-string) 
     (setq target-string (buffer-substring 
        (+ (re-search-backward "[^A-Za-z0-9/[email protected]#\$]") 1) 
        (- (re-search-forward "[^A-Za-z0-9/[email protected]#\$]" nil t 2) 1))) 
     ; post a message saying what we're looking for 
     (message "Search for \`%s\`" target-string) 
    ; (setq case-fold-search nil) 
     (search-forward target-string))) 
    (global-set-key [f5]   'search-token-forward) 

(defun search-token-backward() 
    "Search backward for the ucode token at the point." 
    (interactive) 
    (point) 
    (let (target-string) 
    (setq target-string (buffer-substring 
        (+ (re-search-backward "[^A-Za-z0-9/[email protected]#\$]") 1) 
        (- (re-search-forward "[^A-Za-z0-9/[email protected]#\$]" nil t 2) 1))) 
    (message "backward search for \`%s\`" target-string) 
; (setq case-fold-search nil) 
    ; 
    ; here the search for the target string is done twice. Once 
    ; for the string that the cursor is on, and once more to go 
    ; backwards for the next occurance. 
    ; 
    (search-backward target-string nil nil 2))) 
    (global-set-key [C-f5]   'search-token-backward) 

После первого поиска курсор перемещается до после последнего символа выражения, что хорошо, так как я все еще могу сделать «поиск -token-backward ", используя другую функцию, которая у меня есть. К сожалению, при поиске после последнего вхождения выражения курсор перемещается в конец строки, поэтому я не могу плавно попытаться выполнить поиск назад, так как курсор не находится в выражении «position». Что вызывает такое поведение и как его можно исправить?

В принципе, я бы хотел, чтобы курсор оставался в пространстве после последнего символа выражения, даже если его нет.

Ниже приведен пример: В следующем коде, пока курсор находится на функции foo_func, я нажимаю f5, привязанный к поисковым маркерам. Метки Х, где курсор находится после каждого щелчка:

int foo_func(int w, int y); 
     x cursor here to begin with. 

some code... 

foo_func(1, 2); 
     x After first click 
some code... 

foo_func(3,4); 
     x after second click 
some code... 

return foo_func(5,6); 
       x after third click 

Есть в настоящее время нет более вхождений foo_func в файле, так ударяя f5 один больше времени перемещает курсор на один символ вправо, например, так:

return foo_func(5,6); 
       x after forth click, this is the same line above. 

Поэтому я не могу просто нажать ctrl-f5 для поиска назад для foo_func, потому что курсор больше не смежна с функцией.

ответ

1

Записать найденную информацию успешно найденную (см. match-end). Передайте t в качестве аргумента NOERROR, и если возвращаемое значение равно nil, тогда вы знаете, что строка не найдена, поэтому вы можете вернуться в последнюю успешную позицию (на самом деле точка все равно должна быть там).

Извините, забудьте, что я там сказал. Я думал, что у вас проблема с search-forward. Ваша проблема, несомненно, связана с целевой строкой, которую вы пытаетесь найти. Не совсем понятно, что вы действительно хотите найти. Как это сейчас, вы подбирая текст буфера между этими двумя местами:

  • один символ после первого символа обратного, который не является каким-либо из этих символов: A-Za-z0-9/[email protected]#\$.
  • Один символ перед вторым символом, который не является одним из тех же символов.

В случае отказа второй поиск там не вызывает ошибку или не переводит курсор из начальной позиции.

Я подозреваю, что ваше текущее регулярное выражение для этого не то, что вы хотите. Обратите внимание, например, что он соответствует символам новой строки. Помните, что внутри [] (символьная альтернатива) никакие символы не являются специальными, кроме ^, если это первый. См. (elisp) Regexp Special.

Опишите, что текст вы действительно пытаетесь найти из буфера, использовать в качестве строки поиска search-forward (target-string). Укажите его на английском языке, и мы поможем вам придумать, как выбрать его из буфера. Возможно, дайте пример типичного текста, который у вас есть в буфере, показывая, какую часть его вы хотите подобрать, чтобы искать.

* UPDATE *

OK, либо из них должны делать то, что вы спрашиваете, я думаю, но они довольно некрасиво. (Второй является немного более надежным.) Вы, вероятно, будет лучше начинать с нуля ...

(defun search-token-forward() 
    "..." 
    (interactive) 
    (let* ((opoint   (point)) 
      (case-fold-search nil) 
      (back    (re-search-backward "[^A-Za-z0-9/[email protected]#\$]")) 
      (fwd    (re-search-forward "[^A-Za-z0-9/[email protected]#\$]" nil t 2)) 
      (target-string  (and back fwd (buffer-substring (+ back 1) (- fwd 1))))) 
    (when target-string 
     (message "Search for `%s'" target-string) 
     (unless (search-forward target-string nil t) 
     (goto-char opoint) 
     (message "Search failed for `%s'" target-string))))) 

(defun search-token-forward() 
    "..." 
    (interactive) 
    (let* ((opoint   (point)) 
      (case-fold-search nil) 
      (back    (re-search-backward "[^A-Za-z0-9/[email protected]#\$]")) 
      (fwd    (re-search-forward "[^A-Za-z0-9/[email protected]#\$]" nil t 2)) 
      (target-string  (and back fwd (buffer-substring (+ back 1) (- fwd 1))))) 
    (when target-string 
     (message "Search for `%s'" target-string) 
     (condition-case err 
      (search-forward target-string) 
     (search-failed (goto-char opoint) (error (error-message-string err))))))) 

* UPDATE2 *

(defun search-token-backward() 
    "..." 
    (interactive) 
    (let ((opoint   (point)) 
     (case-fold-search nil) 
     back fwd target-string) 
    (save-excursion 
     (setq back (re-search-backward "[^A-Za-z0-9/[email protected]#\$]") 
      fwd (re-search-forward "[^A-Za-z0-9/[email protected]#\$]" nil t 2))) 
    (setq target-string (and back fwd 
           (buffer-substring (+ back 1) (- fwd 1)))) 
    (when target-string 
     (message "Search for `%s'" target-string) 
     (condition-case err 
      (search-backward target-string) 
     (search-failed (goto-char opoint) (error (error-message-string err))))))) 
+0

Дрю, я не владею elisp. Не могли бы вы сообщить мне, что нужно изменить вышеприведенный код для реализации вашей идеи? – SFbay007

+0

Я обновил текст в ответ. У вас пока нет ответа. Не совсем понятно, что вы действительно ищете. Как только вы знаете, какую строку искать, '(search-forward target-string)', как вы думали, все, что вам нужно. – Drew

+0

Спасибо за анализ. Я действительно взял этот кусок кода из файла .emacs коллеги. Поэтому я не уверен, как он построен, но он отлично справляется с поиском следующего «имени переменной/структуры/функции/макроса ... и т. Д.». Я использую его в основном в C и ассемблере. Я думаю, что шаблон, который вы видите, совпадает с возможными именами функций или переменных на этих двух языках. Например, в C вы вряд ли найдете «-», который используется в именах функций, например, в lisp, поэтому в шаблоне сопоставления нет такого символа. – SFbay007

1

Я не отладкой Elisp но и другие решения о том, как искать токен вперед. Функция

1- Используйте Зла

Evil-mode поставляется с этой функцией, связанной с *. Он вызывает функцию evil-search-symbol-forward (VS …-backward, связанный с #).

Вы можете вызвать эту функцию без использования злого режима, если вы этого не хотите. Устанавливайте зло, требуйте его в ~/.emacs с помощью (require 'evil), НЕ пишите (evil-mode 1), если вы не хотите использовать этот режим, а затем привяжите свои ключи к заданным функциям.

2 См пост по усвоению Emacs

Автор этого блога написал функцию, эквивалентную: http://www.masteringemacs.org/articles/2013/10/31/smart-scan-jump-symbols-buffer/

Его преимущество заключается в том, что он имеет еще две функции: заменить символ в целом буфера или в текущем defun.

ps: evil-goto-definition также очень удобно: перейдите к определению или первому вхождению символа под точкой.

Смежные вопросы