ลบส่วนของสตริง 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 ลบทั้งสตริงที่ล้มเหลว (หรือถ้าไม่มีสตริงที่ล้มเหลวเพียงตัวเดียว)

อย่างไรก็ตามการdelete-regionลบข้อความจากบัฟเฟอร์isearchกำลังค้นหาไม่ใช่บัฟเฟอร์ isearch เอง

วิธีที่เหมาะสมในการทำเช่นนี้คืออะไร? คำติชมเกี่ยวกับส่วนที่เหลือของรูปแบบเสียงกระเพื่อม emacs ของฉันก็ยินดีต้อนรับ :)

คำตอบ:


12

อ่าใช่ iSearch อ่านคีย์ที่คุณพิมพ์ดูพวกเขาในisearch-mode-mapและจะเรียกพวกเขาในบัฟเฟอร์ปัจจุบัน

Isearch ไม่ได้ปรากฏตัว แต่ใช้ minibuffer มันใช้พื้นที่เสียงสะท้อน นั่นคือสิ่งที่คุณเห็นมีข้อความที่ส่งออกจริงรวมถึง echoes ของตัวละครที่คุณพิมพ์

สิ่งนี้ควรทำในสิ่งที่คุณถาม:

(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)

(BTW คำถามของคุณบอกว่าdeleteตัวละคร แต่คุณเขียนDELซึ่งเป็นตัวอักษร Backspace)


@Malabarba ชี้ให้เห็นในความคิดเห็นเมื่อคุณตั้งค่าสตริงการค้นหาใหม่เป็น""(สตริงว่าง) with-isearch-suspendedดำเนินการต่อโดยค้นหาสตริงการค้นหาล่าสุดแทนที่จะเริ่มต้นด้วยสตริงการค้นหาที่ว่างเปล่า

นี่คือ " คุณสมบัติ " ของwith-isearch-suspendedโดยทั่วไป แต่เนื่องจากบางครั้งคุณอาจต้องการล้างสตริงการค้นหาสำหรับการเริ่มต้นใหม่ในเวอร์ชันของwith-isearch-suspendedใน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>ไม่ได้รับการแปลอีกต่อไปDELสำหรับ Isearch (แต่ยังคงได้รับการแปลสำหรับ Emacs โดยทั่วไป)

ดังนั้นหากคุณต้องการปุ่ม Backspace จะทำในสิ่งที่คุณถามใน Emacs 24.4 หรือสูงกว่านั้นคุณก็ไม่สามารถผูกไปDEL mydeleteคุณจำเป็นต้องผูกไป<backspace> mydeleteใบ้, AFAICT, mais บน n'arrete pas le progres ...


ฉันได้เพิ่มคำสั่งที่คล้ายกันในIsearch +และผูกไว้กับC-M-l(คีย์เดียวกันที่ใช้ในการลบไม่ตรงกันเสร็จสมบูรณ์ในIcicles )

ระวังด้วยเช่นกันว่าC-gใน Isearch จะมีข้อความที่ไม่ตรงกันให้ลบข้อความที่ไม่ตรงกันด้วย (แต่C-gก็มีผลเมื่อการค้นหาสำเร็จ)


ฉันควรจะกล่าวว่าIsearch +ยังมีพฤติกรรมที่เป็นตัวเลือกตามบรรทัดที่คล้ายกันมาระยะหนึ่งแล้ว M-kระหว่าง Isearch สลับระหว่าง 3 พฤติกรรมซึ่งควบคุมโดยค่าของตัวเลือกisearchp-drop-mismatch:

  • replace-last- อินพุตปัจจุบันของคุณแทนที่ข้อความที่ไม่ตรงกันล่าสุด คุณสามารถดูอินพุตล่าสุดของคุณได้ตลอดแม้ว่าจะไม่ตรงกัน M-eและจะสามารถใช้ได้สำหรับการแก้ไขโดยใช้

  • nil - อินพุตปัจจุบันของคุณถูกต่อท้ายแม้ว่าอินพุตก่อนหน้านี้มีส่วนที่ไม่ตรงกัน

  • สิ่งอื่นใด - อินพุตปัจจุบันของคุณถูกละเว้น (ลบ) หากไม่ตรงกัน สตริงการค้นหามีการจับคู่ที่ประสบความสำเร็จเสมอ


BTW ฉันคิดเกี่ยวกับการเพิ่มคำสั่งที่คล้ายกันในIsearch +นับตั้งแต่ฉันเพิ่มการเน้นส่วนที่ล้มเหลว (ปีที่แล้วก่อนที่ฉันจะเพิ่มใน GNU Emacs) แต่ฉันไม่เคยเข้าไปใกล้ ผมเคยทำแบบนั้นตอนนี้ (ฉันไม่ได้รวมการลบอักขระ แต่คำสั่งที่ฉันเพิ่มเป็นแบบไม่มีถ้าไม่มีส่วนที่ล้มเหลว)
Drew

ฉันใช้ OS X ฉันหมายถึงลบไปข้างหลัง
asmeurer

การทำงานของ isearch + replace-last นั้นดูค่อนข้างดี มีวิธีใดที่จะทำให้ไม่ส่งเสียงกริ่งทุกครั้งที่การค้นหาล้มเหลว
asmeurer

2
isearch+.elฉันได้อัปโหลดเวอร์ชันใหม่ของ มัน (a) แก้ไขการลบที่ไม่ตรงกันโดยอัตโนมัติเพื่อให้การทำงานเป็นจริงตกลง และเพิ่มตัวเลือกisearchp-ring-bell-functionซึ่งคุณสามารถใช้ระงับเสียงระฆังในระหว่างการค้นหา
Drew

3
Malabarba น่าสนใจ ผมเอากระสุนที่ข้อผิดพลาดและจบลงด้วยนี้ สินค้าส่วนใหญ่มีการเพาะปลูกจากisearch-del-charคำตอบของ Drew แต่ดูเหมือนว่าจะทำงานได้ตามที่ตั้งใจไว้ with-isearch-suspendedแมโครเป็นผู้กระทำความผิด
jbm
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.