* sweeprolog.el (sweeprolog-infer-indent-style): new command.
* sweeprolog-tests.el: test it.
* README.org ("Indentation"): mention it.
#+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:
).
#+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
(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!")
(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."
"
))))
+(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
;;;; 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)