vis

a vi-like editor based on Plan 9's structural regular expressions

git clone https://9o.is/git/vis.git

nix.lua

(4416B)


      1 -- Copyright 2024-2025 Samuel Marquis. See LICENSE.
      2 -- Nix LPeg lexer.
      3 
      4 local lexer = lexer
      5 local P, S = lpeg.P, lpeg.S
      6 
      7 local lex = lexer.new(...)
      8 
      9 -- Keywords.
     10 lex:add_rule('keyword', lex:tag(lexer.KEYWORD, lex:word_match(lexer.KEYWORD)))
     11 
     12 -- Functions.
     13 lex:add_rule('function', lex:tag(lexer.FUNCTION_BUILTIN, lex:word_match(lexer.FUNCTION_BUILTIN)))
     14 
     15 -- Constants.
     16 lex:add_rule('constant', lex:tag(lexer.CONSTANT_BUILTIN, lex:word_match(lexer.CONSTANT_BUILTIN)))
     17 
     18 -- Strings.
     19 local str = lexer.range('"', true)
     20 local ml_str = lexer.range("''", false)
     21 lex:add_rule('string', lex:tag(lexer.STRING, str + ml_str))
     22 
     23 -- Paths.
     24 local path_char = lexer.alnum + S('_-.+')
     25 local path_seg = ('/' * path_char^1)
     26 local path = P('~')^-1 * path_char^0 * path_seg^1 * P('/')^-1
     27 lex:add_rule('path', lex:tag(lexer.LINK, path))
     28 
     29 -- URIs.
     30 local uri_char = lexer.alnum + S("%/?:@&=+$,-_.!~*'")
     31 local uri = lexer.alpha * (lexer.alnum + S('+-.'))^0 * ':' * uri_char^1
     32 lex:add_rule('uri', lex:tag(lexer.LINK, uri))
     33 
     34 -- Angle-bracket paths.
     35 local spath = '<' * path_char^1 * path_seg^0 * '>'
     36 lex:add_rule('spath', lex:tag(lexer.LINK, spath))
     37 
     38 -- Identifiers.
     39 local id = (lexer.alpha + '_') * (lexer.alnum + S('_-'))^0
     40 lex:add_rule('identifier', lex:tag(lexer.IDENTIFIER, id))
     41 
     42 -- Comments.
     43 local line_comment = lexer.to_eol('#', true)
     44 local block_comment = lexer.range('/*', '*/')
     45 lex:add_rule('comment', lex:tag(lexer.COMMENT, line_comment + block_comment))
     46 
     47 -- Numbers.
     48 lex:add_rule('number', lex:tag(lexer.NUMBER, lexer.number))
     49 
     50 -- Operators.
     51 local l_ops = P('&&') + '||' + '->' + '//' + '++'
     52 local s_ops = S('?+-.*/!<>=,;:()[]{}')
     53 lex:add_rule('operator', lex:tag(lexer.OPERATOR, l_ops + s_ops))
     54 
     55 -- Fold points.
     56 lex:add_fold_point(lexer.OPERATOR, '(', ')')
     57 lex:add_fold_point(lexer.OPERATOR, '[', ']')
     58 lex:add_fold_point(lexer.OPERATOR, '{', '}')
     59 lex:add_fold_point(lexer.COMMENT, '/*', '*/')
     60 
     61 -- Word lists.
     62 lex:set_word_list(lexer.KEYWORD, {
     63 	'if', 'then', 'else', 'assert', 'with', 'let', 'in', 'rec', 'inherit', 'or', '...'
     64 })
     65 
     66 lex:set_word_list(lexer.CONSTANT_BUILTIN, {
     67 	'builtins', 'true', 'false', 'null', --
     68 	'builtins.currentSystem', 'builtins.currentTime', 'builtins.langVersion', 'builtins.nixPath',
     69 	'builtins.nixVersion', 'builtins.storeDir'
     70 })
     71 
     72 lex:set_word_list(lexer.FUNCTION_BUILTIN, {
     73 	'derivation', 'import', 'abort', 'throw', --
     74 	'builtins.add', 'builtins.all', 'builtins.any', 'builtins.attrNames', 'builtins.attrValues',
     75 	'builtins.baseNameOf', 'builtins.bitAnd', 'builtins.bitOr', 'builtins.bitXor', 'builtins.break',
     76 	'builtins.catAttrs', 'builtins.ceil', 'builtins.compareVersions', 'builtins.concatLists',
     77 	'builtins.concatMap', 'builtins.concatStringsSep', 'builtins.deepSeq', 'builtins.dirOf',
     78 	'builtins.div', 'builtins.elem', 'builtins.elemAt', 'builtins.fetchClosure', 'builtins.fetchGit',
     79 	'builtins.fetchTarball', 'builtins.fetchurl', 'builtins.filter', 'builtins.filterSource',
     80 	'builtins.findFile', 'builtins.flakeRefToString', 'builtins.floor', "builtins.foldl'",
     81 	'builtins.fromJSON', 'builtins.fromTOML', 'builtins.functionArgs', 'builtins.genList',
     82 	'builtins.genericClosure', 'builtins.getAttr', 'builtins.getContext', 'builtins.getEnv',
     83 	'builtins.getFlake', 'builtins.groupBy', 'builtins.hasAttr', 'builtins.hasContext',
     84 	'builtins.hashFile', 'builtins.hashString', 'builtins.head', 'builtins.import',
     85 	'builtins.intersectAttrs', 'builtins.isAttrs', 'builtins.isBool', 'builtins.isFloat',
     86 	'builtins.isFunction', 'builtins.isInt', 'builtins.isList', 'builtins.isNull', 'builtins.isPath',
     87 	'builtins.isString', 'builtins.length', 'builtins.lessThan', 'builtins.listToAttrs',
     88 	'builtins.map', 'builtins.mapAttrs', 'builtins.match', 'builtins.mul', 'builtins.outputOf',
     89 	'builtins.parseDrvName', 'builtins.parseFlakeRef', 'builtins.partition', 'builtins.path',
     90 	'builtins.pathExists', 'builtins.placeholder', 'builtins.readDir', 'builtins.readFile',
     91 	'builtins.readFileType', 'builtins.removeAttrs', 'builtins.replaceStrings', 'builtins.seq',
     92 	'builtins.sort', 'builtins.split', 'builtins.splitVersion', 'builtins.storePath',
     93 	'builtins.stringLength', 'builtins.sub', 'builtins.substring', 'builtins.tail', 'builtins.throw',
     94 	'builtins.toFile', 'builtins.toJSON', 'builtins.toPath', 'builtins.toString', 'builtins.toXML',
     95 	'builtins.trace', 'builtins.traceVerbose', 'builtins.tryEval', 'builtins.typeOf',
     96 	'builtins.zipAttrsWith'
     97 })
     98 
     99 lexer.property['scintillua.comment'] = '#'
    100 
    101 return lex