Почему клавиша возврата не работает в режиме вставки?

146

Попытка удалить символы в режиме вставки с помощью backspaceклавиши иногда не работает. backspace Иногда я могу , но иногда ничего не происходит; курсор не идет влево, и кажется, что ничего не происходит.

Я заметил это с помощью gVim в Windows. Тем не backspaceменее, кажется, что работает как ожидалось при использовании Vim из терминала в большинстве систем Linux.

  1. Почему это происходит?
  2. Как заставить backspaceключ удалять символы как обычно?
  3. Это поведение задумано как функция? Другими словами: есть ли лучшие альтернативы backspaceдля удаления символов в режиме вставки?
GLS
источник
В то время как ответ ниже правильно решает вашу проблему, я обнаружил, что отключение клавиш, таких как клавиши со стрелками или backspace, помогает вам привыкнуть делать вещи более правильно. Возврат в vim выполняется с помощью X(и удаляется с помощью x), но часто вы действительно хотели, dbнапример, удалить до начала слова или dawудалить все слово и т. Д. Если у вас есть доступный возврат, вы рискуете использовать это неоптимальный ключ в большем количестве случаев, чем необходимо.
Шахбаз
5
@ Shahbaz Я не согласен: в режиме вставки имеет смысл вносить незначительные исправления с помощью клавиши возврата. Я согласен с тем, что нужно учиться использовать команды в нормальном режиме, но использование backspace в режиме вставки не является незначительным для незначительных исправлений.
Карл Ингве Лервог
3
@ KarlYngveLervåg, в случае возврата я согласен (на самом деле я не отключил его сам). Тем не менее, похоже, что OP имеет поведение backspace по умолчанию, которое не работает, например, с началом строки, но работает внутри строки. Тем не менее, OP имеет лучшие варианты, чем Backspace. Например, вместо возврата к предыдущей строке можно использовать тот, Jкоторый также заботится о пробелах. Короче говоря, backspace подходит для быстрого исправления опечаток во время записи, но кроме этого есть и лучшие альтернативы.
Шахбаз
1
Проблема многих людей заключается не в несогласии с этой функцией как таковой, а в том, что они используют не единственный редактор. Поскольку они используют несколько редакторов, нелогично переключать парадигмы, связанные с backspace, поэтому они предпочитают подмножество функций vim.
J RIV
Если вы установили vim-faq , вы можете получить оффлайн ответ: :h vim-faqи искать /backspace. Трудно запомнить тег :h faq-12.26.
Хотчке

Ответы:

178

tl; dr: Добавьте это в ваш vimrc, чтобы заставить backspace работать, как в большинстве других программ:

set backspace=indent,eol,start

Более длинный ответ

Хотя поведение по умолчанию может быть удивительным, возврат на «не работающий» может рассматриваться как функция ; это может предотвратить случайное удаление отступа и слишком большого объема текста, ограничивая его текущей строкой и / или началом вставки.

:help 'backspace' говорит нам:

Influences the working of `<BS>`, `<Del>`, `CTRL-W` and `CTRL-U` in Insert
mode.  This is a list of items, separated by commas.  Each item allows
a way to backspace over something:

value     effect
indent    allow backspacing over autoindent
eol       allow backspacing over line breaks (join lines)
start     allow backspacing over the start of insert; CTRL-W and CTRL-U
          stop once at the start of insert.

Итак, что именно означают эти значения?

indent
Vim добавляет автоматический отступ для многих типов файлов; по умолчанию вы не можете вернуться на это; правила того, что считается «автоиндентированием», несколько неуловимы, например, если бы мы напечатали это (где █ - курсор):

if :; then
    █

Backspace не будет работать.

Но если бы мы затем добавить команды и fi, и вернуться, мы которые позволили удалить отступ:

if :; then
    █:
fi

Это потому, что в первом примере Vim определил, что он должен добавить 1 уровень отступа, когда вы нажимаете Enter; но во втором примере Vim ничего не делал автоматически, это просто символы табуляции или несколько пробелов.

Также см :help 'autoindent'

eol
Это должно быть наиболее очевидным, нажатие Backspace также удаляет маркеры EOL ( \nили \r\n); если отключено, Backspace ничего не сделает, если вы попытаетесь удалить маркер EOL.

start
Это означает, что вы можете удалить только тот текст, который вы вставили с момента запуска режима вставки, и вы не можете удалить текст, который был вставлен ранее.

Итак, каковы настройки по умолчанию?

Я заметил это, используя GVIM в Windows. Backspace, кажется, работает как ожидалось при использовании VIM из терминала в большинстве систем Linux.

Причина этого в том, что многие дистрибутивы Linux поставляются с готовыми файлами vimrc, которые устанавливают некоторые общие параметры. Например, в моей системе Arch Linux у меня есть /usr/share/vim/vimfiles/archlinux.vim:

set nocompatible
set backspace=indent,eol,start
" ... and a few more...

Если вы устанавливаете Vim в Windows, по умолчанию используется vimrc и gvimrc, которые поставляются с Vim по умолчанию.

По умолчанию Vim является пустым значением для backspace. Arch Linux, Debian, CentOS или $other_distrodefault могут отличаться.

Нормальный режим

Этот вопрос касается Backspace в режиме вставки, но позвольте мне также добавить несколько кратких замечаний о Backspace в обычном режиме.

В обычном режиме Backspace действует как h, он просто идет влево.

По умолчанию backspace будет переходить к предыдущей строке, если она находится в начале строки (как если бы она eolбыла внутри backspace); Вы можете контролировать это поведение с помощью 'whichwrap'опции через bфлаг (по умолчанию включено).

Вы также можете сделать символы возврата на обратную позицию, сопоставив их с Xкомандой:

nnoremap <BS> X
Мартин Турной
источник
1
Я думаю, что это "_Xбыло бы "более естественным" поведением для <BS>.
Хаулет
2
Стоит отметить, что дистрибутив почти не поставляется с поведением по умолчанию. Единственный, кого я заметил, был msys2, и это было, вероятно, не решение, а его природа недостаточно развита.
J RIV
5

На всякий случай, если кто-то испытывает необъяснимое <BS>поведение при использовании ConEmu в Windows, вам, возможно, придется переназначить <BS>ключ на:

inoremap <Char-0x07F> <BS>
nnoremap <Char-0x07F> <BS>

Больше информации

Уокер Бо
источник
1
set backspace=2

используется с v5.4 и ранее. работал для меня на Mac.

похоже на Mac у меня v3.2:

$ bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin18)
Copyright (C) 2007 Free Software Foundation, Inc.

Все версии, предшествующие 3.2, используют GNU General Public License v3 (GPLv3), которую Apple не поддерживает. Обсуждение Reddit об этом здесь .

Вы можете перейти на новейшую версию Bash:

brew install bash

это позволяет использовать программируемое завершение, выделенное здесь .

tkjef
источник
0

Если set backspace=indent,eol,startваша последняя строка vimrc, ни одно из решений не будет работать.

Добавьте еще одно правило после этого, например:

set ruler
Мохаммад Шахид Сиддики
источник
4
Мне это кажется довольно странным, не могли бы вы объяснить, почему добавление еще одной команды в ваш vimrc сделает предыдущую работу?
statox