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

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

[nongnu] elpa/scala-mode f0cc3d4 006/217: working on indent rules


From: ELPA Syncer
Subject: [nongnu] elpa/scala-mode f0cc3d4 006/217: working on indent rules
Date: Sun, 29 Aug 2021 11:30:33 -0400 (EDT)

branch: elpa/scala-mode
commit f0cc3d409f866c3de6f7ffccb9b0d68487b4e1de
Author: Heikki Vesalainen <heikkivesalainen@yahoo.com>
Commit: Heikki Vesalainen <heikkivesalainen@yahoo.com>

    working on indent rules
---
 Example.scala        |  31 +++++------
 scala-mode-indent.el | 141 +++++++++++++++++++++++++++++++++++++++++++--------
 scala-mode-map.el    |   1 -
 scala-mode-syntax.el |  14 +++--
 scala-mode.el        |  23 +++++----
 5 files changed, 159 insertions(+), 51 deletions(-)

diff --git a/Example.scala b/Example.scala
index fb315c0..c1aa32a 100644
--- a/Example.scala
+++ b/Example.scala
@@ -19,7 +19,7 @@ def f(s: String,
 /* */ val x = foo(
   zot, // indented relative to '/* */'
   someThing 
-     map (x => x.length) // indented relative to 'someThing'
+      map (x => x.length) // indented relative to 'someThing'
 )
 
 val x =
@@ -73,7 +73,7 @@ class Foo(
   // body here
 }
 
-trait Leijona( x: Int,
+trait Leijona( x: Int with Int,
                y: Int )
     extends Kissa // run-one line, acnhor is 'trait'
     with Harja // ditto
@@ -85,9 +85,10 @@ def someThingReallyLong(having: String, aLot: Int, 
ofParameters: Boolean):
 }
 
 List("foo", "bar") 
-    map ( s => // 'map' indented as run-on, 's =>' start lambda
-      s.length
-    )
+    map { s =>
+      s.length // 'map' indented as run-on, 's =>' start lambda
+          toString
+    }
 
 List("foo") map (
   s => // start lambda
@@ -115,8 +116,8 @@ class Foo( /* */
   k: String
 ) // at indent anchor column
 
-def f(   i: String, j: String,
-         k: String) // indented acording to previous
+def f( /* */ i: String, j: String with Bar,
+       k: String) // indented acording to previous
 
 val f = foo(kissa,
             kala)
@@ -245,22 +246,22 @@ While not couraged, should the opening curly bracket of a 
block be on a new line
   specified return value and one step from anchor otherwise.
 */
 
-class Foo 
-{
+class Foo {
   def foo
   {
-    println(zot)
+    zot
+        foo
   }
 
   def bar =
-    {
+  {
       zot
-    }
+  }
 
   val zot =
-    {
-      "hello"
-    }
+  {
+"hello"
+  }
 }
 
 /* 
diff --git a/scala-mode-indent.el b/scala-mode-indent.el
index 64492c0..6bce7cd 100644
--- a/scala-mode-indent.el
+++ b/scala-mode-indent.el
@@ -4,8 +4,16 @@
 
 (provide 'scala-mode-indent)
 
+(require 'scala-mode-syntax)
+(require 'scala-mode-lib)
+
+(defcustom scala-indent:step 2
+  "The number of spaces an indentation step should be. The actual
+indentation will be one or two steps depending on context."
+  :type 'integer
+  :group 'scala)
+
 (defun scala-indent:run-on-p (&optional point) 
-  (interactive)
   "Returns t if the current point (or point at 'point) is on a
 line that is a run-on from a previous line."
   (save-excursion
@@ -19,27 +27,34 @@ line that is a run-on from a previous line."
 ;    (defconst scala-syntax:mustNotTerminate-re
 ;      scala-syntax:reserved-symbols-unsafe-re
 
-(defun scala-indent:goto-run-on-beginning ()
+(defun scala-indent:goto-run-on-anchor (&optional point)
   "Moves back to the point whose column will be used as the
-anchor relative to which indenting is calculated. If this row is
-not a run on, does nothing."
-  (when (scala-indent:run-on-p)
+anchor relative to which indenting for currnet point (or point
+'point') is calculated. Returns the new point or nil if point is
+not on a run-on line."
+  (if (not (scala-indent:run-on-p point))
+      nil
+    (when point (goto-char point))
     (scala-syntax:beginning-of-code-line)
-    (let ((block-beg (or (nth 1 (syntax-ppss)) (point-min))))
+    (let ((block-beg (1+ (or (nth 1 (syntax-ppss)) (1- (point-min))))))
       (while (and (scala-indent:run-on-p)
                   (> (point) block-beg))
-        (if (scala-syntax:looking-back-token "\\s)" 1)
-            (backward-list)
-          (skip-syntax-backward "^)" (max block-beg (line-beginning-position 
0))))))
-    (unless (= (char-syntax (char-before)) ?\()         
-      (scala-syntax:beginning-of-code-line))))
+        ;; move back all parameter groups, if any
+        (scala-syntax:beginning-of-code-line)
+        (scala-syntax:skip-backward-ignorable)
+        (scala-syntax:backward-parameter-groups)))
+    (back-to-indentation)
+;;;      (when (< (point) block-beg)
+;;;          (goto-char block-beg)))
+    (point)))
 
 (defun scala-indent:list-element-line-p (&optional point)
-  "Returns t if the current point is in a list. A list is
-something that begins with '(' or '[', or 'for {'. A list element
-is preceded by ,"
+  "Returns t if the current point (or point 'point') is in a
+list. A list is something that begins with '(' or '[', or 'for
+{'. A list element is preceded by ,"
   (save-excursion
     ;; first check that the previous line ended with ','
+    (when point (goto-char point))
     (beginning-of-line)
     (let ((list-beg (nth 1 (syntax-ppss))))
       (if (not (and (scala-syntax:looking-back-token "," 1)
@@ -52,12 +67,13 @@ is preceded by ,"
             (and (= (char-after list-beg) ?\{)
                  (scala-syntax:looking-back-token "for")))))))
 
-(defun scala-indent:goto-list-beginning ()
+(defun scala-indent:goto-list-anchor (&optional point)
   "Moves back to the point whose column will be used to indent
-lists rows. If this row is not a list element, does nothing"
-  (interactive)
-  (when (scala-indent:list-element-line-p)
-    (goto-char (1+ (nth 1 (syntax-ppss))))
+list rows at current point (or point 'point'). Returns the new
+point or nil if the point is not in a list element > 1."
+  (if (not (scala-indent:list-element-line-p point))
+      nil
+    (goto-char (1+ (nth 1 (syntax-ppss point))))
     (let ((block-beg (point)))
       (forward-comment (buffer-size))
       (if (= (line-number-at-pos (point))
@@ -66,5 +82,90 @@ lists rows. If this row is not a list element, does nothing"
           (progn (goto-char block-beg)
                  (skip-syntax-forward " "))
         ;; on different line
-        (back-to-indentation)))))
+        (back-to-indentation))
+      (point))))
+
+(defun scala-indent:body-p (&optional point)
+  "Return t if current point (or point 'point) is on a line
+that follows = or => (or it's unicode equivalent)"
+  (save-excursion
+    (when point (goto-char point))
+    (beginning-of-line)
+    (scala-syntax:looking-back-token scala-syntax:body-start-re 2)))
+
+(defun scala-indent:goto-body-anchor (&optional point)
+  (if (not (scala-indent:body-p point))
+      nil
+    (when point (goto-char point))
+    (beginning-of-line)
+    (goto-char (or (nth 1 (syntax-ppss point)) (point-min)))
+    (beginning-of-line)
+    (point)))
+
+(defun scala-indent:goto-block-anchor (&optional point)
+  "Moves back to the point whose column will be used as the
+anchor for calculating block indent for current point (or point
+'point'). Returns point or nil, if not inside a block."
+  (let ((block-beg (nth 1 (syntax-ppss point))))
+    (if (not block-beg)
+        nil
+      (scala-indent:goto-run-on-anchor block-beg))))
+
+(defun scala-indent:parentheses-line-p (&optional point)
+  ""
+  (save-excursion
+    (when point (goto-char point))    
+    (scala-syntax:beginning-of-code-line)
+    (= (char-syntax (char-after)) ?\()))
+
+(defun scala-indent:parentheses-anchor (&optional point)
+  "Moves back to the point whose column will be used as the
+anchor for calculating opening parenthesis indent for the current
+point (or point 'point'). Returns point or nil, if line does not
+start with opening parenthesis."
+  (if (not (scala-indent:parentheses-line-p point))
+      nil
+    (scala-indent:goto-run-on-anchor point)))
+
+(defun scala-indent:apply-indent-rules (rule-indents &optional point)
+  "Evaluates each rule, until one returns non-nil value. Returns
+the sum of the value and the respective indent step, or nil if
+nothing was applied."
+  (if (not rule-indents)
+      nil
+    (save-excursion
+      (let* ((rule-indent (car rule-indents))
+             (rule (car rule-indent))
+             (indent (cadr rule-indent))
+             (anchor (funcall rule point)))
+        (if anchor
+            (+ (current-column) (eval indent))
+          (scala-indent:apply-indent-rules (cdr rule-indents)))))))
+
+(defun scala-indent:calculate-indent-for-line (&optional point)
+  "Calculate the appropriate indent for the current point or the
+point 'point'"
+  (or (scala-indent:apply-indent-rules
+       `((scala-indent:parentheses-anchor 0)
+         (scala-indent:goto-run-on-anchor (* 2 scala-indent:step))
+         (scala-indent:goto-list-anchor 0)
+         (scala-indent:goto-body-anchor scala-indent:step)
+         (scala-indent:goto-block-anchor scala-indent:step))
+       point)
+      0))
+
+(defun scala-indent:indent-line-to (column)
+  "Indent the line to column and move cursor to the indent
+column, if it was at the left margin."
+  (if (<= (current-column) (current-indentation))
+      (indent-line-to column)
+    (save-excursion (indent-line-to column))))
     
+(defun scala-indent:indent-line ()
+  "Indents the current line."
+  (interactive)
+  ;; TODO: do nothing if inside string or comment
+  (let ((indent (scala-indent:calculate-indent-for-line)))
+    (when indent
+      (scala-indent:indent-line-to indent))))
+  
diff --git a/scala-mode-map.el b/scala-mode-map.el
index 1c620af..9ad1758 100644
--- a/scala-mode-map.el
+++ b/scala-mode-map.el
@@ -18,7 +18,6 @@
     (scala-mode-map:define-keys 
      keymap
      (([backspace]                'backward-delete-char-untabify)
-      ([(control c)(control r)]   'scala-indent:goto-list-beginning) ; TODO 
remove
       ;;       ("\r"                       'scala-newline)
       ([(control c)(control c)]   'comment-region)
       ;;       ("}"                        'scala-electric-brace)
diff --git a/scala-mode-syntax.el b/scala-mode-syntax.el
index 6c77a7e..e04f9df 100644
--- a/scala-mode-syntax.el
+++ b/scala-mode-syntax.el
@@ -216,8 +216,8 @@ and the empty line")
 expression, i.e they cannot be run-on to the previous line even
 if there is no semi in between.")
 
-(defconst scala-syntax:double-arrow-re 
-  "=>\\|\u21D2")
+(defconst scala-syntax:body-start-re 
+  "=>?\\|\u21D2")
 
 (defconst scala-syntax:multiLineStringLiteral-start-re
   "\\(\"\\)\"\"")
@@ -274,10 +274,10 @@ if there is no semi in between.")
     ;; by default all opchars are punctuation, but they will be
     ;; modified by syntax-propertize-function to be symbol
     ;; constituents when a part of varid or capitalid
-    (dolist (char (mapcar 'identity "#%:<=>@!&*+-/?\\^|~\u21D2\u2190")) ;; 
TODO: Sm, So
+    (dolist (char (mapcar 'identity "!#%&*+/:<=>?@^|~-\u21D2\u2190")) ;; TODO: 
Sm, So
       (modify-syntax-entry char "." syntab))
 
-    ;; what can I say? It's the escape char.
+    ;; for clarity, the \ is alone here and not in the string above
     (modify-syntax-entry ?\\ "." syntab)
   
     ;; scala strings cannot span lines, so we mark
@@ -413,6 +413,7 @@ symbol constituents (syntax 3)"
 the line, if the line is empty"
   (let ((eol (line-end-position)))
     (beginning-of-line)
+    ;; TODO: check if we are inside a comment and come out of it
     (forward-comment (buffer-size))
     (if (> (point) eol)
         eol
@@ -453,3 +454,8 @@ empty line. Expects to be outside of comment."
       (if (= (point) end)
           nil
         (if (looking-at re) (point) nil)))))
+
+(defun scala-syntax:backward-parameter-groups ()
+  "Move back over all parameter groups to the start of the first one."
+  (while (scala-syntax:looking-back-token "\\s)" 1)
+    (backward-list)))
diff --git a/scala-mode.el b/scala-mode.el
index 5038b7b..2dc9b18 100644
--- a/scala-mode.el
+++ b/scala-mode.el
@@ -18,10 +18,9 @@
    (format "The Scala mode has been tested only on Emacs version 23.x (and not 
your Emacs version %s.%s)"  
            emacs-major-version  emacs-minor-version)))
 
-;; Attach .scala files to the scala-mode
-(add-to-list 'auto-mode-alist '("\\.scala\\'" . scala-mode))
-(modify-coding-system-alist 'file "\\.scala\\'" 'utf-8)
-
+(defgroup scala nil
+  "A programming mode for the Scala language 2.9"
+  :group 'languages)
 
 (defmacro scala-mode:make-local-variables (&rest quoted-names)
   (cons 'progn (mapcar #'(lambda (quoted-name) `(make-local-variable 
,quoted-name)) quoted-names)))
@@ -62,7 +61,9 @@ When started, runs `scala-mode-hook'.
    'comment-end
    'comment-start-skip
    'comment-column
-   'comment-multi-line)
+   'comment-multi-line
+   'indent-line-function
+   'indent-tabs-mode)
 
   (add-hook 'syntax-propertize-extend-region-functions
             'scala-syntax:propertize-extend-region)
@@ -84,14 +85,14 @@ When started, runs `scala-mode-hook'.
         comment-column                  0
         comment-multi-line              t
         ;; TODO: comment-indent-function
+
+        indent-line-function            'scala-indent:indent-line
+        indent-tabs-mode                nil
         )
   (use-local-map scala-mode-map)
   (turn-on-font-lock)
 )
 
-        
-        
-
-        
-        
-  
+;; Attach .scala files to the scala-mode
+(add-to-list 'auto-mode-alist '("\\.scala\\'" . scala-mode))
+(modify-coding-system-alist 'file "\\.scala\\'" 'utf-8)



reply via email to

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