[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/sweeprolog 9bc4ba18b7 1/3: ADDED: numeric argument for swe
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/sweeprolog 9bc4ba18b7 1/3: ADDED: numeric argument for sweeprolog-forward/backward-hole |
Date: |
Sat, 28 Jan 2023 13:59:43 -0500 (EST) |
branch: elpa/sweeprolog
commit 9bc4ba18b7e6da524a63917fba55e5e55291fb49
Author: Eshel Yaron <me@eshelyaron.com>
Commit: Eshel Yaron <me@eshelyaron.com>
ADDED: numeric argument for sweeprolog-forward/backward-hole
* sweeprolog.el (sweeprolog-count-holes): new command, counts holes
in the current buffer.
(sweeprolog-forward-hole, sweeprolog-backward-hole): new numeric
argument, corresponding to the prefix argument when called
interactively. With positive/negative numeric argument, move over
that many holes. With zero numeric argument, call
sweeprolog-count-holes instead.
---
README.org | 20 ++++++++++--
sweeprolog-tests.el | 23 ++++++++++++++
sweeprolog.el | 90 +++++++++++++++++++++++++++++++----------------------
3 files changed, 93 insertions(+), 40 deletions(-)
diff --git a/README.org b/README.org
index d306ddb0bf..67d436cec0 100644
--- a/README.org
+++ b/README.org
@@ -998,10 +998,15 @@ Use these commands to move between holes in the current
Prolog buffer:
#+KINDEX: C-c C-i
- Key: C-c TAB (sweeprolog-forward-hole) :: Move point to the next
- hole in the buffer.
+ hole in the buffer and select it as the region. With numeric prefix
+ argument /n/, move forward over /n/ - 1 holes and select the next one.
#+KINDEX: C-c C-S-i
- Key: C-c S-TAB (sweeprolog-backward-hole) :: Move point to the
- previous hole in the buffer.
+ previous hole in the buffer and select it as the region. With
+ numeric prefix argument /n/, move backward over /n/ - 1 holes and select
+ the next one.
+- Key: C-0 C-c TAB (sweeprolog-count-holes) :: Display the number of
+ holes that are present in the buffer.
- Command: sweeprolog-forward-hole-on-tab-mode :: Toggle moving to the
next hole in the buffer with ~TAB~ if the current line is already
properly indented.
@@ -1010,9 +1015,18 @@ To jump to the next hole in a ~sweeprolog-mode~ buffer,
use the command
~M-x sweeprolog-forward-hole~, bound by default to ~C-c TAB~ (or ~C-c C-i~).
This command sets up the region to cover the next hole after point
leaving the cursor at right after the hole. To jump to the previous
-hole instead, use ~sweeprolog-backward-hole~ or call
+hole use ~C-c S-TAB~ (~sweeprolog-backward-hole~), or call
~sweeprolog-forward-hole~ with a negative prefix argument (~C-- C-c TAB~).
+You can also call ~sweeprolog-forward-hole~ and ~sweeprolog-backward-hole~
+with a numeric prefix argument to jump over the specified number of
+holes. For example, typing ~C-3 C-c TAB~ skips the next two holes in
+the buffer and selects the third as the region. As a special case, if
+you call these commands with a zero prefix argument (~C-0 C-c TAB~),
+they invoke the command ~sweeprolog-count-holes~ instead of jumping.
+This command counts how many holes are left in the current buffer and
+reports its finding via a message in the echo area.
+
When the minor mode ~sweeprolog-forward-hole-on-tab-mode~ is enabled,
the ~TAB~ key is bound to a command moves to the next hole when called
in a properly indented line (otherwise it indents the line). This
diff --git a/sweeprolog-tests.el b/sweeprolog-tests.el
index e44ccca150..c4e3b1fc8f 100644
--- a/sweeprolog-tests.el
+++ b/sweeprolog-tests.el
@@ -287,6 +287,29 @@ foo(Foo) :- bar.
(should (string= (buffer-string)
"foo(bar, (_->_;_), _):-_."))))
+(ert-deftest forward-many-holes ()
+ "Tests jumping over holes with `sweeprolog-forward-hole'."
+ (let ((temp (make-temp-file "sweeprolog-test"
+ nil
+ ".pl"
+ "\n"
+ )))
+ (find-file-literally temp)
+ (sweeprolog-mode)
+ (goto-char (point-min))
+ (sweeprolog-insert-term-with-holes ":-" 2)
+ (deactivate-mark)
+ (goto-char (point-max))
+ (sweeprolog-insert-term-with-holes ":-" 2)
+ (goto-char (point-min))
+ (should (= (sweeprolog-count-holes) 4))
+ (sweeprolog-forward-hole 2)
+ (should (= (point) 5))
+ (sweeprolog-forward-hole -1)
+ (should (= (point) 2))
+ (sweeprolog-forward-hole -2)
+ (should (= (point) 8))))
+
(ert-deftest plunit-testset-skeleton ()
"Tests inserting PlUnit test-set blocks."
(let ((temp (make-temp-file "sweeprolog-test"
diff --git a/sweeprolog.el b/sweeprolog.el
index 893a77b51b..0cec3c681f 100644
--- a/sweeprolog.el
+++ b/sweeprolog.el
@@ -506,6 +506,8 @@ token via its `help-echo' text property."
(eq major-mode 'sweeprolog-mode) ]
[ "Search Term" sweeprolog-term-search
(derived-mode-p 'sweeprolog-mode)]
+ [ "Count Holes" sweeprolog-count-holes
+ (derived-mode-p 'sweeprolog-mode)]
"--"
[ "Set Prolog Flag" sweeprolog-set-prolog-flag t ]
[ "Install Prolog Package" sweeprolog-pack-install t ]
@@ -3094,6 +3096,25 @@ is the prefix argument."
(setq end (1+ end)))
(1+ end))))
+
+(defun sweeprolog-count-holes (&optional interactive)
+ "Count holes in the current buffer and return the total number.
+If INTERACTIVE is non-nil, as it is when called interactively,
+also print a message with the result."
+ (interactive (list t) sweeprolog-mode)
+ (save-excursion
+ (goto-char (point-min))
+ (let ((hole nil) (count 0))
+ (while (setq hole (sweeprolog--next-hole))
+ (goto-char (cdr hole))
+ (setq count (1+ count)))
+ (when interactive
+ (message "%s %s left in buffer %s."
+ (if (zerop count) "No" count)
+ (ngettext "hole" "holes" count)
+ (buffer-name)))
+ count)))
+
(defun sweeprolog--next-hole (&optional wrap)
"Return the bounds of the next hole in the current buffer.
@@ -3127,10 +3148,12 @@ point and the end of the buffer."
When WRAP in non-nil, wrap around if no holes are found between
point and the beginning of the buffer."
+ (when (and (< (point-min) (point))
+ (sweeprolog-at-hole-p (1- (point))))
+ (forward-char -1)
+ (while (and (sweeprolog-at-hole-p) (not (bobp)))
+ (forward-char -1)))
(let ((start (point)))
- (when (use-region-p)
- (goto-char (region-beginning))
- (deactivate-mark))
(when (sweeprolog--backward-wrap wrap)
(if-let ((current-hole-beg (sweeprolog-beginning-of-hole)))
(cons current-hole-beg
@@ -3138,7 +3161,7 @@ point and the beginning of the buffer."
(let ((point (point)))
(while (not (or (sweeprolog-at-hole-p) (bobp)))
(forward-char -1))
- (if (bobp)
+ (if (and (bobp) (not (sweeprolog-at-hole-p)))
(or (and wrap
(save-restriction
(goto-char (point-max))
@@ -3148,44 +3171,37 @@ point and the beginning of the buffer."
(cons (sweeprolog-beginning-of-hole)
(sweeprolog-end-of-hole))))))))
-(defun sweeprolog--forward-hole (&optional wrap)
- (if-let ((hole (sweeprolog--next-hole wrap))
- (beg (car hole))
- (end (cdr hole)))
- (progn
- (goto-char end)
- (push-mark beg t t))
- (user-error "No holes following point")))
-
-(defun sweeprolog--backward-hole (&optional wrap)
- (if-let ((hole (sweeprolog--previous-hole wrap))
- (beg (car hole))
- (end (cdr hole)))
- (progn
- (goto-char end)
- (push-mark beg t t))
- (user-error "No holes before point")))
+(defun sweeprolog-backward-hole (&optional n)
+ "Move point to the previous Nth hole in the current buffer.
+If N is 0, display the number of holes in the current buffer by
+calling `sweeprolog-count-holes' instead.
-(defun sweeprolog-backward-hole (&optional arg)
- "Move point to the previous hole in a `sweeprolog-mode' buffer.
-
-With negative prefix argument ARG, move to the next hole
-instead."
+See also `sweeprolog-forward-hole'."
(interactive "p" sweeprolog-mode)
- (setq arg (or arg 1))
- (sweeprolog-forward-hole (- arg)))
+ (sweeprolog-forward-hole (- (or n 1))))
-(defun sweeprolog-forward-hole (&optional arg)
- "Move point to the next hole in a `sweeprolog-mode' buffer.
+(defun sweeprolog-forward-hole (&optional n)
+ "Move point to the next Nth hole in the current buffer.
+If N is 0, display the number of holes in the current buffer by
+calling `sweeprolog-count-holes' instead.
-With negative prefix argument ARG, move to the previous hole
-instead."
+See also `sweeprolog-backward-hole'."
(interactive "p" sweeprolog-mode)
- (setq arg (or arg 1)
- deactivate-mark nil)
- (if (> 0 arg)
- (sweeprolog--backward-hole t)
- (sweeprolog--forward-hole t)))
+ (setq n (or n 1))
+ (if (zerop n)
+ (sweeprolog-count-holes t)
+ (let* ((func (if (< 0 n)
+ #'sweeprolog--next-hole
+ #'sweeprolog--previous-hole))
+ (hole (funcall func t)))
+ (unless hole
+ (user-error "No holes in buffer %s" (buffer-name)))
+ (goto-char (cdr hole))
+ (dotimes (_ (1- (abs n)))
+ (setq hole (funcall func t))
+ (goto-char (cdr hole)))
+ (setq deactivate-mark nil)
+ (push-mark (car hole) t t))))
(put 'sweeprolog-backward-hole
'repeat-map