Padrão de sintaxe Vim para destacar o argumento da palavra-chave python

17

Estou tendo dificuldades para aprender regexps do vim (também não conheço nenhum outro regexp muito bem), então o principal problema é definir o regexp que corresponda

some_function_call(simple_value, keyword=value)

palavra-chave neste exemplo.

Por isso, deve corresponder a uma palavra se estiver dentro de parênteses e tiver um sinal de igual após ela.

O próximo problema é como definir arquivos de sintaxe no vim. Eu apreciaria a ajuda com isso, mas não deve ser tão difícil de aprender, para que eu possa fazer isso sozinho provavelmente.

EDIT com base na resposta que eu criei meu próprio script de sintaxe para python. Sinta-se livre para experimentar. insira a descrição do link aqui

user1685095
fonte
Há um problema em aberto no Github para que o realce de palavras-chave seja incluído no arquivo de sintaxe Python mais atualizado que eu conheço: github.com/hdima/python-syntax/issues/44 Você pode verificar isso mais tarde. Se você descobrir como fazê-lo, informe as pessoas (ou envie uma mensagem para que eu possa criar uma solicitação de recebimento) para que esse recurso esteja disponível para todos.
cbaumhardt
1
Sim, sou eu quem abriu.
user1685095

Respostas:

12

Com estas configurações:

syn region FCall start='[[:alpha:]_]\i*\s*(' end=')' contains=FCall,FCallKeyword
syn match FCallKeyword /\i*\ze\s*=[^=]/ contained
hi FCallKeyword ctermfg=yellow

Eu recebo:

insira a descrição da imagem aqui

Aqui:

  1. Eu defino uma região de sintaxe na qual argumentos de palavras-chave podem ser encontrados, que seria a chamada de função. A containsopção permite aninhar chamadas de função.
  2. Dentro dessa região, eu correspondo a qualquer sequência feita de caracteres identificadores válidos ( \i*) seguidos por =, mas não ==, para que os testes de igualdade não sejam correspondidos.

Usando regiões, consigo aninhar as correspondências quantas vezes eu precisar, o que seria muito complicado (impossível?) Se eu tivesse usado apenas matchexpressões regulares.

Acredito que as expressões regulares usadas para combinar a chamada de função e a palavra-chave possam ser refinadas, mas considerando o que é válido no Python 3 , essa não é uma tarefa que estou disposto a assumir.

Opcionalmente, acho que você pode usar isso para destacar chamadas de função, usando um matchgroup:

syn region FCall matchgroup=FName start='[[:alpha:]_]\i*\s*(' end=')' contains=FCall,FCallKeyword
syn match FCallKeyword /\i*\ze\s*=[^=]/ contained
hi FCallKeyword ctermfg=yellow
hi FName ctermfg=blue

insira a descrição da imagem aqui

