VIM Disabilita Newline automatico alla fine del file


250

Quindi lavoro in un negozio PHP e tutti usiamo editor diversi e tutti dobbiamo lavorare su Windows. Uso vim e tutti nel negozio continuano a lamentarsi del fatto che ogni volta che modifico un file c'è una nuova riga in fondo. Ho cercato in giro e ho scoperto che questo è un comportamento documentato di vi & vim ... ma mi chiedevo se ci fosse un modo per disabilitare questa funzione. (Sarebbe meglio se potessi disabilitarlo per specifiche estensioni di file).

Se qualcuno lo sapesse, sarebbe fantastico!


23
dovresti dire loro che sono sciocchi - in realtà c'è una buona ragione per cui vim lo fa: stackoverflow.com/questions/729692/… . Immagino che sia pertinente solo se stai implementando su server unix-like.
hdgarrood

5
La pratica ufficiale raccomandata da PHP è di omettere l'ultimo ?>tag di chiusura, proprio per questo motivo.
Sebastián Grignoli,

questa domanda probabilmente precede il superutente ... ma dovrebbe essere lì.
CG

20
La domanda in realtà dovrebbe essere: come facciamo a dire tutti gli altri editori che le persone nel vostro negozio stanno usando per assicurare l'ultima riga del file fa end con un EOL. ;-)
TJ Crowder,

Risposte:


360

E per vim7.4+ puoi usare (preferibilmente sul tuo .vimrc) (grazie a 罗泽轩 per quell'ultima notizia!):

:set nofixendofline

Ora per quanto riguarda le versioni precedenti di vim.

Anche se il file era già stato salvato con nuove righe alla fine:

vim -b file e una volta in vim:

:set noeol
:wq

fatto.

in alternativa puoi aprire i file in vim con :e ++bin file

Ancora un'altra alternativa:

:set binary
:set noeol
:wq

6
Puoi anche aggiungere set binarye set noeolnel tuo .vimrc
dryobs

17
Attenzione : binarysostituisce expandtab, che ti porterà a ottenere schede letterali nella tua fonte.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

4
@CiroSantilli grazie! ho cercato per sempre gli effetti collaterali del binario e mi chiedevo perché non è l'impostazione predefinita! poiché adoro le mie schede, penso che
prenderò in

11
Ora puoi aggiungere set nofixendoflineper risolvere il problema in Vim 7.4+
罗泽轩

1
@TrevorBoydSmith sì, perché storicamente POSIX (potrei sbagliarmi sullo standard attuale) si aspettano una nuova riga alla fine di una riga, in un file di testo. Ecco perché la maggior parte delle soluzioni ha richiesto il trattamento come binario. Probabilmente era molto conveniente allora, ed è indietro oggi, ecco perché ora c'è l'impostazione conveniente. Aggiungilo al tuo vimrc. Ci sono comunque problemi peggiori in altri editor :)
gcb

23

Aggiungi il seguente comando al tuo .vimrc per disattivare l'opzione di fine riga:

autocmd FileType php setlocal noeol binary fileformat=dos

Tuttavia , lo stesso PHP ignorerà l'ultimo end-of-line - non dovrebbe essere un problema. Sono quasi certo che nel tuo caso c'è qualcos'altro che sta aggiungendo l'ultimo carattere di nuova riga, o forse c'è un miscuglio con i tipi di fine linea windows / unix ( \no \r\n, ecc.).

Aggiornare:

Una soluzione alternativa potrebbe essere quella di aggiungere questa riga al tuo .vimrc:

set fileformats+=dos

So che php non sta analizzando la cosa sbagliata ... L'ho dimostrato ai miei colleghi, ma Winmerge li vede come diversi ... Lo proverò e ti farò sapere come va.
Boushley,

