简体   繁体   English

Emacs:删除空格或单词

[英]Emacs: delete whitespaces or a word

How can I configure emacs to work in the same way as other modern editors where pressing Alt + D or Alt + Backspace deletes either adjacent whitespaces or a single word? 如何配置emacs以与其他现代编辑器相同的方式工作,其中按Alt + DAlt + Backspace删除相邻的空格或单个单词? By default, emacs always deletes a word. 默认情况下,emacs始终删除一个单词。

Trough some time of using Emacs I figured that even though I can alter the basic functionality, it usually doesn't pay off much in terms of efficiency. 通过使用Emacs的一段时间我认为尽管我可以改变基本功能,但它在效率方面通常不会带来太多回报。 In fact, after I did it several times, I came to regret it and undid it. 事实上,在我做了几次之后,我后悔并解开它。 This is not true all of the time, some keybindings are really uncomfortable or rarely useful, but I don't think this is the case with how kill word works. 这一直不是真的,有些键绑定真的很不舒服或很少有用,但我不认为这就是kill word如何工作的情况。 In fact, I just now realized that: I did try the keybinding in Eclipse, but I've been using it with Emacs-style kebindings since forever... 事实上,我刚才意识到:我确实在Eclipse中尝试过键绑定,但我一直在使用它与Emacs风格的kebindings永远...

Anyways, as I just said, before you are "fixing" that functionality, make sure it is really broken :) I never find myself needing the kind of function you describe, and maybe here's why: 无论如何,正如我刚才所说,在你“修复”这个功能之前,确保它真的坏了:)我从来没有发现自己需要你描述的那种功能,也许这就是为什么:

  1. M-SPC reduces the space between words to just one space. M-SPC将单词之间的空间缩小到一个空格。 This is what I would've used if the point was between the words and I wanted to delete the extra space separating the words. 如果点在两个单词之间并且我想删除分隔单词的额外空格,那么我就会使用这个。

  2. M-\\ removes all horizontal space. M- \\删除所有水平空间。 This will join two words separated by space. 这将加入由空格分隔的两个单词。

  3. If what you are trying to achieve is some kind of "sparse" formatting, as in: 如果你想要实现的是某种“稀疏”格式,如:


int foo          = 42;
unsigned int bar = 43;

then there's Mx align-regexp to do that. 然后有Mx align-regexp来做到这一点。

  1. I just never happen to have a) long consequent runs of whitepsace, unless it is the indentation, and in the case it is the indentation, TAB usually handles it better. 我只是从来没有碰到过很长时间的whitepsace,除非它是缩进,并且在它是缩进的情况下, TAB通常会更好地处理它。 b) even if there are long consequent runs of whitespace, I so rarely move the point by one character at a time, so it's hard to think of a situation where I'd find the point surrounded by several whitespaces. b)即使有很长时间的空白运行,我也很少一次将这个点移动一个字符,所以我很难想到我会发现这个点被几个空格包围的情况。 Things like Artist mode, or Dot diagrams come to mind, but it doesn't happen during code editing. 我想到了艺术家模式或点图等事情,但在代码编辑过程中不会发生这种情况。

  2. Finally, if you are trying to, well, let's say just edit an arbitrary text file and you want to add or remove horizontal space between words... Again, there's Mx align-regexp to do that, or you could use commands that operate on rectangles, if those are several lines at the time. 最后,如果您正在尝试,那么,让我们说只需编辑一个任意文本文件,并且您想要在单词之间添加或删除水平空格...再次,有Mx align-regexp来做到这一点,或者您可以使用运行的命令在矩形上,如果那些是当时的几行。 Well, Emacs will even recognize the ad hoc tabs and will try to align the text such as to match the last line before the point, when you hit TAB . 好吧,Emacs甚至会识别临时标签,并会尝试对齐文本,以便匹配点之前的最后一行,当您点击TAB时

Finally, if for some reason I cannot fathom :) I really needed to do exactly what you describe, then I'd do it like so: k M-\\ BACKSPACE (it can be any other key instead of "k" - it is just right under your finger, so it's fast to type :) Or, if I'm lazy to think about it: M-SPC Mf Mb Cw - maybe sounds like a lot, but these are the commands you would be using all of the time anyway, so it doesn't hinder you in terms of speed. 最后,如果由于某种原因我无法理解:)我真的需要做你所描述的,然后我会这样做: k M- \\ BACKSPACE (它可以是任何其他键而不是“k” - 它是恰好在你的手指下,所以输入速度很快:)或者,如果我懒得思考它: M-SPC Mf Mb Cw - 也许听起来很多,但这些是你将要使用的所有命令无论如何,时间,所以它不会在速度方面阻碍你。

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

This has most likely been solved before, but instead of looking for code, we can write our own. 这很可能以前已经解决了,但我们可以编写自己的代码,而不是寻找代码。 So much fun! 玩得很尽兴!

This is how I would do it, hope it helps. 我就是这样做的,希望它有所帮助。

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

Then bind it to a key: 然后将其绑定到一个键:

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

If you are using a CC-Mode based buffer, you are probably looking for the Hungry Delete Mode minor mode. 如果您使用的是基于CC模式的缓冲区,则可能正在寻找Hungry Delete Mode次要模式。

Try Cc DEL and Cc DELETE in several places to get a feel for the difference. 尝试在几个地方使用Cc DELCc DELETE来感受差异。

If you like the way it works, you can toggle hungry deletion to work for the standard keys by doing Mx c-toggle-hungry-state or just rebind the hungry deletion functions to your preferred binding. 如果您喜欢它的工作方式,您可以通过执行Mx c-toggle-hungry-state或仅将饥饿的删除功能重新绑定到首选绑定来切换饥饿删除以使用标准键。

If you still think you need to piggyback one key to do forward kill word or whitespace, then you can do something similar to c-hungry-delete-forward , or just temporarily rebind c-delete-function and call it. 如果您仍然认为需要搭载一个键来执行前向杀词空格,那么您可以执行类似于c-hungry-delete-forward ,或者只是临时重新绑定c-delete-function并调用它。

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

Check out the Info page (ccmode) Hungry WS Deletion for more. 查看信息页面(ccmode) Hungry WS Deletion了解更多信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM