[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)))
- [nongnu] elpa/swift-mode 29857ae 002/496: Add initial files, (continued)
- [nongnu] elpa/swift-mode 29857ae 002/496: Add initial files, ELPA Syncer, 2021/08/29
- [nongnu] elpa/swift-mode 7e3bb8e 008/496: Add package deps, ELPA Syncer, 2021/08/29
- [nongnu] elpa/swift-mode bb506d0 015/496: Add flycheck-cask to dir-locals, ELPA Syncer, 2021/08/29
- [nongnu] elpa/swift-mode 48a3a25 016/496: Correctly font-lock backtick-enclosed identifiers in let bindings, ELPA Syncer, 2021/08/29
- [nongnu] elpa/swift-mode 741859e 018/496: Add `convenience` to language keywords, ELPA Syncer, 2021/08/29
- [nongnu] elpa/swift-mode 8d2720b 020/496: Add autoload token, ELPA Syncer, 2021/08/29
- [nongnu] elpa/swift-mode 71e3d6f 033/496: Remove unneeded infrastructure, ELPA Syncer, 2021/08/29
- [nongnu] elpa/swift-mode 28c5b54 027/496: More improvements to comment handling, ELPA Syncer, 2021/08/29
- [nongnu] elpa/swift-mode 9b367fe 038/496: Remove duplicate in keywords list, ELPA Syncer, 2021/08/29
- [nongnu] elpa/swift-mode 0bf214b 030/496: Update readme, ELPA Syncer, 2021/08/29
- [nongnu] elpa/swift-mode cb745d5 029/496: Define basic indentation command.,
ELPA Syncer <=
- [nongnu] elpa/swift-mode 0344f63 036/496: Merge pull request #11 from bbatsov/patch-1, ELPA Syncer, 2021/08/29
- [nongnu] elpa/swift-mode 89ce39c 050/496: Format file sections, ELPA Syncer, 2021/08/29
- [nongnu] elpa/swift-mode 0f99a5a 067/496: Tweak docstring to supress checkdoc error, ELPA Syncer, 2021/08/29
- [nongnu] elpa/swift-mode 821d9af 064/496: Make switch-case indent offset customisable, ELPA Syncer, 2021/08/29
- [nongnu] elpa/swift-mode bbd8f91 096/496: Add tests for all implemented smie grammars, ELPA Syncer, 2021/08/29
- [nongnu] elpa/swift-mode cfbc318 092/496: Merge pull request #24 from ap4y/fix_paragraph_movements, ELPA Syncer, 2021/08/29
- [nongnu] elpa/swift-mode a8fa421 086/496: Use a more descriptive map variable name inside its definition, ELPA Syncer, 2021/08/29
- [nongnu] elpa/swift-mode 0c908ad 103/496: Remove an outdated statement about the indentation code, ELPA Syncer, 2021/08/29
- [nongnu] elpa/swift-mode 41d38bd 117/496: Clarify syntax table for syntactic fontification., ELPA Syncer, 2021/08/29
- [nongnu] elpa/swift-mode 18e1e4a 107/496: Highlight attributes as keyword, ELPA Syncer, 2021/08/29