2013-07-30 40 views
7

Làm thế nào tôi có thể cấu hình emacs để làm việc theo cách tương tự như biên tập viên hiện đại khác, nơi nhấn Alt + D hay Alt + Backspace xóa hoặc khoảng trắng liền kề hoặc một từ duy nhất ? Theo mặc định, emacs luôn xóa một từ.Emacs: xóa khoảng trắng hoặc một từ

+0

Tôi đang cố gắng tìm ra trình soạn thảo hiện đại nào bạn có trong đầu khi bạn đề cập đến các phím nóng này ... Tôi chưa thực sự gặp phải hành vi mà bạn mô tả. Hầu hết những điều tôi vừa thử hoặc không làm gì cả, hoặc một cái gì đó tùy ý không liên quan, như xóa toàn bộ dòng hoặc điều hướng lịch sử mở tài liệu. Vì vậy, tôi không thực sự biết những loại loại bỏ khoảng trắng bạn đã có trong tâm trí. Có phải loại như '' M- \ '' không? Hoặc nó nên xóa trước/sau khi điểm duy nhất? –

+0

Ngoài ra: http://www.emacswiki.org/emacs/DeletingWhitespace đây là một tập hợp lớn mã do người dùng gửi để thực hiện tất cả các loại xóa khoảng trắng. –

+0

@wvxvw xin lỗi nó phải là phím Alt. biên tập viên như eclipse, visual studio và văn bản tuyệt vời. – woodings

Trả lời

4

Điều này rất có thể đã được giải quyết trước đây, nhưng thay vì tìm kiếm mã, chúng tôi có thể viết mã của riêng mình. Rất vui!

Đây là cách tôi sẽ làm điều đó, hy vọng điều đó sẽ hữu ích.

(defun kill-whitespace-or-word() 
    (interactive) 
    (if (looking-at "[ \t\n]") 
     (let ((p (point))) 
     (re-search-forward "[^ \t\n]" nil :no-error) 
     (backward-char) 
     (kill-region p (point))) 
    (kill-word 1))) 

Sau đó ràng buộc nó vào một phím:

(global-set-key (kbd "M-d") 'kill-whitespace-or-word) 
+0

Tôi đang tìm kiếm một chức năng giết chết khoảng trắng-hoặc-từ-lạc hậu chủ yếu. Xóa các từ về phía sau nhưng dừng lại trên \ n chủ yếu. Tôi cảm thấy như mã này có thể được điều chỉnh cho điều đó, nhưng tôi là quá clueless tại elisp để tìm ra:/ – mtourne

1

Nếu bạn đang sử dụng một bộ đệm CC-Mode dựa, bạn có thể tìm cho Hungry Delete Mode chế độ nhỏ.

Hãy thử C-cDELC-cDELETE ở một số nơi để có được một cảm giác về sự khác biệt.

Nếu bạn thích cách nó hoạt động, bạn có thể chuyển đổi xóa đói để làm việc cho các phím tiêu chuẩn bằng cách thực hiện M-x c-toggle-hungry-state hoặc chỉ rebind các chức năng xóa đói để ràng buộc ưa thích của bạn.

Nếu bạn vẫn nghĩ rằng bạn cần phải cõng một chìa khóa để làm phía trước giết từ hoặc khoảng trắng, sau đó bạn có thể làm điều gì đó tương tự như c-hungry-delete-forward, hay chỉ là tạm thời rebind c-delete-function và gọi nó.

(defun c-hungry-delete-forward-word() 
    "Delete the following word or all following whitespace 
up to the next non-whitespace character. 
See also \\[c-hungry-delete-backwards]." 
    (interactive) 
    (let ((c-delete-function (function kill-word))) 
    (c-hungry-delete-forward))) 

Kiểm tra trang Thông tin (ccmode) Hungry WS Deletion để biết thêm.

9

Trough một số thời gian sử dụng Emacs tôi nhận thấy rằng mặc dù tôi có thể thay đổi chức năng cơ bản, nó thường không trả hết nhiều về hiệu quả. Trong thực tế, sau khi tôi đã làm nó nhiều lần, tôi đã hối tiếc và cởi nó. Điều này là không đúng tất cả thời gian, một số keybindings thực sự không thoải mái hoặc hiếm khi hữu ích, nhưng tôi không nghĩ rằng đây là trường hợp với cách giết từ hoạt động. Trong thực tế, tôi vừa mới nhận ra rằng: Tôi đã thử keybinding trong Eclipse, nhưng tôi đã sử dụng nó với kebindings kiểu Emacs từ mãi mãi ...

Anyways, như tôi đã nói, trước khi bạn "sửa chữa "chức năng đó, chắc chắn rằng nó thực sự là tấm :) tôi chưa bao giờ thấy mình cần các loại chức năng mà bạn mô tả, và có lẽ đây là lý do:

  1. M-SPC làm giảm khoảng cách giữa các từ để chỉ một không gian . Đây là những gì tôi sẽ sử dụng nếu điểm giữa các từ và tôi muốn xóa thêm khoảng trống tách các từ.

  2. M- \ xóa tất cả không gian ngang. Điều này sẽ kết hợp hai từ cách nhau bằng dấu cách.

  3. Nếu những gì bạn đang cố gắng để đạt được một số loại định dạng "thưa thớt", như trong:


