Skip to content

Commit

Permalink
toplevel_form -> toplevel
Browse files Browse the repository at this point in the history
  • Loading branch information
TeamSPoon committed Nov 28, 2024
1 parent 7857b45 commit 245e80a
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 37 deletions.
188 changes: 161 additions & 27 deletions src/packs/lsp_server_metta/lsp-callbacks.metta
Original file line number Diff line number Diff line change
@@ -1,44 +1,178 @@
;; LSP Server Configuration and Implementation
;; This file configures hooks and behaviors for an LSP server, including hover functionality,
;; code lenses, and code actions.

;; sometimes a something like this would be nice
;; sometimes something like this would be nice:
;; !(bind! file-context &lsp-server)
;; However, the file is loaded via `!(import! &lsp-server lsp-callbacks)` so it doesn't matter.
;; We still use !(add-atom &lsp-server ..) in case the system needs individual hooks.

;; Hook for displaying hover information.
;; Displays details when hovering over a term in the editor.
;; Parameters:
;; - $path: File path of the hovered term.
;; - $loc: Location details of the hovered term (line/character position).
;; - $term: The term being hovered over (e.g., a symbol or keyword).
;; - $arity: If the term is a symbol, the number of arguments it is used with.
!(add-atom &lsp-server
(= (hook-hover-string $path $loc $term $arity)
(format-args "looking at {}" ($term))))
(= (hook-hover-string $path $_loc $term $arity)
;; Format and display hover information.
(format-args "hovering over '{}', arity: {}, in file: {}" ($term $arity $path))))

;; Hook for logging hover information for debugging purposes.
;; Logs details of the hovered term for further analysis.
!(add-atom &lsp-server
(= (hook-hover-print $path $_loc $term $arity)
;; Log hover information to the console or output channel.
(println! (format-args "hovering over '{}', arity: {}, in file: {}" ($term $arity $path)))))

;; Code lenses provide inline suggestions and actions based on source file analysis.
;; Parameters:
;; - $uri: URI of the file being analyzed.
;; - $lvl: Depth of the S-expressions for the term or expression ($what).
;; - $ord: File order of these terms or expressions.
;; - $kind: The type of the target object (e.g., 'string', 'symbol', 'variable', 'type', etc.).
;; For details, see: https://github.com/trueagi-io/metta-wam/blob/main/src/packs/lsp_server_metta/prolog/lsp_metta_outline.pl#L101-L139
;; - $what: The term or expression being analyzed.
;; - $vl: If the expression uses variables, their original names.
;; - $path: Absolute file path of the analyzed code (may differ from $uri for includes).
;; - $range: Range of code where the lens applies.
!(add-atom &lsp-server
(= (compute-each-code-lens $uri $lvl $ord $kind $what $vl $path $range)
;; Debugging the lens computation.
(sequential
(lsp-debug! todo (quote (compute-each-code-lens $uri $lvl $ord $kind $what $vl $path $range))))))

;; Computes actions available at a specific code position upon user request.
;; Dynamically determines actions based on the type of the code object.
;; Parameters:
;; - $objecttype: Specifies the scope of the code action (e.g., 'term', 'block', 'file').
;; - $uri: URI of the file where the action is computed.
;; - $range: Code range applicable for the action.
;; - $object: The target code object for which the action applies.
!(add-atom &lsp-server
(= (compute-typed-code-action $objecttype $uri $range $object)
(sequential
;; Debugging the typed-code-action computation.
(lsp-debug! todo (quote (compute-typed-code-action $objecttype $uri $range $object))))))

;; === Individual Hooks for compute-typed-code-action ===

;; Hook for handling variables.
;; Provides a "Rename Variable" action.
!(add-atom &lsp-server
(= (compute-typed-code-action term $uri $range $object)
(if (== Variable (get-type $object))
((range $range)
(command
((title "Rename Variable")
(command rename-variable)
(arguments ($object))))))))

