6

我最近一直在尝试使用 emacs,而我需要做的一件事就是缩进。

示例 1:

sub foo {
    my $bar = 'quux';
    |

示例 2:

sub foo {
    my $bar = 'quux';       |# foo

想象一下,上面示例中的竖线字符表示光标位置。现在,我为每个缩进级别(没有制表符)使用(4)个空格,并且我已经设置了 emacs 来自动缩进我的代码。那里没有问题。但是在上面的示例中,如果我要在指定的光标位置按退格键,我希望 emacs 一直退格键回到下一个缩进级别(第 4 列)。也就是说,我希望它将前面的空格视为由制表符组成。相反,它总是只删除一个空格字符。

在 vim 中,我打开 'expandtab' 以使其插入空格而不是制表符,并打开 'softtabstop',这使其(除其他外)退格到下一个“软制表符”,如上所述。

在 emacs 中,我想我可以(如果我更了解 emacs/elisp)将退格键绑定到执行以下操作的函数:

if indent-tabs-mode is nil
    if the cursor position is preceded by whitespace
        calculate the position of the previous "soft tabstop"
        if there's enough whitespace
            backspace all the way to that point
        else
            backspace by one character

我想知道的是,有没有更简单的方法可以做到这一点,和/或有人知道现有的解决方案吗?

4

1 回答 1

7

这对我有用,其中'tab-width用作列的宽度。在适当的键盘映射中设置键...

(local-set-key (kbd "DEL") 'backward-delete-whitespace-to-column)
(defun backward-delete-whitespace-to-column ()
  "delete back to the previous column of whitespace, or as much whitespace as possible,
or just one char if that's not possible"
  (interactive)
  (if indent-tabs-mode
      (call-interactively 'backward-delete-char-untabify)
    (let ((movement (% (current-column) tab-width))
          (p (point)))
      (when (= movement 0) (setq movement tab-width))
      (save-match-data
        (if (string-match "\\w*\\(\\s-+\\)$" (buffer-substring-no-properties (- p movement) p))
            (backward-delete-char-untabify (- (match-end 1) (match-beginning 1)))
        (call-interactively 'backward-delete-char-untabify))))))
于 2009-09-20T06:35:52.777 回答