int foo   = 42; 
unsigned int bar = 43; 

sau đó có M-xalign-regexp để làm điều đó.

  1. Tôi chỉ không bao giờ xảy ra để có một) chạy hậu quả lâu dài của whitepsace, trừ khi nó là thụt đầu dòng, và trong trường hợp nó là thụt đầu dòng, TAB thường xử lý nó tốt hơn. b) ngay cả khi có các khoảng trắng dài do hậu quả, tôi hiếm khi di chuyển từng điểm một, vì vậy thật khó để nghĩ về một tình huống mà tôi tìm thấy điểm được bao quanh bởi một vài khoảng trắng. Những thứ như chế độ Nghệ sĩ, hoặc biểu đồ Dot đến tâm trí, nhưng nó không xảy ra trong khi chỉnh sửa mã.

  2. Cuối cùng, nếu bạn đang cố gắng, tốt, chúng ta hãy nói chỉ cần chỉnh sửa một tập tin văn bản tùy ý và bạn muốn thêm hoặc loại bỏ không gian ngang giữa các từ ... Một lần nữa, có Mxalign-regexp để làm điều đó, hoặc bạn có thể sử dụng các lệnh hoạt động trên hình chữ nhật, nếu đó là một số dòng tại thời điểm đó. Vâng, Emacs thậm chí sẽ nhận ra các tab quảng cáo và sẽ cố gắng căn chỉnh văn bản như để khớp với dòng cuối cùng trước thời điểm, khi bạn nhấn TAB.

Cuối cùng, nếu vì một lý do tôi không thể hiểu được :) Tôi thực sự cần thiết để thực hiện chính xác những gì bạn mô tả, sau đó tôi muốn làm điều đó như vậy: kM \BACKSPACE (nó có thể bất kỳ phím nào khác thay vì "k" - nó chỉ nằm ngay dưới ngón tay của bạn, do đó, nó nhanh chóng gõ :) Hoặc, nếu tôi là lười biếng suy nghĩ về nó: M-SPCMfMbCw - có thể nghe có vẻ rất nhiều, nhưng đây là những lệnh bạn muốn ld được sử dụng tất cả các thời gian anyway, do đó, nó không cản trở bạn về tốc độ.

