3 votes

Comment avertir avant d'ouvrir certains types de fichiers dans vim ?

Il est facile d'ouvrir accidentellement un grand fichier binaire ou de données avec vim lorsqu'on se fie à l'autocomplétion de la ligne de commande.

Est-il possible d'ajouter un avertissement interactif lors de l'ouverture de certains types de fichiers dans vim ?

Par exemple, j'aimerais ajouter un avertissement lors de l'ouverture de fichiers sans extension :

> vim someBinary
Edit someBinary? [y/N]

Ou peut-être :

> vim someBinary
# vim buffer opens and displays warning about filetype, 
# giving user a chance to quit before loading the file

Cela pourrait s'appliquer à une série d'extensions, telles que .pdf , .so , .o , .a pas d'extension, etc.

Il y a une question connexe sur empêcher vim d'ouvrir des fichiers binaires mais il s'agit surtout de modifier la complétion automatique pour éviter d'ouvrir accidentellement les fichiers.

2voto

bencray Points 1158

Voici la solution que j'ai trouvée, en utilisant les autocommandes de vim avec l'option BufReadCmd événement. C'est beaucoup de vimscript, mais c'est assez robuste. Il émet un avertissement si le fichier ouvert est un fichier non-ascii ou a une extension sur liste noire ( .csv y .tsv pour cet exemple) :

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

Pour lire avec la coloration syntaxique activée, voir ceci Gist .

Peut-être pas très élégant, mais j'ai aimé apprendre un peu de vimscript en cours de route.

Je n'ai pas trop d'expérience avec vimscript, donc je suis sûr qu'il y a place pour des améliorations - les suggestions et les solutions alternatives sont les bienvenues.

Note : Il n'est pas prévu que cela fonctionne sur les systèmes Windows autres que WSL ou Cygwin, en raison de la nécessité d'appeler file .

1voto

Walter A Points 129

Vous pouvez utiliser une fonction comme celle-ci

promptvim() { 
   grep -Fq "." <<< "$1" || read -p "Edit $1? [y/N]" && [[ $REPLY == "y" ]] || return
   /usr/bin/vim "$1"
}

Vous pouvez choisir un autre nom de fonction. Lorsque vous utilisez vim d'autres scripts pourraient échouer.

EDIT : Lorsque vous aimez cette construction (wrapper, pas les paramètres vim), vous pouvez améliorer la fonction avec plus de tests :

promptvim() {
   if [ $# -eq 0 ]; then
      echo "arguments are missing"
      return
   fi
   local maybe_dot=$(grep -Fq "." <<< "$1")
   for file in $*; do
      # skip tests when creating a new file
      if [ -f "${file}" ]; then
         maybe_dot=$(grep -F "." <<< "${file}")
         if (( ${#maybe_dot} == 0 )); then
            read -p "Edit ${file}? [y/N]"
            # check default response variable REPLY
            # Convert to lowercase and check other ways of confirming too
            if [[ ! "${REPLY,,}" =~ ^(y|yes|j|ja|s|si|o|oui)$ ]]; then
               continue
            fi
         fi
      fi
      echo /usr/bin/vim "${file}"
   done
}

Cela ne couvre pas encore tous les cas particuliers. Vous pourriez vouloir ajouter le support de la vim sur la ligne de commande, vérifiez l'existence d'une session interactive et pensez ce que vous voulez avec here documents .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X