]> git.eshelyaron.com Git - dict.git/commitdiff
ADDED: new command and user option for updating whitespace
authorEshel Yaron <me@eshelyaron.com>
Sat, 8 Oct 2022 20:38:45 +0000 (23:38 +0300)
committerEshel Yaron <me@eshelyaron.com>
Sat, 8 Oct 2022 20:38:45 +0000 (23:38 +0300)
* sweeprolog.el:
- sweeprolog-align-spaces: new command, updates whitespace around
point according to SWI-Prolog conventions.
- sweeprolog-enable-cycle-spacing: new user option, when non-nil
sweeprolog-align-spaces is added to cycle-spacing-actions.
- sweeprolog-mode: use it.
- README.org: document it.
- NEWS.org: announce it.

NEWS.org
README.org
sweeprolog.el

index e4b8d6582883d3ca5d6beb9b99cab9724903305d..5382631e18366922a8fa792d07f30677d2bc9e19 100644 (file)
--- a/NEWS.org
+++ b/NEWS.org
@@ -11,6 +11,22 @@ SWI-Prolog in Emacs.
 For further details, please consult the manual:
 <https://eshelyaron.com/sweep.html>.
 
+* Version 0.5.3 on 2022-10-08
+
+** New command ~sweeprolog-align-spaces~ in ~sweeprolog-mode~ buffers
+
+~sweeprolog-align-spaces~ is a new command available in ~sweeprolog-mode~
+buffers for updating the whitespace around point according to the
+SWI-Prolog convention used in if-then-else constructs where the next
+token begins four columns after the start of the previous token.
+
+** New user option ~sweeprolog-enable-cycle-spacing~
+
+In Emacs 29, when this user option is non-nil (the default),
+~sweeprolog-align-spaces~ is added to ~cycle-spacing-actions~ such that
+pressing ~M-SPC~ once invokes it by default.
+
+
 * Version 0.5.2 on 2022-10-07
 
 ** Fixed bug in detecting the end of a clause with commented fullstops
