Patrón de sintaxis de Vim para resaltar el argumento de palabra clave de Python


17

Estoy luchando con el aprendizaje de expresiones regulares vim (tampoco conozco muy bien otra expresión regular), por lo que el problema principal es definir expresiones regulares que coincidan

some_function_call(simple_value, keyword=value)

palabra clave en este ejemplo.

Por lo tanto, debe coincidir con una palabra si está dentro de parens y tiene el mismo signo después.

El siguiente problema es cómo definir archivos de sintaxis en vim. Agradecería ayuda con eso, pero no debería ser tan difícil de aprender, así que probablemente pueda hacerlo por mi cuenta.

EDITAR en función de la respuesta He hecho mi propio script de sintaxis para python. Siéntase libre de probarlo. ingrese la descripción del enlace aquí


Hay un problema abierto en Github para que el resaltado de palabras clave se incluya en el archivo de sintaxis de Python más actualizado que conozco: github.com/hdima/python-syntax/issues/44 Es posible que desee consultar allí más adelante. Si descubre cómo hacerlo, avísele a las personas allí (o envíeme un mensaje para que pueda crear una solicitud de extracción) para que esta función esté disponible para todos.
cbaumhardt

1
Sí, soy yo quien lo abrió.
user1685095

Respuestas:


12

Con estas configuraciones:

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

Yo obtengo:

ingrese la descripción de la imagen aquí

Aquí:

  1. Defino una región de sintaxis dentro de la cual se pueden encontrar argumentos de palabras clave, que sería la llamada a la función. La containsopción me permite anidar llamadas de función.
  2. Dentro de esa región, coincido con cualquier cadena hecha de caracteres de identificación válidos ( \i*) seguidos de =, pero no ==, para que las pruebas de igualdad no coincidan.

Al usar regiones, puedo anidar las coincidencias tanto como lo necesito, lo que habría sido muy complicado (¿imposible?) Si hubiera elegido solo matchcon expresiones regulares.

Creo que las expresiones regulares utilizadas para hacer coincidir la llamada a la función y la palabra clave se pueden refinar, pero teniendo en cuenta lo que es válido en Python 3 , esa no es una tarea que esté dispuesto a asumir.

Opcionalmente, creo que puede usar esto para resaltar llamadas a funciones, usando un 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

ingrese la descripción de la imagen aquí


Probablemente debería crear otra pregunta, pero ¿tiene ideas sobre cómo resaltar solo las funciones integradas?
user1685095

@ user1685095 Las funciones incorporadas se enumeran en el pythonBuiltingrupo de sintaxis de forma predeterminada syntax/python.vim. Sin embargo, no distingue entre las funciones y variables incorporadas ( True, Falsey Nonetambién están en pythonBuiltin). Probablemente podría copiar las definiciones para su uso.
Muru

Bueno, he usado una sintaxis más refinada que la predeterminada de vim como hdima / python y vim-polyglot. Todos definen funciones incorporadas como una palabra clave que tienen consecuencias importantes. No solo se resaltan las funciones integradas, sino que también se resaltan las variables con los mismos nombres y las funciones en otros módulos con el mismo nombre. El query(...).***filter***()filtro Me gusta se resalta mientras no tiene nada que ver con las funciones de filtro incorporado.
user1685095

@ user1685095 el valor predeterminado las syntax.vimconvierte en palabras clave. Ver github.com/vim/vim/blob/master/runtime/syntax/python.vim#L184
muru

1
@ user1685095 impar. No tengo syntax/python.vimarchivos adicionales (solo el predeterminado, y no veo el comportamiento que usted hace: i.stack.imgur.com/LgF6F.png , y estoy de acuerdo con la definición de la palabra clave: ese es el ajuste más cercano, y yo no piense que las palabras clave coinciden en casos como nonkeyword.keyword. En cuanto a las variables, tenga en cuenta que estas incorporadas son variables, son variables que contienen objetos de función y se pueden asignar como cualquier otra variable. Nada le impide hacer sorted = filtery luego usar sortedcomo filter.
muru

8

Aquí es donde puedes comenzar:

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

Descomponiendo:

/(       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 )

Esto necesita mejoras, pero le brinda una visión general de cómo puede hacerlo.


6

Además de la respuesta @ Nobe4, puede hacer lo siguiente:

  • Crea el archivo ~/.vim/after/syntax/python.vim
  • Ponga la línea de tesis en el archivo:

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

Esto creará un archivo de sintaxis que agregará una coincidencia de sintaxis para sus argumentos seguido de a =y establecerá el estilo a usar. Este tema :h mysyntaxfile-adddebería ser interesante para ti.

También utilicé una expresión regular diferente a la otra respuesta, aquí está el detalle (no sé cuál funciona mejor, así que probablemente tengas que intentarlo):

(      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

Gracias por tu ayuda. No sabía que podía agregar mi sintaxis personalizada sin modificar las reglas existentes. Su patrón no coincide con el argumento de palabra clave si es un primer argumento en función. Trataré de arreglar eso yo mismo (estoy aprendiendo expresiones regulares ahora mismo para hacerlo). Tan pronto como sepa cómo hacerlo, publicaré un comentario.
user1685095

Estoy probando esta expresión regular a través de vim search y creo que solo coincide con una palabra clave en la llamada a la función. Lo necesito para que coincida con todos '
user1685095

@ user1685095: Sí, tienes razón, mi patrón no es bueno. Intentaré mejorarlo y editar mi respuesta.
statox

3

Descubrí que la respuesta de @ Wolfie captura el desenvolvimiento de una tupla como palabra clave y también tuvo problemas para capturar argumentos de palabras clave con saltos de línea.

Inspirado por su expresión regular, se me ocurrió lo siguiente para poner en mi python.vimarchivo de sintaxis. (Tenga en cuenta que originalmente estoy usando el python.vimarchivo de sintaxis 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

Y el desglose de expresiones regulares es muy similar a la respuesta 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

Tenga en cuenta que esto no va a colorear un argumento de palabra clave escrita como: key = value. Lo cual considero algo bueno, ya que va en contra de la recomendación oficial de espacios en blanco PEP-8 para argumentos de palabras clave .


2

La respuesta aceptada al momento de escribir se rompió al resaltar las cadenas dentro de las listas de argumentos de función para mí (por qué alquimia no lo sé), así que aquí hay una versión con suerte más segura, basada en la de Statox .

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

ctermfges para terminal de consola, guifges para gui. Por supuesto, eres libre de cambiar los colores a lo que te parezca elegante. Aquí hay una lista útil .

Como siempre, es mejor poner esto dentro ~/.vim/after/syntax/python.vim

Para un desglose de expresiones regulares, aquí tienes:

\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

La comprobación final detiene el resaltado de los condicionales para colorear. Puede eliminarlo si lo desea.


Lo siento, llegas tarde. Tengo el archivo de sintaxis de mucama para mí.
user1685095

Esta bien; si alguien más se encuentra con el mismo problema que yo, pueden echar un vistazo aquí con suerte.
Wolfie
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.