Как запустить autocmd при запуске Vim без файла, несуществующего файла или пустого файла (но не при запуске с существующим файлом)?

11

Я хотел бы запустить autocmd в следующих сценариях при запуске Vim:

  • Без указания имени файла.
  • Когда файл новый.
  • Когда файл существует, но полностью пуст.

Во всех трех вышеупомянутых случаях я хотел бы запустить autocmd; в частности, я хотел бы запустить режим вставки автоматически только для указанных выше сценариев (а не когда я открываю файл, который уже существует и не является пустым).


ОБНОВИТЬ:

Я попытался поместить следующее в мой _vimrc, но не повезло (плюс я не уверен, есть ли в vim функция, которая подсчитывает количество символов в файле (чтобы узнать, равен ли он нулю) перед его открытием:

if @% == "" || filereadable(@%)
  autocmd BufRead,BufNewFile * startinsert
endif
Джон Сондерсон
источник
Нет, это не дубликат. Я хочу, чтобы vi запускалась в режиме вставки ТОЛЬКО ДЛЯ ТРЕХ СЦЕНАРИЙ, КОТОРЫЕ Я НАМЕРЕН.
Джон Сондерсон
3
Ладно, мне очень жаль, но на самом деле это выглядело как дубликат. ;-) Я немного отредактировал ваш вопрос, чтобы прояснить разницу.
Мартин Турной
2
@JohnSonderson первая ссылка говорит вам, как найти, если имя файла не указано, вторую можно адаптировать, используя normalвместо exec.
Муру
1
Файл vimrc читается только один раз : при запуске Vim. Содержимое autocmd запускается каждый раз, когда запускается. Таким образом, ifоператор не должен находиться вокруг autocmd, если он должен находиться внутри autocmd, поэтому он будет запускаться каждый раз, когда запускается autocmd.
Мартин Турной

Ответы:

10

Это работает для всех 3 ваших дел для меня:

function InsertIfEmpty()
    if @% == ""
        " No filename for current buffer
        startinsert
    elseif filereadable(@%) == 0
        " File doesn't exist yet
        startinsert
    elseif line('$') == 1 && col('$') == 1
        " File is empty
        startinsert
    endif
endfunction

au VimEnter * call InsertIfEmpty()

Вероятно, они могут быть сведены к последней проверке наличия пустого файла, поскольку ни одно имя файла или несуществующий файл обычно не начинаются как пустые буферы. Тем не менее, возможно, что какой-то другой плагин предварительно заполняет некоторые вещи в одном из первых двух случаев (например, некоторые плагины шаблонов), поэтому лучше проверить все три.

Первый тест у вас уже был.

Второй тест должен проверить filereadableна значение ноль (не существует), чтобы определить, является ли он новым (в отличие от того, что у вас было).

Последний тест проверяет, что номер последней строки в файле равен 1 (что также является первой строкой, что означает, что есть только одна строка), и что номер столбца конца строки (столбец после последнего символа в строка) равно 1, что означает, что есть 0 символов. Если в нем только 1 строка с 0 символами, то файл должен быть пустым.

Последнее замечание: то, как вы сформулировали свои утверждения в вопросе, может привести к неожиданным результатам. А именно, вы настраиваете BufReadи BufNewFileтолько если условия выполняются при запуске, но тогда эти автокоманды существуют до конца вашего сеанса. Таким образом, если бы вы начали с пустого файла, который устанавливает эти команды, каждый последующий открытый файл (новый или нет, пустой или нет) запустился бы в режиме вставки.

Автокоманда VimEnterзапускается в конце запуска Vim и только один раз для всего сеанса. Таким образом, ваши тесты запускаются только при запуске Vim, а не в любой другой раз.

Джон ОМ.
источник