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

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

[nongnu] elpa/swift-mode cb745d5 029/496: Define basic indentation comma


From: ELPA Syncer
Subject: [nongnu] elpa/swift-mode cb745d5 029/496: Define basic indentation command.
Date: Sun, 29 Aug 2021 11:33:01 -0400 (EDT)

branch: elpa/swift-mode
commit cb745d5f98b88d3eb23dfa8539ec7490f83d10bd
Author: Chris Barrett <chris.d.barrett@me.com>
Commit: Chris Barrett <chris.d.barrett@me.com>

    Define basic indentation command.
    
    Fixes #3
---
 swift-indent.el | 175 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 swift-mode.el   |   5 +-
 2 files changed, 179 insertions(+), 1 deletion(-)

diff --git a/swift-indent.el b/swift-indent.el
new file mode 100644
index 0000000..d6eba24
--- /dev/null
+++ b/swift-indent.el
@@ -0,0 +1,175 @@
+;;; swift-indent.el --- Indentation commands for Swift mode.
+
+;; Copyright (C) 2014 Chris Barrett
+
+;; Author: Chris Barrett <chris.d.barrett@me.com>
+;; Version: 0.1
+
+;; This file is not part of GNU Emacs.
+
+;; This program is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Indentation commands for Swift mode. It's based on the code for `rust-mode',
+;; which is very clean.
+
+;;; Code:
+
+(defgroup swift-indent nil
+  "Configuration for swift-mode indentation behaviour."
+  :group 'languages
+  :prefix "swift-indent-")
+
+(defcustom swift-indent-offset 4
+  "Defines the indentation offset for Swift code."
+  :group 'swift-indent
+  :type 'integer)
+
+(defun swift-indent--paren-level ()
+  "Return the paren level at point."
+  (nth 0 (syntax-ppss)))
+
+(defun swift-indent--in-str-or-cmnt ()
+  "Non-nil if point is in a string or comment."
+  (nth 8 (syntax-ppss)))
+
+(defun swift-indent--back-to-start-of-level ()
+  "Move backwards up to the start of the current indentation level."
+  (let ((current-level (swift-indent--paren-level)))
+    (back-to-indentation)
+    (while (> (swift-indent--paren-level) current-level)
+      (backward-up-list)
+      (back-to-indentation))))
+
+(defun swift-indent--rewind-past-str-cmnt ()
+  (goto-char (nth 8 (syntax-ppss))))
+
+(defun swift-indent--rewind-irrelevant ()
+  (let ((starting (point)))
+    (skip-chars-backward "[:space:]\n")
+    (if (looking-back "\\*/") (backward-char))
+    (if (swift-indent--in-str-or-cmnt)
+        (swift-indent--rewind-past-str-cmnt))
+    (if (/= starting (point))
+        (swift-indent--rewind-irrelevant))))
+
+(defun swift-indent--align-to-expr-after-brace ()
+  (save-excursion
+    (forward-char)
+    ;; We don't want to indent out to the open bracket if the
+    ;; open bracket ends the line.
+    (when (not (looking-at "[[:blank:]]*\\(?://.*\\)?$"))
+      (when (looking-at "[[:space:]]")
+        (forward-word 1)
+        (backward-word 1))
+      (current-column))))
+
+(defun swift-indent--rewind-to-beginning-of-current-level-expr ()
+  (let ((current-level (swift-indent--paren-level)))
+    (back-to-indentation)
+    (while (> (swift-indent--paren-level) current-level)
+      (backward-up-list)
+      (back-to-indentation))))
+
+(defun swift-indent--calculate-indentation ()
+  "Calculate the indentation column to use for `swift-indent-line'.
+Returns the column number as an integer."
+  (save-excursion
+    (back-to-indentation)
+    ;; Point is now at beginning of line.
+    (let* ((level (swift-indent--paren-level))
+           ;; Our "baseline" is one level out from the indentation of the
+           ;; expression containing the innermost enclosing opening bracket.
+           ;; That way if we are within a block that has a different 
indentation
+           ;; than this mode would give it, we still indent the inside of it
+           ;; correctly relative to the outside.
+           (baseline
+            (if (zerop level)
+                0
+              (save-excursion
+                (backward-up-list)
+                (swift-indent--back-to-start-of-level)
+                (+ (current-column) swift-indent-offset)))))
+      (cond
+       ;; A function return type is indented to the corresponding function 
arguments
+       ((looking-at "->")
+        (save-excursion
+          (backward-list)
+          (or (swift-indent--align-to-expr-after-brace)
+              (+ baseline swift-indent-offset))))
+
+       ;; A closing brace is 1 level unindented
+       ((looking-at "}") (- baseline swift-indent-offset))
+
+       ;; Doc comments in /** style with leading * indent to line up the *s
+       ((and (nth 4 (syntax-ppss)) (looking-at "*"))
+        (+ 1 baseline))
+
+       ;; If we're in any other token-tree / sexp, then:
+       (t
+        (or
+         ;; If we are inside a pair of braces, with something after the
+         ;; open brace on the same line and ending with a comma, treat
+         ;; it as fields and align them.
+         (when (> level 0)
+           (save-excursion
+             (swift-indent--rewind-irrelevant)
+             (backward-up-list)
+             ;; Point is now at the beginning of the containing set of braces
+             (swift-indent--align-to-expr-after-brace)))
+
+         (progn
+           (back-to-indentation)
+           ;; Point is now at the beginning of the current line
+           (cond
+            ;; If this line begins with "else" or "{", stay on the
+            ;; baseline as well (we are continuing an expression,
+            ;; but the "else" or "{" should align with the beginning
+            ;; of the expression it's in.)
+            ((looking-at (rx (or (and bow "else" eow) "{")))
+             baseline)
+            ;; Cases are indented to the same level as the enclosing switch 
statement.
+            ((looking-at (rx bow (or "case" "default") eow))
+             (- baseline swift-indent-offset))
+            ((save-excursion
+               (swift-indent--rewind-irrelevant)
+               ;; Point is now at the end of the previous line
+               (or
+                ;; If we are at the first line, no indentation is needed, so 
stay at baseline...
+                (= 1 (line-number-at-pos (point)))
+                ;; ..or if the previous line ends with any of these:
+                ;;     { ? : ( , ; [ }
+                ;; then we are at the beginning of an expression, so stay on 
the baseline...
+                (looking-back "[(,:;?[{}]\\|[^|]|")
+                ;; or if the previous line is the end of an attribute, stay at 
the baseline...
+                (progn 
(swift-indent--rewind-to-beginning-of-current-level-expr) (looking-at "#"))))
+             baseline)
+            (t
+             ;; Otherwise, we are continuing the same expression from the 
previous line,
+             ;; so add one additional indent level
+             (+ baseline swift-indent-offset))))))))))
+
+(defun swift-indent-line ()
+  "Indent the current line.  Also see `swift-indent-offset'."
+  (interactive "*")
+  (let ((indent (swift-indent--calculate-indentation)))
+    (if (<= (current-column) (current-indentation))
+        (indent-line-to indent)
+      (save-excursion
+        (indent-line-to indent)))))
+
+(provide 'swift-indent)
+
+;;; swift-indent.el ends here
diff --git a/swift-mode.el b/swift-mode.el
index 480bef2..e8bb28a 100644
--- a/swift-mode.el
+++ b/swift-mode.el
@@ -30,6 +30,8 @@
 (require 'dash)
 (require 'rx)
 
+(require 'swift-indent)
+
 (eval-and-compile
   ;; Added in Emacs 24.3
   (unless (fboundp 'setq-local)
@@ -172,8 +174,9 @@
   (setq-local font-lock-defaults swift-mode--font-lock-defaults)
   (setq-local comment-start "// ")
   (setq-local comment-end "")
-  (setq-local tab-width 4)
+  (setq-local tab-width swift-indent-offset)
   (setq-local indent-tabs-mode nil)
+  (setq-local indent-line-function 'swift-indent-line)
 
   (setq-local comment-start-skip
               (rx (or (and "//" (* "/")) (and "/*" (* "*"))) (* space)))



reply via email to

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