Open levinotik opened 8 months ago
I will put this on my backlog, but I would review a PR faster than I will get to doing it myself. #273 is a pretty good template for what needs to be done to add support for a new language.
@stevearc For sure. I'll try my hand at it!
@levinotik can you check if the following set of rules results in a reasonable outline?
after/queries/nim/aerial.scm
:
;; extends
(const_section
(variable_declaration
(symbol_declaration_list
(symbol_declaration
name: (_) @name)
)
) @symbol
(#set! "kind" "Constant"))
(let_section
(variable_declaration
(symbol_declaration_list
(symbol_declaration
name: (_) @name
)
)
) @symbol
(#set! "kind" "Variable"))
(var_section
(variable_declaration
(symbol_declaration_list
(symbol_declaration
name: (_) @name
)
)
) @symbol
(#set! "kind" "Variable"))
((proc_declaration
name: (_) @name) @symbol
(#set! "kind" "Function"))
((template_declaration
name: (_) @name) @symbol
(#set! "kind" "Constructor"))
; A version that doesn't show type in the outline
; ((parameter_declaration
; (symbol_declaration_list
; (symbol_declaration
; name: (_) @name
; )
; )
; ) @symbol (#set! "kind" "Property"))
((parameter_declaration) @name @symbol (#set! "kind" "Property"))
(generic_parameter_list
(parameter_declaration
(symbol_declaration_list
(symbol_declaration) @name @symbol)
(#set! "kind" "TypeParameter"))
)
(import_statement
(expression_list
(_) @name @symbol
(#set! "kind" "Package"))
)
(include_statement
(expression_list
(_) @name @symbol
(#set! "kind" "Package"))
)
((type_declaration
(type_symbol_declaration
name: (_) @name)
(enum_declaration)
) @symbol
(#set! "kind" "Enum"))
((type_declaration
(type_symbol_declaration
name: (_) @name)
(object_declaration)
) @symbol
(#set! "kind" "Class"))
(enum_field_declaration
(symbol_declaration
name: (_) @name) @symbol
(#set! "kind" "EnumMember"))
((while
condition: (_) @name
(#gsub! @name "^" "while ")
) @symbol
(#set! "kind" "Boolean"))
((for
left: (_) @name
(#gsub! @name "^" "for ")
) @symbol
(#set! "kind" "Boolean"))
((when
condition: (_) @name
) @symbol
(#gsub! @name "^" "when ")
(#set! "kind" "Boolean"))
((if
condition: (_) @name
) @symbol
(#gsub! @name "^" "if ")
(#set! "kind" "Boolean"))
(_
alternative: (elif_branch
condition: (_) @name
) @symbol
(#gsub! @name "^" "elif ")
(#set! "kind" "Boolean"))
(_
alternative: (else_branch) @name @symbol
(#set! @name "text" "else")
(#set! "kind" "Boolean"))
((case
value: (_) @name
(#gsub! @name "^" "case ")
) @symbol
(#set! "kind" "Enum"))
(case
(of_branch
values: (_) @name
) @symbol
(#set! "kind" "EnumMember")
(#gsub! @name "^" "of "))
(case
(else_branch) @symbol @name
(#set! "kind" "EnumMember")
(#set! @name "text" "else"))
((call
function: (_) @name
(argument_list
(statement_list))
) @symbol
(#set! "kind" "Interface"))
I've been testing it against nimlsp's source code. It's not truly honest — conditionals are not booleans, for example, — but if the goal is to have a (too) detailed code outline, it should do the job.
Overall, main nym's syntax tree is very easy to work with. Find the node you're interested in, descend, enjoy.
Thanks very much @Slotos My apologies for the delayed response; I'm just seeing this message now. I'll give this a try as soon as I can and report back. Thanks so much for this.
Language: Nim
Mappings for each of the Nim language constructs to their corresponding
SymbolKind
values:Constants and Variables:
SymbolKind
, but they can be categorized asVariable
orConstant
depending on their context.Procedures (Functions):
Function
in LSP'sSymbolKind
.Control Flow:
if
,elif
, andelse
are not usually considered symbols in LSP, so they don't have a directSymbolKind
.Loops:
for
are not typically categorized as symbols in LSP.Sequences:
Array
,Object
, orVariable
in LSP, depending on context.Record (Custom Data Type):
Class
orTypeParameter
in LSP.Exception Handling:
try
andexcept
are not usually categorized as symbols in LSP.Modules:
Module
in LSP.Templates (Generics):
TypeParameter
in LSP.Custom Types:
Enum
, while objects may be mapped toObject
.Case Blocks:
SymbolKind
but may be categorized asObject
,Enum
, orClass
depending on the context.I've made some guesses here since the categorization is not always straightforward; Nim is a flexible language with various constructs that may not align perfectly with LSP's
SymbolKind
categories.I imagine looking at https://github.com/PMunch/nimlsp and/or may help.