Emacs: Làm thế nào để xóa văn bản mà không có vòng đệm?


80

Tôi chỉ muốn xóa một số văn bản để tôi có thể kéo một số văn bản khác thay vì nó. Làm thế nào tôi có thể làm điều đó? Cw cắt văn bản đã chọn để giết vòng và tôi kết thúc không có văn bản mà tôi muốn kéo.

Ngoài ra, liệu có thể kéo văn bản trực tiếp thay vì một số văn bản mà thậm chí không cần nhấn các nút để tắt nó không?



2
tham khảo câu trả lời của tôi dưới đây, bạn có thể sử dụng nút Backspace trên bàn phím cho câu hỏi 1, văn bản đánh dấu cho câu hỏi thứ 2
Kevin Zhu

Nó không chỉ là Cx rk sau khi bạn đã xác định khối của mình?
yalu2015

Câu trả lời:


49

Tôi gõ M-x delete-regionkhá thường xuyên, nhưng bạn có thể liên kết nó với một khóa.

Với Chế độ lựa chọn Xóa trong các phiên bản Emacs mới hơn, bạn không cần phải nhập lệnh mà chỉ cần bắt đầu nhập:

Theo mặc định, tính năng chèn văn bản diễn ra bình thường ngay cả khi dấu đang hoạt động — ví dụ: nhập một ký tự chèn ký tự 'a', sau đó tắt dấu. Chế độ chọn Xóa, một chế độ phụ, sửa đổi hành vi này: nếu bạn bật chế độ đó, thì việc chèn văn bản trong khi dấu đang hoạt động sẽ khiến văn bản trong vùng bị xóa trước tiên. Ngoài ra, các lệnh thường chỉ xóa một ký tự, chẳng hạn như C-dhoặc DEL, sẽ xóa toàn bộ vùng. Để bật hoặc tắt chế độ Xóa lựa chọn, hãy nhậpM-x delete-selection-mode.


33
Ngoài ra, với phiên bản Emacs mới nhất, bạn thậm chí không cần phải liên kết delete-regionvới một khóa vì Backspace hiện thực hiện điều đó. Backspace xóa vùng đã chọn thay vì xóa nó, nói cách khác, Backspace xóa văn bản đã chọn mà không lưu / đẩy nó vào vòng loại bỏ. Điều này là do giá trị của delete-active-regionttrừ khi bạn tùy chỉnh nó để một số giá trị khác.
Jisang Yoo


20

Tôi cũng từng gặp vấn đề tương tự. Điều gần nhất mà tôi có cho đến nay là chỉ tạo một chức năng nhỏ về cơ bản:

(defun ruthlessly-kill-line ()
  "Deletes a line, but does not put it in the kill-ring. (kinda)"
  (interactive)
  (move-beginning-of-line 1)
  (kill-line 1)
  (setq kill-ring (cdr kill-ring)))

1
Tại sao không chỉ (xóa-vùng (dòng-đầu-vị trí) (dòng-cuối-vị trí))?
CodyChan

Chức năng được liệt kê có vẻ tốt, nhưng không hoạt động đối với tôi nói chung. Đặc biệt, tôi thấy rằng nó sẽ khiến con trỏ kéo trỏ vào đầu kia của vòng giết, nói chung (trên thực tế là hầu như luôn luôn?) Không phải là yếu tố tiếp theo trong danh sách! (Stll cố gắng để hack lên một chức năng mà làm việc đáng tin cậy thông qua uỷ quyền cho `kill-line' ... có lẽ tôi sẽ chỉ nghỉ mát để xóa vùng như những người khác đã làm ...)
pnkfelix

11

Lấy từ EmacsWiki :

Tương đương với ‘kill-line’( ‘C-k’) nhưng không có tác dụng phụ vòng giết chết:

(delete-region (point) (line-end-position))

Câu trả lời hay nhất IMO. Và tôi đã ràng buộc ctrl-shift-W để xóa khu vực: (global-set-key (kbd "CSw") 'delete-region)
Tongfa

5

Mx eval-expression (setq kill-ring (cdr kill-ring)) - xóa mục cuối cùng khỏi kill-ring


Nó chỉ làm điều đó cho phiên hiện tại một cách kỳ lạ. Bên ngoài emacs nó không bị loại khỏi vòng giết!
PascalVKooten

4

Đối với câu hỏi thứ hai của bạn, ngoài ra với DeleteSelectionMode, bạn có thể bật Chế độ CUA, chế độ này cũng cung cấp cho bạn một chế độ chọn hình chữ nhật đẹp được kích hoạt bởi C-Return. Chế độ CUA là một phần của emacs kể từ ngày 22.1.


3

Tìm thấy một câu trả lời cho điều này.

Đăng nó đầu tiên ở đây .

;; Ctrl-K with no kill
(defun delete-line-no-kill ()
  (interactive)
  (delete-region
   (point)
   (save-excursion (move-end-of-line 1) (point)))
 (delete-char 1)
)
(global-set-key (kbd "C-k") 'delete-line-no-kill)

Vấn đề là lệnh này cũng luôn xóa dòng mới, trong khi kill-line chỉ xóa dòng mới nếu giá trị của biến kill-whole-line không phải là nil. Sẽ tốt hơn nếu thay đổi "(delete-char 1)" thành "(if kill-whole-line (delete-char 1))".
Alan

3

Hầu hết các hàm giết sử dụng kill-regionđể thực hiện công việc thực sự là giết văn bản. Tôi sử dụng macro lisp để tạo các hàm xóa khỏi các hàm giết.

(defmacro jpk/delete-instead-of-kill (&rest body)
  "Replaces `kill-region' with `delete-region' in BODY."
  `(cl-letf (((symbol-function 'kill-region)
              (lambda (beg end &optional yank-handler)
                (delete-region beg end))))
     ,@body))

(defun jpk/delete-word (arg)
  "Like `kill-word', but does not save to the `kill-ring'."
  (interactive "*p")
  (jpk/delete-instead-of-kill (kill-word arg)))

