emacs 中的 Ctrl-backspace 删除太多内容

问题描述 投票:0回答:7

emacs 中的 ctrl-backspace 会删除所有空格,这很好。然而,它并不止于此!好像只有删除了至少一个字才停止。例如,这意味着在这里使用它:

foo(bar)
    <cursor>

结果

foo(<cursor>

这真的很愚蠢(恕我直言)!我想要的行为类似于以下内容:

  1. 如果光标前面有空格,则删除所有空格(然后停止!)。
  2. 如果光标前面有单词,则删除该单词。
  3. 否则,删除光标前面任何字符的所有相邻重复项。

这看起来是一个更合理的 Ctrl-Backspace,但说实话,如果我能得到 (1),那将是一个巨大的改进。有这个包或者设置吗?我不太了解 emacs lisp,但也许可以向我指出相关 API 的位置...

emacs
7个回答
6
投票

我使用以下intellij风格的智能向后杀字

(defun aborn/backward-kill-word ()
  "Customize/Smart backward-kill-word."
  (interactive)
  (let* ((cp (point))
         (backword)
         (end)
         (space-pos)
         (backword-char (if (bobp)
                            ""           ;; cursor in begin of buffer
                          (buffer-substring cp (- cp 1)))))
    (if (equal (length backword-char) (string-width backword-char))
        (progn
          (save-excursion
            (setq backword (buffer-substring (point) (progn (forward-word -1) (point)))))
          (setq ab/debug backword)
          (save-excursion
            (when (and backword          ;; when backword contains space
                       (s-contains? " " backword))
              (setq space-pos (ignore-errors (search-backward " ")))))
          (save-excursion
            (let* ((pos (ignore-errors (search-backward-regexp "\n")))
                   (substr (when pos (buffer-substring pos cp))))
              (when (or (and substr (s-blank? (s-trim substr)))
                        (s-contains? "\n" backword))
                (setq end pos))))
          (if end
              (kill-region cp end)
            (if space-pos
                (kill-region cp space-pos)
              (backward-kill-word 1))))
      (kill-region cp (- cp 1)))         ;; word is non-english word
    ))

(global-set-key  [C-backspace]
            'aborn/backward-kill-word)

4
投票

我想要的行为是 C-Backspace 能够:

  1. 如果光标之前的字符是空格,则删除光标之前的所有空格(包括换行符)。
  2. 如果光标之前的字符不是空格,则执行正常的杀字行为。

这是我的实现:

(defun ryanmarcus/backward-kill-word ()
  "Remove all whitespace if the character behind the cursor is whitespace, otherwise remove a word."
  (interactive)
  (if (looking-back "[ \n]")
      ;; delete horizontal space before us and then check to see if we
      ;; are looking at a newline
      (progn (delete-horizontal-space 't)
             (while (looking-back "[ \n]")
               (backward-delete-char 1)))
    ;; otherwise, just do the normal kill word.
    (backward-kill-word 1)))

3
投票

Ctrl-退格键运行命令

backward-kill-word
,顾名思义,该命令将始终尝试删除前一个单词。

也许您需要 M-\ (

delete-horizontal-space
),它会删除光标周围的所有空白。无论如何,这将满足您的第一个要求。


2
投票

我不久前遇到了同样的问题,并用它覆盖了 C-backspace。

;;Eclipse-like C-backspace
(defun my-kill-back ()
  (interactive)
  (if (bolp)  ; beginnning of line, just delete 1
      (backward-delete-char 1)
    (if (string-match "[^[:space:]]" (buffer-substring (point-at-bol) (point)))
        ; There's a word on the line, delete it
        (backward-kill-word 1)
      (delete-region (point-at-bol) (point))))) ; all whitespace, delete it

(global-set-key [C-backspace] 'my-kill-back)

有点麻烦。例如,如果该行中的所有存在都是分号,则向后删除字可以删除太多。尽管如此,大部分工作还是完成了。


0
投票

在引用的特定情况下,人们可能使用了“删除缩进”(通常绑定到 M-^),这将删除行开头和前面的换行符处的所有空格,实际上将当前行向上移动到该行多于。我发现这个命令非常有帮助,即使可能无法解决所述的确切问题。


0
投票

@AbornJiang 谢谢。我做了一个小小的更改,使其行为类似于 Atom 向后删除单词的默认方式。

(when (and backword  ;; when backword contains space
           (s-contains? " " backword))
  (setq space-pos (1+ (ignore-errors (search-backward-regexp "[[:space:]][[:word:]]")))))

此正则表达式选择一个开始 pos,删除下一个单词开头的任意数量的空格。这与 MacOS、Google Docs、Sublime 和 Atom 中的行为相同。

https://gist.github.com/jclosure/d838a672ba77482f2dcc1fc4df3368de#file-emacs-el-L447


0
投票

这是一个老问题,但这是一个多年来对我很有帮助的解决方案。我喜欢它,因为它不贪婪,而且我更喜欢多次输入

C-backspace
,而不是一次删除太多内容并不得不撤消。非贪婪行为在所有情况下都很有效。

每次调用时,它都会删除以下任一内容:

  • 如果光标前面有空格,则全是空格,
  • 如果光标之前有行尾,
  • 如果光标前有一个单词,则为一个单词。
(defun my-backward-kill-char-or-word ()
  (interactive)
  (cond
   ((looking-back (rx (char word)) 1)
    (backward-kill-word 1))
   ((looking-back (rx (char blank)) 1)
    (delete-horizontal-space t))
   (t
    (backward-delete-char 1))))

(global-set-key (kbd "<C-backspace>") 'my-backward-kill-char-or-word)

我不值得赞扬,因为我多年前在某个地方发现了它,而且不幸的是,我不记得作者是谁。

由于人们在几条评论中要求类似的向前删除功能,我只是对其进行了调整以继续工作:

(defun my-forward-kill-char-or-word ()
  (interactive)
  (cond
   ((looking-at (rx (char word)) 1)
    (kill-word 1))
   ((looking-at (rx (char blank)) 1)
    (delete-horizontal-space))
   (t
    (delete-forward-char 1))))

(global-set-key (kbd "M-d") 'my-forward-kill-char-or-word)
© www.soinside.com 2019 - 2024. All rights reserved.