;; Maintainer: Eshel Yaron <~eshel/dev@lists.sr.ht>
;; Keywords: prolog languages extensions
;; URL: https://git.sr.ht/~eshel/sweep
-;; Package-Version: 0.7.1
+;; Package-Version: 0.7.2
;; Package-Requires: ((emacs "28.1"))
;; This file is NOT part of GNU Emacs.
(require 'find-func)
(require 'shr)
+(defvar sweeprolog--directory (file-name-directory load-file-name))
+
+(defvar sweeprolog-prolog-server-port nil)
+
(defgroup sweeprolog nil
"SWI-Prolog Embedded in Emacs."
:group 'prolog)
other non-nil value instructs `sweeprolog-predicate-location' to
try and find the SWI-Prolog sources among known project roots
obtained from `project-known-project-roots', which see."
- :package-version '((sweeprolog . "0.4.6"))
+ :package-version '((sweeprolog . "0.7.1"))
:type '(choice (const :tag "Detect" t)
(string :tag "Manual")
(const :tag "Disable" nil))
:type 'boolean
:group 'sweeprolog)
+(make-obsolete-variable 'sweeprolog-init-on-load
+ (concat
+ "Prolog is initialized on-demand,"
+ " regardless of the value of this option.")
+ "sweeprolog version 0.7.2")
+
(defcustom sweeprolog-init-args (list "-q"
"--no-signals"
"-g"
"create_prolog_flag(sweep,true,[access(read_only),type(boolean)])"
(expand-file-name
"sweep.pl"
- (file-name-directory load-file-name)))
+ sweeprolog--directory))
"List of strings used as initialization arguments for Prolog."
:package-version '((sweeprolog "0.5.2"))
:type '(repeat string)
:type 'boolean
:group 'sweeprolog)
-(defvar sweeprolog-prolog-server-port nil)
(declare-function sweeprolog-initialize "sweep-module")
(declare-function sweeprolog-initialized-p "sweep-module")
"-t" "halt"
(expand-file-name
"sweep.pl"
- (file-name-directory load-file-name)))))
+ sweeprolog--directory))))
"\n" t))))
(mapc #'sweeprolog--load-module lines)
(error (concat "Failed to locate `sweep-module'. "
"Make sure SWI-Prolog is installed "
"and up to date")))))
+(defun sweeprolog-ensure-initialized ()
+ (sweeprolog--ensure-module)
+ (sweeprolog-init))
+
+(defun sweeprolog--open-query (ctx mod fun arg &optional rev)
+ "Ensure that Prolog is initialized and execute a new query.
+
+CTX, MOD and FUN are strings. CTX is the context Prolog module
+in which the query in invoked. MOD is the Prolog module in which
+the invoked predicate is defined. FUN is the functor of the
+invoked predicate.
+
+ARG is converted to a Prolog term and used as the input argument
+for the query. When REV is a nil, the input argument is the
+first argument, and the output argument is second. Otherwise,
+the order of the arguments is reversed."
+ (sweeprolog-ensure-initialized)
+ (sweeprolog-open-query ctx mod fun arg rev))
+
+(defvar sweeprolog--initialized nil)
+
+(defun sweeprolog-init (&rest args)
+ "Initialize and setup the embedded Prolog runtime.
+
+If specified, ARGS should be a list of string passed to Prolog as
+extra initialization arguments."
+ (unless sweeprolog--initialized
+ (apply #'sweeprolog-initialize
+ (cons (or sweeprolog-swipl-path (executable-find "swipl"))
+ (append sweeprolog-init-args args)))
+ (setq sweeprolog--initialized t)
+ (sweeprolog-setup-message-hook)
+ (sweeprolog-start-prolog-server)))
+
+(defun sweeprolog-restart (&rest args)
+ "Restart the embedded Prolog runtime.
+
+ARGS is a list of strings appended to the value of
+`sweeprolog-init-args' to produce the Prolog initialization
+arguments.
+
+Interactively, with a prefix arguments, prompt for ARGS.
+Otherwise set ARGS to nil."
+ (interactive
+ (and
+ current-prefix-arg
+ (fboundp 'split-string-shell-command)
+ (split-string-shell-command (read-string "swipl arguments: "))))
+ (when-let ((top-levels (seq-filter (lambda (buffer)
+ (eq 'sweeprolog-top-level-mode
+ (buffer-local-value 'major-mode
+ buffer)))
+ (buffer-list))))
+ (if (y-or-n-p "Stop running sweep top-level processes?")
+ (dolist (buffer top-levels)
+ (let ((process (get-buffer-process buffer)))
+ (when (process-live-p process)
+ (delete-process process))))
+ (user-error "Cannot restart sweep with running top-level processes")))
+ (message "Stoping sweep.")
+ (sweeprolog-cleanup)
+ (message "Starting sweep.")
+ (apply #'sweeprolog-init args))
+
+
(defface sweeprolog-debug-prefix-face
'((default :inherit shadow))
"Face used to highlight the \"DEBUG\" message prefix."
(defun sweeprolog-current-prolog-flags (&optional prefix)
"Return the list of defined Prolog flags defined with prefix PREFIX."
- (sweeprolog-open-query "user" "sweep" "sweep_current_prolog_flags" (or prefix ""))
+ (sweeprolog--open-query "user" "sweep" "sweep_current_prolog_flags" (or prefix ""))
(let ((sol (sweeprolog-next-solution)))
(sweeprolog-close-query)
(when (sweeprolog-true-p sol)
FLAG and VALUE are specified as strings and read as Prolog terms."
(interactive (let ((f (sweeprolog-read-prolog-flag)))
(list f (read-string (concat "Set " f " to: ")))))
- (sweeprolog-open-query "user"
+ (sweeprolog--open-query "user"
"sweep"
"sweep_set_prolog_flag"
(cons flag value))
(with-current-buffer (get-buffer-create sweeprolog-messages-buffer-name)
(setq-local window-point-insertion-type t)
(compilation-minor-mode 1))
- (sweeprolog-open-query "user"
+ (sweeprolog--open-query "user"
"sweep"
"sweep_setup_message_hook"
nil)
(defun sweeprolog-start-prolog-server ()
"Start the `sweep' Prolog top-level embedded server."
- (sweeprolog-open-query "user"
+ (sweeprolog--open-query "user"
"sweep"
"sweep_top_level_server"
nil)
(when (sweeprolog-true-p sol)
(setq sweeprolog-prolog-server-port (cdr sol)))))
-(defun sweeprolog-init (&rest args)
- "Initialize and setup the embedded Prolog runtime.
-
-If specified, ARGS should be a list of string passed to Prolog as
-extra initialization arguments."
- (apply #'sweeprolog-initialize
- (cons (or sweeprolog-swipl-path (executable-find "swipl"))
- (append sweeprolog-init-args args)))
- (sweeprolog-setup-message-hook)
- (sweeprolog-start-prolog-server))
-
-(defun sweeprolog-restart (&rest args)
- "Restart the embedded Prolog runtime.
-
-ARGS is a list of strings appended to the value of
-`sweeprolog-init-args' to produce the Prolog initialization
-arguments.
-
-Interactively, with a prefix arguments, prompt for ARGS.
-Otherwise set ARGS to nil."
- (interactive
- (and
- current-prefix-arg
- (fboundp 'split-string-shell-command)
- (split-string-shell-command (read-string "swipl arguments: "))))
- (when-let ((top-levels (seq-filter (lambda (buffer)
- (eq 'sweeprolog-top-level-mode
- (buffer-local-value 'major-mode
- buffer)))
- (buffer-list))))
- (if (y-or-n-p "Stop running sweep top-level processes?")
- (dolist (buffer top-levels)
- (let ((process (get-buffer-process buffer)))
- (when (process-live-p process)
- (delete-process process))))
- (user-error "Cannot restart sweep with running top-level processes")))
- (message "Stoping sweep.")
- (sweeprolog-cleanup)
- (message "Starting sweep.")
- (apply #'sweeprolog-init args))
(defvar sweeprolog-predicate-completion-collection nil)
"Return a list of prediactes accessible in the current buffer.
When non-nil, only predicates whose name contains PREFIX are returned."
- (sweeprolog-open-query "user" "sweep" "sweep_local_predicate_completion"
+ (sweeprolog--open-query "user" "sweep" "sweep_local_predicate_completion"
(cons sweeprolog-buffer-module
prefix))
(let ((sol (sweeprolog-next-solution)))
(defun sweeprolog-predicates-collection (&optional prefix)
"Return a list of prediacte completion candidates matchitng PREFIX."
- (sweeprolog-open-query "user" "sweep" "sweep_predicates_collection" prefix)
+ (sweeprolog--open-query "user" "sweep" "sweep_predicates_collection" prefix)
(let ((sol (sweeprolog-next-solution)))
(sweeprolog-close-query)
(when (sweeprolog-true-p sol)
(defun sweeprolog-predicate-references (mfn)
"Find source locations where the predicate MFN is called."
- (sweeprolog-open-query "user" "sweep" "sweep_predicate_references" mfn)
+ (sweeprolog--open-query "user" "sweep" "sweep_predicate_references" mfn)
(let ((sol (sweeprolog-next-solution)))
(sweeprolog-close-query)
(when (sweeprolog-true-p sol)
For native built-in predicates, the behavior of this function
depends on the value of the user option
`sweeprolog-swipl-sources', which see."
- (sweeprolog-open-query "user" "sweep" "sweep_predicate_location" mfn)
+ (sweeprolog--open-query "user" "sweep" "sweep_predicate_location" mfn)
(let ((sol (sweeprolog-next-solution)))
(sweeprolog-close-query)
(if (sweeprolog-true-p sol)
(defun sweeprolog-predicate-apropos (pattern)
"Return a list of predicates whose name resembeles PATTERN."
- (sweeprolog-open-query "user" "sweep" "sweep_predicate_apropos" pattern)
+ (sweeprolog--open-query "user" "sweep" "sweep_predicate_apropos" pattern)
(let ((sol (sweeprolog-next-solution)))
(sweeprolog-close-query)
(when (sweeprolog-true-p sol)
(cons start (point))))))))
(defun sweeprolog-prefix-operators (&optional file)
- (sweeprolog-open-query "user"
+ (sweeprolog--open-query "user"
"sweep" "sweep_prefix_ops"
(or file (buffer-file-name)))
(let ((sol (sweeprolog-next-solution)))
(user-error "Unable to locate predicate %s" mfn)))
(defun sweeprolog-modules-collection ()
- (sweeprolog-open-query "user" "sweep" "sweep_modules_collection" nil)
+ (sweeprolog--open-query "user" "sweep" "sweep_modules_collection" nil)
(let ((sol (sweeprolog-next-solution)))
(sweeprolog-close-query)
(when (sweeprolog-true-p sol)
(cdr sol))))
(defun sweeprolog-module-path (mod)
- (sweeprolog-open-query "user" "sweep" "sweep_module_path" mod)
+ (sweeprolog--open-query "user" "sweep" "sweep_module_path" mod)
(let ((sol (sweeprolog-next-solution)))
(sweeprolog-close-query)
(when (sweeprolog-true-p sol)
(defun sweeprolog--set-buffer-module ()
- (sweeprolog-open-query "user" "sweep" "sweep_path_module" (buffer-file-name))
+ (sweeprolog--open-query "user" "sweep" "sweep_path_module" (buffer-file-name))
(let ((sol (sweeprolog-next-solution)))
(sweeprolog-close-query)
(setq sweeprolog-buffer-module
(find-file (sweeprolog-module-path mod)))
(defun sweeprolog-packs-collection ()
- (sweeprolog-open-query "user" "sweep" "sweep_packs_collection" "")
+ (sweeprolog--open-query "user" "sweep" "sweep_packs_collection" "")
(let ((sol (sweeprolog-next-solution)))
(sweeprolog-close-query)
(when (sweeprolog-true-p sol)
(defun sweeprolog-pack-install (pack)
"Install or upgrade Prolog package PACK."
(interactive (list (sweeprolog-read-pack-name)))
- (sweeprolog-open-query "user" "sweep" "sweep_pack_install" pack)
+ (sweeprolog--open-query "user" "sweep" "sweep_pack_install" pack)
(let ((sol (sweeprolog-next-solution)))
(sweeprolog-close-query)
(if (sweeprolog-true-p sol)
(contents (buffer-substring-no-properties beg end)))
(with-silent-modifications
(font-lock-unfontify-region beg end))
- (sweeprolog-open-query "user"
+ (sweeprolog--open-query "user"
"sweep"
"sweep_colourise_buffer"
(cons contents (buffer-file-name)))
(contents (buffer-substring-no-properties beg end)))
(with-silent-modifications
(font-lock-unfontify-region beg end))
- (sweeprolog-open-query "user"
+ (sweeprolog--open-query "user"
"sweep"
"sweep_colourise_some_terms"
(list contents
(query (buffer-substring-no-properties beg end)))
(with-silent-modifications
(font-lock-unfontify-region beg end))
- (sweeprolog-open-query "user"
+ (sweeprolog--open-query "user"
"sweep"
"sweep_colourise_query"
(cons query (marker-position beg)))
(let* ((beg (point-min))
(end (point-max))
(contents (buffer-substring-no-properties beg end)))
- (sweeprolog-open-query "user"
+ (sweeprolog--open-query "user"
"sweep"
"sweep_load_buffer"
(cons contents (buffer-file-name)))
(with-current-buffer buf
(unless (eq major-mode 'sweeprolog-top-level-mode)
(sweeprolog-top-level-mode)))
- (sweeprolog-open-query "user"
+ (sweeprolog--open-query "user"
"sweep"
"sweep_accept_top_level_client"
(buffer-name buf))
"Prolog top-level thread ID corresponding to this buffer.")
(defun sweeprolog-top-level--populate-thread-id ()
- (sweeprolog-open-query "user"
+ (sweeprolog--open-query "user"
"sweep"
"sweep_top_level_thread_buffer"
(buffer-name)
(setq sweeprolog-top-level-thread-id (cdr sol)))))
(defun sweeprolog-signal-thread (tid goal)
- (sweeprolog-open-query "user"
+ (sweeprolog--open-query "user"
"sweep"
"sweep_thread_signal"
(cons tid goal))
(cancel-timer sweeprolog-top-level-timer)))
nil t))
-(sweeprolog--ensure-module)
-(when sweeprolog-init-on-load (sweeprolog-init))
-
;;;###autoload
(defvar sweeprolog-help-prefix-map
(let ((map (make-sparse-keymap)))
(cond ((eq operation 'expand-file-name)
(let ((fn (car args))
(dn (cadr args)))
- (sweeprolog-open-query "user"
+ (sweeprolog--open-query "user"
"sweep"
"sweep_expand_file_name"
(cons fn dn))
(setq times (1- times)))))
(defun sweeprolog-op-suffix-precedence (token)
- (sweeprolog-open-query "user" "sweep" "sweep_op_info" (cons token (buffer-file-name)))
+ (sweeprolog--open-query "user" "sweep" "sweep_op_info" (cons token (buffer-file-name)))
(let ((res nil) (go t))
(while go
(if-let ((sol (sweeprolog-next-solution))
res))
(defun sweeprolog-op-prefix-precedence (token)
- (sweeprolog-open-query "user" "sweep" "sweep_op_info" (cons token (buffer-file-name)))
+ (sweeprolog--open-query "user" "sweep" "sweep_op_info" (cons token (buffer-file-name)))
(let ((res nil) (go t))
(while go
(if-let ((sol (sweeprolog-next-solution))
res))
(defun sweeprolog-op-infix-precedence (token)
- (sweeprolog-open-query "user" "sweep" "sweep_op_info" (cons token (buffer-file-name)))
+ (sweeprolog--open-query "user" "sweep" "sweep_op_info" (cons token (buffer-file-name)))
(let ((res nil) (go t))
(while go
(if-let ((sol (sweeprolog-next-solution))
(sweeprolog-end-of-top-term)
(point)))
(contents (buffer-substring-no-properties beg end)))
- (sweeprolog-open-query "user"
+ (sweeprolog--open-query "user"
"sweep"
"sweep_definition_at_point"
(cons contents
(sweeprolog-end-of-top-term)
(point)))
(contents (buffer-substring-no-properties beg end)))
- (sweeprolog-open-query "user"
+ (sweeprolog--open-query "user"
"sweep"
"sweep_file_at_point"
(list contents
(sweeprolog-end-of-top-term)
(point)))
(contents (buffer-substring-no-properties beg end)))
- (sweeprolog-open-query "user"
+ (sweeprolog--open-query "user"
"sweep"
"sweep_identifier_at_point"
(list contents
matches)))
(defun sweeprolog-create-index-function ()
- (sweeprolog-open-query "user"
+ (sweeprolog--open-query "user"
"sweep"
"sweep_imenu_index"
(buffer-file-name))
(defun sweeprolog-predicate-modes-doc (cb)
(when-let ((pi (sweeprolog-identifier-at-point)))
- (sweeprolog-open-query "user"
+ (sweeprolog--open-query "user"
"sweep"
"sweep_documentation"
pi)
(defvar-local sweeprolog--colourise-buffer-duration 0.2)
(defun sweeprolog-local-predicate-export-comment (fun ari)
- (sweeprolog-open-query "user"
+ (sweeprolog--open-query "user"
"sweep"
"sweep_local_predicate_export_comment"
(list (buffer-file-name) fun ari))
"\n\n*/\n\n"))
(defun sweeprolog-top-level-menu--entries ()
- (sweeprolog-open-query "user"
+ (sweeprolog--open-query "user"
"sweep"
"sweep_top_level_threads"
nil)
(defun sweeprolog--describe-module (mod)
(let ((page
(progn
- (sweeprolog-open-query "user"
+ (sweeprolog--open-query "user"
"sweep"
"sweep_module_html_documentation"
mod)
(defun sweeprolog--describe-predicate (pred)
(let ((page
(progn
- (sweeprolog-open-query "user"
+ (sweeprolog--open-query "user"
"sweep"
"sweep_predicate_html_documentation"
pred)