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

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

[nongnu] elpa/julia-mode 011435c 237/352: julia-mode: Fix indent for han


From: ELPA Syncer
Subject: [nongnu] elpa/julia-mode 011435c 237/352: julia-mode: Fix indent for hanging ops and module
Date: Sun, 29 Aug 2021 11:22:52 -0400 (EDT)

branch: elpa/julia-mode
commit 011435c3079dc23b3f7a53ebaf7c89e89a67ac6b
Author: justbur <justin@burkett.cc>
Commit: Yichao Yu <yyc1992@gmail.com>

    julia-mode: Fix indent for hanging ops and module
    
    Introduce julia-indent-hanging to calculate indentation following any
    hanging operators as defined in julia-hanging-operator-regexp on the
    previous line. If a line follows a hanging operator increase the
    indentation by one increment, unless it is preceded by two hanging
    operators. julia-hanging-operator-regexp is taken from julia-parser.scm.
    
    Added two tests
    
    Fixes #15118
    
    Fix indentation after module kw
    
    Register "module" as a keyword that starts a block, and add to new var
    julia-block-start-keywords-no-indent for block keywords that should not
    increase the indentation level.
    
    Fixes #11559
---
 julia-mode-tests.el |  44 +++++++++++++++++
 julia-mode.el       | 138 +++++++++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 169 insertions(+), 13 deletions(-)

diff --git a/julia-mode-tests.el b/julia-mode-tests.el
index 1ad866f..de68089 100644
--- a/julia-mode-tests.el
+++ b/julia-mode-tests.el
@@ -109,6 +109,35 @@ if foo
     end
 end"))
 
