Xóa một phần chuỗi Isearch không khớp hoặc char cuối cùng nếu khớp hoàn toàn


11

Tôi có những điều sau đây

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

Mục đích của mã là làm cho deleteisearch xóa toàn bộ chuỗi thất bại (hoặc nếu không có chuỗi thất bại chỉ là một ký tự đơn).

Tuy nhiên, việc delete-regionxóa văn bản khỏi bộ đệm isearchđang tìm kiếm, không phải chính bộ đệm isearch.

Cách thích hợp để làm điều này là gì? Phê bình về phần còn lại của phong cách lac emacs của tôi cũng được chào đón :)

Câu trả lời:


12

À đúng rồi. Isearch đọc các khóa bạn nhập, tra cứu chúng isearch-mode-mapvà gọi chúng trong bộ đệm hiện tại .

Isearch không , mặc dù xuất hiện, sử dụng xe buýt nhỏ. Nó sử dụng khu vực tiếng vang. Đó là, những gì bạn thấy thực sự có thông điệp đầu ra , bao gồm tiếng vang của các ký tự bạn nhập.

Điều này sẽ làm những gì bạn yêu cầu:

(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, câu hỏi của bạn cho biết deleteký tự, nhưng bạn đã viết DEL, đó là ký tự backspace.)


Như @Malabarba chỉ ra trong một nhận xét, khi bạn đặt chuỗi tìm kiếm mới thành ""(chuỗi trống), with-isearch-suspendedtiếp tục bằng cách tìm kiếm chuỗi tìm kiếm cuối cùng, thay vì bắt đầu bằng chuỗi tìm kiếm trống.

Đây là một " tính năng " của with-isearch-suspended, nói chung. Nhưng vì bạn đôi khi có thể thực sự muốn làm rỗng chuỗi tìm kiếm cho nối lại, trong phiên bản with-isearch-suspendedtrong isearch + .el biến Tôi đã thêm isearchp-if-empty-prefer-resuming-with-last, để kiểm soát này. Nếu bạn liên kết nó với nilvà bạn đặt isearch-new-stringthành ""thì tìm kiếm sẽ tiếp tục với một chuỗi tìm kiếm trống.

Vì vậy, với Isearch + bạn có thể làm những gì bạn muốn với định nghĩa này:

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

Bây giờ tôi cũng nhận thấy rằng Emacs 24.4 đã đưa ra một hồi quy, mà tôi đã gửi lỗi Emacs # 20466 cho, điều đó có nghĩa là ràng buộc DELtrong isearch-mode-maplà không đủ. Họ đã thêm một ràng buộc riêng cho <backspace>, ngoài một ràng buộc cho DEL. Điều đó có nghĩa là <backspace>không còn được dịch sang DEL, cho Isearch (nhưng nó vẫn được dịch như vậy cho Emacs nói chung).

Vì vậy, nếu bạn muốn phím Backspace để làm những gì bạn yêu cầu trong Emacs 24,4 hay muộn thì bạn có thể không chỉ là ràng buộc DELđể mydelete. Bạn cần phải liên kết <backspace>với mydelete. Câm, AFAICT , mais trên n'arittle pas le progres ...


Tôi đã thêm một lệnh tương tự với Isearch + và ràng buộc nó C-M-l(cùng một khóa được sử dụng để loại bỏ sự không phù hợp hoàn thành trong Icicles ).

Cũng lưu ý rằng C-gtrong Isearch cũng vậy, khi có sự không phù hợp, hãy xóa văn bản không khớp. (Nhưng C-gcũng có tác dụng khi tìm kiếm thành công.)


Tôi nên đã đề cập rằng Isearch + cũng đã có một hành vi tùy chọn dọc theo các dòng tương tự trong một thời gian khá lâu. M-ktrong quá trình tìm kiếm Isggles trong số 3 hành vi, được kiểm soát bởi giá trị của tùy chọn isearchp-drop-mismatch:

  • replace-last- Đầu vào hiện tại của bạn thay thế văn bản không khớp cuối cùng. Bạn luôn có thể thấy đầu vào cuối cùng của mình, ngay cả khi đó là một sự không phù hợp. Và nó có sẵn để chỉnh sửa bằng cách sử dụng M-e.

  • nil - Đầu vào hiện tại của bạn được nối thêm, ngay cả khi đầu vào trước đó có phần không khớp.

  • bất cứ điều gì khác - đầu vào hiện tại của bạn bị bỏ qua (loại bỏ) nếu nó gây ra sự không phù hợp. Chuỗi tìm kiếm luôn có các trận đấu thành công.


BTW, tôi đã nghĩ về việc thêm một lệnh tương tự vào Isearch + kể từ khi tôi thêm phần tô sáng phần bị lỗi (nhiều năm trước, trước khi tôi thêm nó vào GNU Emacs), nhưng tôi chưa bao giờ hiểu về nó. Tôi đã làm điều đó bây giờ . (Tuy nhiên, tôi đã không bao gồm xóa một ký tự. Lệnh tôi đã thêm là không có nếu không có phần thất bại.)
Drew

Tôi đang dùng OS X. Ý tôi là xóa ngược.
asmeurer

Hành vi isearch + thay thế cuối cùng trông khá đẹp. Có cách nào để làm cho nó không rung chuông mỗi khi tìm kiếm thất bại, mặc dù?
asmeker 30/03/2015

2
Tôi đã tải lên một phiên bản mới của isearch+.el. Nó (a) sửa lỗi loại bỏ không khớp tự động để việc đóng gói hoạt động tốt. Và nó thêm một tùy chọn, isearchp-ring-bell-functionmà bạn có thể sử dụng để tắt chuông trong khi tìm kiếm.
vẽ

3
Malabarba, thú vị. Tôi đã bắn một con bọ và kết thúc với điều này . Chủ yếu là hàng hóa được nuôi dưỡng từ isearch-del-charvà câu trả lời của Drew nhưng nó dường như hoạt động như dự định. Các with-isearch-suspendedvĩ mô là thủ phạm.
jbm
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.