]> git.eshelyaron.com Git - sweep.git/commitdiff
ADDED: new command sweeprolog-infer-indent-style
authorEshel Yaron <me@eshelyaron.com>
Sat, 17 Dec 2022 05:58:43 +0000 (07:58 +0200)
committerEshel Yaron <me@eshelyaron.com>
Sat, 17 Dec 2022 05:58:43 +0000 (07:58 +0200)
* sweeprolog.el (sweeprolog-infer-indent-style): new command.
* sweeprolog-tests.el: test it.
* README.org ("Indentation"): mention it.

README.org
sweeprolog-tests.el
sweeprolog.el

index 9e338ca9c11d94d578e654cde6c59580b4fa2986..b6663dee38fe86311ae79924fb895282d7204f66 100644 (file)
@@ -376,12 +376,33 @@ appropriate indentation to apply based on a set of rules.
 
 #+FINDEX: sweeprolog-indent-line
 The entry point of the indentation engine is the function
-=sweeprolog-indent-line= which takes no arguments and indents that line at
-point.  =sweeprolog-mode= supports the standard Emacs interface for
-indentation by arranging for =sweeprolog-indent-line= to be called whenever a
-line should be indented, notably after pressing =TAB=.  For more a full
-description of the available commands and options that pertain to
-indentation, see [[info:emacs#Indentation][Indentation in the Emacs manual]].
+=sweeprolog-indent-line= which takes no arguments and indents that line
+at point.  =sweeprolog-mode= supports the standard Emacs interface for
+indentation by arranging for =sweeprolog-indent-line= to be called
+whenever a line should be indented, notably after pressing =TAB=.  For a
+full description of the available commands and options that pertain to
+indentation, see [[info:emacs#Indentation][Indentation]] in the Emacs manual.
+
+#+FINDEX: sweeprolog-infer-indent-style
+#+KINDEX: C-c C-I
+#+CINDEX: indentation style
+#+VINDEX: indent-tabs-mode
+#+VINDEX: sweeprolog-indent-offset
+The user option ~sweeprolog-indent-offset~ specifies how many columns
+lines are indented with.  The standard Emacs variable ~indent-tabs-mode~
+determines if indentation can use tabs or only spaces.  You may
+sometimes want to adjust these options to match the indentation style
+used in an existing Prolog codebase, the command
+~sweeprolog-infer-indent-style~ can do that for you by analyzing the
+contents of the current buffer and updating the buffer-local values of
+~sweeprolog-indent-offset~ and ~indent-tabs-mode~ accordingly.  Consider
+adding ~sweeprolog-infer-indent-style~ to ~sweeprolog-mode-hook~ to have
+it set up the indentation style automatically in all ~sweeprolog-mode~
+buffers:
+
+#+begin_src emacs-lisp
+  (add-hook 'sweeprolog-mode-hook #'sweeprolog-infer-indent-style)
+#+end_src
 
 *** Indentation rules
 :PROPERTIES:
@@ -412,7 +433,6 @@ rules:
                  ).
    #+end_src
 
-#+VINDEX: sweeprolog-indent-offset
 4. If the current line is the first non-comment line of a clause body,
    indent to the starting column of the head term plus the value of
    the user option =sweeprolog-indent-offset= (by default, four extra
index 5ccbb031118ce180a2f2d5a7fb4dfeafc20a2a9d..c62a031bc7ec0c2768d66ee97fff152a24c09d8e 100644 (file)
@@ -5,6 +5,10 @@
 (remove-hook 'flymake-diagnostic-functions
              #'flymake-proc-legacy-flymake)
 
+(add-hook 'sweeprolog-mode-hook (lambda ()
+                                  (setq-local indent-tabs-mode nil
+                                              inhibit-message t)))
+
 (defconst sweeprolog-tests-greeting
   "Hello from Elisp from Prolog from Elisp from Prolog from Elisp!")
 
@@ -17,7 +21,7 @@
     (cdr sol)))
 
 (defun sweeprolog-tests-greet-1 ()
-  (message sweeprolog-tests-greeting))
+  sweeprolog-tests-greeting)
 
 (ert-deftest elisp->prolog->elisp->prolog->elisp ()
   "Tests calling Elisp from Prolog from Elisp from Prolog from Elisp."
@@ -1130,6 +1134,25 @@ test_bindings(Name-Value) -->
 "
                      ))))
 
+(ert-deftest infer-indent-style ()
+  "Test inferring indentation style from buffer contents."
+  (with-temp-buffer
+    (sweeprolog-mode)
+    (insert "
+foo :-
+  bar.")
+    (sweeprolog-infer-indent-style)
+    (should (= sweeprolog-indent-offset 2))
+    (should (not indent-tabs-mode)))
+  (with-temp-buffer
+    (sweeprolog-mode)
+    (insert "
+foo :-
+\tbar.")
+    (sweeprolog-infer-indent-style)
+    (should (= sweeprolog-indent-offset tab-width))
+    (should indent-tabs-mode)))
+
 (ert-deftest custom-indentation ()
   "Test forcefully setting custom indentation levels."
   (with-temp-buffer
index b50a12bbd87a035b1bb2dd2966b42f51317f5321..3bde49fde1699ac3c8e504c0be572234e6e7f7a2 100644 (file)
@@ -3656,6 +3656,45 @@ valid Prolog atom."
 
 ;;;; Indentation
 
+(defun sweeprolog-infer-indent-style ()
+  "Infer indentation style for the current buffer from its contents.
+
+Examine the indentation of the first clause body starting on a
+line of its own and update the buffer-local values of
+`sweeprolog-indent-offset' and `indent-tabs-mode' are updated
+accordingly."
+  (interactive "" sweeprolog-mode)
+  (let ((offset nil)
+        (usetab nil))
+    (sweeprolog-analyze-buffer-with
+     (lambda (beg _end arg)
+       (pcase arg
+         ("body"
+          (unless offset
+            (save-excursion
+              (goto-char beg)
+              (let ((prefix (buffer-substring (line-beginning-position)
+                                              (point))))
+                (save-match-data
+                  (cond
+                   ((string-match (rx bos (+ " ") eos)
+                                  prefix)
+                    (setq offset (current-column)))
+                   ((string-match (rx bos (+ (or " " "\t")) eos)
+                                  prefix)
+                    (setq offset (current-column)
+                          usetab t)))))))))))
+    (if (not offset)
+        (message (concat "No indented body term found in"
+                         " current buffer.  Keeping current"
+                         " indentation style: offset=%s tabs=%s")
+                 sweeprolog-indent-offset
+                 indent-tabs-mode)
+      (message "Inferred indentation style: offset=%s tabs=%s"
+               offset usetab)
+      (setq-local sweeprolog-indent-offset offset
+                  indent-tabs-mode usetab))))
+
 (defun sweeprolog-indent-line-after-functor (fbeg _fend)
   (save-excursion
     (goto-char fbeg)