As regiões de sintaxe do vim podem ser feitas para tocar / se sobrepor?


13

Há algum tempo, eu decidi aprender mais sobre como os arquivos de sintaxe do vim funcionam, criando os meus. Meu objetivo era criar um arquivo de sintaxe simples que dividisse o arquivo em 3 partes com base em delimitadores e incluísse arquivos de sintaxe preexistentes para duas dessas três partes.

Este é um arquivo de exemplo:

Some text, unstyled

==================== Log
(Output of git log)

==================== Diff
(Output of diff)

O objetivo era aplicar git.vimapenas ao log e diff.vimapenas ao diff, excluindo os dois cabeçalhos. 1 Foi assim que meu arquivo de sintaxe acabou:

if exists("b:current_syntax")
    finish
endif

syntax include @gitlog $VIMRUNTIME/syntax/git.vim
syntax region GitLog
    \ start=/^===* Log/
    \ end=/^===* Diff/
    \ contains=@gitlog

syntax include @gitdiff $VIMRUNTIME/syntax/diff.vim
syntax region Diff
    \ start=/^===* Diff/
    \ end=/\n\n/
    \ contains=@gitdiff

let b:current_syntax = "logdiff"

Observe como endna primeira região é o mesmo que startna segunda região. Isso não funciona; a segunda região aparentemente não é detectada e o realce da sintaxe não é aplicado.

Eu posso fazer isso afrouxando a regex para end=/^===/e start=/=== Diff/, para que as regiões não se toquem, mas não gostem particularmente disso - é menos óbvio que se deve começar onde a outra termina.

Existe uma maneira de permitir que duas definições de região toquem os mesmos caracteres (e / ou tornem as arestas correspondentes exclusivas em vez de inclusivas) ou estou preso ao regex mais flexível?

1 (Sim, eu sei que git.viminclui diff.vim, mas este foi um exercício de aprendizado)


Eu acho que isso deve ser possível usando um deslocamento "Region End" para tornar as bordas exclusivas (consulte :h :syn-pattern-offset), ou alterando a região GitLog para estender até o final do arquivo e a região Diff para estar inteiramente dentro da região GitLog . Eu não consegui fazer com que nenhum desses métodos funcionasse.
Rich

Testar isso ficou um pouco mais difícil pelo fato de que - como você observa - o git.vim já destaca a saída do diff. Pode ser uma ideia alterar seu exemplo de acordo!
Rico

Respostas:


4

Você pode dizer ao mecanismo de regex do Vim por onde começar a próxima partida.

Até agora eu sei que existem 2 maneiras:

  1. Use \zepara definir o final de uma partida:

    syntax region GitLog
        \ start=/^===* Log/
        \ end=/\ze^===* Diff/
        \ contains=@gitlog
    
  2. Use lookahead positivo \@=, que é chamado de correspondência de largura zero no Vim:

    syntax region GitLog
        \ start=/^===* Log/
        \ end=/\(^===* Diff\)\@=/
        \ contains=@gitlog
    

Assim, o fim-de-jogo "ponteiro" tipo de retrocede para o início da ^===* Difflinha, de modo que region Diff's startirá iniciar a sua correspondência na ^===* Difflinha novamente.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.