From 6363ddef3a64bfc26137293e630998bd5aca229d Mon Sep 17 00:00:00 2001 From: Eshel Yaron Date: Mon, 5 Sep 2022 22:25:06 +0300 Subject: [PATCH] ADDED: implemented all xref backend callback functions --- sweep.el | 49 ++++++++++++++++++++++++++------- sweep.pl | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 120 insertions(+), 11 deletions(-) diff --git a/sweep.el b/sweep.el index 9603c17..9304d2b 100644 --- a/sweep.el +++ b/sweep.el @@ -26,6 +26,7 @@ ;;; Code: (require 'comint) +(require 'xref) (defgroup sweep nil "SWI-Prolog Embedded in Emacs." @@ -144,6 +145,13 @@ (when (sweep-true-p sol) (cdr sol)))) +(defun sweep-predicate-references (mfn) + (sweep-open-query "user" "sweep" "sweep_predicate_references" mfn) + (let ((sol (sweep-next-solution))) + (sweep-close-query) + (when (sweep-true-p sol) + (cdr sol)))) + (defun sweep-predicate-location (mfn) (sweep-open-query "user" "sweep" "sweep_predicate_location" mfn) (let ((sol (sweep-next-solution))) @@ -151,6 +159,13 @@ (when (sweep-true-p sol) (cdr sol)))) +(defun sweep-predicate-apropos (pattern) + (sweep-open-query "user" "sweep" "sweep_predicate_apropos" pattern) + (let ((sol (sweep-next-solution))) + (sweep-close-query) + (when (sweep-true-p sol) + (cdr sol)))) + (defun sweep-read-predicate () "Read a Prolog predicate (M:F/N) from the minibuffer, with completion." (let* ((col (sweep-predicates-collection)) @@ -227,7 +242,7 @@ module name, F is a functor name and N is its arity." (interactive (list (sweep-read-predicate))) (let* ((loc (sweep-predicate-location mfn)) (path (car loc)) - (line (cdr loc))) + (line (or (cdr loc) 1))) (find-file path) (goto-char (point-min)) (forward-line (1- line)))) @@ -1015,23 +1030,39 @@ Interactively, a prefix arg means to prompt for BUFFER." "Hook for `xref-backend-functions'." 'sweep) - (cl-defmethod xref-backend-identifier-at-point ((_backend (eql 'sweep))) (sweep-identifier-at-point)) (cl-defmethod xref-backend-identifier-completion-table ((_backend (eql 'sweep))) - (sweep-identifier-completion-table)) + (completion-table-with-cache #'sweep-predicates-collection)) (cl-defmethod xref-backend-identifier-completion-ignore-case ((_backend (eql 'sweep))) "Case is always significant for Prolog identifiers, so return nil." nil) -(cl-defmethod xref-backend-definitions ((_backend (eql 'sweep)) symbol)) - -(cl-defmethod xref-backend-references ((_backend (eql 'sweep)) symbol)) - -(cl-defmethod xref-backend-apropos ((_backend (eql 'sweep)) pattern)) - +(cl-defmethod xref-backend-definitions ((_backend (eql 'sweep)) mfn) + (when-let ((loc (sweep-predicate-location mfn)) + (path (car loc)) + (line (or (cdr loc) 1))) + (list (xref-make (concat path ":" (number-to-string line)) (xref-make-file-location path line 0))))) + +(cl-defmethod xref-backend-references ((_backend (eql 'sweep)) mfn) + (let ((refs (sweep-predicate-references mfn))) + (seq-map (lambda (loc) + (let ((path (car loc)) + (line (or (cdr loc) 1))) + (xref-make (concat path ":" (number-to-string line)) (xref-make-file-location path line 0)))) + refs))) + +(cl-defmethod xref-backend-apropos ((_backend (eql 'sweep)) pattern) + (let ((matches (sweep-predicate-apropos pattern))) + (seq-map (lambda (match) + (let ((mfn (car match)) + (path (cadr match)) + (line (or (cddr match) 1))) + (xref-make mfn + (xref-make-file-location path line 0)))) + matches))) ;;;###autoload (define-derived-mode sweep-mode prog-mode "sweep" diff --git a/sweep.pl b/sweep.pl index 179d5be..823f6e5 100644 --- a/sweep.pl +++ b/sweep.pl @@ -38,8 +38,11 @@ sweep_expand_file_name/2, sweep_path_module/2, sweep_colourise_query/2, + sweep_predicate_references/2, sweep_predicate_location/2, + sweep_predicate_apropos/2, sweep_predicates_collection/2, + sweep_local_predicate_completion/2, sweep_modules_collection/2, sweep_packs_collection/2, sweep_pack_install/2, @@ -57,6 +60,7 @@ :- use_module(library(pldoc/man_index)). :- use_module(library(lynx/html_text)). :- use_module(library(prolog_pack)). +:- use_module(library(help)). :- use_module(library(prolog_server)). :- dynamic sweep_current_color/3, @@ -336,11 +340,71 @@ sweep_module_description([M0|P], [M|[P|D]]) :- atom_string(D0, D). sweep_module_description([M0|P], [M|[P]]) :- atom_string(M0, M). +sweep_predicate_references(MFN, Refs) :- + term_string(M:F/N, MFN), + pi_head(F/N, H), + findall([Path|Line], + (xref_called(Path0, H, _, _, Line), + atom_string(Path0, Path)), + Refs, + Tail), + findall([Path|Line], + (xref_called(Path0, M:H, _, _, Line), + atom_string(Path0, Path)), + Tail). + + sweep_predicate_location(MFN, [Path|Line]) :- + !, term_string(M:F/N, MFN), pi_head(F/N, H), + sweep_predicate_location_(M, H, Path, Line). +sweep_predicate_location(FN, [Path|Line]) :- + !, + term_string(F/N, FN), + pi_head(F/N, H), + sweep_predicate_location_(H, Path, Line). + +sweep_predicate_apropos(Query0, Matches) :- + atom_string(Query, Query0), + findall([S,Path|Line], + (prolog_help:apropos(Query, M:F/N, _, _), + format(string(S), '~w:~W/~w', [M, F, [quoted(true), character_escapes(true)], N]), + pi_head(F/N, Head), + sweep_predicate_location_(M, Head, Path, Line)), + Matches, Tail), + findall([S,Path], + (prolog_help:apropos(Query, F/N, _, _), + format(string(S), '~W/~w', [F, [quoted(true), character_escapes(true)], N]), + pi_head(F/N, Head), + sweep_predicate_location_(Head, Path, Line)), + Tail). + +sweep_predicate_location_(H, Path, Line) :- + predicate_property(H, file(Path0)), + predicate_property(H, line_count(Line)), + !, + atom_string(Path0, Path). +sweep_predicate_location_(H, Path, Line) :- + xref_defined(Path0, H, How), + atom_string(Path0, Path), + ( xref_definition_line(How, Line) + -> true + ; Line = [] + ). + +sweep_predicate_location_(M, H, Path, Line) :- + predicate_property(M:H, file(Path0)), predicate_property(M:H, line_count(Line)), - predicate_property(M:H, file(Path0)), atom_string(Path0, Path). + !, + atom_string(Path0, Path). +sweep_predicate_location_(M, H, Path, Line) :- + xref_defined(Path0, M:H, How), + atom_string(Path0, Path), + ( xref_definition_line(How, Line) + -> true + ; Line = [] + ). sweep_local_predicate_completion([Mod|Sub], Preds) :- atom_string(M, Mod), @@ -399,11 +463,25 @@ sweep_predicates_collection(Sub, Preds) :- \+ (predicate_property(M:H, imported_from(M1)), M \= M1) ), Preds0, - Tail), + Tail0), findall(M:F/N, ( '$autoload':library_index(H, M, _), pi_head(F/N, H) ), + Tail0, + Tail1), + findall(M:F/N, + ( xref_defined(SourceId, H, local(_)), + xref_module(SourceId, M), + pi_head(F/N, H) + ), + Tail1, + Tail), + findall(M:F/N, + ( xref_defined(_, H, imported(SourceId)), + xref_module(SourceId, M), + pi_head(F/N, H) + ), Tail), list_to_set(Preds0, Preds1), maplist(sweep_predicate_description, Preds1, Preds2), -- 2.39.2