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!


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

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

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)

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? ".


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


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.


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.


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.


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



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.


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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.