let b:commentChar='//'
: Это создает переменную в vim. b
здесь относится к области, которая в данном случае содержится в буфер, то есть открытый в данный момент файл. Ваши символы комментариев являются строками и должны быть заключены в кавычки, кавычки не являются частью того, что будет подставлено при переключении комментариев.
autocmd BufNewFile,BufReadPost *...
: Автокоманды запускаются для разных вещей, в этом случае они запускаются, когда новый файл или прочитанный файл заканчивается с определенным расширением. После запуска выполните следующую команду, которая позволяет нам изменять commentChar
зависимости в зависимости от типа файла. Есть и другие способы сделать это, но они больше сбивают с толку новичков (таких как я).
function! Docomment()
: Функции объявляются, начиная с function
и заканчивая endfunction
. Функции должны начинаться с заглавной буквы. что !
гарантирует , что эта функция переопределяет все предыдущие функции , определенные как Docomment()
с этой версией Docomment()
. Без этого у !
меня были ошибки, но это могло быть потому, что я определял новые функции через командную строку vim.
execute '''<,''>s/^\s*/&'.escape(b:commentChar, '\/').' /e'
: Выполнить вызывает команду. В этом случае мы выполняем substitute
, который может принимать диапазон (по умолчанию это текущая строка), например, %
для всего буфера или '<,'>
для выделенного раздела. ^\s*
является регулярным выражением, чтобы соответствовать началу строки, за которой следует любое количество пробелов, которые затем добавляются (из-за &
). .
Здесь используется для конкатенации, так как escape()
не может быть завернуты в кавычки. escape()
позволяет вам экранировать символ, commentChar
который соответствует аргументам (в данном случае \
и /
), добавляя их с помощью \
. После этого мы соединяем снова с концом нашегоsubstitute
строки, который имеетe
флаг. Этот флаг позволяет нам молча потерпеть неудачу, что означает, что если мы не найдем совпадения в данной строке, мы не будем кричать об этом. В целом, эта строка позволяет поставить символ комментария, за которым следует пробел перед первым текстом, что означает, что мы сохраняем наш уровень отступа.
execute '''<,''>s/\v(^\s*)'.escape(b:commentChar, '\/').'\v\s*/\1/e'
Это похоже на нашу последнюю огромную длинную команду. У нас есть уникальная возможность \v
, которая гарантирует, что нам не нужно избегать наших ()
, и 1
которая относится к группе, которую мы создали с нашей ()
. По сути, мы сопоставляем строку, начинающуюся с любого количества пробелов, а затем наш символ комментария, за которым следует любое количество пробелов, и мы сохраняем только первый набор пробелов. Опять же, e
давайте молча потерпим неудачу, если у нас нет символа комментария в этой строке.
let l:line=getpos("'<")[1]
: это устанавливает переменную так же, как мы сделали с нашим символом комментария, но l
ссылается на локальную область видимости (локальную для этой функции). getpos()
получает позицию, в данном случае, начала нашего выделения, и [1]
означает, что мы заботимся только о номере строки, а не о других вещах, таких как номер столбца.
if match(getline(l:line), '^\s*'.b:commentChar)>-1
Знаете, как if
работает. match()
проверяет, содержит ли первая вещь вторую, поэтому мы берем строку, с которой мы начали выделение, и проверяем, начинается ли она с пробела, за которым следует символ комментария. match()
возвращает индекс, где это правда, и -1
если совпадений не найдено. Так как if
все ненулевые числа оцениваются как истинные, мы должны сравнить наш вывод, чтобы увидеть, больше ли он -1. Сравнение в vim
возвращает 0, если ложь, и 1, если истина, что и if
нужно видеть, чтобы оценить правильно.
vnoremap <silent> <C-r> :<C-u>call Comment()<cr><cr>
: vnoremap
означает отображать следующую команду в визуальном режиме, но не отображать ее рекурсивно (то есть не изменять никакие другие команды, которые могут использоваться другими способами). По сути, если вы новичок Vim, всегда используйте, noremap
чтобы убедиться, что вы не сломать вещи. <silent>
означает «Я не хочу ваших слов, только ваши действия» и говорит, что ничего не печатать в командной строке. <C-r>
это то, что мы отображаем, в данном случае это ctrl + r (обратите внимание, что вы все равно можете использовать Cr обычно для «повторения» в обычном режиме с этим отображением). C-u
это немного сбивает с толку, но в основном это гарантирует, что вы не потеряете свою визуальную подсветку (в соответствии с этим ответом ваша команда начинает с '<,'>
чего мы и хотим).call
здесь просто говорит vim выполнить функцию, которую мы назвали, и<cr>
ссылается на enter
нажатие кнопки. Мы должны нажать ее один раз, чтобы фактически вызвать функцию (в противном случае мы просто набрали ее call function()
в командной строке, и нам нужно нажать ее снова, чтобы наши заменители прошли весь путь (не совсем понятно, почему, но как угодно).
NERD Commenter
это путь сюда, по моему мнению! +1 за это