在vim中打开某些文件类型之前如何警告? [英] How to warn before opening certain filetypes in vim?
问题描述
依靠命令行自动完成功能很容易意外地用vim打开大的二进制文件或数据文件.
It is easy to accidentally open a large binary or data file with vim when relying on command line autocomplete.
在vim中打开某些文件类型时是否可以添加交互式警告?
Is it possible to add an interactive warning when opening certain file types in vim?
例如,我想在打开不带扩展名的文件时添加一条警告:
For example, I'd like to add a warning when opening files without an extension:
> vim someBinary
Edit someBinary? [y/N]
或者:
> vim someBinary
# vim buffer opens and displays warning about filetype,
# giving user a chance to quit before loading the file
这可以应用于一系列扩展名,例如 .pdf
, .so
, .o
, .a
,无扩展名等.
This could be applied to a range of extensions, such as .pdf
, .so
, .o
, .a
, no extension, etc.
防止vim打开二进制文件有一个相关问题,但这主要是为了修改自动完成功能,以防止首先意外打开文件.
There is a related question on preventing vim from opening binary files, but it is primarily about modifying autocomplete to prevent accidentally opening the files in the first place.
推荐答案
下面是我想出的解决方案,它通过vim自动命令与 BufReadCmd
事件一起使用.它有很多vimscript,但是非常健壮.如果正在打开的文件是非ascii文件或扩展名已列入黑名单(此示例为 .csv
和 .tsv
),则会发出警告:
Below is the solution I came up with, using vim autocommands with the BufReadCmd
event. It's a lot of vimscript, but it's pretty robust. It issues a warning if the file being opened is a non-ascii file or has a blacklisted extension (.csv
and .tsv
for this example):
augroup bigfiles
" Clear the bigfiles group in case defined elsewhere
autocmd!
" Set autocommand to run before reading buffer
autocmd BufReadCmd * silent call PromptFileEdit()
augroup end
" Prompt user input if editing an existing file before reading
function! PromptFileEdit()
" Current file
let file = expand("%")
" Whether or not we should continue to open the file
let continue = 1
" Skip if file has an extension or is not readable
if filereadable(file) && (IsNonAsciiFile(file) || IsBlacklistedFile())
" Get response from user
let response = input('Are you sure you want to open "' . file . '"? [y/n]')
" Bail if response is a 'n' or contains a 'q'
if response ==? "n" || response =~ "q"
let continue = 0
if (winnr("$") == 1)
" Quit if it was the only buffer open
quit
else
" Close buffer if other buffers open
bdelete
endif
endif
endif
if continue == 1
" Edit the file
execute "e" file
" Run the remaining autocommands for the file
execute "doautocmd BufReadPost" file
endif
endfunction
" Return 1 if file is a non-ascii file, otherwise 0
function! IsNonAsciiFile(file)
let ret = 1
let fileResult = system('file ' . a:file)
" Check if file contains ascii or is empty
if fileResult =~ "ASCII" || fileResult =~ "empty" || fileResult =~ "UTF"
let ret = 0
endif
return ret
endfunction
" Return 1 if file is blacklisted, otherwise 0
function! IsBlacklistedFile()
let ret = 0
let extension = expand('%:e')
" List contains ASCII files that we don't want to open by accident
let blacklistExtensions = ['csv', 'tsv']
" Check if we even have an extension
if strlen(extension) == 0
let ret = 0
" Check if our extension is in the blacklisted extensions
elseif index(blacklistExtensions, extension) >= 0
let ret = 1
endif
return ret
endfunction
要在启用语法突出显示的情况下阅读,请参见以下要点.
To read with syntax highlighting enabled, see this gist.
也许不是超级优雅,但是我很喜欢沿途学习一些vimscript.
Maybe not super elegant, but I enjoyed learning some vimscript along the way.
我对vimscript不太了解,因此我确定还有改进的余地-欢迎提出建议和替代解决方案.
I am not too experienced with vimscript so I'm sure there is room for improvements -- suggestions and alternative solutions welcome.
注意:由于调用 file
,因此这在WSL或Cygwin之外的Windows系统上不起作用.
Note: This is not expected to work on Windows systems outside of WSL or Cygwin, due to calling file
.
这篇关于在vim中打开某些文件类型之前如何警告?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!