Desativar VIM nova linha automática no final do arquivo

250

Então, eu trabalho em uma loja de PHP, e todos nós usamos editores diferentes, e todos temos que trabalhar no Windows. Eu uso o vim, e todos na loja ficam reclamando que sempre que eu edito um arquivo, há uma nova linha na parte inferior. Eu procurei e descobri que esse é um comportamento documentado do vi & vim ... mas eu queria saber se havia alguma maneira de desativar esse recurso. (Seria melhor se eu pudesse desativá-lo para extensões de arquivo específicas).

Se alguém souber disso, seria ótimo!

Boushley
fonte
23
você deve dizer a eles que eles estão sendo tolos - na verdade, há uma boa razão pela qual o vim faz isso: stackoverflow.com/questions/729692/… . Eu acho que só é relevante se você estiver implantando em servidores tipo Unix.
hdgarrood
5
A prática oficial recomendada pelo PHP é omitir a última ?>tag de fechamento, apenas por esse motivo.
Sebastián Grignoli
esta pergunta provavelmente antecede o superusuário ... mas deve estar lá.
Gcb # 22/13
20
A questão realmente deve ser: Como podemos dizer a todos os outros editores que as pessoas em sua loja está usando para garantir a última linha do arquivo faz final com um EOL. ;-)
TJ Crowder

Respostas:

360

E para o vim7.4+ você pode usar (de preferência no seu .vimrc) (obrigado a 罗泽轩 pelas últimas notícias!):

:set nofixendofline

Agora, em relação às versões mais antigas do vim.

Mesmo se o arquivo já tiver sido salvo com novas linhas no final:

vim -b file e uma vez no vim:

:set noeol
:wq

feito.

Como alternativa, você pode abrir arquivos no vim com :e ++bin file

Ainda outra alternativa:

:set binary
:set noeol
:wq
gcb
fonte
6
Você também pode adicionar set binarye set noeolem seu .vimrc
dryobs 4/14
17
Cuidado : binarysubstituições expandtab, o que o levará a obter guias literais em sua fonte.
Ciro Santilli escreveu:
4
@CiroSantilli thank you! Eu estive procurando efeitos colaterais do binário para sempre e me perguntando por que não é o padrão! desde que eu amo meus guias, eu acho que irá considerar que benefício adicional :)
gcb
11
Agora você pode adicionar set nofixendoflinepara resolver o problema no Vim 7.4+
罗泽轩
1
@TrevorBoydSmith sim, porque historicamente o POSIX (eu posso estar errado no padrão atual) espera uma nova linha no final de uma linha, em um arquivo de texto. É por isso que a maioria das soluções exigia tratá-lo como um binário. Provavelmente era muito conveniente na época e está atrasado hoje, é por isso que agora existe a configuração conveniente. Basta adicioná-lo ao seu vimrc. Há problemas piores em outros editores de qualquer maneira :)
gcb
23

Adicione o seguinte comando ao seu .vimrc para desativar a opção de final de linha:

autocmd FileType php setlocal noeol binary fileformat=dos

No entanto , o próprio PHP ignorará o último final de linha - não deve ser um problema. Estou quase certo de que, no seu caso, há outra coisa que está adicionando o último caractere de nova linha, ou possivelmente existe uma confusão com os tipos de final de linha do Windows / Unix (\n ou \r\netc).

Atualizar:

Uma solução alternativa pode ser apenas adicionar esta linha ao seu .vimrc:

set fileformats+=dos
muito php
fonte
Eu sei que o php não está analisando errado ... Eu mostrei isso para meus colegas de trabalho, mas o winmerge os vê como diferentes ... Vou tentar isso e deixar você saber como fica.
Boushley 02/07/2009
Fazer isso tem o efeito desejado de nenhuma linha final, mas também converte o arquivo em terminações de linha unix ... (mesmo em uma caixa do Windows) ... Então, eu já havia feito isso antes mudando para o modo binário ... mas depois as terminações das linhas não aparecem escritas no bloco de notas ... tudo é apenas uma linha.
Boushley 02/07/2009
Infelizmente, nenhuma dessas sugestões funciona. Adicionando os FileFormat = DOS para o autocmd não tem nenhum efeito, e conjunto filetype + = DOS ainda adiciona o arrasto \ n
Boushley
Desculpe, eu tenho que 'filetypes SET + = Dos' errado, uso, e não 'Definir formatos de arquivos ...'
muito php
17

