一致しないIsearch文字列の一部、または完全一致の場合は最後の文字を削除します


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)

このコードの目的は、deleteisearchで失敗した文字列全体を削除することです(または、失敗した文字列が1文字しかない場合)。

ただし、delete-regionバッファからテキストを削除するとisearch、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-suspendedisearch + .elのバージョンでは、isearchp-if-empty-prefer-resuming-with-lastこれを制御するためにvariableを追加しました。これをバインドして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を提出したためです。つまり、バインディングは十分DELisearch-mode-mapはありません。彼らはの<backspace>ための1つに加えて、別のバインディングを追加しましたDEL。つまり、Isearchの場合<backspace>はに翻訳されなくなりますDEL(ただし、Emacsの場合は一般的に翻訳されます)。

あなたがEmacsの24.4以降に尋ね行うにBackspaceキーをしたいのであれば、あなただけのバインドすることはできませんDELmydelete。あなたはバインドする必要があります<backspace>mydelete。Dumb、AFAICT、n'arrete pas le progresのメイス ...


同様のコマンドをIsearch +に追加してバインドしましたC-M-lIciclesの補完の不一致を削除するために使用したのと同じキー)。

C-gまた、Isearchでは、不一致がある場合、不一致のテキストを削除することにも注意してください。(ただしC-g、検索が成功した場合にも効果があります。)


Isearch +も、かなり長い間、同様の線に沿ってオプションの動作があったことを述べたはずです。M-kIsearch中に、オプションの値によって制御される3つの動作を切り替えますisearchp-drop-mismatch

  • replace-last-現在の入力により、最後に一致しないテキストが置き換えられます。それが不一致であっても、常に最後の入力を確認できます。また、を使用して編集することもできますM-e

  • nil -前の入力に不一致部分がある場合でも、現在の入力が追加されます。

  • その他-不一致が発生した場合、現在の入力は無視(削除)されます。検索文字列は常に一致します。


ちなみに、失敗した部分の強調表示を追加してから(数年前、GNU Emacsに追加する前)、Isearch +に同様のコマンドを追加することを考えましたが、回避できませんでした。私はそれを今やった。(ただし、文字の削除は含めませんでした。追加したコマンドは、失敗した部分がない場合は何もしません。)
Drew

私はOS Xを使用しています。逆方向の削除を意味しました。
asmeurer 2015年

isearch +のreplace-lastの動作は非常によく見えます。検索が失敗するたびにベルが鳴らないようにする方法はありますか?
asmeurer 2015年

2
の新しいバージョンをアップロードしましたisearch+.el。(a)ラップアラウンドが正常に機能するように、自動ミスマッチ除去を修正します。また、isearchp-ring-bell-function検索中にベルを非表示にするために使用できるオプションが追加されます。
2015年

3
マラバルバ、面白い。私はそのバグを撃ち、これで終わりました。主に貨物栽培isearch-del-charとドリューの答えですが、意図したとおりに機能しているようです。with-isearch-suspendedマクロが犯人でした。
jbm
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.