2011-06-02 2 views
15

Я набираю очень быстро и понимаю, что иногда я случайно сохраняю файл с именем ; или : (я печатаю :wq, а иногда и опечатку).Предотвращение сохранения файлов с определенными именами в Vim

Есть ли способ написать макрос, который отклоняет сохранение файлов, соответствующих определенным именам?

+3

Я думаю, вы могли бы использовать автокоманду с 'BufWritePre', чтобы предупредить вас и не писать файлы, начинающиеся с'; * '. Но сейчас я сон, и когда я проснусь, я выстрелю в него, если к этому еще не ответят. – abcd

ответ

17

Простым, но эффективным решением было бы определить автоматическую команду, соответствующую потенциально туманным именам файлов, которые вызывают предупреждение и прекращают сохранение.

:autocmd BufWritePre [:;]* throw 'Forbidden file name: ' . expand('<afile>') 

Обратите внимание, что команда :throw необходимо сделать Vim остановить написание содержимое буфера.

Для того, чтобы избежать попадания E605 ошибки из-за неперехваченное исключение, один может выдать сообщение об ошибке с помощью :echoerr запустить команду в try блоке. (:echoerr поднимает сообщение об ошибке, как исключение при вызове из внутренней в try конструкции. См :help :echoerr.)

:autocmd BufWritePre [:;]* 
\ try | echoerr 'Forbidden file name: ' . expand('<afile>') | endtry 

Если когда-либо необходимо сохранить файл с именем, совпадающим шаблоном, используемым в вышеизложенной auto-command, можно добавить команду на запись с :noautocmd или соответственно установить eventignore (см. :help :noautocmd и :help eventignore), например

:noa w :ok.txt 
+0

Это замечательно (и у меня есть функция предварительного сохранения, которая делает что-то очень похожее), но есть ли более тонкий способ предотвратить сохранение во время BufWritePre? Выброс ошибки таким образом приводит к «E605: Исключение не поймано». Было бы неплохо, если бы сообщение можно было повторить, а не уродливое сообщение об ошибке. –

+0

@ Принц: К сожалению, нет другого способа прекратить действие, которое запускает событие autocmd, чем бросает исключение, насколько я знаю. Однако можно избавиться от ошибки 'E605', обернув« throw »в' try'-'catch', ответ обновлен. –

+0

Я думаю, вам нужно 'echohl ErrorMsg | echom 'Подозрительное имя файла:. .v: exception | echohl NONE' вместо 'echoerr': echoerr не следует использовать, потому что он предоставляет не необходимую информацию об этом контексте ошибки. 2. В зависимости от контекста он может или не может быть преобразован в исключение. Последнее потому, что я ненавижу 'echoerr': исключения сами по себе не хороши, поскольку они создают дополнительные скрытые точки выхода для всех функций в стеке до тех пор, пока не будет найдено' try..catch', но 'echoerr' хуже, так как он делает число точки выхода зависят от контекста. У меня когда-то было «хорошее» время отладки проблемы с «echoerr». – ZyX