Existe outra maneira de abordar isso se você estiver usando o Git para controle de origem. Inspirado por uma resposta aqui , escrevi meu próprio filtro para uso em atributos de git arquivo .

Para instalar este filtro, salve-o como noeol_filterem algum lugar no seu $PATH, torne-o executável e execute os seguintes comandos:

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

Para começar a usar o filtro apenas para você, coloque a seguinte linha no seu $GIT_DIR/info/attributes:

*.php filter=noeol

Isso garantirá que você não confirme nenhuma nova linha no eof em um .php arquivo, independentemente do que o Vim faça.

E agora, o próprio script:

#!/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
fonte
Essa é uma ótima solução ... embora, infelizmente, eu não estivesse usando o git. Eu estava usando svn, embora eu suspeite que uma abordagem semelhante possa ter sido adotada. De qualquer forma, eu mudei a partir dessa posição e não tem que se preocupar mais com isso :)
Boushley
12

Eu não tentei essa opção, mas as seguintes informações são fornecidas no sistema de ajuda do vim (ou seja, 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 você não precisa definir ou redefinir esta opção. Quando 'binário' está desativado, o valor não é usado ao gravar o arquivo. Quando 'binário' está ativado, é usado para lembrar a presença de um para a última linha do arquivo, para que, quando você escrever o arquivo, a situação do arquivo original possa ser mantida. Mas você pode mudar se quiser.

Você também pode estar interessado na resposta a uma pergunta anterior: " Por que os arquivos devem terminar com uma nova linha "?

Tim Henigan
fonte
Eu também me deparei com a configuração eol ... mas ela não realiza essa tarefa. É mais uma variável que determina se uma já foi colocada no final do arquivo ou não. Além disso, não tem efeito em arquivos de texto, mas apenas em arquivos binários.
Boushley 26/06/09
3
A ajuda do vim também diz "Quando 'binário' está desativado, o valor não é usado ao gravar o arquivo". sobre eol
Boushley 27/06/09
1
+1 para a resposta do VonC sobre essa pergunta, que destaca que "nova linha" e EOL estão sendo confundidas. Editores inferiores exibem incorretamente uma nova linha extra devido a uma EOL, o vim não está adicionando uma "nova linha"!
ches 28/05
9

Adicionei uma dica no wiki do Vim para um problema semelhante (embora diferente):

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

Jo Liss
fonte
5
“O Vim 7.4.785 adiciona a fixeolopção que pode ser desativada para preservar automaticamente qualquer EOL ausente no final do arquivo. Esse script se torna desnecessário para o Vim 7.4.785 e posterior. ” (Fonte: a mesma página da wiki.) Obrigado, eu não estava ciente dessa nova opção.
Amir
1
Eu tive que definir os dois noeole nofixeolalcançar o resultado desejável.
selurvedu 8/09/16
8

OK, você estar no Windows complica as coisas;)

Como a opção 'binary' redefine a opção 'fileformat' (e escrever com o conjunto 'binary' sempre escreve com terminações de linha unix), vamos pegar o grande martelo e fazê-lo externamente!

Que tal definir um comando automático (: comando automático de ajuda) para o evento BufWritePost? Esse comando automático é executado depois de cada vez que você escreve um buffer inteiro. Neste comando automático, chame uma pequena ferramenta externa (php, perl ou qualquer outro script) que retire a última nova linha do arquivo recém-escrito.

Portanto, isso seria algo parecido com isto e entraria no seu arquivo .vimrc:

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

Certifique-se de ler toda a documentação do vim sobre comandos automáticos, se esta é a primeira vez que você lida com comandos automáticos. Existem algumas advertências, por exemplo, é recomendável remover todos os autocmds do seu .vimrc, caso o seu .vimrc possa ser originado várias vezes.

