VIM désactiver la nouvelle ligne automatique à la fin du fichier

251

Je travaille donc dans une boutique PHP, et nous utilisons tous des éditeurs différents, et nous devons tous travailler sur Windows. J'utilise vim, et tout le monde dans la boutique se plaint que chaque fois que je modifie un fichier, il y a une nouvelle ligne en bas. J'ai cherché et trouvé que c'était un comportement documenté de vi & vim ... mais je me demandais s'il y avait un moyen de désactiver cette fonctionnalité. (Il serait préférable que je puisse le désactiver pour des extensions de fichier spécifiques).

Si quelqu'un le sait, ce serait génial!

Boushley
la source
23
vous devez leur dire qu'ils sont stupides - il y a en fait une bonne raison pour laquelle vim fait ça: stackoverflow.com/questions/729692/… . Je suppose que cela n'est pertinent que si vous déployez sur des serveurs de type Unix, cependant.
hdgarrood
5
La pratique officielle recommandée par PHP est d'omettre la dernière ?>balise de fermeture, juste pour cette raison.
Sebastián Grignoli
cette question est probablement antérieure au superutilisateur ... mais elle devrait être là.
gcb
20
La question devrait vraiment être: Comment pouvons-nous dire à tous les autres éditeurs que les gens dans votre magasin utilisent pour assurer la dernière ligne du fichier ne fin avec un EOL. ;-)
TJ Crowder

Réponses:

361

Et pour vim7.4+, vous pouvez utiliser (de préférence sur votre .vimrc) (merci à 罗泽轩 pour ces dernières nouvelles!):

:set nofixendofline

Maintenant, concernant les anciennes versions de vim.

Même si le fichier a déjà été enregistré avec de nouvelles lignes à la fin:

vim -b file et une fois dans vim:

:set noeol
:wq

terminé.

vous pouvez également ouvrir des fichiers dans vim avec :e ++bin file

Encore une autre alternative:

:set binary
:set noeol
:wq
gcb
la source
6
Vous pouvez également ajouter set binaryet set noeoldans votre .vimrc
dryobs
17
Attention : les binarysubstitutions expandtab, qui vous amèneront à obtenir des onglets littéraux dans votre source.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
4
@CiroSantilli merci! J'ai toujours cherché les effets secondaires du binaire et je me demande pourquoi ce n'est pas le défaut! depuis que j'aime mes onglets, je pense que je considérerai cet avantage supplémentaire :)
gcb
11
Maintenant , vous pouvez ajouter set nofixendoflineà résoudre le problème dans vim 7.4+
罗泽轩
1
@TrevorBoydSmith oui, car historiquement POSIX (je peux me tromper sur la norme actuelle) attend une nouvelle ligne à la fin d'une ligne, dans un fichier texte. C'est pourquoi la plupart des solutions nécessitaient de le traiter comme un binaire. C'était probablement très pratique à l'époque, et c'est en arrière aujourd'hui, c'est pourquoi maintenant il y a le réglage pratique. Ajoutez-le simplement à votre vimrc. Il y a quand même des problèmes pires dans les autres éditeurs :)
gcb
23

Ajoutez la commande suivante à votre .vimrc pour désactiver l'option de fin de ligne:

autocmd FileType php setlocal noeol binary fileformat=dos

Cependant , PHP lui-même ignorera cette dernière fin de ligne - cela ne devrait pas être un problème. Je suis presque certain que dans votre cas, il y a quelque chose d'autre qui ajoute le dernier caractère de nouvelle ligne, ou peut-être qu'il y a un mélange avec les types de fin de ligne windows / unix ( \nou \r\n, etc.).

Mettre à jour:

Une autre solution pourrait être d'ajouter simplement cette ligne à votre .vimrc:

set fileformats+=dos
trop de php
la source
Je sais que php ne l'analyse pas mal ... J'ai montré cela à mes collègues, mais winmerge les considère comme différents ... Je vais essayer et je vous ferai savoir comment cela se passe.
Boushley
Faire cela a l'effet souhaité de ne pas avoir de ligne finale, mais cela convertit également le fichier en fins de ligne unix ... (même sur une boîte Windows) ... Donc je l'avais fait avant en passant en mode binaire ... mais ensuite les fins de ligne ne s'affichent pas dans le bloc-notes ... tout est juste une ligne.
Boushley
Malheureusement, aucune de ces suggestions ne fonctionne. L'ajout du format de fichier = dos à l'autocmd n'a aucun effet, et définir filetype + = dos ajoute toujours le \ n
Boushley
Désolé, je me suis trompé, utilisez 'set filetypes + = dos', not 'set fileformats ...'
trop de php le
17

Il existe une autre façon d'aborder cela si vous utilisez Git pour le contrôle de code source. Inspiré par une réponse ici , j'ai écrit mon propre filtre à utiliser dans un fichier gitattributes .