index 98519a6c8e3f482397d0f21212c9632512b2a746..f2311414f1f661954aed9f2d9bde5c4aa5914b01 100644 (file)
@@ -527,6 +527,74 @@ For more information about quasi-quotations in SWI-Prolog, see
 [[https://www.swi-prolog.org/pldoc/man?section=quasiquotations][library(quasi_quotations) in the SWI-Prolog manual]].
 
 
+** Aligning with multiple spaces
+:PROPERTIES:
+:CUSTOM_ID: whitespace
+:END:
+
+#+CINDEX: whitespace
+By convention, if-then-else constructs are aligned such that each goal
+starts at the fourth column after the /start/ of the opening parenthesis
+or operator, as follows:
+
+  #+begin_src prolog
+    (   if
+    ->  then
+    ;   else
+    ,*-> elif
+    ;   true
+    )
+  #+end_src
+
+To simplify maintaining the desired layout without manually counting
+spaces, ~sweep~ provides a command that updates the whitespace around
+point such that the next token is aligned to a (multiple of) four
+columns from the start of the previous token.
+
+#+FINDEX: sweeprolog-align-spaces
+#+FINDEX: cycle-spacing
+To insert or update whitespace around point, use the command ~M-x
+sweeprolog-align-spaces~.  For example, consider a ~sweeprolog-mode~
+buffer with the following contents, where =^= designates the location of
+the cursor:
+
+#+begin_src prolog
+  foo :-
+      (   if
+      ;
+       ^
+#+end_src
+
+Calling ~M-x sweeprolog-align-spaces~ will insert three spaces, to yield
+the expected layout:
+
+#+begin_src prolog
+  foo :-
+      (   if
+      ;
+          ^
+#+end_src
+
+In Emacs 29, the command ~M-x cycle-spacing~ is extensible through a
+list of callback functions stored in the variable
+~cycle-spacing-actions~.  ~sweep~ leverages this facility and adds
+~sweeprolog-align-spaces~ as the first action of ~cycle-spacing~.  To
+inhibit this ~sweeprolog-mode~ from doing so, set the user option
+~sweeprolog-enable-cycle-spacing~ to nil.
+
+Moreover, in Emacs 29 ~cycle-spacing~ is bound by default to ~M-SPC~, thus
+aligning if-then-else and similar constructs only requires typing
+~M-SPC~ after the first token.
+
+In Emacs prior to version 29, users are advised to bind
+~sweeprolog-align-spaces~ to ~M-SPC~ directly by adding the following
+lines to Emacs' initialization file (see [[info:emacs#Init File][The Emacs Initialization File]]).
+
+#+begin_src emacs-lisp
+  (eval-after-load 'sweeprolog
+    '(define-key sweeprolog-mode-map (kbd "M-SPC") #'sweeprolog-align-spaces))
+#+end_src
+
 ** Term-based editing and motion commands
 :PROPERTIES:
 :CUSTOM_ID: term-based-commands
@@ -994,6 +1062,9 @@ completion candidates are annotated with description and the version
 of each package.
 
 * Contributing
+:PROPERTIES:
+:CUSTOM_ID: contributing
+:END:
 
 We highly appreciate all contributions, including bug reports,
 patches, improvement suggestions, and general feedback.
@@ -1001,6 +1072,9 @@ patches, improvement suggestions, and general feedback.
 For a list of known desired improvements in ~sweep~, see [[*Things to do][Things to do]].
 
 ** Setting up sweep for local development
+:PROPERTIES:
+:CUSTOM_ID: development-setup
+:END:
 
 Since the Prolog and C parts of ~sweep~ are intended to be distributed
 and installed along with SWI-Prolog (see [[#installation][Installation]]), the easiest
@@ -1033,6 +1107,9 @@ achieved with the following command executed in
 #+end_src
 
 ** Submitting patches and bug reports
+:PROPERTIES:
+:CUSTOM_ID: submitting-patches
+:END:
 
 The best way to get in touch with the ~sweep~ maintainers is via [[https://lists.sr.ht/~eshel/dev][the
 sweep mailing list]].
@@ -1044,11 +1121,17 @@ new buffer with a message template ready to be sent to the ~sweep~
 mailing list.
 
 * Things to do
+:PROPERTIES:
+:CUSTOM_ID: thigs-to-do
+:END:
 
 While ~sweep~ is ready to be used for effective editing of Prolog code,
 there some further improvements that we want to pursue:
 
 ** Improvements around editing Prolog
+:PROPERTIES:
+:CUSTOM_ID: todo-editing
+:END:
 
 - Inherit user customizations from ~prolog-mode~ :: ~sweep~ should inherit
   user customizations from the standard =prolog.el= built into Emacs to
@@ -1058,31 +1141,6 @@ there some further improvements that we want to pursue:
   modifications, but careful consideration is required to make sure
   ~sweeprolog-mode~ overrides all conflicting ~prolog-mode~ features.
 
-- Provide automatic whitespace formatting for if-then-else constructs :: By
-  convention, if-then-else constructs are aligned such that each goal
-  starts at the fourth column after the /start/ of the opening
-  parenthesis or operator, as follows:
-
-  #+begin_src prolog
-    (   if
-    ->  then
-    ;   else
-    ,*-> elif
-    ;   true
-    )
-  #+end_src
-
-  Note that the number of spaces differs from line to line, e.g. in
-  the first line there are three spaces because the opening
-  parenthesis in only spans a single column, while the second line
-  contains two spaces since the operator ~->~ is already two columns
-  long.
-
-  ~sweep~ should make it trivial for users to achieve the conventional
-  layout without manually counting spaces.  Ideally, pressing ~TAB~ or
-  ~SPC~, possibly with a modifier, after the opening parenthesis or
-  operator should result in the above layout.
-
 - Reflect buffer status in the mode line :: It may be useful to
   indicate in the mode line whether the current ~sweeprolog-mode~ buffer
   has been loaded into the Prolog runtime and/or if its
@@ -1149,11 +1207,17 @@ there some further improvements that we want to pursue:
   to matching candidates in the specified module.
 
 ** Improvements around running Prolog
+:PROPERTIES:
+:CUSTOM_ID: todo-running
+:END:
 - Persist top-level history across sessions :: ~sweep~ should persist
   Prolog top-level histories across invocations of
   ~sweeprolog-top-level~, ideally also across different Emacs sessions.
 
 ** General improvements
+:PROPERTIES:
+:CUSTOM_ID: todo-general
+:END:
 - Facilitate interactive debugging :: ~sweep~ should facilitate
   interactive debugging of SWI-Prolog code.  This is a big topic that
   we don't currently address.  Perhaps this should handled through
index 7f68079d0ccfcb62d7d06bb34502b143245def1a..32ca7688b519d884c449cf27007efaf03f86b7d3 100644 (file)
@@ -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.5.2
+;; Package-Version: 0.5.3
 ;; Package-Requires: ((emacs "28"))
 
 ;; This file is NOT part of GNU Emacs.
@@ -70,6 +70,16 @@ symbol specifing a major mode."
   :type '(alist :key-type string :value-type symbol)
   :group 'sweeprolog)
 
+(defcustom sweeprolog-enable-cycle-spacing t
+  "If non-nil and `cycle-spacing-actions' is defined, extend it.
+
+This makes the first invocation of \\[cycle-spacing] in
+`sweeprolog-mode' buffers update whitespace around point using
+`sweeprolog-align-spaces', which see."
+  :package-version '((sweeprolog . "0.5.3"))
+  :type 'boolean
+  :group 'sweeprolog)
+
 (defcustom sweeprolog-colourise-buffer-on-idle t
   "If non-nil, update highlighting of `sweeprolog-mode' buffers on idle."
   :package-version '((sweeprolog . "0.2.0"))
@@ -2485,6 +2495,26 @@ variable at point, if any."
 (defvar-local sweeprolog--timer nil)
 (defvar-local sweeprolog--colourise-buffer-duration 0.2)
 
+
+(defun sweeprolog-align-spaces (&optional _)
+  "Adjust in-line whitespace between the previous next Prolog tokens.
+
+This command ensures that the next token starts at a column
+distanced from the beginning of the previous by a multiple of
+four columns, which accommodates the convetional alignment for
+if-then-else constructs in SWI-Prolog."
+  (interactive "" sweeprolog-mode)
+  (let ((bol (line-beginning-position)))
+    (pcase (sweeprolog-last-token-boundaries)
+      (`(,_ ,lbeg ,lend)
+       (when (<= bol lend)
+         (let ((num (- 4 (% (- lend lbeg) 4))))
+           (when (< 0 num)
+             (goto-char lend)
+             (combine-after-change-calls
+               (delete-horizontal-space)
+               (insert (make-string num ? ))))))))))
+
 ;;;###autoload
 (define-derived-mode sweeprolog-mode prog-mode "sweep"
   "Major mode for reading and editing Prolog code."
@@ -2508,6 +2538,10 @@ variable at point, if any."
   (when sweeprolog-enable-eldoc
     (setq-local eldoc-documentation-strategy #'eldoc-documentation-default)
     (add-hook 'eldoc-documentation-functions #'sweeprolog-predicate-modes-doc nil t))
+  (when (and (boundp 'cycle-spacing-actions)
+             (consp cycle-spacing-actions)
+             sweeprolog-enable-cycle-spacing
+             (setq-local cycle-spacing-actions (cons #'sweeprolog-align-spaces cycle-spacing-actions))))
   (let ((time (current-time)))
     (sweeprolog-colourise-buffer)
     (setq sweeprolog--colourise-buffer-duration (float-time (time-since time))))