Видаліть частину рядка Isearch, що не відповідає, або останній знак char, якщо завершено збіг


11

У мене є таке

(defun isearch-del-fail-or-char ()
  "Delete failed isearch text, or if there is none, a single character."
  (interactive)
  (if (isearch-fail-pos)
      (delete-region (isearch-fail-pos) (point))
    (isearch-del-char)))

(define-key isearch-mode-map (kbd "DEL") 'isearch-del-fail-or-char)

Призначення коду полягає в тому, щоб зробити deleteв пошуку пошук видалити всю невдалу рядок (або, якщо немає невдалого рядка, лише один символ).

Однак delete-regionвидалення тексту з буфера isearchпошуку, а не самого буфера пошуку.

Який правильний спосіб це зробити? Критика щодо решти мого стилю emacs lisp також вітається :)

Відповіді:


12

Ага так. Isearch зчитує введені вами ключі, шукає їх isearch-mode-mapі викликає їх у поточному буфері .

ISearch робить НЕ , незважаючи на виступи, використовуйте мінібуфер. Він використовує зону відлуння. Тобто те, що ви бачите там, насправді виводить повідомлення, включаючи відгомони символів, які ви вводите.

Це має робити те, що ви просите:

(defun mydelete ()
  "Delete the failed portion of the search string, or the last char if successful."
  (interactive)
  (with-isearch-suspended
      (setq isearch-new-string
            (substring
             isearch-string 0 (or (isearch-fail-pos) (1- (length isearch-string))))
            isearch-new-message
            (mapconcat 'isearch-text-char-description isearch-new-string ""))))

(define-key isearch-mode-map (kbd "DEL") 'mydelete)

(До речі, у вашому запитанні йдеться про deleteперсонажа, але ви написали DEL, що є символом зворотної області.)


Як зазначає @Malabarba в коментарі, коли ви встановите новий рядок пошуку ""(порожній рядок), with-isearch-suspendedпоновлюється шляхом пошуку останнього рядка пошуку, замість цього починаючи з порожнього рядка пошуку.

Це " особливість " with-isearch-suspendedзагалом. Але оскільки ви іноді можете дуже спорожнити рядок пошуку для відновлення, у версії with-isearch-suspendedin isearch + .el я додав змінну isearchp-if-empty-prefer-resuming-with-lastдля управління цим. Якщо ви пов'язуєте це з nilвами та налаштовуєте isearch-new-stringна ""потім, пошук поновлюється із порожнім рядком пошуку.

Тож за допомогою Isearch + ви можете робити все, що завгодно, з цим визначенням:

(defun mydelete ()
  "Delete the failed portion of the search string, or the last char if successful."
  (interactive)
  (let ((isearchp-if-empty-prefer-resuming-with-last  nil))
    (with-isearch-suspended
        (setq isearch-new-string
              (substring
               isearch-string 0 (or (isearch-fail-pos) (1- (length isearch-string))))
              isearch-new-message
              (mapconcat 'isearch-text-char-description isearch-new-string "")))))

Я помітив , що тепер теж Emacs 24,4 ввів регрес, який я подану Emacs помилка # 20466 для, що означає , що зв'язування DELв isearch-mode-mapне є достатнім. Вони додали окрему палітурку для <backspace>, крім однієї для DEL. Це означає, що <backspace>більше не перекладається на DELIsearch (але він все ще так перекладається для Emacs).

Так що якщо ви хочете, щоб клавіша Backspace , щоб робити те , що ви просили в Emacs 24.4 або більш пізньої версії , то ви не можете просто зв'язати DELз mydelete. Ви повинні зв'язати <backspace>з mydelete. Тупий, АФАКТИЧНИЙ, маїс на Наррет-па-про-прогресі ...


Я додав подібну команду до Isearch + і зв'язав її C-M-l(той самий ключ, який використовується для видалення невідповідності завершення в Icicles ).

Також пам’ятайте, що C-gв Isearch також буде видалено невідповідний текст у випадку невідповідності. (Але це C-gтакож впливає на успішний пошук.)


Я мав би зазначити, що Isearch + вже досить довго мав необов'язкову поведінку у подібних напрямках. M-kпід час Isearch перемикається серед 3 поведінок, які контролюються значенням параметра isearchp-drop-mismatch:

  • replace-last- Ваш поточний текст замінює останній невідповідний текст. Ви завжди можете бачити свій останній внесок, навіть якщо це невідповідність. І він доступний для редагування за допомогою M-e.

  • nil - Ваш поточний вхід додається, навіть якщо попередній вхід має невідповідну частину.

  • що-небудь інше - Ваш поточний вклад ігнорується (видаляється), якщо він викликає невідповідність. У рядку пошуку завжди є збіги.


До речі, я думав над тим, щоб додати подібну команду до Isearch + ще з тих пір, коли я додав виділення невдалої частини (років тому, перш ніж я додав її до GNU Emacs), але я ніколи не обійшов її. Я це зробив зараз . (Однак я не включав вилучення символу. Команда, яку я додав, є неоперативною, якщо немає невдалої частини.)
Дрю

Я в ОС X. Я мав на увазі видалити назад.
асмеурер

Поведінка пошуку / заміни-останнього виглядає досить приємно. Чи є спосіб зробити так, щоб він не дзвонив у дзвінок щоразу, коли пошук не вдається?
асмеурер

2
Я завантажив нову версію isearch+.el. Він (a) фіксує автоматичне видалення невідповідностей, щоб обмотка працювала нормально. І додає опцію, isearchp-ring-bell-functionяку ви можете використовувати для придушення дзвоника під час пошуку.
Дрю

3
Малабарба, цікаво. Я зняв помилку і закінчився цим . Здебільшого з вантажу isearch-del-charі відповіді Дрю, але, здається, працює за призначенням. with-isearch-suspendedМакрос був винуватцем.
jbm
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.