Luddite is the language Komodo uses for user-defined syntax highlighting and multi-language lexing. An introduction to the Luddite language can be found in the User-Defined Language Support documentation.
The following is a list of Luddite keywords - not to be confused with the keywords described by the UDL file itself for the target language definition. The Luddite keyword is always given followed by its argument list, where applicable; optional arguments are given in square brackets ([ ... ]).
name-or-string-list | all
all
is specified, then a
token_check
test will always succeed. If the
previous token falls in the name-or-string list, the
token_check
test succeeds. Otherwise Luddite will
look at the results of any skip and reject statements in the current family to decide
which action to take.token_check
test will follow
whatever directive is associated with this occurrence of
all
.state-name
)Good % if ($time > 12) { afternoon % } else { morning % }
state IN_M_DEFAULT: /^%/ : paint(upto, M_DEFAULT), paint(include, TPL_OPERATOR), \ at_eol(IN_M_DEFAULT), => IN_SSL_DEFAULT
keep_delimiter
action is given in the transition.csl | markup | ssl | style | tpl
The sub-type of this sub-language. The meaning of each family name is:
"name-or-string" style
+|-
fold "{" CSL_OPERATOR + fold "if" SSL_WORD + fold "end" SSL_WORD -
delimiter
directive was used in
place of a pattern or string, this tells the UDL lexer to
retain that directive for subsequent matching. This is useful
for matching a construct like Perl's s,/,\\,
construct, where we would be using ',' as the regex delimiter,
instead of the normal '/'.name-or-string-list
keywords ["build/release/docs/komodo-doc-luddite.html", "193", BEGIN, class ensure nil ]
style-name =>
style-name
keyword_style SSL_IDENTIFIER => SSL_WORD
[path/]file
include "html2ruby.udl"
state-name
initial IN_SSL_DEFAULT
name
language RHTML
namespace "http://www.w3.org/2001/XMLSchema" namespace "http://www.w3.org/1999/XMLSchema" # Be prepared if a new version is released in a few centuries. namespace "http://www.w3.org/2525/XMLSchema"
state IN_SSL_DEFAULT: /\.(?=[a-z])/ : paint(upto, SSL_DEFAULT), \ paint(include, SSL_OPERATOR), => IN_SSL_NON_KEYWORD_IDENTIFIER_1 state IN_SSL_NON_KEYWORD_IDENTIFIER_1: /[^a-zA-Z0-9_]/ : paint(upto, SSL_IDENTIFIER), redo, no_keyword, \ => IN_SSL_DEFAULT
include|upto, style-name
)state IN_SSL_COMMENT_1 : /$/ : paint(include, SSL_COMMENT) => IN_SSL_DEFAULT
name = string
pattern NMSTART = '_\w\x80-\xff' # used inside character sets only pattern NMCHAR = '$NMSTART\d' # used inside character sets only ... state IN_SSL_SYMBOL_1: /[$NMCHAR]+/ : paint(include, SSL_STRING), => IN_SSL_DEFAULT
public_id "-//MOZILLA//DTD XBL V1.0//EN" publicid "-//MOZILLA//DTD XBL V1.1//EN" # Be prepared # "publicid" is a synonym for "public_id"
state IN_SSL_NUMBER_3: ... /[^\d]/ : paint(upto, SSL_NUMBER), redo, => IN_SSL_DEFAULT
This specifies that when we're processing numbers (assuming the arbitrary name "IN_SSL_NUMBER_3" reflects the idea that we're trying to recognize numeric terms in the input), and find a non-digit, we should paint everything up to but not including the start of the matched text with the SCE_UDL_SSL_NUMBER style, change to the default state for this family, and retry lexing the same character.
Since having both a redo
action and a
paint(include...)
action in the same transition
would be contradictory, the Luddite compiler gives an error
message when it detects this condition and stops
processing.
name-or-string-list | all
(number)
/m([^\w\d])/ : paint(upto, SSL_DEFAULT), set_delimiter(1), \ => IN_SSL_REGEX1_TARGET
(number)
/m([\{\[\(\<])/ : paint(upto, SSL_DEFAULT), \ set_opposite_delimiter(1), => IN_SSL_REGEX1_TARGET
name-or-string-list | all
state-name:
transition-list
name
sublanguage ruby
system_id "http://www.w3.org/2001/XMLSchema" systemid "http://www.w3.org/1999/XMLSchema" # "systemid" is a synonym for "system_id"
token-recognition-list
A set of directives that define the token checking set for this family.
Used in state transitions immediately after a pattern or string (match target) is given. This is used for token disambiguation. For example in Ruby, Perl, and JavaScript, a '/' can either be a division operator or the start of a regular expression. By looking at how the previous token was styled, we can determine how to interpret this character.
If the token_check test fails, the pattern is deemed to fail, and UDL tries subsequent transitions in the state block.
style-name
state-name
)state IN_SSL_DSTRING: '#{' : paint(include, SSL_STRING), spush_check(IN_SSL_DSTRING), \ => IN_SSL_DEFAULT ... state IN_SSL_OP1: '{' : paint(include, SSL_OPERATOR), spush_check(IN_SSL_DEFAULT) \ => IN_SSL_DEFAULT ... state IN_SSL_DEFAULT: '}' : paint(upto, SSL_DEFAULT), paint(include, SSL_OPERATOR), \ spop_check, => IN_SSL_DEFAULT
The style names are all listed in Scintilla.iface, in the section for UDL. The ones for client-side, server-side, style, and template languages are generic, and shouldn't need much explanation here. This section will focus on the markup section in specifics.
First, we are limited to about 56 styles, as UDL partitions the style byte associated with each character by 6 bits for styles, 1 bit for error squigging, and 1 bit for warnings. Additionally, scintilla reserves styles 32 through 39 for its own use, leaving us with 56.
This reduces the number of available styles for each family down to the basics. This includes the default style (which should only be used for white-space in most cases), comments, numbers, strings, keywords, identifiers, operators, and regular expressions. We add a style for variable names for the server-side, and leave comment-blocks in as well, although their usefulness is in question.
Some of the styles in the markup block reflect terms used in ISO 8859, the SGML standard. These are:
The statements in a token_check directive are followed in order, and are family-specific. The default action, if no term is chosen, depend on what kinds of statements are specified:
UDL walks the list of transitions for the current state. As soon as it finds one, it does whatever painting is called for, switches to the specified state, and then restarts at the next state.
The target state is optional. A transition that contains both a "paint(include...)" and a "redo" directive would loop indefinitely, so UDL contains a limit of 1000 before it bypasses the current character and continue with the next one.