VIM deshabilita la nueva línea automática al final del archivo

250

Entonces trabajo en una tienda PHP, y todos usamos editores diferentes, y todos tenemos que trabajar en Windows. Uso vim, y todos en la tienda se quejan de que cada vez que edito un archivo hay una nueva línea en la parte inferior. Busqué y descubrí que este es un comportamiento documentado de vi & vim ... pero me preguntaba si había alguna forma de desactivar esta función. (Sería mejor si pudiera deshabilitarlo para extensiones de archivo específicas).

Si alguien sabe sobre esto, ¡sería genial!

Boushley
fuente
23
debes decirles que están siendo tontos; en realidad, hay una buena razón por la cual vim hace eso: stackoverflow.com/questions/729692/… . Sin embargo, supongo que solo es relevante si está implementando en servidores tipo Unix.
hdgarrood
55
La práctica recomendada oficial de PHP es omitir la última ?>etiqueta de cierre, solo por esta razón.
Sebastián Grignoli
esta pregunta probablemente es anterior al superusuario ... pero debería estar allí.
gcb
20
La pregunta debería ser: ¿Cómo le decimos a todos los otros editores que la gente en su tienda están utilizando para garantizar la última línea del archivo hace extremo con un EOL. ;-)
TJ Crowder

Respuestas:

360

Y para vim7.4+ puedes usar (preferiblemente en tu .vimrc) (¡gracias a 罗泽轩 por esa última noticia!):

:set nofixendofline

Ahora con respecto a versiones anteriores de vim.

Incluso si el archivo ya se guardó con nuevas líneas al final:

vim -b file y una vez en vim:

:set noeol
:wq

hecho.

alternativamente, puede abrir archivos en vim con :e ++bin file

Otra alternativa más:

:set binary
:set noeol
:wq
gcb
fuente
66
También puede agregar set binaryy set noeolen su .vimrc
dryobs
17
Cuidado : las binaryanulaciones expandtab, lo que te llevará a obtener pestañas literales en tu fuente.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
44
@CiroSantilli gracias! He estado buscando efectos secundarios del binario para siempre y me preguntaba por qué no es el predeterminado. ya que amo mis pestañas, creo que voy a considerar que el beneficio añadido :)
GCB
11
Ahora puede agregar set nofixendoflinepara resolver el problema en Vim 7.4+
罗泽轩
1
@TrevorBoydSmith sí, porque históricamente POSIX (podría estar equivocado en el estándar real) espera una nueva línea al final de una línea, en un archivo de texto. Es por eso que la mayoría de las soluciones requieren tratarlo como un binario. Probablemente fue muy conveniente entonces, y hoy está al revés, por eso ahora está la configuración conveniente. Simplemente agréguelo a su vimrc. Hay problemas peores en otros editores de todos modos :)
gcb
23

Agregue el siguiente comando a su .vimrc para desactivar la opción de fin de línea:

autocmd FileType php setlocal noeol binary fileformat=dos

Sin embargo , PHP ignorará el último final de línea, no debería ser un problema. Estoy casi seguro de que en su caso hay algo más que está agregando el último carácter de nueva línea, o posiblemente hay una confusión con los tipos de final de línea de Windows / Unix ( \no \r\n, etc.).

Actualizar:

Una solución alternativa podría ser simplemente agregar esta línea a su .vimrc:

set fileformats+=dos
demasiado php
fuente
Sé que php no lo está analizando mal ... Se lo he mostrado a mis compañeros de trabajo, pero Winmerge los ve como diferentes ... Lo intentaré y les haré saber cómo resulta.
Boushley el
Hacer esto tiene el efecto deseado de no tener una línea final, pero también convierte el archivo en terminaciones de línea unix ... (incluso en un cuadro de Windows) ... Así que lo había hecho antes al cambiar al modo binario ... pero luego los finales de línea no aparecen escribir en el bloc de notas ... todo es solo una línea.
Boushley el
Lamentablemente, ninguna de esas sugerencias funciona. Agregar fileformat = dos al autocmd no tiene ningún efecto, y establecer filetype + = dos aún agrega el final \ n
Boushley
Lo siento, me equivoqué, use 'set filetypes + = dos', no 'set fileformats ...'
demasiado php
17