;; Hook for handling symbols.
;; Provides a "Rename Symbol" action.
!(add-atom &lsp-server
(= (hook-hover-print $path $loc $term $arity)
(println! (format-args "printing {}" ($term)))))
(= (compute-typed-code-action term $uri $range $object)
(if (== Symbol (get-type $object))
((range $range)
(command
((title "Rename Symbol")
(command rename-symbol)
(arguments ($object))))))))

;; code lenses appear inline as to what is available even without user asking
;; Hook for handling expressions.
;; Provides an "Evaluate Expression" action, running the code and displaying results in the UI.
!(add-atom &lsp-server
(= (compute-each-code-lens $uri $lvl $ord $kind $what $vl $path $range)
(sequential
( ;; (fail)
(lsp-debug! todo (quote (compute-each-code-lens $uri $lvl $ord $kind $what $vl $path $range)))))))
(= (compute-typed-code-action term $uri $range $object)
(if (== $object (type-cast Expression $object))
((range $range)
(command
((title "Evaluate Expression")
(command lsp-eval-into-ui)
(arguments (eval $object))))))))

;; code actions appear only when user asks what they can do
;; Hook for handling types.
;; Provides a "Check Type" action to validate the type of the object.
!(add-atom &lsp-server
(= (compute-typed-code-action $objecttype $uri $range $object)
(sequential
( ;; (fail)
(lsp-debug! todo (quote (compute-typed-code-action $objecttype $uri $range $object)))))))
(= (compute-typed-code-action term $uri $range $object)
(if (== Type (get-type $object))
((range $range)
(command
((title "Check Type")
(command lsp-eval-into-ui)
(arguments ((check-type $object))))))))))

;; code lenses and actions have almost the same json format
(registered-every-file
((range
((start (line 0) (character 0))
(end (line 0) (character 1))))
(command
((title "Run File At Toplevel")
(command re-run-file)
(arguments ($Uri))))))
;; Hook for handling enums.
;; Provides a "Show Instances of Type" action to display instances matching the given type.
!(add-atom &lsp-server
(= (compute-typed-code-action term $uri $range $object)
(if (== Type (get-type $object))
((range $range)
(command
((title "Show Instances of Type")
(command lsp-eval-into-ui)
(arguments ((match &self (: $inst $object) $inst))))))))))

;; Hook for handling strings.
;; Provides a "Transform String to ProperCase" action.
!(add-atom &lsp-server
(= (compute-typed-code-action term $uri $range $object)
(if (== String (get-type $object))
((range $range)
(command
((title "Transform String to ProperCase")
(command lsp-eval-into-ui)
(arguments ((toProperCase! $object))))))))))

;; Hook for handling blocks.
;; Provides an "Extract Block as Function" action.
!(add-atom &lsp-server
(= (compute-typed-code-action block $uri $range $code)
((range $range)
(command
((title "Extract Block as Function")
(command lsp-eval-into-ui)
(arguments ((quote (= <function-name> $code)))))))))

;; Hook for handling top-level forms.
;; Provides a "Format Toplevel Form" action using the editor's built-in formatter.
!(add-atom &lsp-server
(= (compute-typed-code-action toplevel $uri $range $object)
((range $range)
(command
((title "Format Toplevel Form")
(command format-block)
(arguments ($uri $range)))))))

;; example of an action
;; Hook for handling entire files.
;; Provides two actions: "Run This Entire File" and "Open File".
!(add-atom &lsp-server
(= (re-run-file $path)
(include $path)))
(= (compute-typed-code-action file $uri $range $object)
(if (== $uri $object)
;; Action: Run the entire file.
((range $range)
(command
((title "Run This Entire File")
(command lsp-eval-into-ui)
(arguments ((run-file $uri)))))))
(if (not (== $uri $object))
;; Action: Open a different file.
(let $title (format-args "Open File: {}" ($object))
((range $range)
(command
((title $title)
(command lsp-eval-into-ui)
;; see https://github.com/trueagi-io/metta-wam/blob/main/src/packs/lsp_server_metta/prolog/lsp_server_requests.pl#L379
(arguments ((show-document! $object "true" null $_success))))))))))