7
(defvar movement-syntax-table 
    (let ((st (make-syntax-table))) 
    ;; ` default = punctuation 
    ;; ' default = punctuation 
    ;; , default = punctuation 
    ;; ; default = punctuation 
    (modify-syntax-entry ?{ "." st) ;; { = punctuation 
    (modify-syntax-entry ?} "." st) ;; } = punctuation 
    (modify-syntax-entry ?\" "." st) ;; " = punctuation 
    (modify-syntax-entry ?\\ "_" st) ;; \ = symbol 
    (modify-syntax-entry ?\$ "_" st) ;; $ = symbol 
    (modify-syntax-entry ?\% "_" st) ;; % = symbol 
    st) 
    "Syntax table used while executing custom movement functions.") 

(defun delete-word-or-whitespace (&optional arg) 
"http://stackoverflow.com/a/20456861/2112489" 
(interactive "P") 
    (with-syntax-table movement-syntax-table 
    (let* (
     beg 
     end 
     (word-regexp "\\sw") 
     (punctuation-regexp "\\s.") 
     (symbol-regexp "\\s_\\|\\s(\\|\\s)")) 
     (cond 
     ;; Condition # 1 
     ;; right of cursor = word or punctuation or symbol 
     ((or 
      (save-excursion (< 0 (skip-syntax-forward "w"))) 
      (save-excursion (< 0 (skip-syntax-forward "."))) 
      (save-excursion (< 0 (skip-syntax-forward "_()")))) 
      ;; Condition #1 -- Step 1 of 2 
      (cond 
      ;; right of cursor = word 
      ((save-excursion (< 0 (skip-syntax-forward "w"))) 
       (skip-syntax-forward "w") 
       (setq end (point)) 
       (while (looking-back word-regexp) 
       (backward-char)) 
       (setq beg (point)) 
       (delete-region beg end)) 
      ;; right of cursor = punctuation 
      ((save-excursion (< 0 (skip-syntax-forward "."))) 
       (skip-syntax-forward ".") 
       (setq end (point)) 
       (while (looking-back punctuation-regexp) 
       (backward-char)) 
       (setq beg (point)) 
       (delete-region beg end)) 
      ;; right of cursor = symbol 
      ((save-excursion (< 0 (skip-syntax-forward "_()"))) 
       (skip-syntax-forward "_()") 
       (setq end (point)) 
       (while (looking-back symbol-regexp) 
       (backward-char)) 
       (setq beg (point)) 
       (delete-region beg end))) 
      ;; Condition #1 -- Step 2 of 2 
      (cond 
      ;; right of cursor = whitespace 
      ;; left of cursor = not word/not symbol/not punctuation = whitespace or bol 
      ((and 
       (save-excursion (< 0 (skip-chars-forward "\s\t"))) 
       (not (save-excursion (> 0 (skip-syntax-backward "w")))) 
       (not (save-excursion (> 0 (skip-syntax-backward ".")))) 
       (not (save-excursion (> 0 (skip-syntax-backward "_()"))))) 
       (setq beg (point)) 
       (skip-chars-forward "\s\t") 
       (setq end (point)) 
       (delete-region beg end)) 
      ;; right of cursor = whitespace 
      ;; left of cursor = word or symbol or punctuation 
      ((and 
       (save-excursion (< 0 (skip-chars-forward "\s\t"))) 
       (or 
        (save-excursion (> 0 (skip-syntax-backward "w"))) 
        (save-excursion (> 0 (skip-syntax-backward "."))) 
        (save-excursion (> 0 (skip-syntax-backward "_()"))))) 
       (fixup-whitespace)))) 
     ;; Condition # 2 
     ;; right of cursor = whitespace 
     ;; left of cursor = bol | left of cursor = whitespace | right of cursor = whitespace + eol 
     ((and 
      (save-excursion (< 0 (skip-chars-forward "\s\t"))) 
      (or 
       (bolp) 
       (save-excursion (> 0 (skip-chars-backward "\s\t"))) 
       (save-excursion (< 0 (skip-chars-forward "\s\t")) (eolp)))) 
      (setq beg (point)) 
      (skip-chars-forward "\s\t") 
      (setq end (point)) 
      (delete-region beg end)) 
     ;; Condition # 3 
     ;; right of cursor = whitespace or eol 
     ;; left of cursor = word or symbol or punctuation 
     ;; not bol + word or symbol or punctuation 
     ;; not bol + whitespace + word or symbol or punctuation 
     ((and 
      (or (save-excursion (< 0 (skip-chars-forward "\s\t"))) (eolp)) 
      (or 
       (save-excursion (> 0 (skip-syntax-backward "w"))) 
       (save-excursion (> 0 (skip-syntax-backward "."))) 
       (save-excursion (> 0 (skip-syntax-backward "_()")))) 
      (not (save-excursion (> 0 (skip-syntax-backward "w")) (bolp))) 
      (not (save-excursion (> 0 (skip-syntax-backward ".")) (bolp))) 
      (not (save-excursion (> 0 (skip-syntax-backward "_()")) (bolp))) 
      (not (save-excursion (and (> 0 (skip-syntax-backward "w")) (> 0 (skip-chars-backward "\s\t")) (bolp)))) 
      (not (save-excursion (and (> 0 (skip-syntax-backward ".")) (> 0 (skip-chars-backward "\s\t")) (bolp)))) 
      (not (save-excursion (and (> 0 (skip-syntax-backward "_()")) (> 0 (skip-chars-backward "\s\t")) (bolp))))) 
      (setq end (point)) 
      (cond 
      ((save-excursion (> 0 (skip-syntax-backward "w"))) 
       (while (looking-back word-regexp) 
       (backward-char))) 
      ((save-excursion (> 0 (skip-syntax-backward "."))) 
       (while (looking-back punctuation-regexp) 
       (backward-char))) 
      ((save-excursion (> 0 (skip-syntax-backward "_()"))) 
       (while (looking-back symbol-regexp) 
       (backward-char)))) 
      (setq beg (point)) 
      (when (save-excursion (> 0 (skip-chars-backward "\s\t"))) 
      (skip-chars-backward "\s\t") 
      (setq beg (point))) 
      (delete-region beg end) 
      (skip-chars-forward "\s\t")) 
     ;; Condition # 4 
     ;; not bol = eol 
     ;; left of cursor = bol + word or symbol or punctuation | bol + whitespace + word or symbol or punctuation 
     ((and 
      (not (and (bolp) (eolp))) 
      (or 
       (save-excursion (> 0 (skip-syntax-backward "w")) (bolp)) 
       (save-excursion (> 0 (skip-syntax-backward ".")) (bolp)) 
       (save-excursion (> 0 (skip-syntax-backward "_()")) (bolp)) 
       (save-excursion (and (> 0 (skip-syntax-backward "w")) (> 0 (skip-chars-backward "\s\t")) (bolp))) 
       (save-excursion (and (> 0 (skip-syntax-backward ".")) (> 0 (skip-chars-backward "\s\t")) (bolp))) 
       (save-excursion (and (> 0 (skip-syntax-backward "_()")) (> 0 (skip-chars-backward "\s\t")) (bolp))))) 
      (skip-chars-forward "\s\t") 
      (setq end (point)) 
      (setq beg (point-at-bol)) 
      (delete-region beg end)) 
     ;; Condition # 5 
     ;; point = eol 
     ;; not an empty line 
     ;; whitespace to the left of eol 
     ((and 
      (not (and (bolp) (eolp))) 
      (eolp) 
      (save-excursion (> 0 (skip-chars-backward "\s\t")))) 
      (setq end (point)) 
      (skip-chars-backward "\s\t") 
      (setq beg (point)) 
      (delete-region beg end)) 
     ;; Condition # 6 
     ;; point = not eob 
     ;; point = bolp and eolp 
     ;; universal argument = C-u = '(4) 
     ((and 
      (not (eobp)) 
      (and (bolp) (eolp)) 
      (equal arg '(4))) 
      (delete-forward-char 1)))))) 
+0

Tôi thích chức năng nói chung, nhưng tôi thấy rằng nó không phải là khá 'phổ quát'. Tức là 1) Một khi bạn xóa để bắt đầu một dòng, nó không quấn quanh để xóa dòng trước đó, nó chỉ 'dừng' –

+0

và nếu bạn có một dòng có dấu cách trắng, nó không bắt đầu xóa ký tự tại tất cả các? –

+0

@Leo Ufimtsev - Tôi đã thêm điều kiện để xử lý khoảng trắng ở cuối dòng. Khi điểm ở cuối dòng và khoảng trắng ở bên trái, sau đó xóa tất cả khoảng trắng ở bên trái. Đây là tình huống duy nhất mà khoảng trống bên trái bị xóa. Cảm ơn bạn đã giúp tôi cải thiện chức năng này. Tôi muốn đưa ra một số suy nghĩ về việc liệu phạm vi chức năng có nên được tăng lên để xóa các đường chuyển tiếp hoặc lùi sau khi đoạn hiện tại đã bị xóa hay không. Lý do tôi do dự là nhiều người dùng, kể cả bản thân tôi, đôi khi trở nên quá hăng hái với việc lặp lại chức năng. – lawlist

Các vấn đề liên quan