In questo modo si ottiene l'effetto desiderato di nessuna riga finale, ma converte anche il file in terminazioni di riga unix ... (anche su una finestra di Windows) ... Quindi l'avevo fatto prima passando alla modalità binaria ... ma poi le terminazioni di riga non vengono visualizzate nel blocco note ... tutto è solo una riga.
Boushley,

Sfortunatamente nessuno di questi suggerimenti funziona. L'aggiunta del fileformat = dos all'autocmd non ha alcun effetto e impostare il tipo di file + = dos aggiunge ancora il finale \ n
Boushley

Scusa, ho sbagliato, usa 'set filetypes + = dos', non 'set fileformats ...'
troppo php,

17

C'è un altro modo per affrontarlo se stai usando Git per il controllo del codice sorgente. Ispirato da una risposta qui , ho scritto il mio filtro per l'uso in un gitattributes file .

Per installare questo filtro, salvalo come noeol_filterda qualche parte nel tuo $PATH, rendilo eseguibile ed esegui i seguenti comandi:

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

Per iniziare a utilizzare il filtro solo per te stesso, inserisci la seguente riga nel tuo $GIT_DIR/info/attributes:

*.php filter=noeol

Questo farà in modo di non impegnare nessuna nuova riga a eof in a .php file, indipendentemente da ciò che fa Vim.

E ora, la sceneggiatura stessa:

#!/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)

È un'ottima soluzione ... anche se sfortunatamente non stavo usando Git. Stavo usando svn, anche se sospetto che avrebbe potuto essere adottato un approccio simile. Comunque, sono passato da quella posizione e non devo più preoccuparmene :)
Boushley

12

Non ho provato questa opzione, ma le seguenti informazioni sono fornite nel sistema di aiuto di vim (cioè 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.  

Normalmente non è necessario impostare o ripristinare questa opzione. Quando 'binary' è disattivato, il valore non viene utilizzato durante la scrittura del file. Quando 'binary' è attivo, viene utilizzato per ricordare la presenza di a per l'ultima riga nel file, in modo che quando si scrive il file sia possibile conservare la situazione dal file originale. Ma puoi cambiarlo se vuoi.

Potresti essere interessato anche alla risposta a una domanda precedente: " Perché i file dovrebbero terminare con una nuova riga ".


Mi ero anche imbattuto nell'ambientazione eol ... ma non compie questo compito. È più di una variabile che determina se uno è già stato inserito alla fine del file o meno. Inoltre, non ha alcun effetto sui file di testo, ma solo sui file binari.
Boushley,

3
La guida di Vim dice anche "Quando 'binary' è disattivato, il valore non viene utilizzato durante la scrittura del file." a proposito di eol
Boushley il

1
+1 per la risposta di VonC su quella domanda, che evidenzia che "newline" e EOL si stanno unendo. Gli editor inferiori visualizzano erroneamente una nuova riga aggiuntiva a causa di un EOL, vim non sta aggiungendo una "nuova riga"!
ches,

9

Ho aggiunto un suggerimento sul wiki di Vim per un problema simile (anche se diverso):

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


5
“Vim 7.4.785 aggiunge l' fixeolopzione che può essere disabilitata per preservare automaticamente qualsiasi EOL mancante alla fine del file. Questa sceneggiatura diventa indispensabile per Vim 7.4.785 e successive. ” (Fonte: la stessa pagina wiki.) Grazie, non ero a conoscenza di quella nuova opzione.
Amir,

1
Ho dovuto impostare entrambi noeolenofixeol per ottenere il risultato desiderabile.
selurvedu,

8

OK, essere su Windows complica le cose;)

Dato che l'opzione 'binaria' reimposta l'opzione 'fileformat' (e scrivere con il set 'binario' scrive sempre con terminazioni di linea unix), estraiamo il grosso martello e lo facciamo esternamente!

Che ne dici di definire un autocommand (: help autocommand) per l'evento BufWritePost? Questo comando automatico viene eseguito ogni volta che si scrive un intero buffer. In questo comando automatico chiama un piccolo strumento esterno (php, perl o qualunque script) che rimuove l'ultima riga del file appena scritto.

