Formateado personalizado de código en Xojo

imprenta

En una entrada anterior ya se apuntaban las claves para mantener un estilo de código unificado en nuestros proyectos. A continuación encontrarás la información técnica sobre formateado de código que puedes aplicar directamente desde el IDE a partir de la release de Xojo 2017r2 y que permite, además, la personalización mediante la escritura de nuestros propios scripts. Esta información es la traducción al castellano del original que puedes encontrar en el área de desarrolladores de Xojo. ¡Sigue leyendo para saber cómo puedes hacerlo!

El Editor de Cödigo Xojo puede formatear tu código por ti a medida que escribes o bien cuando seleccionas un fragmento de código y seleccionas la opción Standardize Format en el menú contextual. Si no te gusta el modo en el que el Editor de Código formatea el código entonces puedes sobreescribir el formateador de código proporcionando un Script del IDE que se encargue de formatearlo del modo en el que prefieras.

Hay dos tipos de formateado de código:

  • Formateado de línea: si la opción Apply standardized format after ending line está seleccionado en las Preferencias del Editor de Código, entonces significa que el formateado de código se aplicará cada vez que se introduzca o pegue una línea de código.
  • Formateado de bloque: se aplica cuando se selecciona un bloque de código y se selecciona la opción Standardize Format en el menú contextual o bien se pegan múltiples líneas de código.

Para utilizar tu propio formateador de código, crea un Script del IDE y nómbralo como ReformatCode.xojo_script. Has de ubicar dicho script en la carpeta Scripts que se encuentra en la carpeta del IDE de Xojo o bien junto con tu proyecto.

En este Script del IDE has de implementar el método CleanBlock de modo que se sobreescriba el formateado estándar de código:

Este Script del IDE se ejecuta con un Contexto especial que te proporciona acceso a elementos que te permiten identificar lo que quieras formatear. En esencia, obtienes acceso al Lexer (el utilizado por el compilador), junto con todos los identificadores tokenizados.

Limitaciones

El guión ReformatCode.xojo_script tiene estas limitaciones:

  • Sólo puedes usar el lenguaje central de Xojo con los métodos de Context y las propiedades descritas a continuación, así como las funciones por defecto del lenguaje para Xojo Script. No puedes usar otros comandos de Scripting del IDE.
  • El guión ReformatCode.xojo_script se carga y compila una vez que se inicia el IDE. Si haces cambios tendrás que reiniciar el IDE para que tengan efecto.
  • No puedes ejecutar el guión ReformatCode.xojo_script desde el menú IDE Scripts.

Script de ejemplo

Este código simple se encarga de poner en mayúsculas cada identificador:

Sub CleanBlock()
For i As Integer = 0 To LineCount - 1
Dim s As String
StartTokenizer(Line(i))
While NextToken = True
If s <> "" Then s = s + " "
s = s + UpperCase(TokenText)
Wend
' Si la línea finaliza con un comentario, no obtendrás un Token para el comentario,
' pero accederás al texto de comentario en RemainingLine.
If RemainingLine() <> "" Then
s = s + RemainingLine
End If
Line(i) = s
Next
End Sub

Métodos Context

Estos son los métodos disposibles para su uso en el guión ReformatCode.

ConstantValue(propName As String) As String

Devuelve el valor de una constante en un elemento del proyecto. El valor es devuelto como una String independientemente de cual sea su tipo.

DebugLog(message As String)

Imprime el mensaje en el log de depuración.

LineCount As Integer

La cantidad de líneas de código a formatear.

Line(i As Integer, Assigns s As String)

Line(i As Integer) As String

Obtiene o define una línea de código concreta.

NextToken As Boolean

Actualiza TokenText para que contenga el siguiente token en el flujo de tokens del código. Devuelve False cuando no hay más tokens.

RemainingLine As String

Este es el texto restante en la línea una vez que se ha parseado un token. Puedes usarlo para obtener los comentarios en una línea tras parsear todos los tokens de la línea.

TokenText As String

La representación textual del token en curso

TokenType As Integer

