vis

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

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

jq.lua

(4083B)


      1 -- Copyright 2006-2025 Mitchell. See LICENSE.
      2 -- jq 1.6 Lua lexer -- https://stedolan.github.io/jq/wiki
      3 -- Anonymously contributed.
      4 
      5 local lexer = require('lexer')
      6 local token, word_match = lexer.token, lexer.word_match
      7 local P, S = lpeg.P, lpeg.S
      8 
      9 local lex = lexer.new('jq')
     10 
     11 -- Whitespace.
     12 lex:add_rule('whitespace', token(lexer.WHITESPACE, lexer.space^1))
     13 
     14 -- Keywords.
     15 lex:add_rule('keyword', token(lexer.KEYWORD, word_match{
     16 	-- keywords not listed by jq's "builtins", minus operators 'and' and 'or', plus the '?' shorthand
     17 	'as', 'break', 'catch', 'def', 'elif', 'else', 'end', 'foreach', 'if', 'import', 'include',
     18 	'label', 'module', 'reduce', 'then', 'try'
     19 } + '?'))
     20 
     21 -- Functions.
     22 lex:add_rule('function', token(lexer.FUNCTION, word_match{
     23 	-- jq 1.6 built-in functions (SQL in upper caisse)
     24 	'acos', 'acosh', 'add', 'all', 'any', 'arrays', 'ascii_downcase', 'ascii_upcase', 'asin', 'asinh',
     25 	'atan', 'atan2', 'atanh', 'booleans', 'bsearch', 'builtins', 'capture', 'cbrt', 'ceil',
     26 	'combinations', 'contains', 'copysign', 'cos', 'cosh', 'debug', 'del', 'delpaths', 'drem',
     27 	'empty', 'endswith', 'env', 'erf', 'erfc', 'error', 'exp', 'exp10', 'exp2', 'explode', 'expm1',
     28 	'fabs', 'fdim', 'finites', 'first', 'flatten', 'floor', 'fma', 'fmax', 'fmin', 'fmod', 'format',
     29 	'frexp', 'from_entries', 'fromdate', 'fromdateiso8601', 'fromjson', 'fromstream', 'gamma',
     30 	'get_jq_origin', 'get_prog_origin', 'get_search_list', 'getpath', 'gmtime', 'group_by', 'gsub',
     31 	'halt', 'halt_error', 'has', 'hypot', 'implode', 'IN', 'in', 'INDEX', 'index', 'indices',
     32 	'infinite', 'input', 'input_filename', 'input_line_number', 'inputs', 'inside', 'isempty',
     33 	'isfinite', 'isinfinite', 'isnan', 'isnormal', 'iterables', 'j0', 'j1', 'jn', 'JOIN', 'join',
     34 	'keys', 'keys_unsorted', 'last', 'ldexp', 'leaf_paths', 'length', 'lgamma', 'lgamma_r', 'limit',
     35 	'localtime', 'log', 'log10', 'log1p', 'log2', 'logb', 'ltrimstr', 'map', 'map_values', 'match',
     36 	'max', 'max_by', 'min', 'min_by', 'mktime', 'modf', 'modulemeta', 'nan', 'nearbyint', 'nextafter',
     37 	'nexttoward', 'normals', 'not', 'now', 'nth', 'nulls', 'numbers', 'objects', 'path', 'paths',
     38 	'pow', 'pow10', 'range', 'recurse', 'recurse_down', 'remainder', 'repeat', 'reverse', 'rindex',
     39 	'rint', 'round', 'rtrimstr', 'scalars', 'scalars_or_empty', 'scalb', 'scalbln', 'scan', 'select',
     40 	'setpath', 'significand', 'sin', 'sinh', 'sort', 'sort_by', 'split', 'splits', 'sqrt',
     41 	'startswith', 'stderr', 'strflocaltime', 'strftime', 'strings', 'strptime', 'sub', 'tan', 'tanh',
     42 	'test', 'tgamma', 'to_entries', 'todate', 'todateiso8601', 'tojson', 'tonumber', 'tostream',
     43 	'tostring', 'transpose', 'trunc', 'truncate_stream', 'type', 'unique', 'unique_by', 'until',
     44 	'utf8bytelength', 'values', 'walk', 'while', 'with_entries', 'y0', 'y1', 'yn'
     45 }))
     46 
     47 -- Strings.
     48 local string = token(lexer.STRING, lexer.range('"', true))
     49 local literal = token(lexer.STRING, word_match('null false true'))
     50 lex:add_rule('string', string + literal)
     51 
     52 -- Operators.
     53 -- 'not' isn't an operator but a function (filter)
     54 lex:add_rule('operator', token(lexer.OPERATOR,
     55 	P('.[]') + '?//' + '//=' + 'and' + '[]' + '//' + '==' + '!=' + '>=' + '<=' + '|=' + '+=' + '-=' +
     56 		'*=' + '/=' + '%=' + 'or' + S('=+-*/%<>()[]{}.,') + '|' + ';'))
     57 
     58 -- Identifiers.
     59 lex:add_rule('identifier', token(lexer.IDENTIFIER, lexer.word))
     60 
     61 -- Comments.
     62 lex:add_rule('comment', token(lexer.COMMENT, lexer.to_eol('#')))
     63 
     64 -- Numbers.
     65 lex:add_rule('number', token(lexer.NUMBER, lexer.number))
     66 
     67 -- Formats.
     68 lex:add_rule('format',
     69 	token('format', '@' * word_match('text json html uri csv tsv sh base64 base64d')))
     70 lex:add_style('format', lexer.styles.constant)
     71 
     72 -- Variables.
     73 lex:add_rule('sysvar', token('sysvar', '$' * word_match('ENV  ORIGIN  __loc__')))
     74 lex:add_style('sysvar', lexer.styles.constant .. {bold = true})
     75 lex:add_rule('variable', token(lexer.VARIABLE, '$' * lexer.word))
     76 
     77 -- Fold points.
     78 lex:add_fold_point(lexer.KEYWORD, 'if', 'end')
     79 lex:add_fold_point(lexer.OPERATOR, '[', ']')
     80 lex:add_fold_point(lexer.OPERATOR, '{', '}')
     81 
     82 lexer.property['scintillua.comment'] = '#'
     83 
     84 return lex