+(ert-deftest julia--test-indent-module-keyword ()
+  "Module should not increase indentation at any level."
+  (julia--should-indent
+   "
+module
+begin
+    a = 1
+end
+end"
+   "
+module
+begin
+    a = 1
+end
+end")
+  (julia--should-indent
+   "
+begin
+module
+foo
+end
+end"
+   "
+begin
+    module
+    foo
+    end
+end"))
+
 (ert-deftest julia--test-indent-function ()
   "We should indent function bodies."
   (julia--should-indent
@@ -164,6 +193,21 @@ bar"
 foo() =
     bar"))
 
+(ert-deftest julia--test-indent-operator ()
+  "We should increase indent after the first trailing operator
+but not again after that."
+  (julia--should-indent
+   "
+foo() |>
+bar |>
+baz
+qux"
+   "
+foo() |>
+    bar |>
+    baz
+qux"))
+
 (ert-deftest julia--test-indent-ignores-blank-lines ()
   "Blank lines should not affect indentation of non-blank lines."
   (julia--should-indent
diff --git a/julia-mode.el b/julia-mode.el
index 58aafa3..fb17d4a 100644
--- a/julia-mode.el
+++ b/julia-mode.el
@@ -131,6 +131,71 @@ This function provides equivalent functionality, but makes 
no efforts to optimis
              "\\\\"))
         (group "'"))))
 
+(defconst julia-hanging-operator-regexp
+  ;; taken from julia-parser.scm
+  (concat "^[^#\n]+ "
+          (regexp-opt
+           '( ;; conditional
+             "?"
+             ;; assignment
+             "=" ":=" "+=" "-=" "*=" "/=" "//=" ".//=" ".*=" "./=" "\\=" ".\\="
+             "^=" ".^=" "÷=" ".÷=" "%=" ".%=" "|=" "&=" "$=" "=>" "<<=" ">>="
+             ">>>=" "~" ".+=" ".-="
+             ;; arrow
+             "--" "-->" "←" "→" "↔" "↚" "↛" "↠" "↣" "↦" "↮" "⇎" "⇏" "⇒" "⇔" "⇴"
+             "⇶" "⇷" "⇸" "⇹" "⇺" "⇻" "⇼" "⇽" "⇾" "⇿" "⟵" "⟶" "⟷" "⟷" "⟹"
+             "⟺" "⟻" "⟼" "⟽" "⟾" "⟿" "⤀" "⤁" "⤂" "⤃" "⤄" "⤅" "⤆" "⤇" "⤌"
+             "⤍" "⤎" "⤏" "⤐" "⤑" "⤔" "⤕" "⤖" "⤗" "⤘" "⤝" "⤞" "⤟" "⤠" "⥄" "⥅"
+             "⥆" "⥇" "⥈" "⥊" "⥋" "⥎" "⥐" "⥒" "⥓" "⥖" "⥗" "⥚" "⥛" "⥞" "⥟" "⥢"
+             "⥤" "⥦" "⥧" "⥨" "⥩" "⥪" "⥫" "⥬" "⥭" "⥰" "⧴" "⬱" "⬰" "⬲" "⬳" "⬴"
+             "⬵" "⬶" "⬷" "⬸" "⬹" "⬺" "⬻" "⬼" "⬽" "⬾" "⬿" "⭀" "⭁" "⭂" "⭃" "⭄"
+             "⭇" "⭈" "⭉" "⭊" "⭋" "⭌" "←" "→"
+             ;; or and and
+             "&&" "||"
+             ;; comparison
+             ">" "<" ">=" "≥" "<=" "≤" "==" "===" "≡" "!=" "≠" "!==" "≢" ".>"
+             ".<" ".>=" ".≥" ".<=" ".≤" ".==" ".!=" ".≠" ".=" ".!" "<:" ">:" 
"∈"
+             "∉" "∋" "∌" "⊆" "⊈" "⊂" "⊄" "⊊" "∝" "∊" "∍" "∥" "∦" "∷" "∺" "∻" 
"∽"
+             "∾" "≁" "≃" "≄" "≅" "≆" "≇" "≈" "≉" "≊" "≋" "≌" "≍" "≎" "≐" "≑" 
"≒"
+             "≓" "≔" "≕" "≖" "≗" "≘" "≙" "≚" "≛" "≜" "≝" "≞" "≟" "≣" "≦" "≧" 
"≨"
+             "≩" "≪" "≫" "≬" "≭" "≮" "≯" "≰" "≱" "≲" "≳" "≴" "≵" "≶" "≷" "≸" 
"≹"
+             "≺" "≻" "≼" "≽" "≾" "≿" "⊀" "⊁" "⊃" "⊅" "⊇" "⊉" "⊋" "⊏" "⊐" "⊑" 
"⊒"
+             "⊜" "⊩" "⊬" "⊮" "⊰" "⊱" "⊲" "⊳" "⊴" "⊵" "⊶" "⊷" "⋍" "⋐" "⋑" "⋕" 
"⋖"
+             "⋗" "⋘" "⋙" "⋚" "⋛" "⋜" "⋝" "⋞" "⋟" "⋠" "⋡" "⋢" "⋣" "⋤" "⋥" "⋦" 
"⋧"
+             "⋨" "⋩" "⋪" "⋫" "⋬" "⋭" "⋲" "⋳" "⋴" "⋵" "⋶" "⋷" "⋸" "⋹" "⋺" "⋻" 
"⋼"
+             "⋽" "⋾" "⋿" "⟈" "⟉" "⟒" "⦷" "⧀" "⧁" "⧡" "⧣" "⧤" "⧥" "⩦" "⩧" "⩪" 
"⩫"
+             "⩬" "⩭" "⩮" "⩯" "⩰" "⩱" "⩲" "⩳" "⩴" "⩵" "⩶" "⩷" "⩸" "⩹" "⩺" "⩻" 
"⩼"
+             "⩽" "⩾" "⩿" "⪀" "⪁" "⪂" "⪃" "⪄" "⪅" "⪆" "⪇" "⪈" "⪉" "⪊" "⪋" "⪌" 
"⪍"
+             "⪎" "⪏" "⪐" "⪑" "⪒" "⪓" "⪔" "⪕" "⪖" "⪗" "⪘" "⪙" "⪚" "⪛" "⪜" "⪝" 
"⪞"
+             "⪟" "⪠" "⪡" "⪢" "⪣" "⪤" "⪥" "⪦" "⪧" "⪨" "⪩" "⪪" "⪫" "⪬" "⪭" "⪮" 
"⪯"
+             "⪰" "⪱" "⪲" "⪳" "⪴" "⪵" "⪶" "⪷" "⪸" "⪹" "⪺" "⪻" "⪼" "⪽" "⪾" "⪿" 
"⫀"
+             "⫁" "⫂" "⫃" "⫄" "⫅" "⫆" "⫇" "⫈" "⫉" "⫊" "⫋" "⫌" "⫍" "⫎" "⫏" "⫐" 
"⫑"
+             "⫒" "⫓" "⫔" "⫕" "⫖" "⫗" "⫘" "⫙" "⫷" "⫸" "⫹" "⫺" "⊢" "⊣"
+             ;; pipe, colon
+             "|>" "<|" ":" ".."
+             ;; plus
+             "+" "-" "⊕" "⊖" "⊞" "⊟" ".+" ".-" "++" "|" "∪" "∨" "$" "⊔" "±" "∓"
+             "∔" "∸" "≂" "≏" "⊎" "⊻" "⊽" "⋎" "⋓" "⧺" "⧻" "⨈" "⨢" "⨣" "⨤" "⨥" 
"⨦"
+             "⨧" "⨨" "⨩" "⨪" "⨫" "⨬" "⨭" "⨮" "⨹" "⨺" "⩁" "⩂" "⩅" "⩊" "⩌" "⩏" 
"⩐"
+             "⩒" "⩔" "⩖" "⩗" "⩛" "⩝" "⩡" "⩢" "⩣"
+             ;; bitshift
+             "<<" ">>" ">>>" ".<<" ".>>" ".>>>"
+             ;; times
+             "*" "/" "./" "÷" ".÷" "%" "⋅" "∘" "×" ".%" ".*" "\\"
+             ".\\" "&" "∩" "∧" "⊗" "⊘" "⊙" "⊚" "⊛" "⊠" "⊡" "⊓" "∗" "∙" "∤" "⅋"
+             "≀" "⊼" "⋄" "⋆" "⋇" "⋉" "⋊" "⋋" "⋌" "⋏" "⋒" "⟑" "⦸" "⦼" "⦾" "⦿" 
"⧶"
+             "⧷" "⨇" "⨰" "⨱" "⨲" "⨳" "⨴" "⨵" "⨶" "⨷" "⨸" "⨻" "⨼" "⨽" "⩀" "⩃" 
"⩄"
+             "⩋" "⩍" "⩎" "⩑" "⩓" "⩕" "⩘" "⩚" "⩜" "⩞" "⩟" "⩠" "⫛" "⊍" "▷" "⨝" 
"⟕"
+             "⟖" "⟗"
+             ;; rational
+             "//" ".//"
+             ;; power
+             "^" ".^" "↑" "↓" "⇵" "⟰" "⟱" "⤈" "⤉" "⤊" "⤋" "⤒" "⤓" "⥉" "⥌" "⥍"
+             "⥏" "⥑" "⥔" "⥕" "⥘" "⥙" "⥜" "⥝" "⥠" "⥡" "⥣" "⥥" "⥮" "⥯" "↑" "↓"
+             ;; decl, dot
+             "::" "."))
+          (regexp-opt '(" #" " \n" "#" "\n"))))
+
 (defconst julia-triple-quoted-string-regex
   ;; We deliberately put a group on the first and last delimiter, so
   ;; we can mark these as string delimiters for font-lock.
@@ -258,7 +323,11 @@ This function provides equivalent functionality, but makes 
no efforts to optimis
 
 (defconst julia-block-start-keywords
   (list "if" "while" "for" "begin" "try" "function" "type" "let" "macro"
-        "quote" "do" "immutable"))
+        "quote" "do" "immutable" "module"))
+
+;; For keywords that begin a block without additional indentation
+(defconst julia-block-start-keywords-no-indent
+  (list "module"))
 
 (defconst julia-block-end-keywords
   (list "end" "else" "elseif" "catch" "finally"))
@@ -426,6 +495,56 @@ with it. Returns nil if we're not within nested parens."
                  (current-column))
         nil))))
 
