From 71b7e7811265d43910cda960e3d0629235d3df96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Pankowski?= Date: Mon, 10 Nov 2025 15:17:05 +0100 Subject: [PATCH] vis: add odin language lexer and define ols as lsp for odin --- vis/.config/vis/lexers/odin.lua | 87 +++++++++++++++++++++++++++++++++ vis/.config/vis/visrc.lua | 9 ++++ 2 files changed, 96 insertions(+) create mode 100644 vis/.config/vis/lexers/odin.lua diff --git a/vis/.config/vis/lexers/odin.lua b/vis/.config/vis/lexers/odin.lua new file mode 100644 index 0000000..23784b0 --- /dev/null +++ b/vis/.config/vis/lexers/odin.lua @@ -0,0 +1,87 @@ +-- Copyright 2006-2024 Mitchell. See LICENSE. +-- Odin LPeg lexer. + +local lexer = lexer +local P, S = lpeg.P, lpeg.S + +local lex = lexer.new(...) + +-- Keywords. +lex:add_rule('keyword', lex:tag(lexer.KEYWORD, lex:word_match(lexer.KEYWORD))) + +-- Constants. +lex:add_rule('constant', lex:tag(lexer.CONSTANT_BUILTIN, lex:word_match(lexer.CONSTANT_BUILTIN))) + +-- Types. +lex:add_rule('type', lex:tag(lexer.TYPE, lex:word_match(lexer.TYPE))) + +-- Functions. +local builtin_proc = -lpeg.B('.') * + lex:tag(lexer.FUNCTION_BUILTIN, lex:word_match(lexer.FUNCTION_BUILTIN)) +local proc = lex:tag(lexer.FUNCTION, lexer.word) +lex:add_rule('function', (builtin_proc + proc) * #(lexer.space^0 * '(') + + proc * #(lexer.space^0 * '::' * lexer.space^0 * "proc")) + +-- Identifiers. +lex:add_rule('identifier', lex:tag(lexer.IDENTIFIER, lexer.word)) + +-- Strings. +local sq_str = lexer.range("'", true) +local dq_str = lexer.range('"', true) +local raw_str = lexer.range('`', false, false) +lex:add_rule('string', lex:tag(lexer.STRING, sq_str + dq_str + raw_str)) + +-- Comments. +local line_comment = lexer.to_eol('//') +local block_comment = lexer.range('/*', '*/') +lex:add_rule('comment', lex:tag(lexer.COMMENT, line_comment + block_comment)) + +-- Numbers. +lex:add_rule('number', lex:tag(lexer.NUMBER, lexer.number * P('i')^-1)) + +-- Operators. +lex:add_rule('operator', lex:tag(lexer.OPERATOR, + P('%%=') + P('&~=') + P('<<=') + P('>>=') + P('&&=') + P('||=') + P('---') + P('..=') + + P('..<') + P('%%') + P('&~') + P('<<') + P('>>') + P('&&') + P('||') + P('+=') + P('-=') + + P('*=') + P('/=') + P('%=') + P('&=') + P('|=') + P('~=') + P('++') + P('--') + P('->') + + P('==') + P('!=') + P('<=') + P('>=') + P('..') + S('=!#@$^?+-*/%&|~<>()[]{}:;.,'))) + +-- Fold points. +lex:add_fold_point(lexer.OPERATOR, '{', '}') +lex:add_fold_point(lexer.COMMENT, '/*', '*/') + +-- Word lists. +lex:set_word_list(lexer.KEYWORD, { + 'import', 'foreign', 'package', 'typeid', 'when', 'where', 'if', 'else', 'for', 'switch', 'in', + 'not_in', 'do', 'case', 'break', 'continue', 'fallthrough', 'defer', 'return', 'proc', 'struct', + 'union', 'enum', 'bit_set', 'bit_field', 'map', 'dynamic', 'auto_cast', 'cast', 'transmute', + 'distinct', 'using', 'context', 'or_else', 'or_return', 'or_break', 'or_continue', 'asm', 'matrix' +}) + +lex:set_word_list(lexer.CONSTANT_BUILTIN, { + 'ODIN_ARCH', 'ODIN_BUILD_MODE', 'ODIN_COMPILE_TIMESTAMP', 'ODIN_DEBUG', + 'ODIN_DEFAULT_TO_NIL_ALLOCATOR', 'ODIN_DEFAULT_TO_PANIC_ALLOCATOR', 'ODIN_DISABLE_ASSERT', + 'ODIN_ENDIAN', 'ODIN_ERROR_POS_STYLE', 'ODIN_NO_CRT', 'ODIN_NO_ENTRY_POINT', 'ODIN_NO_RTTI', + 'ODIN_OS', 'ODIN_PLATFORM_SUBTARGET', 'ODIN_ROOT', 'ODIN_VENDOR', 'ODIN_VERSION', + 'ODIN_WINDOWS_SUBSYSTEM', 'false', 'nil', 'true' +}) + +lex:set_word_list(lexer.TYPE, { + 'b16', 'b32', 'b64', 'b8', 'bool', 'byte', 'complex128', 'complex32', 'complex64', 'cstring', + 'cstring16', 'f16', 'f16be', 'f16le', 'f32', 'f32be', 'f32le', 'f64', 'f64be', 'f64le', 'i128', + 'i128be', 'i128le', 'i16', 'i16be', 'i16le', 'i32', 'i32be', 'i32le', 'i64', 'i64be', 'i64le', + 'i8', 'int', 'quaternion128', 'quaternion256', 'quaternion64', 'rawptr', 'rune', 'string', + 'string16', 'typeid', 'u128', 'u128be', 'u128le', 'u16', 'u16be', 'u16le', 'u32', 'u32be', + 'u32le', 'u64', 'u64be', 'u64le', 'u8', 'uint', 'uintptr', 'Maybe', 'Objc_Block' +}) + +lex:set_word_list(lexer.FUNCTION_BUILTIN, { + 'abs', 'align_of', 'cap', 'clamp', 'complex', 'compress_values', 'conj', 'expand_values', 'imag', + 'jmag', 'kmag', 'len', 'max', 'min', 'offset_of', 'offset_of_by_string', 'offset_of_member', + 'offset_of_selector', 'quaternion', 'raw_data', 'real', 'size_of', 'soa_unzip', 'soa_zip', + 'swizzle', 'type_info_of', 'type_of', 'typeid_of' +}) + +lexer.property['scintillua.comment'] = '//' + +return lex diff --git a/vis/.config/vis/visrc.lua b/vis/.config/vis/visrc.lua index a7232dc..b38460e 100644 --- a/vis/.config/vis/visrc.lua +++ b/vis/.config/vis/visrc.lua @@ -23,6 +23,10 @@ vis.ftdetect.filetypes.templ = { ext = { "%.templ$" }, } +vis.ftdetect.filetypes.odin = { + ext = { "%.odin$" }, +} + lspc.message_level = 2 lspc.ls_map.templ = { @@ -30,6 +34,11 @@ lspc.ls_map.templ = { cmd = 'templ lsp', } +lspc.ls_map.odin = { + name = 'ols', + cmd = 'ols', +} + fzfmru.fzfmru_history = 60 local function open_file(file, cmd)