Làm thế nào nó hoạt động? Bạn có thêm thông tin về điều này? Thật đáng kinh ngạc.
sinekonata

1
cl-letfcó thể tạo ràng buộc cục bộ của một hàm với phạm vi động. Điều đó có nghĩa là nó chỉ có hiệu lực đối với mã bên trong cl-letf, nhưng nó áp dụng cho toàn bộ cây cuộc gọi (ví dụ: kill-regionkhông xuất hiện trực tiếp trong body, nhưng kill-wordcác cuộc gọi kill-regionvà được thay thế bằng delete-region).
jpkotta

Bạn thậm chí có thể gọi hàm gốc từ chức năng thay thế nếu lần đầu tiên bạn liên kết nó với một tên khác trong cl-letf. cl-letfhoạt động như let*vậy theo nghĩa đó.
jpkotta

Tôi hiểu được ý chính của nó, nó vẫn còn quá kỹ thuật đối với tôi. Tôi hầu như không có kinh nghiệm trung cấp với python. Tên chung cho các chức năng "ghi đè" / ghi đè / viết lại này là gì? Nó có phải là một tính năng cụ thể của các ngôn ngữ như ngọng không?
sinekonata

Tôi không chắc chính xác tên chung của kỹ thuật này là gì. Tôi nghĩ rằng tôi sẽ mô tả nó như là phạm vi động cho các hàm và không phổ biến trong hầu hết các ngôn ngữ vì nó có thể rất dễ bị lạm dụng. Emacs đang dần chuyển sang phạm vi từ vựng vốn là thứ mà hầu hết các ngôn ngữ sử dụng. Tôi không chắc bạn có thể làm điều đó bằng Python nói chung, bạn phải thiết kế mã của mình để cho phép ghi đè hàm trong một phạm vi cụ thể.
jpkotta

2

Về mặt kỹ thuật, các câu trả lời khác đều sai ở phần đầu tiên.

Đây là cách thực hiện và động lực của tôi:

(defun delete-word (arg)
  "Delete characters backward until encountering the beginning of a word.
With argument ARG, do this that many times."
  (interactive "p")
  (delete-region (point) (progn (backward-word arg) (point))))

Tôi đã điều chỉnh mã ở đây từ " kill-word" trong simple.el. Tôi đã chuyển đổi kill-regionvới delete-regionforward-wordcho backward-word. Bằng cách này, nó THẬT SỰ không ảnh hưởng đến kill-ring, không giống như những tình huống khác, ngoài emacs, tôi nhận thấy rằng cái kill-ringđã bị ảnh hưởng.


2
Tôi thích câu trả lời này bởi vì nó không vít lên dán từ clipboard OS (nơi thả điều cuối cùng từ vòng kill không giúp đỡ vì những gì trong clipboard OS bị mất)
Brel

Hãy xem câu trả lời của tôi để biết cách thực hiện điều này mà không cần sao chép định nghĩa của hàm kill.
jpkotta

1
(defun copy-to-register-z (p1 p2)
  "Copy text selection to register named “z”."
  (interactive "r")
  (copy-to-register ?z p1 p2))
(defun replace-register-content-z (p1 p2)
  "Replace register named “z”'s content."
  (interactive "r")
  (delete-region p1 p2)
  (insert-register ?z))