;; Example of a custom action to include and execute a file.
;; Loads the specified file into the runtime environment.
!(add-atom &lsp-server
(= (run-file $path)
(include $path)))

;; Utility for sending evaluation results to the UI.
(= (lsp-eval-into-ui $code)
;; https://github.com/trueagi-io/metta-wam/blob/main/src/packs/lsp_server_metta/prolog/lsp_server_requests.pl#L148
(send_feedback_message $code info))

6 changes: 2 additions & 4 deletions src/packs/lsp_server_metta/prolog/lsp_metta_code_actions.pl
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% lsp_hooks:compute_code_action/3 for Load Metta Code
lsp_hooks:compute_code_action(Uri, Range, MettaFileAction) :-
get_src_code_at_range(toplevel_form, Uri, Range, Expression),
get_src_code_at_range(toplevel, Uri, Range, Expression),
RunLoadTitle = "Run/Load Metta",
sformat(RunLoadTitleExpression, "~w: ~w", [RunLoadTitle, Expression]),
MettaFileAction = _{
Expand Down Expand Up @@ -310,7 +310,7 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% lsp_hooks:compute_code_action/3 for Evaluate Metta Expression
lsp_hooks:compute_code_action(Uri, Range, EvalMettaAction) :-
once(get_src_code_at_range(toplevel_form, Uri, Range, TopExpression)),
once(get_src_code_at_range(toplevel, Uri, Range, TopExpression)),
get_src_code_at_range(expression, Uri, Range, Expression),
TopExpression \=@= Expression,
EvalTitle = "Eval Expression",
Expand Down Expand Up @@ -527,8 +527,6 @@

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Handle Execute Command
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Handle Execute Command
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Implement handle_execute_command/2
handle_execute_command(Msg, Response) :-
Expand Down
6 changes: 3 additions & 3 deletions src/packs/lsp_server_metta/prolog/lsp_metta_hover.pl
Original file line number Diff line number Diff line change
Expand Up @@ -322,9 +322,9 @@

get_code_at_range_type(term).
get_code_at_range_type(expression).
get_code_at_range_type(toplevel_form).
%get_code_at_range_type(block).
%get_code_at_range_type(file).
get_code_at_range_type(toplevel).
get_code_at_range_type(block).
get_code_at_range_type(file).
%get_code_at_range_type(exact).
%get_code_at_range_type(symbol).

Expand Down
6 changes: 3 additions & 3 deletions src/packs/lsp_server_metta/prolog/lsp_metta_utils.pl
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@
clause_with_arity_in_file_at_position(Target, _Arity, Path, Start) % Get the clause at the specified position.
)).

get_code_at_range(toplevel_form, Path, Range, Code) :-
get_code_at_range(toplevel, Path, Range, Code) :-
%get_code_at_range(symbol, Path, Range, Target), % First, get the symbol at the range.
%Target \== '',
%path_doc(Path, Uri), % Extract the file path from the URI.
Expand All @@ -269,7 +269,7 @@
%\+ completely_after_range(BRange, LspLCRange), % Ensure the buffer range is relevant to the LSP range.
maybe_name_vars(Vs), !.
% brange_to_dict(BRange,CodeRange), get_code_at_range(exact, Uri, BRange, Code). % Refine the code extraction with exact range.
get_code_at_range(toplevel_form, Uri, Range, Target):- !, get_code_at_range(expression, Uri, Range, Target).
get_code_at_range(toplevel, Uri, Range, Target):- !, get_code_at_range(expression, Uri, Range, Target).

% For `term`, it first resolves the symbol and then looks for the code within the buffer at the range.
get_code_at_range(term, Path, Range, Code) :-
Expand Down Expand Up @@ -310,7 +310,7 @@

% For `block`, it acts similarly to expression but with larger code blocks.
get_code_at_range(block, Uri, Range, Code):-
get_code_at_range(toplevel_form, Uri, Range, Code),!.
get_code_at_range(toplevel, Uri, Range, Code),!.


% Extracts the exact range of code specified by the Range (LSP-style start and end).
Expand Down

0 comments on commit 245e80a

Please sign in to comment.