muru
fonte
Eu provavelmente deveria criar outra pergunta, mas você tem idéias sobre como destacar apenas funções internas?
user1685095
@ user1685095 As funções incorporadas estão listadas no pythonBuiltingrupo de sintaxe no padrão syntax/python.vim. No entanto, ele não distingue entre funções e variáveis ​​internas ( True, Falsee Nonetambém estão dentro pythonBuiltin). Você provavelmente pode copiar as definições para seu uso.
muru 23/03
Bem, eu usei sintaxe mais refinada do que o padrão do vim, como hdima / python e vim-polyglot. Todos eles definem funções internas como uma palavra-chave que tem conseqüências importantes. Não apenas as funções internas são destacadas, mas apenas as variáveis ​​com os mesmos nomes e as funções em outros módulos com o mesmo nome. O query(...).***filter***()filtro Like é destacado enquanto não tem nada a ver com as funções de filtro embutidas.
user1685095
@ user1685095, o padrão as syntax.vimtorna palavras-chave. Veja github.com/vim/vim/blob/master/runtime/syntax/python.vim#L184
muru
1
@ user1685095 Ímpar. Não tenho syntax/python.vimarquivos adicionais (apenas o padrão e não vejo o comportamento que você faz: i.stack.imgur.com/LgF6F.png , e concordo com a definição de palavra-chave - esse é o ajuste mais próximo e eu não pense que as palavras-chave são correspondidas em casos como o nonkeyword.keyword. Quanto às variáveis, observe que esses componentes internos são variáveis, são variáveis ​​que contêm objetos de função e podem ser atribuídos a qualquer outra variável. Nada impede que você faça sorted = filtere use sortedcomo filter.
Muru
8

Aqui é onde você pode começar:

/([^,]\+,\s\(\w\+\)=.*)

Decomposição:

/(       start matching a (
[^,]\+   match multiple characters that are not ,
,\s      match a , and a space
\(       start a matching group
\w\+     match word characters
\)       end the matching group
=.*)      match an = and anything until the closing )

Isso precisa de melhorias, mas fornece uma visão geral de como você pode fazer isso.

nobe4
fonte
6

Além da resposta no @ Nobe4, você pode fazer o seguinte:

  • Crie o arquivo ~/.vim/after/syntax/python.vim
  • Coloque estas linhas no arquivo:

    syntax match PythonArg /(.*\,\s*\zs\w\+\ze\s*=.*)/
    hi PythonArg guibg=blue
    
  • Adapte o segundo com seus valores preferidos.

Isso criará um arquivo de sintaxe que adicionará uma correspondência de sintaxe aos seus argumentos, seguida por a =e definirá o estilo a ser usado. Este tópico :h mysyntaxfile-adddeve ser interessante para você.

Também usei um regex diferente do que a outra resposta, aqui está o detalhe (não sei qual funciona melhor, então você provavelmente terá que tentar):

(      Begin the pattern with a bracket
.*,    Look for any number of any character before a ,
\s*    Zero or more white spaces after the ,
\zs    Start the matching group (what will be highlighted)
\w\+   Match one or more word characters
\ze    End the matching group
\s*    Zero or more white spaces between your argument and the = sign
=      A literal = sign after your argument
.*)    Any number of any characters between your = sign and the closing bracket
statox
fonte
Obrigado pela ajuda. Eu não sabia que posso adicionar minha sintaxe personalizada sem modificar as regras existentes. Seu padrão não corresponde ao argumento da palavra-chave se for o primeiro argumento da função. Vou tentar consertar isso sozinho (estou aprendendo regexps agora para fazer isso). Assim que eu aprender como fazer isso, publicarei um comentário.
user1685095
Estou tentando esse regexp através da pesquisa vim e acho que ele corresponde apenas a uma palavra-chave na chamada de função. Eu preciso dele para coincidir com todos eles'
user1685095
@ user1685095: Sim, você está certo, meu padrão não é bom. Vou tentar melhorá-lo e editar minha resposta.
statox
3

Descobri que a resposta de @ Wolfie captura o desempacotamento de uma tupla como uma palavra-chave e também teve problemas para capturar argumentos de palavras-chave com quebra de linha.

Inspirado pelo regex dele, criei o seguinte para colocar no meu python.vimarquivo de sintaxe. (Lembre-se de que estou usando o python.vimarquivo de sintaxe originalmente de sheerun / vim-polyglot )

syn match pythonFunctionKeyword "\v\s{-}\zs\w+\ze\=(\=)@!(\_s)@!" display
syn cluster pythonExpression add=pythonFunctionKeyword
syn region pythonFunctionKwargs start=+(+ end=+)+ contains=@pythonExpression

E a divisão do regex é muito semelhante à resposta de @ Wolfie :

\v      set to very magic mode
\s{-}   capture whitespace, nongreedy
\zs     start of the match (what to actually highlight)
\w+     one or more alphanumeric character, underscore included
\ze     stop matching; anything after this is delimiting only
\=      one single equal sign
(\=)@!  ...not followed by another equal sign
(\_s)@! ...not followed by any whitespace or newline character

Note que isso não irá colorir um argumento palavra-chave escrita como: key = value. O que considero uma coisa boa, pois isso vai contra a recomendação oficial de espaço em branco do PEP-8 para argumentos de palavras-chave .

ludo
fonte
2

A resposta aceita no momento da redação quebrou o destaque para seqüências de caracteres dentro de listas de argumentos de funções para mim (pelo que a alquimia eu não sei), então aqui está uma versão esperançosamente mais segura, baseada na Statox ' .

syntax match PythonArg "\v[\(\,]\s{-}\zs\w+\ze\s{-}\=(\=)@!"
hi PythonArg ctermfg = 214 guifg = #ffaf00

ctermfgé para terminal de console, guifgé para GUI. É claro que você pode mudar as cores para o que achar melhor. Aqui está uma lista útil .

Como sempre, é melhor colocar isso dentro ~/.vim/after/syntax/python.vim

Para uma divisão de regex, aqui está:

\v      set to very magic mode
[\(\,]  capture either a ( or a ,
\s{-}   capture whitespace, nongreedy
\zs     start of the match (what to actually highlight)
\w+     one or more alphanumeric character, underscore included
\ze     stop matching; anything after this is delimiting only
\s{-}   once again, capture whitespace.
\=      one single equal sign
(\=)@!  ...not followed by another equal sign

A verificação final interrompe o realce das condicionais de coloração. Você pode remover se quiser.

Wolfie
fonte
Desculpe, você está atrasado. Eu tenho arquivo de sintaxe de empregada para mim.
user1685095
Isso é bom; se alguém encontrar o mesmo problema, posso dar uma olhada aqui, espero.
21416