aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorSean Whitton <spwhitton@spwhitton.name>2020-05-13 10:11:30 -0700
committerSean Whitton <spwhitton@spwhitton.name>2020-05-13 10:11:30 -0700
commitc0bd13db0c3817aa23fffc790dbe4a1c5a0ad03b (patch)
tree647823fca52a1ae3502c56e855a6673f1eed3478
parentc1363f35d3f1e67111420b96795f02aaff2c1b8c (diff)
downloadhaskell-tab-indent-c0bd13db0c3817aa23fffc790dbe4a1c5a0ad03b.tar.gz
improve behaviour when the previous line was a declaration
Signed-off-by: Sean Whitton <spwhitton@spwhitton.name>
-rw-r--r--NEWS.md6
-rw-r--r--haskell-tab-indent.el59
2 files changed, 42 insertions, 23 deletions
diff --git a/NEWS.md b/NEWS.md
index 8d68021..b5cc9f5 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -5,6 +5,12 @@
require 'where' followed by end of line, rather than just a line
starting with 'where'.
+- Recognise all declarations, not just top level declarations, in code
+ handling the case where the last command was `newline-and-indent'.
+
+- Attempt to line up the first line of definitions with declarations
+ on the previous line, rather than indenting further.
+
- Drop reference to an old git subtrees script from README.md.
- Code cleanup.
diff --git a/haskell-tab-indent.el b/haskell-tab-indent.el
index 06b64c8..723786d 100644
--- a/haskell-tab-indent.el
+++ b/haskell-tab-indent.el
@@ -59,7 +59,13 @@
(length (seq-filter (lambda (c) (equal c ?\t))
(buffer-substring
(line-beginning-position)
- (point)))))))
+ (point))))))
+ (line-first-word () (save-excursion
+ (back-to-indentation)
+ (let ((beg (point)))
+ (while (not (looking-at "[[:space:]]"))
+ (forward-char))
+ (buffer-substring-no-properties beg (point))))))
(defun haskell-tab-indent ()
"Auto indentation on TAB for `haskell-tab-indent-mode'."
(interactive)
@@ -69,34 +75,41 @@
(cl-loop do (beginning-of-line 0)
while (looking-at "[[:space:]]*$"))
(count-line-tabs)))
- ;; determine whether previous line is a top-level declaration
- (prev-line-topdecl
+ (this-first-word (line-first-word))
+ (prev-first-word (save-excursion
+ (beginning-of-line 0)
+ (line-first-word)))
+ ;; determine whether previous line is a declaration
+ (prev-line-decl
(save-excursion
(beginning-of-line 0)
- (eq 'haskell-definition-face
- (get-text-property (point) 'face)))))
+ (looking-at "[[:space:]]*[^[:space:]]+ ::"))))
(save-excursion
(back-to-indentation)
(if (looking-at "where$")
(setf (buffer-substring (line-beginning-position) (point)) " ")
- ;; check for special case of being called by
- ;; `newline-and-indent': if the user has `electric-indent-mode'
- ;; on and RET bound to `newline-and-indent', we'll end up
- ;; indenting too far, or not enough if the previous line was a
- ;; top level declaration
- (unless (or
- ;; avoid indenting too far
- (and (equal this-command 'newline-and-indent)
- (= this-line-tabs prev-line-tabs)
- (not prev-line-topdecl))
- ;; avoid indenting too little
- (and prev-line-topdecl
- (= 1 this-line-tabs)))
- (if (= (1+ prev-line-tabs) this-line-tabs)
- ;; reset
- (delete-region (line-beginning-position) (point))
- ;; indent
- (insert "\t"))))))
+ ;; attempt to line up declarations and definitions
+ (if (and prev-line-decl
+ (string= this-first-word prev-first-word))
+ (setf (buffer-substring (line-beginning-position) (point))
+ (make-string prev-line-tabs ?\t))
+ ;; check for special case of being called by
+ ;; `newline-and-indent': if the user has `electric-indent-mode'
+ ;; on and RET bound to `newline-and-indent', we'll end up
+ ;; indenting too far, or not enough if the previous line was a
+ ;; declaration
+ (unless (or
+ ;; avoid indenting too far
+ (and (equal this-command 'newline-and-indent)
+ (= this-line-tabs prev-line-tabs)
+ (not prev-line-decl))
+ ;; avoid indenting too little
+ (and prev-line-decl (= 1 this-line-tabs)))
+ (if (= (1+ prev-line-tabs) this-line-tabs)
+ ;; reset
+ (delete-region (line-beginning-position) (point))
+ ;; indent
+ (insert "\t")))))))
;; on a line with only indentation, ensure point is at the end
(when (save-excursion (beginning-of-line) (looking-at "[[:space:]]*$"))
(end-of-line))))