如何在Emacs中模拟Vim的'softtabstop'?

时间:2009-09-20 03:00:47

标签: vim emacs indentation

我最近一直试图进入emacs,我需要做的一件事就是缩进。

示例1:

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

示例2:

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

想象一下,上面例子中的竖线字符表示光标位置。现在,我为每个缩进级别(没有选项卡)使用(4)空格,并且我有emacs设置以自动缩进我的代码并考虑到这一点。没有问题。但是在上面的示例中,如果我要在指示的光标位置点击退格,我希望emacs一直退回到下一个缩进级别(列/ 4)。也就是说,我希望它将前面的空格视为由标签组成。相反,它总是只删除一个空格字符。

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

在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

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

1 个答案:

答案 0 :(得分: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))))))