Blixtor
fonte
Bem ... eu esperava que houvesse uma solução melhor que essa ... mas isso definitivamente funciona!
216 Boushley
3
Isso funciona muito bem! Yay! No entanto, eu tenho uma pergunta ... existe uma maneira de fazer isso para que eu não precise pressionar Enter duas vezes após cada salvamento. Eu tenho que pressionar enter na janela do cmd que apareceu e porque o vim está me dizendo que o script retornou com sucesso ... Alguma maneira de fazer com que todos eles desapareçam?
Boushley 08/07/2009
2
Para evitar as solicitações <Pressione Enter>, basta prefixar o comando silent. Por exemplo silent !your-script <afile>.
traço-tom-bang
6

Eu implementei as sugestões do Blixtor com o pós-processamento do Perl e Python, executando dentro do Vim (se for compilado com esse suporte de linguagem) ou por meio de um script externo do Perl. Está disponível como o plugin PreserveNoEOL no vim.org.

Ingo Karkat
fonte
Não testei completamente, mas isso parece uma solução melhor.
Boushley
O plug-in funciona, mas após a instalação eu tive que colocar let g:PreserveNoEOL = 1no meu .vimrcarquivo! Tive que aprender vimscript para descobrir isso na descrição do plugin! : D
DarthVanger
1
@ DarthVanger: :help PreserveNoEOL-usageteria dito a você também. RTFM :-)
Ingo Karkat 05/10
@IngoKarkat Oh, desculpe. Estava procurando por isso em INSTALLATIONe CONFIGURATION. Nem sequer notar a USAGEseção na descrição, porque é acima da instalação :)
DarthVanger
3

Talvez você possa ver por que eles estão reclamando. Se um arquivo php tiver uma nova linha após o final?>, O php o exibirá como parte da página. Isso não é um problema, a menos que você tente enviar cabeçalhos após a inclusão do arquivo.

No entanto, o?> No final de um arquivo php é opcional. Sem final?>, Não há problema com uma nova linha no final do arquivo.

Ken
fonte
2
Você está correto, mas nós, como uma loja, decidimos que parece melhor ter o final?> Eu sei que poderíamos parar de usá-lo ... mas prefiro ajustar meu editor para ajustar-me ao meu estilo de codificação do que o contrário.
22410 Boushley
1
Além disso, você sabe que o php analisará automaticamente sua tag final como?> Ou como?> \ N (porque no linux todos os arquivos válidos devem terminar com a \ n) ... Então, meu código não causa esses problemas ... eles simplesmente não gostam do visual.
Boushley
2

Eu adiciono .vimrc

set binary

e ajuda, tente

IvanM
fonte
2

Acho que encontrei uma solução melhor do que a resposta aceita. As soluções alternativas não estavam funcionando para mim e eu não queria ter que trabalhar no modo binário o tempo todo. Felizmente, isso parece fazer o trabalho e ainda não encontrei efeitos colaterais desagradáveis: preserve o final de linha ausente no final dos arquivos de texto . Acabei de adicionar a coisa toda ao meu ~ / .vimrc.

Jay Paroline
fonte
1

Seria possível usar um comando especial para salvar esses arquivos?

Se você fizer: set binary,: w e: set nobinary, o arquivo será gravado sem nova linha, se não houver nenhum.

Essa sequência de comandos pode ser colocada em um comando definido pelo usuário ou em um mapeamento, é claro.

Blixtor
fonte
Infelizmente, porque estou trabalhando com o Windows, se eu o salvar no modo binário, ele força o salvamento a estar no modo unix. Mesmo quando eu faço: set binary: set fileformat = dos: w: set nobinary Depois que eu saí, ele salvou o arquivo no formato unix ... Não acredito que não há uma maneira de simplesmente desativar isso.
Boushley
0

Achei que este plugin vimscript é útil para esta situação.

Plugin 'vim-scripts/PreserveNoEOL'

Ou leia mais no github

Alan Dong
fonte