Pour installer ce filtre, enregistrez-le noeol_filterquelque part dans votre $PATH, rendez-le exécutable et exécutez les commandes suivantes:

git config --global filter.noeol.clean noeol_filter
git config --global filter.noeol.smudge cat

Pour commencer à utiliser le filtre uniquement pour vous, mettez la ligne suivante dans votre $GIT_DIR/info/attributes:

*.php filter=noeol

Cela garantira que vous n'engagerez aucune nouvelle ligne à eof dans un .phpfichier, quoi que Vim fasse.

Et maintenant, le script lui-même:

#!/usr/bin/python

# a filter that strips newline from last line of its stdin
# if the last line is empty, leave it as-is, to make the operation idempotent
# inspired by: /programming/1654021/how-can-i-delete-a-newline-if-it-is-the-last-character-in-a-file/1663283#1663283

import sys

if __name__ == '__main__':
    try:
        pline = sys.stdin.next()
    except StopIteration:
        # no input, nothing to do
        sys.exit(0)

    # spit out all but the last line
    for line in sys.stdin:
        sys.stdout.write(pline)
        pline = line

    # strip newline from last line before spitting it out
    if len(pline) > 2 and pline.endswith("\r\n"):
        sys.stdout.write(pline[:-2])
    elif len(pline) > 1 and pline.endswith("\n"):
        sys.stdout.write(pline[:-1])
    else:
        sys.stdout.write(pline)
Amir
la source
C'est une excellente solution ... même si malheureusement je n'utilisais pas git. J'utilisais svn, bien que je soupçonne qu'une approche similaire aurait pu être adoptée. Quoi qu'il en soit, je suis passé de cette position et je n'ai plus à m'en soucier :)
Boushley
12

Je n'ai pas essayé cette option, mais les informations suivantes sont fournies dans le système d'aide de vim (ie help eol):

'endofline' 'eol'   boolean (default on)
            local to buffer
            {not in Vi}

When writing a file and this option is off and the 'binary' option
is on, no <EOL> will be written for the last line in the file.  This
option is automatically set when starting to edit a new file, unless
the file does not have an <EOL> for the last line in the file, in
which case it is reset.  

Normalement, vous n'avez pas besoin de définir ou de réinitialiser cette option. Lorsque «binaire» est désactivé, la valeur n'est pas utilisée lors de l'écriture du fichier. Lorsque «binaire» est activé, il est utilisé pour se souvenir de la présence d'un pour la dernière ligne du fichier, de sorte que lorsque vous écrivez le fichier, la situation du fichier d'origine peut être conservée. Mais vous pouvez le changer si vous le souhaitez.

Vous pouvez également être intéressé par la réponse à une question précédente: " Pourquoi les fichiers devraient-ils se terminer par une nouvelle ligne ".

Tim Henigan
la source
J'avais également rencontré le cadre eol ... mais il n'accomplit pas cette tâche. Il s'agit plutôt d'une variable qui détermine si une a déjà été placée à la fin du fichier ou non. De plus, cela n'a aucun effet sur les fichiers texte, mais uniquement sur les fichiers binaires.
Boushley
3
L'aide de vim indique également "Lorsque" binaire "est désactivé, la valeur n'est pas utilisée lors de l'écriture du fichier." à propos de eol
Boushley
1
+1 pour la réponse de VonC à cette question, qui met en évidence le fait que "newline" et EOL sont confondus. Les éditeurs inférieurs affichent de manière incorrecte une nouvelle ligne supplémentaire à cause d'une fin de vie, vim n'ajoute pas de "nouvelle ligne"!
ches
9

J'ai ajouté une astuce sur le wiki Vim pour un problème similaire (bien que différent):

http://vim.wikia.com/wiki/Do_not_auto-add_a_newline_at_EOF

Jo Liss
la source
5
«Vim 7.4.785 ajoute l' fixeoloption qui peut être désactivée pour conserver automatiquement tout EOL manquant à la fin du fichier. Ce script devient inutile pour Vim 7.4.785 et versions ultérieures. » (Source: la même page wiki.) Merci, je n'étais pas au courant de cette nouvelle option.
Amir
1
J'ai dû régler les deux noeolet nofixeolobtenir le résultat souhaité.
selurvedu
8

OK, être sous Windows complique les choses;)

Comme l'option «binaire» réinitialise l'option «fileformat» (et l'écriture avec l'ensemble «binaire» écrit toujours avec des fins de ligne unix), sortons le gros marteau et faisons-le en externe!

Que diriez-vous de définir une autocommande (: help autocommand) pour l'événement BufWritePost? Cette autocommande est exécutée après chaque fois que vous écrivez un tampon entier. Dans cette autocommande, appelez un petit outil externe (php, perl ou autre script) qui supprime la dernière nouvelle ligne du fichier qui vient d'être écrit.

