@@ -16,6 +16,7 @@ defmodule NextLS do
1616 alias GenLSP.Notifications.WorkspaceDidChangeWorkspaceFolders
1717 alias GenLSP.Requests.Initialize
1818 alias GenLSP.Requests.Shutdown
19+ alias GenLSP.Requests.TextDocumentCompletion
1920 alias GenLSP.Requests.TextDocumentDefinition
2021 alias GenLSP.Requests.TextDocumentDocumentSymbol
2122 alias GenLSP.Requests.TextDocumentFormatting
@@ -117,6 +118,9 @@ defmodule NextLS do
117118 save: % SaveOptions { include_text: true } ,
118119 change: TextDocumentSyncKind . full ( )
119120 } ,
121+ completion_provider: % GenLSP.Structures.CompletionOptions {
122+ trigger_characters: [ "." , "@" , "&" , "%" , "^" , ":" , "!" , "-" , "~" ]
123+ } ,
120124 document_formatting_provider: true ,
121125 hover_provider: true ,
122126 workspace_symbol_provider: true ,
@@ -504,6 +508,74 @@ defmodule NextLS do
504508 resp
505509 end
506510
511+ def handle_request ( % TextDocumentCompletion { params: % { text_document: % { uri: uri } , position: position } } , lsp ) do
512+ document = lsp . assigns . documents [ uri ]
513+
514+ document_slice =
515+ document
516+ |> Enum . take ( position . line + 1 )
517+ |> Enum . reverse ( )
518+ |> then ( fn [ last_line | rest ] ->
519+ [ String . slice ( last_line , 1 .. ( position . character + 1 ) ) | rest ]
520+ end )
521+ |> Enum . reverse ( )
522+ |> Enum . join ( "\n " )
523+
524+ results =
525+ lsp . assigns . registry
526+ |> dispatch ( :runtimes , fn entries ->
527+ [ result ] =
528+ for { runtime , % { uri: wuri } } <- entries , String . starts_with? ( uri , wuri ) do
529+ NextLS.Autocomplete . expand ( document_slice |> String . to_charlist ( ) |> Enum . reverse ( ) , runtime )
530+ end
531+
532+ case result do
533+ { :yes , _ , entries } -> entries
534+ _ -> [ ]
535+ end
536+ end )
537+ |> Enum . map ( fn % { name: name , kind: kind } = symbol ->
538+ { label , kind , docs } =
539+ case kind do
540+ :struct -> { name , GenLSP.Enumerations.CompletionItemKind . struct ( ) , "" }
541+ :function -> { "#{ name } /#{ symbol . arity } " , GenLSP.Enumerations.CompletionItemKind . function ( ) , symbol . docs }
542+ :module -> { name , GenLSP.Enumerations.CompletionItemKind . module ( ) , "" }
543+ :variable -> { name , GenLSP.Enumerations.CompletionItemKind . variable ( ) , "" }
544+ _ -> { name , GenLSP.Enumerations.CompletionItemKind . text ( ) , "" }
545+ end
546+
547+ % GenLSP.Structures.CompletionItem {
548+ label: label ,
549+ kind: kind ,
550+ insert_text: name ,
551+ documentation: docs
552+ }
553+ end )
554+
555+ # results =
556+ # for snippet <- [
557+ # "defmodule",
558+ # "def",
559+ # "defp",
560+ # "defmacro",
561+ # "defmacrop",
562+ # "for",
563+ # "with",
564+ # "case",
565+ # "cond",
566+ # "defprotocol",
567+ # "defimpl",
568+ # "defexception",
569+ # "defstruct"
570+ # ],
571+ # item <- List.wrap(NextLS.Snippet.get(snippet, context.trigger_character)),
572+ # item do
573+ # item
574+ # end
575+
576+ { :reply , results , lsp }
577+ end
578+
507579 def handle_request ( % Shutdown { } , lsp ) do
508580 { :reply , nil , assign ( lsp , exit_code: 0 ) }
509581 end
0 commit comments