vis: implement :set cursorline
[vis.git] / lexers / tcl.lua
blobf014c354e5d1bf89d7285a03660281d84d232725
1 -- Copyright 2014-2015 Joshua Krämer. See LICENSE.
2 -- Tcl LPeg lexer.
3 -- This lexer follows the TCL dodekalogue (http://wiki.tcl.tk/10259).
4 -- It is based on the previous lexer by Mitchell.
6 local l = require('lexer')
7 local token, word_match = l.token, l.word_match
8 local P, R, S = lpeg.P, lpeg.R, lpeg.S
10 local M = {_NAME = 'tcl'}
12 -- Whitespace.
13 local whitespace = token(l.WHITESPACE, l.space^1)
15 -- Separator (semicolon).
16 local separator = token(l.CLASS, P(';'))
18 -- Delimiters.
19 local braces = token(l.KEYWORD, S('{}'))
20 local quotes = token(l.FUNCTION, '"')
21 local brackets = token(l.VARIABLE, S('[]'))
23 -- Argument expander.
24 local expander = token(l.LABEL, P('{*}'))
26 -- Variable substitution.
27 local variable = token(l.STRING, '$' * (l.alnum + '_' + P(':')^2)^0)
29 -- Backslash substitution.
30 local backslash = token(l.TYPE, '\\' * ((l.digit * l.digit^-2) +
31 ('x' * l.xdigit^1) + ('u' * l.xdigit * l.xdigit^-3) +
32 ('U' * l.xdigit * l.xdigit^-7) + P(1)))
34 -- Comment.
35 local comment = token(l.COMMENT, '#' * P(function(input, index)
36 local i = index - 2
37 while i > 0 and input:find('^[ \t]', i) do i = i - 1 end
38 if i < 1 or input:find('^[\r\n;]', i) then return index end
39 end) * l.nonnewline^0)
41 M._rules = {
42 {'whitespace', whitespace},
43 {'comment', comment},
44 {'separator', separator},
45 {'expander', expander},
46 {'braces', braces},
47 {'quotes', quotes},
48 {'brackets', brackets},
49 {'variable', variable},
50 {'backslash', backslash},
53 M._foldsymbols = {
54 _patterns = {'[{}]', '#'},
55 [l.KEYWORD] = {['{'] = 1, ['}'] = -1},
56 [l.COMMENT] = {['#'] = l.fold_line_comments('#')}
59 return M