La representación simbólica del token en curso (debería corresponderse con una de las propiedades TOKEN_TK_xxxx indicadas a continuación.

StartTokenizer(code As String)

Inicializa el tokenizer de modo que pueda comenzar a obtener tokens para el código proporcionado.

Propiedades de Context

Estas son las propiedades disponibles para su uso con el guión ReformatCode. Estas propiedades indican el tipo de token en TokenText. (Todas ellas sólo de lectura).

TOKEN_TK_IF As Integer
TOKEN_TK_SUB As Integer
TOKEN_TK_FUNCTION As Integer
TOKEN_TK_UNTIL As Integer
TOKEN_TK_AS As Integer
TOKEN_TK_END As Integer
TOKEN_TK_MOD As Integer
TOKEN_TK_DIM As Integer
TOKEN_TK_THEN As Integer
TOKEN_TK_ELSE As Integer
TOKEN_TK_WHILE As Integer
TOKEN_TK_WEND As Integer
TOKEN_TK_RAISE As Integer
TOKEN_TK_FOR As Integer
TOKEN_TK_EXCEPTION As Integer
TOKEN_TK_ARRAY As Integer
TOKEN_TK_OF As Integer
TOKEN_TK_NOT As Integer
TOKEN_TK_GOTO As Integer
TOKEN_TK_AND As Integer
TOKEN_TK_OR As Integer
TOKEN_TK_NIL As Integer
TOKEN_TK_REM As Integer
TOKEN_TK_NEXT As Integer
TOKEN_TK_ELSEIF As Integer
TOKEN_TK_TO As Integer
TOKEN_TK_TRUE As Integer
TOKEN_TK_FALSE As Integer
TOKEN_TK_BYREF As Integer
TOKEN_TK_NEW As Integer
TOKEN_TK_SELECT As Integer
TOKEN_TK_CASE As Integer
TOKEN_TK_RETURN As Integer
TOKEN_TK_SELF As Integer
TOKEN_TK_DO As Integer
TOKEN_TK_LOOP As Integer
TOKEN_TK_EXIT As Integer
TOKEN_TK_REDIM As Integer
TOKEN_TK_DOWNTO As Integer
TOKEN_TK_STEP As Integer
TOKEN_TK_ISA As Integer
TOKEN_TK_ME As Integer
TOKEN_TK_PRAGMA As Integer
TOKEN_TK_BYVAL As Integer
TOKEN_TK_OPTIONAL As Integer
TOKEN_TK_EXTENDS As Integer
TOKEN_TK_ASSIGNS As Integer
TOKEN_TK_CONST As Integer
TOKEN_TK_COMPILEIF As Integer
TOKEN_TK_COMPILEELSE As Integer
TOKEN_TK_COMPILEENDIF As Integer
TOKEN_TK_DECLARE As Integer
TOKEN_TK_CLASS As Integer
TOKEN_TK_INTERFACE As Integer
TOKEN_TK_IMPLEMENTS As Integer
TOKEN_TK_INHERITS As Integer
TOKEN_TK_PROPERTY As Integer
TOKEN_TK_PUBLIC As Integer
TOKEN_TK_PRIVATE As Integer
TOKEN_TK_PROTECTED As Integer
TOKEN_TK_SHARED As Integer
TOKEN_TK_NAMESPACE As Integer
TOKEN_TK_MODULE As Integer
TOKEN_TK_STATIC As Integer
TOKEN_TK_EVENT As Integer
TOKEN_TK_HANDLES As Integer
TOKEN_TK_EACH As Integer
TOKEN_TK_IN As Integer
TOKEN_TK_CATCH As Integer
TOKEN_TK_TRY As Integer
TOKEN_TK_FINALLY As Integer
TOKEN_TK_SUPER As Integer
TOKEN_TK_LIB As Integer
TOKEN_TK_IS As Integer
TOKEN_TK_CALL As Integer
TOKEN_TK_ADDRESSOF As Integer
TOKEN_TK_DELEGATE As Integer
TOKEN_TK_PARAMARRAY As Integer
TOKEN_TK_COMPILEELSEIF As Integer
TOKEN_TK_SOFT As Integer
TOKEN_TK_CONTINUE As Integer
TOKEN_TK_WITH As Integer
TOKEN_TK_STRUCTURE As Integer
TOKEN_TK_ENUM As Integer
TOKEN_TK_RAISEEVENT As Integer
TOKEN_TK_XOR As Integer
TOKEN_TK_GLOBAL As Integer
TOKEN_TK_AGGREGATES As Integer
TOKEN_TK_BREAK As Integer
TOKEN_TK_GETTYPE As Integer
TOKEN_TK_ATTRIBUTE As Integer
TOKEN_TK_CTYPE As Integer
TOKEN_TK_ADDHANDLER As Integer
TOKEN_TK_REMOVEHANDLER As Integer
TOKEN_TK_WITHEVENTS As Integer
TOKEN_TK_WEAKADDRESSOF As Integer
TOKEN_TK_USING As Integer
TOKEN_TK_ASYNC As Integer
TOKEN_TK_AWAIT As Integer
TOKEN_IDENTIFIER As Integer
TOKEN_NUMBER As Integer
TOKEN_STRING As Integer
TOKEN_ASSIGN As Integer
TOKEN_GE_RELOP As Integer
TOKEN_LE_RELOP As Integer
TOKEN_NE_RELOP As Integer
TOKEN_REALNUMBER As Integer
TOKEN_ENDL As Integer
TOKEN_UNMATCHEDQUOTES As Integer
TOKEN_COLOR As Integer
TOKEN_LINE_CONTINUATION As Integer
Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *