Как мне эмулировать 'softtabstop' Vim в Emacs? - PullRequest
6 голосов
/ 20 сентября 2009

В последнее время я пытался попасть в emacs, и одна из вещей, которые мне нужны, чтобы получить правильные значения, это отступ.

Пример 1:

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

Пример 2:

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

Представьте, что символ трубы в приведенных выше примерах указывает положение курсора. Теперь я использую (4) пробела для каждого уровня отступа (без вкладок), и у меня есть настройка emacs для автоматического отступа моего кода с учетом этого. Там нет проблем. Но в приведенных выше примерах, если бы я нажал клавишу Backspace в указанных позициях курсора, я бы хотел, чтобы emacs возвращался назад на следующий уровень отступа (колонка / 4). То есть я хочу, чтобы предыдущий пробел обрабатывался так, как если бы он состоял из вкладок. Вместо этого он всегда просто стирает один пробел.

В vim я включаю «expandtab», чтобы он вставлял пробелы вместо табуляции, и «softtabstop», который превращает его (среди прочего) в забой до следующей «мягкой табуляции», как описано выше.

В emacs, я полагаю, я мог бы (если бы я знал emacs / elisp лучше) связать backspace с функцией, которая выполняет что-то вроде следующего:

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 Ответ

7 голосов
/ 20 сентября 2009

Это работает для меня, где '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))))))
...