Hay otra forma de abordar esto si está utilizando Git para el control de fuente. Inspirado por una respuesta aquí , escribí mi propio filtro para usar en un archivo de atributos .

Para instalar este filtro, guárdelo como noeol_filteren algún lugar de su $PATH, hágalo ejecutable y ejecute los siguientes comandos:

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

Para comenzar a usar el filtro solo para usted, ponga la siguiente línea en su $GIT_DIR/info/attributes:

*.php filter=noeol

Esto asegurará que no confirmes ninguna nueva línea en eof en un .phparchivo, sin importar lo que haga Vim.

Y ahora, el script en sí:

#!/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
fuente
Esa es una gran solución ... aunque desafortunadamente no estaba usando git. Estaba usando svn, aunque sospecho que se podría haber tomado un enfoque similar. De todos modos, me mudé de esa posición y ya no tengo que preocuparme por eso :)
Boushley
12

No he probado esta opción, pero la siguiente información se proporciona en el sistema de ayuda de vim (es decir, 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 no tiene que configurar o restablecer esta opción. Cuando 'binario' está desactivado, el valor no se utiliza al escribir el archivo. Cuando 'binario' está activado, se usa para recordar la presencia de a para la última línea del archivo, de modo que cuando se escribe el archivo se puede mantener la situación del archivo original. Pero puedes cambiarlo si quieres.

También puede interesarle la respuesta a una pregunta anterior: " ¿Por qué los archivos deben terminar con una nueva línea? ".

Tim Henigan
fuente
También me encontré con la configuración de EOL ... pero no cumple con esta tarea. Es más una variable que determina si ya se ha colocado uno al final del archivo o no. Además, no tiene ningún efecto en los archivos de texto, sino solo en los archivos binarios.
Boushley
3
La ayuda de vim también dice "Cuando 'binario' está desactivado, el valor no se usa al escribir el archivo". sobre EOL
Boushley
1
+1 para la respuesta de VonC a esa pregunta, que destaca que "nueva línea" y EOL se están combinando. Los editores inferiores muestran incorrectamente una nueva línea adicional debido a una EOL, ¡vim no está agregando una "nueva línea"!
Ches
9

He agregado un consejo en la wiki de Vim para un problema similar (aunque diferente):

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

Jo Liss
fuente
55
“Vim 7.4.785 agrega la fixeolopción que se puede deshabilitar para preservar automáticamente cualquier EOL faltante al final del archivo. Este script se vuelve innecesario para Vim 7.4.785 y posterior ". (Fuente: la misma página wiki.) Gracias, no estaba al tanto de esa nueva opción.
Amir
1
Tuve que establecer ambos noeoly nofixeollograr el resultado deseable.
selurvedu
8

OK, estar en Windows complica las cosas;)

Como la opción 'binario' restablece la opción 'formato de archivo' (y escribir con el conjunto 'binario' siempre escribe con terminaciones de línea unix), saquemos el gran martillo y hagámoslo externamente.

¿Qué hay de definir un autocomando (: autocomando de ayuda) para el evento BufWritePost? Este comando automático se ejecuta después de cada vez que escribe un búfer completo. En este comando automático, llame a una pequeña herramienta externa (php, perl o cualquier script) que elimine la última línea nueva del archivo recién escrito.

Entonces esto se vería así y entraría en su archivo .vimrc:

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

Asegúrese de leer toda la documentación de vim sobre los comandos automáticos si es la primera vez que trata con los comandos automáticos. Hay algunas advertencias, por ejemplo, se recomienda eliminar todos los autocmds en su .vimrc en caso de que su .vimrc se obtenga varias veces.

