From 87da262379c04ce604fd066c49aa2e39e82ea9f3 Mon Sep 17 00:00:00 2001 From: Eshel Yaron Date: Fri, 11 Nov 2022 12:39:58 +0200 Subject: [PATCH] ADDED: user option specifying where to define new predicates * sweeprolog.el (sweeprolog-default-new-predicate-location) (sweeprolog-new-predicate-location-above-current): new functions. (sweeprolog-new-predicate-location-function): new user option. (sweeprolog-maybe-define-predicate): use it. --- NEWS.org | 20 +++++++++++++++++++- README.org | 8 ++++++-- sweeprolog-tests.el | 25 +++++++++++++++++++++++++ sweeprolog.el | 29 ++++++++++++++++++++++++++--- 4 files changed, 76 insertions(+), 6 deletions(-) diff --git a/NEWS.org b/NEWS.org index 8a30a5f..23602eb 100644 --- a/NEWS.org +++ b/NEWS.org @@ -11,6 +11,24 @@ SWI-Prolog in Emacs. For further details, please consult the manual: . +* Version 0.8.6 on 2022-11-11 + +** New user option ~sweeprolog-new-predicate-location-function~ + +This user option specifies a function to be called from +~sweeprolog-insert-term-dwim~ when defining a new predicate to choose +the location of the new predicate definition. The default value of +the option is a function ~sweeprolog-default-new-predicate-location~ +which preserves the current behavior of placing the new predicate +right below the current predicate. Other options include the new +function ~sweeprolog-new-predicate-location-above-current~ which places +the new predicate above the current one. + +** Fixes + +- Fixed issue where ~sweeprolog-describe-predicate~ would throw an error + when describing predicates that were cross referenced but not loaded. + * Version 0.8.5 on 2022-11-10 ** New command ~sweeprolog-xref-project-source-files~ @@ -19,7 +37,7 @@ This command updates ~sweep~'s cross reference data for all Prolog source files in the current project. Bound to ~X~ in ~sweeprolog-prefix-map~. -** Minor bug fixed +** Minor bug fixes - Fixed issue where ~sweeprolog-predicate-location~ sometimes returned a file importing the predicate in question, rather than actually diff --git a/README.org b/README.org index 1220b1b..1d09df0 100644 --- a/README.org +++ b/README.org @@ -984,12 +984,16 @@ functions, in order: #+FINDEX: sweeprolog-maybe-insert-next-clause #+FINDEX: sweeprolog-maybe-define-predicate +#+VINDEX: sweeprolog-new-predicate-location-function - ~sweeprolog-maybe-insert-next-clause~ :: If the last token before point is a fullstop ending a predicate clause, insert a new clause below it. - ~sweeprolog-maybe-define-predicate~ :: If point is over a call to an - undefined predicate, insert a definition for that predicate below - the last clause of the current predicate definition. + undefined predicate, insert a definition for that predicate. By + default, the new predicate definition is inserted right below the + last clause of the current predicate definition. The user option + ~sweeprolog-new-predicate-location-function~ can be customized to + control where this function inserts new predicate definitions. *** Filling Holes :PROPERTIES: diff --git a/sweeprolog-tests.el b/sweeprolog-tests.el index 8dbe500..2f3e5a5 100644 --- a/sweeprolog-tests.el +++ b/sweeprolog-tests.el @@ -294,6 +294,31 @@ foo :- bar. bar :- foo. ")))) + +(ert-deftest dwim-define-predicate-above () + "Tests adherence to `sweeprolog-new-predicate-location-function'." + (with-temp-buffer + (sweeprolog-mode) + (insert " +%! foo is det. + +foo :- bar. +") + (backward-word) + (let ((sweeprolog-new-predicate-location-function + #'sweeprolog-new-predicate-location-above-current)) + (sweeprolog-insert-term-dwim)) + (call-interactively #'kill-region) + (insert "foo") + (should (string= (buffer-string) + " +bar :- foo. + +%! foo is det. + +foo :- bar. +")))) + (ert-deftest end-of-top-term-with-univ () "Tests detecting the fullstop in presence of `=..'." (with-temp-buffer diff --git a/sweeprolog.el b/sweeprolog.el index 0aa088a..52ed334 100644 --- a/sweeprolog.el +++ b/sweeprolog.el @@ -6,7 +6,7 @@ ;; Maintainer: Eshel Yaron <~eshel/dev@lists.sr.ht> ;; Keywords: prolog languages extensions ;; URL: https://git.sr.ht/~eshel/sweep -;; Package-Version: 0.8.5 +;; Package-Version: 0.8.6 ;; Package-Requires: ((emacs "28.1")) ;; This file is NOT part of GNU Emacs. @@ -309,6 +309,21 @@ clause." :type 'boolean :group 'sweeprolog) +(defcustom sweeprolog-new-predicate-location-function + #'sweeprolog-default-new-predicate-location + "Function used to choose a location for a new predicate definition. +It should take one argument, the name of the new predicate given +as a string, and move point to a suitable position in the current +buffer where the new predicate defintion should be inserted." + :package-version '((sweeprolog "0.8.6")) + :type '(choice (const :tag "Below Current Predicate" + sweeprolog-default-new-predicate-location) + (const :tag "Above Current Predicate" + sweeprolog-new-predicate-location-above-current) + (function :tag "Custom Function")) + :group 'sweeprolog) + + ;;;; Keymaps @@ -2423,11 +2438,19 @@ instead." (sweeprolog-insert-clause functor arity) t)) +(defun sweeprolog-default-new-predicate-location (_pred) + (sweeprolog-end-of-predicate-at-point)) + +(defun sweeprolog-new-predicate-location-above-current (_pred) + (sweeprolog-beginning-of-predicate-at-point) + (let ((last (or (caddr (sweeprolog-last-token-boundaries)) + (point-min)))) + (while (re-search-backward (rx bol "%" (or "%" "!")) last t)))) + (defun sweeprolog-maybe-define-predicate (point _kind _beg _end) (when-let ((pred (sweeprolog-identifier-at-point point))) (unless (sweeprolog-predicate-properties pred) - (push-mark) - (sweeprolog-end-of-predicate-at-point) + (funcall sweeprolog-new-predicate-location-function pred) (let ((functor-arity (sweeprolog--mfn-to-functor-arity pred))) (sweeprolog-insert-clause (car functor-arity) (cdr functor-arity))) -- 2.39.2