Donc, cela ressemblerait à quelque chose comme ceci et irait dans votre fichier .vimrc:

autocmd!   "Remove all autocmds (for current group), see below"
autocmd BufWritePost *.php !your-script <afile>

Assurez-vous de lire l'intégralité de la documentation vim sur les autocommandes si c'est la première fois que vous traitez avec des autocommandes. Il y a quelques mises en garde, par exemple, il est recommandé de supprimer tous les autocmds de votre .vimrc au cas où votre .vimrc pourrait provenir de plusieurs fois.

Blixtor
la source
Eh bien ... j'espérais qu'il y avait une meilleure solution que ça ... mais ça marche vraiment!
Boushley
3
Cela fonctionne très bien! Yay! Cependant, j'ai une question ... existe-t-il un moyen de le faire, donc je n'ai pas à appuyer sur Entrée deux fois après chaque sauvegarde. Je dois appuyer sur Entrée dans la fenêtre cmd qui est apparue, puis à nouveau parce que Vim me dit que le script a réussi ... Une façon de les faire disparaître?
Boushley
2
Pour éviter les invites <Appuyez sur Entrée>, préfixez simplement la commande avec silent. Par exemple silent !your-script <afile>.
dash-tom-bang
6

J'ai implémenté les suggestions de Blixtor avec le post-traitement Perl et Python, soit en cours d'exécution dans Vim (s'il est compilé avec un tel support de langage), soit via un script Perl externe. Il est disponible en tant que plugin PreserveNoEOL sur vim.org.

Ingo Karkat
la source
Je ne l'ai pas testé à fond, mais cela semble être une meilleure solution.
Boushley
Le plugin fonctionne, mais après l'installation, j'ai dû le mettre let g:PreserveNoEOL = 1dans mon .vimrcfichier! J'ai dû apprendre vimscript pour comprendre cela à partir de la description du plugin! : D
DarthVanger
1
@DarthVanger: vous l' :help PreserveNoEOL-usageaurait dit aussi. RTFM :-)
Ingo Karkat
@IngoKarkat Oh, désolé. Je cherchais cela sous INSTALLATIONet CONFIGURATION. Je n'ai même pas remarqué la USAGEsection dans la description, car elle est au-dessus de l'installation :)
DarthVanger
3

Vous pourriez peut-être voir pourquoi ils se plaignent. Si un fichier php a une nouvelle ligne après la fin?>, Php le sortira dans le cadre de la page. Ce n'est pas un problème sauf si vous essayez d'envoyer des en-têtes une fois le fichier inclus.

Cependant, le?> À la fin d'un fichier php est facultatif. Pas de fin?>, Pas de problème avec une nouvelle ligne à la fin du fichier.

Ken
la source
2
Vous avez raison, mais nous, en tant que magasin, avons décidé qu'il semblait préférable d'avoir la fin?> Je sais que nous pourrions cesser de l'utiliser ... mais je préfère ajuster mon éditeur pour qu'il corresponde à mon style de codage que l'inverse.
Boushley
1
De plus, pour que vous sachiez que php analysera automatiquement votre balise de fin en tant que?> Ou en tant que?> \ N (car sous linux, tous les fichiers valides doivent se terminer par un \ n) ... Mon code ne cause donc pas ces problèmes ... ils n'aiment tout simplement pas le look.
Boushley
2

J'ajoute .vimrc

set binary

et ça aide, essayez-le

IvanM
la source
2

Je pense que j'ai trouvé une meilleure solution que la réponse acceptée. Les solutions alternatives ne fonctionnaient pas pour moi et je ne voulais pas avoir à travailler en mode binaire tout le temps. Heureusement, cela semble faire le travail et je n'ai pas encore rencontré d'effets secondaires désagréables: conserver la fin de ligne manquante à la fin des fichiers texte . Je viens d'ajouter le tout à mon ~ / .vimrc.

Jay Paroline
la source
1

Serait-il possible pour vous d'utiliser une commande spéciale pour enregistrer ces fichiers?

Si vous faites: set binary,: w et: set nobinary, le fichier sera écrit sans retour à la ligne s'il n'y en avait pas pour commencer.

Cette séquence de commandes peut être insérée dans une commande définie par l'utilisateur ou un mappage, bien sûr.

Blixtor
la source
Malheureusement parce que je travaille avec Windows, si je l'enregistre en mode binaire, cela force l'enregistrement à être en mode unix. Même quand je le fais: set binary: set fileformat = dos: w: set nobinary Une fois que je quitte, il enregistre le fichier au format Unix ... Je ne peux pas croire qu'il n'y ait pas moyen de désactiver cela.
Boushley
0

J'ai trouvé que ce plugin vimscript est utile pour cette situation.

Plugin 'vim-scripts/PreserveNoEOL'

Ou lisez plus sur github

Alan Dong
la source