Quindi questo sarebbe simile a questo e andrebbe nel tuo file .vimrc:

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

Assicurati di leggere tutta la documentazione di VIM sui autocomandi se è la prima volta che gestisci i autocomandi. Ci sono alcuni avvertimenti, ad esempio si consiglia di rimuovere tutti i file autocmds nel tuo .vimrc nel caso in cui il tuo .vimrc possa essere reperito più volte.


Beh ... speravo che ci fosse una soluzione migliore di questa ... ma sicuramente funziona!
Boushley,

3
Funziona benissimo! Sìì! Comunque ho una domanda ... c'è un modo per farlo, quindi non devo premere Invio due volte dopo ogni salvataggio. Devo premere Invio nella finestra cmd che è spuntata e poi di nuovo perché Vim mi sta dicendo che la sceneggiatura è tornata con successo ... Qualche modo per farli sparire tutti?
Boushley,

2
Per evitare i prompt <Premere Invio> è sufficiente aggiungere il comando al prefisso silent. Es silent !your-script <afile>.
dash-tom-bang

6

Ho implementato i suggerimenti di Blixtor con post-elaborazione Perl e Python, sia all'interno di Vim (se compilato con tale supporto linguistico), sia tramite uno script Perl esterno. È disponibile come plug-in PreserveNoEOL su vim.org.


Non l'ho testato a fondo, ma sembra una soluzione migliore.
Boushley,

Il plugin funziona, ma dopo l'installazione ho dovuto inserire il let g:PreserveNoEOL = 1mio .vimrcfile! Ho dovuto imparare vimscript per capirlo dalla descrizione del plugin! : D
DarthVanger,

1
@DarthVanger: l' :help PreserveNoEOL-usageavresti detto anche a te. RTFM :-)
Ingo Karkat,

@IngoKarkat Oh, scusa. Stavo cercando questo sotto INSTALLATIONe CONFIGURATION. Non ho nemmeno notato la USAGEsezione nella descrizione, perché è sopra l'installazione :)
DarthVanger il

3

Forse potresti vedere perché si stanno lamentando. Se un file php ha una nuova riga dopo la fine?>, Php lo produrrà come parte della pagina. Questo non è un problema se non si tenta di inviare le intestazioni dopo aver incluso il file.

Tuttavia, il?> Alla fine di un file php è facoltativo. Nessuna fine?>, Nessun problema con una nuova riga alla fine del file.


2
Hai ragione, ma come negozio abbiamo deciso che sarebbe meglio avere il finale?> So che potremmo smettere di usarlo ... Ma preferirei adattare il mio editor per adattarlo al mio stile di codifica rispetto al contrario.
Boushley,

1
Inoltre, sai che php analizzerà automaticamente il tuo tag finale come?> O come?> \ N (perché in Linux tutti i file validi dovrebbero terminare con un \ n) ... Quindi il mio codice non causa questi problemi ... semplicemente non gli piace l'aspetto.
Boushley,

2

Aggiungo in .vimrc

set binary

e aiuta, provalo



1

Sarebbe possibile utilizzare un comando speciale per salvare questi file?

Se lo fai: set binary,: w and: set nobinary il file verrà scritto senza newline se non ce n'era uno con cui iniziare.

Questa sequenza di comandi potrebbe essere inserita in un comando definito dall'utente o in una mappatura, ovviamente.


Sfortunatamente perché sto lavorando con Windows, se lo salvo in modalità binaria, forza il salvataggio in modalità unix. Anche quando lo faccio: set binary: set fileformat = dos: w: set nobinary Una volta che ho smesso, ha salvato il file in formato unix ... Non riesco a credere che non ci sia un modo per disattivarlo.
Boushley,


0

Ho trovato questo plugin di vimscript utile per questa situazione.

Plugin 'vim-scripts/PreserveNoEOL'

O leggi di più su github

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.