[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/zig-mode 3778fb5 030/104: Make indentation more nuanced (a
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/zig-mode 3778fb5 030/104: Make indentation more nuanced (and add more tests for it) |
Date: |
Sun, 29 Aug 2021 11:36:57 -0400 (EDT) |
branch: elpa/zig-mode
commit 3778fb55ca675f1eaa5cc85f941ef952a2daa5f4
Author: Matthew D. Steele <mdsteele@alum.mit.edu>
Commit: Matthew D. Steele <mdsteele@alum.mit.edu>
Make indentation more nuanced (and add more tests for it)
---
README.md | 18 ++++++++++-----
tests.el | 56 ++++++++++++++++++++++++++++++++++++++++++++++
zig-mode.el | 74 +++++++++++++++++++++++++++++++++++++++++++++----------------
3 files changed, 124 insertions(+), 24 deletions(-)
diff --git a/README.md b/README.md
index be2ab54..28b851c 100644
--- a/README.md
+++ b/README.md
@@ -1,14 +1,22 @@
# zig-mode
-Syntax highlighting for the [Zig programming language](http://ziglang.org) in
Emacs.
+
+Syntax highlighting and automatic indentation for the
+[Zig programming language](http://ziglang.org) in Emacs. Requires Emacs 24 or
+later.
## Installation
-Simply install the `zig-mode` package via
[MELPA](https://melpa.org/#/getting-started).
+
+[![MELPA](https://melpa.org/packages/zig-mode-badge.svg)](https://melpa.org/#/zig-mode)
+
+Simply install the `zig-mode` package via
+[MELPA](https://melpa.org/#/getting-started).
Alternatively, you can `git clone` the `zig-mode` repository somewhere
(e.g. under your `~/.emacs.d/`), then add the following to your `.emacs` file:
```elisp
-(add-to-list 'load-path "~/path/to/your/zig-mode/")
-(autoload 'zig-mode "zig-mode" nil t)
-(add-to-list 'auto-mode-alist '("\\.zig\\'" . zig-mode))
+(unless (version< emacs-version "24")
+ (add-to-list 'load-path "~/path/to/your/zig-mode/")
+ (autoload 'zig-mode "zig-mode" nil t)
+ (add-to-list 'auto-mode-alist '("\\.zig\\'" . zig-mode)))
```
diff --git a/tests.el b/tests.el
index f5f7fb2..304103e 100644
--- a/tests.el
+++ b/tests.el
@@ -103,6 +103,29 @@ const python =
;;===========================================================================;;
;; Indentation tests
+(defun zig-test-indent-line (line-number original expected-line)
+ (with-temp-buffer
+ (zig-mode)
+ (insert original)
+ (goto-line line-number)
+ (indent-for-tab-command)
+ (let* ((current-line (thing-at-point 'line t))
+ (stripped-line (replace-regexp-in-string "\n\\'" "" current-line)))
+ (should (equal expected-line stripped-line)))))
+
+(ert-deftest test-indent-from-current-block ()
+ (zig-test-indent-line
+ 6
+ "
+{
+ // Normally, zig-mode indents to 4, but suppose
+ // someone indented this part to 2 for some reason.
+ {
+ // This line should get indented to 6, not 8.
+ }
+}"
+ " // This line should get indented to 6, not 8."))
+
(defun zig-test-indent-region (original expected)
(with-temp-buffer
(zig-mode)
@@ -231,4 +254,37 @@ const msg = []u8{'h', 'e', 'l', 'l', 'o',
const msg = []u8{'h', 'e', 'l', 'l', 'o',
'w', 'o', 'r', 'l', 'd'};"))
+(ert-deftest test-indent-paren-block ()
+ (zig-test-indent-region
+ "
+const foo = (
+some_very_long + expression_that_is * set_off_in_parens
+);"
+ "
+const foo = (
+ some_very_long + expression_that_is * set_off_in_parens
+);"))
+
+(ert-deftest test-indent-double-paren-block ()
+ (zig-test-indent-region
+ "
+const foo = ((
+this_expression_is + set_off_in_double_parens * for_some_reason
+));"
+ "
+const foo = ((
+ this_expression_is + set_off_in_double_parens * for_some_reason
+));"))
+
+(ert-deftest test-indent-with-comment-after-open-brace ()
+ (zig-test-indent-region
+ "
+if (false) { // This comment shouldn't mess anything up.
+launchTheMissiles();
+}"
+ "
+if (false) { // This comment shouldn't mess anything up.
+ launchTheMissiles();
+}"))
+
;;===========================================================================;;
diff --git a/zig-mode.el b/zig-mode.el
index 2a3a737..f78080a 100644
--- a/zig-mode.el
+++ b/zig-mode.el
@@ -1,6 +1,6 @@
;;; zig-mode.el --- A major mode for the Zig programming language -*-
lexical-binding: t -*-
-;; Version: 0.0.7
+;; Version: 0.0.8
;; Author: Andrea Orru <andreaorru1991@gmail.com>, Andrew Kelley
<superjoe30@gmail.com>
;; Keywords: zig, languages
;; Package-Requires: ((emacs "24"))
@@ -110,6 +110,9 @@
;; Other constants
"null" "undefined" "this"))
+(defconst zig-electric-indent-chars
+ '( ?\; ?, ?) ?] ?} ))
+
(defgroup zig-mode nil
"Support for Zig code."
:link '(url-link "https://ziglang.org/")
@@ -151,7 +154,6 @@
("fn" . font-lock-function-name-face)))))
(defun zig-paren-nesting-level () (nth 0 (syntax-ppss)))
-(defun zig-prev-open-paren-pos () (car (last (nth 9 (syntax-ppss)))))
(defun zig-currently-in-str () (nth 3 (syntax-ppss)))
(defun zig-start-of-current-str-or-comment () (nth 8 (syntax-ppss)))
@@ -167,27 +169,57 @@
(defun zig-mode-indent-line ()
(interactive)
+ ;; First, calculate the column that this line should be indented to.
(let ((indent-col
(save-excursion
(back-to-indentation)
- (let ((paren-level
- (let ((level (zig-paren-nesting-level)))
- (if (looking-at "[]})]") (1- level) level))))
- (+ (if (<= paren-level 0)
- 0
- (or (save-excursion
- (goto-char (1+ (zig-prev-open-paren-pos)))
- (and (not (looking-at "\n"))
- (current-column)))
- (* zig-indent-offset paren-level)))
- (if (and
- (not (looking-at ";"))
+ (let* (;; paren-level: How many sets of parens (or other delimiters)
+ ;; we're within, except that if this line closes the
+ ;; innermost set(s) (e.g. the line is just "}"), then we
+ ;; don't count those set(s).
+ (paren-level
+ (save-excursion
+ (while (looking-at "[]})]") (forward-char))
+ (zig-paren-nesting-level)))
+ ;; prev-block-indent-col: If we're within delimiters, this is
+ ;; the column to which the start of that block is indented
+ ;; (if we're not, this is just zero).
+ (prev-block-indent-col
+ (if (<= paren-level 0) 0
(save-excursion
- (zig-skip-backwards-past-whitespace-and-comments)
- (when (> (point) 1)
- (backward-char)
- (not (looking-at "[,;([{}]")))))
- zig-indent-offset 0))))))
+ (while (>= (zig-paren-nesting-level) paren-level)
+ (backward-up-list)
+ (back-to-indentation))
+ (current-column))))
+ ;; base-indent-col: The column to which a complete expression
+ ;; on this line should be indented.
+ (base-indent-col
+ (if (<= paren-level 0)
+ prev-block-indent-col
+ (or (save-excursion
+ (backward-up-list)
+ (forward-char)
+ (and (not (looking-at " *\\(//[^\n]*\\)?\n"))
+ (current-column)))
+ (+ prev-block-indent-col zig-indent-offset))))
+ ;; is-expr-continutation: True if this line continues an
+ ;; expression from the previous line, false otherwise.
+ (is-expr-continutation
+ (and
+ (not (looking-at "[]});]"))
+ (save-excursion
+ (zig-skip-backwards-past-whitespace-and-comments)
+ (when (> (point) 1)
+ (backward-char)
+ (not (looking-at "[,;([{}]")))))))
+ ;; Now we can calculate indent-col:
+ (if is-expr-continutation
+ (+ base-indent-col zig-indent-offset)
+ base-indent-col)))))
+ ;; If point is within the indentation whitespace, move it to the end of the
+ ;; new indentation whitespace (which is what the indent-line-to function
+ ;; always does). Otherwise, we don't want point to move, so we use a
+ ;; save-excursion.
(if (<= (current-column) (current-indentation))
(indent-line-to indent-col)
(save-excursion (indent-line-to indent-col)))))
@@ -256,6 +288,10 @@
"A major mode for the Zig programming language."
(setq-local comment-start "// ")
(setq-local comment-end "")
+ (setq-local electric-indent-chars
+ (append zig-electric-indent-chars
+ (and (boundp 'electric-indent-chars)
+ electric-indent-chars)))
(setq-local indent-line-function 'zig-mode-indent-line)
(setq-local indent-tabs-mode nil) ; Zig forbids tab characters.
(setq-local syntax-propertize-function 'zig-syntax-propertize)
- [nongnu] elpa/zig-mode a716bdd 041/104: Require Emacs v24.3 for setq-local, (continued)
- [nongnu] elpa/zig-mode a716bdd 041/104: Require Emacs v24.3 for setq-local, ELPA Syncer, 2021/08/29
- [nongnu] elpa/zig-mode ef59edd 042/104: Prefer Homepage to URL, ELPA Syncer, 2021/08/29
- [nongnu] elpa/zig-mode 77202ac 044/104: update syntax keywords, ELPA Syncer, 2021/08/29
- [nongnu] elpa/zig-mode d885809 068/104: Merge pull request #30 from joachimschmidt557/var-anytype, ELPA Syncer, 2021/08/29
- [nongnu] elpa/zig-mode a0dc7dc 063/104: Merge pull request #27 from joachimschmidt557/add-nosuspend, ELPA Syncer, 2021/08/29
- [nongnu] elpa/zig-mode 89385d7 088/104: Make read-only-mode deactivation/activation explicit, ELPA Syncer, 2021/08/29
- [nongnu] elpa/zig-mode 3e3c0d5 102/104: Fix font-lock of parameters with optional, pointer or array types, ELPA Syncer, 2021/08/29
- [nongnu] elpa/zig-mode 8e0e610 086/104: Use (read-only-mode) instead of (toggle-read-only), ELPA Syncer, 2021/08/29
- [nongnu] elpa/zig-mode 12fe3c9 001/104: Initial commit, ELPA Syncer, 2021/08/29
- [nongnu] elpa/zig-mode 7c6323c 021/104: orelse, f16, comptime_int, comptime_float, ELPA Syncer, 2021/08/29
- [nongnu] elpa/zig-mode 3778fb5 030/104: Make indentation more nuanced (and add more tests for it),
ELPA Syncer <=
- [nongnu] elpa/zig-mode 9dc36e1 046/104: move defgroup and defcustom to the beginning of the code, ELPA Syncer, 2021/08/29
- [nongnu] elpa/zig-mode 4eafa60 050/104: colorize compilation buffer, ELPA Syncer, 2021/08/29
- [nongnu] elpa/zig-mode 107a67b 060/104: Runs `revert-buffer` after formatting on save., ELPA Syncer, 2021/08/29
- [nongnu] elpa/zig-mode b4ae21a 061/104: Merge pull request #26 from Saikyun/master, ELPA Syncer, 2021/08/29
- [nongnu] elpa/zig-mode 6309295 069/104: Hide the *zig-fmt* window when formatting succeeds again, ELPA Syncer, 2021/08/29
- [nongnu] elpa/zig-mode 1e75c04 100/104: Remove irrelevant comment, ELPA Syncer, 2021/08/29
- [nongnu] elpa/zig-mode 0babe7e 103/104: Merge pull request #59 from eric-p-hutchins/params-with-optionals-pointers-and-arrays-oh-my, ELPA Syncer, 2021/08/29
- [nongnu] elpa/zig-mode 2d0eb23 097/104: Merge pull request #55 from arqv/optim-mode, ELPA Syncer, 2021/08/29
- [nongnu] elpa/zig-mode 232bfff 010/104: Merge pull request #2 from syohex/fix-package, ELPA Syncer, 2021/08/29
- [nongnu] elpa/zig-mode fead48b 002/104: Initial revision., ELPA Syncer, 2021/08/29