Blixtor
fuente
Bueno ... esperaba que hubiera una solución mejor que esta ... ¡pero esto definitivamente funciona!
Boushley el
3
¡Esto funciona muy bien! ¡Hurra! Sin embargo, tengo una pregunta ... ¿hay alguna manera de hacerlo para que no tenga que presionar enter dos veces después de cada guardado? Tengo que presionar enter en la ventana de cmd que apareció y luego otra vez porque vim me dice que el script regresó con éxito ... ¿Alguna forma de hacer que desaparezcan?
Boushley
2
Para evitar las indicaciones <Presione Entrar>, simplemente prefije el comando con silent. Por ej silent !your-script <afile>.
dash-tom-bang
6

He implementado las sugerencias de Blixtor con el posprocesamiento de Perl y Python, ya sea que se ejecute dentro de Vim (si está compilado con dicho soporte de lenguaje) o mediante un script Perl externo. Está disponible como el complemento PreserveNoEOL en vim.org.

Ingo Karkat
fuente
No lo he probado a fondo, pero parece una mejor solución.
Boushley
El complemento funciona, pero después de la instalación tuve que ponerlo let g:PreserveNoEOL = 1en mi .vimrcarchivo. ¡Tuve que aprender vimscript para descubrirlo a partir de la descripción del complemento! : D
DarthVanger
1
@DarthVanger: también :help PreserveNoEOL-usagete lo habría dicho. RTFM :-)
Ingo Karkat
@IngoKarkat Oh, lo siento. Estaba buscando esto debajo INSTALLATIONy CONFIGURATION. Ni siquiera noté la USAGEsección en la descripción, porque está por encima de la instalación :)
DarthVanger
3

Tal vez podrías ver por qué se están quejando. Si un archivo php tiene una nueva línea después del final?>, Php lo mostrará como parte de la página. Esto no es un problema a menos que intente enviar encabezados después de incluir el archivo.

Sin embargo, el?> Al final de un archivo php es opcional. ¿Sin finalización?>, No hay problema con una nueva línea al final del archivo.

Conocido
fuente
2
Tienes razón, pero nosotros como tienda decidimos que se ve mejor tener el final?> Sé que podríamos dejar de usarlo ... pero preferiría ajustar mi editor para que se ajuste a mi estilo de codificación que al revés.
Boushley
1
Además, para que sepa, php analizará automáticamente su etiqueta final como?> O como?> \ N (porque en Linux todos los archivos válidos deben terminar con una \ n) ... Entonces mi código no causa estos problemas ... simplemente no les gusta la apariencia.
Boushley
2

Agrego .vimrc

set binary

y ayuda, pruébalo

IvanM
fuente
2

Creo que he encontrado una mejor solución que la respuesta aceptada. Las soluciones alternativas no me funcionaban y no quería tener que trabajar en modo binario todo el tiempo. Afortunadamente, esto parece hacer el trabajo y aún no he encontrado ningún efecto secundario desagradable: preservar el final de línea que falta al final de los archivos de texto . Acabo de agregar todo a mi ~ / .vimrc.

Jay Paroline
fuente
1

¿Le sería posible utilizar un comando especial para guardar estos archivos?

Si lo hace: set binary,: w and: set nobinary, el archivo se escribirá sin nueva línea si no había ninguno para empezar.

Esta secuencia de comandos podría ponerse en un comando definido por el usuario o una asignación, por supuesto.

Blixtor
fuente
Desafortunadamente porque estoy trabajando con Windows, si lo guardo en modo binario, obliga a guardar en modo Unix. Incluso cuando lo hago: set binary: set fileformat = dos: w: set nobinary Una vez que salí, guardó el archivo en formato unix ... No puedo creer que no haya alguna forma de desactivar esto.
Boushley 01 de
0

Encontré que este complemento vimscript es útil para esta situación.

Plugin 'vim-scripts/PreserveNoEOL'

O lea más en github

Alan Dong
fuente