Sobreposição de região / palavra-chave de destaque da sintaxe


7

Estou tentando escrever um arquivo de sintaxe para scripts de logrotate do Linux.

Muitas vezes, eles contêm definições embutidas de scripts a serem executados antes ou depois da ação de rotação.

Um exemplo (o cups-daemonscript logrotate conforme fornecido pelo Ubuntu 14.04):

    prerotate
            if [ -e /var/run/cups/cupsd.pid ]; then
                    invoke-rc.d --quiet cups stop > /dev/null
                    touch /var/run/cups/cupsd.stopped
            fi
    endscript
    postrotate
            if [ -e /var/run/cups/cupsd.stopped ]; then
                    rm /var/run/cups/cupsd.stopped
                    invoke-rc.d --quiet cups start > /dev/null
                    sleep 10
            fi
    endscript

Existe alguma maneira de ambos:

  • destacar prerotatee postrotatecomo palavras-chave, e
  • destacar tudo como região?

Posso definir um realce adequado para qualquer um desses, mas parece que não para ambos.

" this works
syntax keyword LogrotateKeyword prerotate postrotate endscript

" this also works
syntax region LogrotateScript start=/prerotate/ms=e+1 end=/endscript/me=s-1

Agora, os dois no mesmo arquivo de sintaxe produzem apenas destaque para palavras-chave, independentemente da ordem de regra usada.

Eu tentei match(com \zs/ \zeou lookaheads / lookbehinds) em vez de regiontambém. Também tentei usar matchas palavras-chave e os scripts embutidos, esperando que as definições não se sobrepusessem, os resultados pareciam os mesmos.

Posso manter a cor padrão do script embutido, mas aparentemente o material embutido contém outras palavras-chave com rotação de log, o que pode ser confuso.

Provavelmente irrelevante para esse problema: Vim 7.4 com patches 1-1529 (pi-rho PPA) e Ubuntu 14.04.


Se você terminar o arquivo de sintaxe de logrotate, compartilhe. Seria bom ter.
muru 21/03/16

@ muru Aqui está. Obrigado por sua excelente resposta :)
Łukasz Górski

Respostas:


5

Após algumas experiências, aqui está algo que funciona:

syntax keyword LogrotateKeyword prerotate postrotate endscript contained
syntax region LogrotateScript start=/\v^\s*(pre|post)rotate\s*$/rs=e+1 end=/^\s*endscript\s*$/re=s-1 keepend contains=LogrotateKeyword

Para que um syntaxconjunto coopere com outro sobreposto, podemos conter a correspondência mais estreita dentro da correspondência mais ampla.

Nesse caso:

  • Marque as palavras-chave como containede a região como contendo as palavras-chave. Não é necessário marcar as palavras-chave, mas, considerando a natureza dessas palavras-chave, elas sempre serão acompanhadas por essa região no caso válido.
  • Eu tive que usar keependpara que a correspondência para a palavra-chave não oculte a correspondência para o fim da região.
  • Eu escolhi as expressões regulares mais amplas que cobrem toda a linha, para que o realce não se estenda a essas linhas (ou, se você definir um plano de fundo colorido, ficará muito estranho).

Combinando com o destaque da sintaxe do script de shell do Vim:

syntax include @sh syntax/sh.vim
syntax keyword LogrotateKeyword prerotate postrotate endscript contained
syntax region LogrotateScript start=/\v^\s*(pre|post)rotate\s*$/rs=e+1 end=/^\s*endscript\s*$/re=s-1 keepend contains=LogrotateKeyword,@sh
highlight LogrotateKeyword ctermfg=yellow 

Eu recebo:

insira a descrição da imagem aqui

Note que eu usei ree em rsvez de ms/ hs, me/ he. Com as outras opções, combinar as palavras-chave com a sintaxe do script de shell não funcionou, embora eu não saiba o porquê.


O seguinte seria melhor:

syntax region LogrotateScript matchgroup=LogrotateKeyword start=/\v(pre|post)rotate/ end=/endscript/ contains=@sh

Nesse caso, aproveito matchgroup:

                                                        :syn-matchgroup
        "matchgroup" can be used to highlight the start and/or end pattern
        differently than the body of the region.  Example: 
  :syntax region String matchgroup=Quote start=+"+  skip=+\\"+  end=+"+
       This will highlight the quotes with the "Quote" group, and the text in
        between with the "String" group.

Olhando para trás, matchgrouppretendia resolver exatamente esse problema. Não precisamos listar as palavras-chave delimitadoras separadamente, pois matchgrougpodemos destacar os delimitadores separadamente.


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.