emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/jade-mode e128ce3b07 067/128: add custom indent functions


From: ELPA Syncer
Subject: [nongnu] elpa/jade-mode e128ce3b07 067/128: add custom indent functions for line/region
Date: Sat, 29 Jan 2022 08:24:47 -0500 (EST)

branch: elpa/jade-mode
commit e128ce3b078e8b779e963b3afb7acb1749221fad
Author: Travis Jefferson <tjefferson@signpost.com>
Commit: Travis Jefferson <tjefferson@signpost.com>

    add custom indent functions for line/region
    
        Some things to expect:
        1. Indent line works as outlined in readme
        2. Indent region takes uppermost line's indent behavior and applies
           it to entire region.
        3. Region stays active after indent/unindent (so you can repeat!)
        4. Unindent behaves slightly differently: no wraparound at column 0
           and unindenting will continue to 'collapse the hierarchy' until
           all lines' indentation is at 0.
---
 jade-mode.el | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 132 insertions(+), 7 deletions(-)

diff --git a/jade-mode.el b/jade-mode.el
index b62fcd1b1c..8ae8eb984c 100644
--- a/jade-mode.el
+++ b/jade-mode.el
@@ -11,16 +11,15 @@
 
 (defmacro jade-line-as-string ()
   "Returns the current line as a string."
-  `(buffer-substring (point-at-bol) (point-at-eol)))
-
+  `(buffer-substring-no-properties (point-at-bol) (point-at-eol)))
 
 (defun jade-empty-line-p ()
   "If line is empty or not."
   (= (point-at-eol) (point-at-bol)))
 
 (defun jade-blank-line-p ()
-  "If line contains only spaces."
-  (string-match-p "^[ ]*$" (jade-line-as-string)))
+  "Returns t when line contains only whitespace chars, nil otherwise."
+  (string-match-p "^\\s-*$" (jade-line-as-string)))
 
 ;; command to comment/uncomment text
 (defun jade-comment-dwim (arg)
@@ -68,6 +67,132 @@ For detail, see `comment-dwim'."
       (next-line)
       (end-of-line))))
 
+(defun jade-indent ()
+  "Indent current region or line.
+Calls `jade-indent-region' with an active region or `jade-indent-line'
+without."
+  (interactive)
+  (if (region-active-p)
+      (jade-indent-region
+
+       ;; use beginning of line at region-beginning
+       (save-excursion
+         (goto-char (region-beginning))
+         (line-beginning-position))
+
+       ;; use end of line at region-end
+       (save-excursion
+         (goto-char (region-end))
+         (line-end-position)))
+    (jade-indent-line)))
+
+(defun jade-indent-line ()
+  "Indent current line of jade code.
+If the cursor is left of the current indentation, then the first call
+will simply jump to the current indent. Subsequent calls will indent
+the current line by `jade-tab-width' until current indentation is
+nested one tab-width deeper than its parent tag. At that point, an
+additional call will reset indentation to column 0."
+  (interactive)
+  (let ((left-of-indent (>= (current-column) (current-indentation)))
+        (indent (jade-calculate-indent-target)))
+    (if left-of-indent
+
+        ;; if cursor is at or beyond current indent, indent normally
+        (indent-line-to indent)
+
+      ;; if cursor is trailing current indent, first indentation should
+      ;; jump to the current indentation column (subsequent calls
+      ;; will indent normally)
+      (indent-line-to (current-indentation)))))
+
+(defun jade-indent-region (start end)
+  "Indent active region according to indentation of region's first
+line relative to its parent. Keep region active after command
+terminates (to facilitate subsequent indentations of the same region)"
+
+  (interactive "r")
+  (save-excursion
+
+    ;; go to start of region so we can find out its target indent
+    (goto-char start)
+
+    ;; keep region active after command
+    (let* ((deactivate-mark)
+
+           ;; find indent target for first line
+           (first-line-indent-target (jade-calculate-indent-target))
+
+           ;; use current-indentation to turn target indent into
+           ;; a relative indent to apply to each line in region
+           (first-line-relative-indent
+            (- first-line-indent-target (current-indentation))))
+
+      ;; apply relative indent
+      (indent-rigidly start end first-line-relative-indent))))
+
+(defun jade-calculate-indent-target ()
+  "Return the column to which the current line should be indented."
+  (let ((max-indent (+ (jade-previous-line-indentation) jade-tab-width)))
+    (if (>= (current-indentation) max-indent) ;; if at max indentation
+        0
+      (+ (current-indentation) jade-tab-width))))
+
+(defun jade-unindent ()
+  "Unindent active region or current line."
+  (interactive)
+  (if (region-active-p)
+      (jade-unindent-region
+
+       ;; use beginning of line at region-beginning
+       (save-excursion
+         (goto-char (region-beginning))
+         (line-beginning-position))
+
+       ;; use end of line at region-end
+       (save-excursion
+         (goto-char (region-end))
+         (line-end-position)))
+
+    ;; when no region is active
+    (jade-unindent-line)
+    ))
+
+(defun jade-unindent-line ()
+  "Unindent line under point by `jade-tab-width'.
+Calling when `current-indentation' is 0 will have no effect."
+  (indent-line-to
+   (max
+    (- (current-indentation) jade-tab-width)
+    0)))
+
+(defun jade-unindent-region (start end)
+  "Unindent active region by `jade-tab-width'.
+Follows indentation behavior of `indent-rigidly'."
+
+  (interactive "r")
+  (let (deactivate-mark)
+    (indent-rigidly start end (- jade-tab-width))))
+
+(defun jade-previous-line-indentation ()
+  "Get the indentation of the previous (non-blank) line (from point)."
+  (interactive)
+  (save-excursion
+
+    ;; move up to the nearest non-blank line (or buffer start)
+    (while (progn ;; progn used to get do...while control flow
+             (forward-line -1)
+             (and (jade-blank-line-p) (not (= (point-at-bol) (point-min))))))
+    (let ((prev-line-indent (current-indentation)))
+      prev-line-indent)))
+
+(defun jade-newline-and-indent ()
+  "Insert newline and indent to parent's indentation level."
+  (interactive)
+  (newline)
+  (indent-line-to (max (jade-previous-line-indentation) 0))
+  )
+
 (defvar jade-mode-map (make-sparse-keymap))
 
 ;; mode declaration
@@ -96,6 +221,9 @@ For detail, see `comment-dwim'."
 
   ;; modify the keymap
   (define-key jade-mode-map [remap comment-dwim] 'jade-comment-dwim)
+  (define-key jade-mode-map [tab] 'jade-indent)
+  (define-key jade-mode-map [backtab] 'jade-unindent)
+  (define-key jade-mode-map (kbd "RET") 'jade-newline-and-indent)
 
   ;; highlight syntax
   (setq font-lock-defaults '(jade-font-lock-keywords)))
@@ -107,6 +235,3 @@ For detail, see `comment-dwim'."
 (provide 'jade-mode)
 ;;; jade-mode.el ends here
 
-  (define-key jade-mode-map [tab] 'jade-indent)
-  (define-key jade-mode-map [backtab] 'jade-unindent)
-  (define-key jade-mode-map (kbd "RET") 'jade-newline-and-indent)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]