+(defun julia-prev-line-skip-blank-or-comment ()
+  "Move point to beginning of previous line skipping blank lines
+and lines including only comments. Returns number of lines moved.
+A return of -1 signals that we moved to the first line of
+the (possibly narrowed) buffer, so there is nowhere else to go."
+  (catch 'result
+    (let ((moved 0) this-move)
+      (while t
+        (setq this-move (forward-line -1))
+        (cond
+         ;; moved into comment or blank
+         ((and (= 0 this-move)
+               (or (looking-at-p "^\\s-*\\(?:#.*\\)*$")
+                   (julia-in-comment)))
+          (incf moved))
+         ;; success
+         ((= 0 this-move)
+          (throw 'result (1+ moved)))
+         ;; on first line and in comment
+         ((and (bobp)
+               (or (looking-at-p "^\\s-*\\(?:#.*\\)*$")
+                   (julia-in-comment)))
+          (throw 'result -1))
+         ((bobp)
+          (throw 'result moved))
+         (t
+          (throw 'result 0)))))))
+
+(defun julia-indent-hanging ()
+  "Calculate indentation for lines that follow \"hanging\"
+operators (operators that end the previous line) as defined in
+`julia-hanging-operator-regexp'. An assignment operator ending
+the previous line increases the indent as do the other operators
+unless another operator is found two lines up. Previous line
+means previous line after skipping blank lines and lines with
+only comments."
+  (let (prev-indent)
+    (save-excursion
+      (when (> (julia-prev-line-skip-blank-or-comment) 0)
+        (setq prev-indent (current-indentation))
+        (when (looking-at-p julia-hanging-operator-regexp)
+          (if (and (> (julia-prev-line-skip-blank-or-comment) 0)
+                   (looking-at-p julia-hanging-operator-regexp))
+              ;; two preceding hanging operators => indent same as line
+              ;; above
+              prev-indent
+            ;; one preceding hanging operator => increase indent from line
+            ;; above
+            (+ julia-indent-offset prev-indent)))))))
+
 (defun julia-indent-line ()
   "Indent current line of julia code."
   (interactive)
@@ -437,17 +556,8 @@ with it. Returns nil if we're not within nested parens."
       (save-excursion
         (beginning-of-line)
         (ignore-errors (julia-paren-indent)))
-      ;; If the previous line ends in =, increase the indent.
-      (ignore-errors ; if previous line is (point-min)
-        (save-excursion
-          (if (and (not (equal (point-min) (line-beginning-position)))
-                   (progn
-                     (forward-line -1)
-                     (end-of-line) (backward-char 1)
-                     (and (equal (char-after (point)) ?=)
-                          (not (julia-in-comment)))))
-              (+ julia-indent-offset (current-indentation))
-            nil)))
+      ;; indent due to hanging operators or a line ending in =
+      (julia-indent-hanging)
       ;; Indent according to how many nested blocks we are in.
       (save-excursion
         (beginning-of-line)
@@ -455,7 +565,9 @@ with it. Returns nil if we're not within nested parens."
         (let ((endtok (julia-at-keyword julia-block-end-keywords))
               (last-open-block (julia-last-open-block (- (point) 
julia-max-block-lookback))))
           (max 0 (+ (or last-open-block 0)
-                    (if endtok (- julia-indent-offset) 0)))))))
+                    (if (or endtok
+                            (julia-at-keyword 
julia-block-start-keywords-no-indent))
+                        (- julia-indent-offset) 0)))))))
     ;; Point is now at the beginning of indentation, restore it
     ;; to its original position (relative to indentation).
     (when (>= point-offset 0)



reply via email to

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