From: Eshel Yaron Date: Sat, 3 Sep 2022 12:44:35 +0000 (+0300) Subject: ADDED: sweep-file-name-handler X-Git-Tag: v0.2.0~46 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=e70b4aef2f8a9b7d7c990d1f9d70f8dbc84aeee5;p=sweep.git ADDED: sweep-file-name-handler --- diff --git a/README.org b/README.org index 87f0ee3..44c7f51 100644 --- a/README.org +++ b/README.org @@ -325,6 +325,17 @@ Along with =M-x sweep-find-module=, =sweep= provides the command =M-x sweep-find-predicate= jumping to the definition a loaded or auto-loadable Prolog predicate. +** Prolog file specification expansion + +=sweep= defines a handler for file name the Emacs function +=expand-file-file= that recognizes Prolog file specifications, such as +=library(lists)=, and expands them to the corresponding absolute paths. +This means that one can use Prolog file specifications with Emacs' +standard =find-file= (=C-x C-f=) to locate Prolog resources directly. + +For example, typing =C-x C-f library(pldoc/doc_man)= will open the +source of the =pldoc_man= module from the Prolog library. + * Installing Prolog packages :PROPERTIES: :CUSTOM_ID: prolog-packages @@ -354,6 +365,8 @@ to a prefix key, e.g. =C-c p=, use: As an example, with the above binding the =sweep= top-level can be access from anywhere with =C-c p t=. +#+html: diff --git a/sweep.el b/sweep.el index bd1d33e..42c00a0 100644 --- a/sweep.el +++ b/sweep.el @@ -672,6 +672,53 @@ Interactively, a prefix arg means to prompt for BUFFER." map) "Keymap for `sweep' global commands.") +;;;###autoload +(defun sweep-file-name-handler (operation &rest args) + (cond ((eq operation 'expand-file-name) + (let ((fn (car args)) + (dn (cadr args))) + (sweep-open-query "user" + "sweep" + "sweep_expand_file_name" + (cons fn dn)) + (let ((sol (sweep-next-solution))) + (sweep-close-query) + (if (sweep-true-p sol) + (cdr sol) + (let ((inhibit-file-name-handlers + (cons 'sweep-file-name-handler + (and (eq inhibit-file-name-operation operation) + inhibit-file-name-handlers))) + (inhibit-file-name-operation operation)) + (apply operation args)))))) + (t (let ((inhibit-file-name-handlers + (cons 'sweep-file-name-handler + (and (eq inhibit-file-name-operation operation) + inhibit-file-name-handlers))) + (inhibit-file-name-operation operation)) + (apply operation args))))) + +(add-to-list 'file-name-handler-alist + (cons (rx (seq bol (one-or-more lower) "(")) + #'sweep-file-name-handler)) + +(defun sweep-beginning-of-top-term () + (unless (bobp) + (when-let ((safe-start (nth 8 (syntax-ppss)))) + (goto-char safe-start)) + (re-search-backward (rx (seq bol graph)) nil t) + (let ((safe-start (nth 8 (syntax-ppss)))) + (while (and safe-start (not (bobp))) + (goto-char safe-start) + (re-search-backward (rx (seq bol graph)) nil t) + (setq safe-start (nth 8 (syntax-ppss))))))) + +(defun sweep-end-of-top-term () + (unless (eobp) + (while (nth 8 (syntax-ppss)) + (forward-char)) + (or (re-search-forward (rx (seq "." (or white "\n"))) nil t) + (goto-char (point-max))))) ;;;; Testing: ;; (add-to-list 'load-path (file-name-directory (buffer-file-name))) diff --git a/sweep.pl b/sweep.pl index d0461cf..9f9987b 100644 --- a/sweep.pl +++ b/sweep.pl @@ -33,6 +33,7 @@ :- module(sweep, [ sweep_colors/2, sweep_documentation/2, + sweep_expand_file_name/2, sweep_predicate_location/2, sweep_predicates_collection/2, sweep_modules_collection/2, @@ -346,3 +347,24 @@ sweep_color_goal(goal). sweep_color_goal(goal_term). sweep_color_goal(head). sweep_color_goal(head_term). + + +sweep_expand_file_name([String|Dir], Exp) :- + term_string(Spec, String, [syntax_errors(quiet)]), + sweep_expand_file_name_(Dir, Spec, Atom), + ( exists_file(Atom) + -> true + ; exists_directory(Atom) + ), + atom_string(Atom, Exp). + +sweep_expand_file_name_([], Spec, Atom) :- + absolute_file_name(Spec, Atom, [file_errors(fail), + solutions(all), + extensions(['', '.pl'])]). +sweep_expand_file_name_(Dir, Spec, Exp) :- + !, + absolute_file_name(Spec, Exp, [file_errors(fail), + relative_to(Dir), + solutions(all), + extensions(['', '.pl'])]).