(global-set-key (kbd "C-c c") 'copy-to-register-z)
(global-set-key (kbd "C-c v") 'replace-register-content-z)

Tôi thích điều này, nhưng vì tôi không sử dụng chế độ đánh dấu tạm thời, tôi thích "insert-register-content-z" với tất cả trừ dòng xóa vùng.
Joshua Goldberg

1

Thêm tương đương xóa của các khóa vùng tiêu diệt và khóa dòng tiêu diệt Cw và Ck như sau. Liên kết với các phím Cv và Cz.

;; Việc liên kết phím với vùng xóa sẽ cho "Windows CUT Ctrl-x tương đương" tốt.
;; Keybinding để sử dụng là gì thật khó chọn.
;; sử dụng Cv "Windows PASTE Ctrl-v" là một lựa chọn khá lật đổ.
;; Cv = cuộn lên trong emacs mà tôi không sử dụng.
(global-set-key (kbd "Cv") 'delete-region)

;; Để có một "Windows CUT" thay thế cho Ck (kill-line), bạn có thể thực hiện:
(defun delete-line () "xóa dòng, đưa nó ra khỏi vòng giết. ràng buộc func này với Cz"
 (tương tác)
 (setq last-command 'delete-line)
 (kill-line)
 (setq kill-ring (cdr kill-ring))
 (setq kill-ring-yank-pointer kill-ring)
 (setq last-command 'delete-line)
)
(global-set-key (kbd "Cz") 'delete-line)
;; mà không cài đặt lệnh cuối cùng 2+ C-z sẽ làm rối loạn kill-ring

1

Câu trả lời của tôi cho câu hỏi đầu tiên: đánh dấu văn bản bằng emacs (sử dụng chuột hoặc dấu thiết lập C-SPC) và nhấn nút "<- Backspace" trên bàn phím thay vì C-w. Bằng cách này, bạn vẫn có thể dán lên văn bản trong khay nhớ tạm thời của hệ thống mà không phải lo lắng rằng khay nhớ tạm bị ghi đè bởi văn bản bị giết bởiC-w

Cơ sở cho câu trả lời này: đôi khi tôi nhận được văn bản bên ngoài emacs mà tôi muốn sử dụng để thay thế một vùng trong emacs, tôi thường mắc lỗi khi sao chép văn bản đó vào khay nhớ tạm hệ thống (tức là trên Windows Ctrl + C), sau đó thực hiện C-wtrong emacs để " xóa "vùng văn bản mà tôi muốn thay thế, với hy vọng rằng sau này M-wcó thể khôi phục văn bản của tôi trong khay nhớ tạm từ kill-ring. Thật không may, khay nhớ tạm sẽ chỉ bị ghi đè bởi văn bản bị giết bởi C-wvà thông báo gốc trong khay nhớ tạm sẽ không bao giờ hiển thị trong kill-ring.

Đối với câu hỏi thứ 2, có, bạn luôn có thể đánh dấu văn bản trong emacs trước và sau đó trực tiếp C-y


0

Đây là một phiên bản của kill-regionđiều đó không buộc các giá trị vào vòng tiêu diệt.

(defun kill-or-delete-region (beg end prefix)
  "Delete the region, storing it in the kill-ring.
If a prefix argument is given, don't change the kill-ring."
  (interactive "r\nP")
  (if prefix
      (delete-region beg end)
    (kill-region beg end)))

(global-set-key (kbd "C-w") 'kill-or-delete-region)

Điều này cho phép bạn làm C-wnhư trước đây, nhưng C-u C-wbây giờ xóa văn bản mà không cần thay đổi vòng cấm.


0

làm thế nào để xóa văn bản mà không có vòng giết?

các delete-regionchức năng sẽ xóa các khu vực được lựa chọn mà không cần thêm nó vào vòng kill

Ngoài ra, liệu có thể kéo văn bản trực tiếp thay vì một số văn bản mà thậm chí không cần nhấn các nút để tắt nó không?

Tôi nghĩ rằng bạn đang hỏi làm thế nào để thay thế văn bản trong một vùng đã chọn bằng một thứ gì đó mà bạn đã đưa vào vòng kết thúc.

Cài đặt (delete-selection-mode 1)sẽ cho phép bạn kéo / dán lên một vùng đã chọn. Nó cũng cho phép bạn chỉ nhập và thay thế một vùng đã chọn.

Trên phiên bản 25.1.1 trên OS XI cũng phải thêm (setq select-enable-primary nil)vào để ngăn nó sao chép vùng đã chọn vào vòng tiêu diệt


0

Như một sự bổ sung cho tất cả các câu trả lời. Nếu bạn viết mã elisp để xóa, bạn có thể gọi các hàm tiêu diệt miễn là bạn sử dụng đối tượng kill-ring cục bộ như sau:

(defun delete-something()
  "Delete something without storing in kill ring."
  (let (kill-ring)
     (kill-something)))

Sử dụng bất kỳ chức năng tiêu diệt thứ gì đó thay cho chức năng tiêu diệt thứ gì đó. Sau đó, chức năng sẽ xóa và không có gì sẽ được ghi nhớ trong vòng tiêu diệt thực.

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.