changed indentation code and tests

- more changes to plantuml-indent-regexs
- added more test
- changed function to determine indentation level and tests accordingly
- changed plantuml-indent-line and tests accordingly
- changed test names and doc strings to be more consistent
This commit is contained in:
René Schmelzer 2018-12-30 15:38:24 +01:00
parent e97b7a3d64
commit 6be2e82857
2 changed files with 270 additions and 81 deletions

View File

@ -343,8 +343,8 @@ Uses prefix (as PREFIX) to choose where to display it:
(defvar plantuml-keywords-regexp (concat "^\\s *" (regexp-opt plantuml-keywords 'words) "\\|\\(<\\|<|\\|\\*\\|o\\)\\(\\.+\\|-+\\)\\|\\(\\.+\\|-+\\)\\(>\\||>\\|\\*\\|o\\)\\|\\.\\{2,\\}\\|-\\{2,\\}")) (defvar plantuml-keywords-regexp (concat "^\\s *" (regexp-opt plantuml-keywords 'words) "\\|\\(<\\|<|\\|\\*\\|o\\)\\(\\.+\\|-+\\)\\|\\(\\.+\\|-+\\)\\(>\\||>\\|\\*\\|o\\)\\|\\.\\{2,\\}\\|-\\{2,\\}"))
(defvar plantuml-builtins-regexp (regexp-opt plantuml-builtins 'words)) (defvar plantuml-builtins-regexp (regexp-opt plantuml-builtins 'words))
(defvar plantuml-preprocessors-regexp (concat "^\\s *" (regexp-opt plantuml-preprocessors 'words))) (defvar plantuml-preprocessors-regexp (concat "^\\s *" (regexp-opt plantuml-preprocessors 'words)))
(defvar plantuml-indent-regexp-start "^[ \t]*\\(\\(?:.*\\)?\s*\\(?:[<>.*a-z-|]+\\)?\s*\\(?:\\[[a-zA-Z]+\\]\\)?\s+if\s+.*\\|loop\s+.*\\|group\s+.*\\|par\s+\\|opt\s+.*\\|alt\s+.*\\|else\\|note\s+over\\|note\sas\s.*\\|note\s+\\(\\(?:\\(?:buttom\\|left\\|right\\|top\\)\\)\\)\\(?:\s+of\\)?\\|\\(?:class\\|enum\\|package\\)\s+.*{\\|activate\s+.*\\)") (defvar plantuml-indent-regexp-start "^[ \t]*\\(\\(?:.*\\)?\s*\\(?:[<>.*a-z-|]+\\)?\s*\\(?:\\[[a-zA-Z]+\\]\\)?\s+if\s+.*\\|loop\s+.*\\|group\s+.*\\|par\s+\\|opt\s+.*\\|alt\s+.*\\|else\\|note\s+over\\|note\sas\s.*\\|note\s+\\(\\(?:\\(?:buttom\\|left\\|right\\|top\\)\\)\\)\\(?:\s+of\\)?\\|\\(?:class\\|enum\\|package\\)\s+.*{\\|activate\s+.+\\)")
(defvar plantuml-indent-regexp-end "^[ \t]*\\(endif\\|else\\|end\\|end\s+note\\|.*}\\|deactivate\s+.*\\)") (defvar plantuml-indent-regexp-end "^[ \t]*\\(endif\\|else\\|end\\|end\s+note\\|.*}\\|deactivate\s+.+\\)")
(setq plantuml-font-lock-keywords (setq plantuml-font-lock-keywords
`( `(
@ -405,40 +405,39 @@ Uses prefix (as PREFIX) to choose where to display it:
(defvar plantuml-indent-regexp-start) (defvar plantuml-indent-regexp-start)
(defvar plantuml-indent-regexp-end) (defvar plantuml-indent-regexp-end)
(save-excursion (save-excursion
(let ((relative-depth 0) (let ((relative-depth 0))
(bob-visited? nil)) ;; current line
(beginning-of-line) (beginning-of-line)
(forward-line -1) (if (looking-at plantuml-indent-regexp-end)
(while (not bob-visited?) (setq relative-depth (1- relative-depth)))
(if (bobp)
(setq bob-visited? t)) ;; from current line backwards to beginning of buffer
(while (not (bobp))
(forward-line -1)
(if (looking-at plantuml-indent-regexp-end) (if (looking-at plantuml-indent-regexp-end)
(setq relative-depth (1- relative-depth))) (setq relative-depth (1- relative-depth)))
(if (looking-at plantuml-indent-regexp-start) (if (looking-at plantuml-indent-regexp-start)
(setq relative-depth (1+ relative-depth))) (setq relative-depth (1+ relative-depth))))
(forward-line -1))
(if (<= relative-depth 0) (if (<= relative-depth 0)
0 0
relative-depth)))) relative-depth))))
(defun plantuml-indent-line () (defun plantuml-indent-line ()
"Indent the current line to its desired indentation level." "Indent the current line to its desired indentation level.
Restore point to same position in text of the line as before indentation."
(interactive) (interactive)
;; forward declare the lazy initialized constants ;; forward declare the lazy initialized constants
(defvar plantuml-indent-regexp-start) (defvar plantuml-indent-regexp-start)
(defvar plantuml-indent-regexp-end) (defvar plantuml-indent-regexp-end)
(let ((original-indentation (current-indentation))) ;; store position of point in line measured from end of line
(let ((original-position-eol (- (line-end-position) (point))))
(save-excursion (save-excursion
(beginning-of-line) (beginning-of-line)
(if (bobp) (indent-line-to (* tab-width (plantuml-current-block-depth))))
(indent-line-to 0)
(let ((depth (plantuml-current-block-depth))) ;; restore position in text of line
(when (looking-at plantuml-indent-regexp-end) (goto-char (- (line-end-position) original-position-eol))))
(setq depth (max (1- depth) 0)))
(indent-line-to (* tab-width depth)))))
(forward-char (- (current-indentation)
original-indentation))))
;;;###autoload ;;;###autoload

View File

@ -1,4 +1,4 @@
;;; plantuml-mode-indentation-test.el --- PlantUML Mode indentation tests -*- lexical-binding: t; -*- ;;; plantuml-indentation-test.el --- PlantUML Mode indentation tests -*- lexical-binding: t; -*-
;; Author: Raymond Huang (rymndhng) ;; Author: Raymond Huang (rymndhng)
;; Maintainer: Carlo Sciolla (skuro) ;; Maintainer: Carlo Sciolla (skuro)
@ -10,47 +10,142 @@
;;; Code: ;;; Code:
(defun add-text-and-position-cursor (txt) (defun plantuml-test-add-text-and-position-cursor (txt)
"Add TXT into the buffer, move cursor to the position of the marker | and delete the marker." "Test helper for `plantuml-mode' tests.
Add TXT into the buffer, move cursor to the position of the marker
?| and delete the marker."
(insert txt) (insert txt)
(goto-char (point-min)) (goto-char (point-min))
(search-forward "|") (search-forward "|")
(delete-char -1)) (delete-char -1))
(defun assert-block-depth (expected txt) (defun plantuml-test-assert-block-depth (expected txt)
"Assert the EXPECTED indentation level for the given TXT." "Test helper for `plantuml-mode' tests.
Assert the EXPECTED indentation level for the given TXT."
(with-temp-buffer (with-temp-buffer
(add-text-and-position-cursor txt) (plantuml-test-add-text-and-position-cursor txt)
(let ((actual (plantuml-current-block-depth))) (let ((actual (plantuml-current-block-depth)))
(should (equal expected actual))))) (should (equal expected actual)))))
(ert-deftest test-plantuml-current-block-depth () (ert-deftest plantuml-test-current-block-depth_bob ()
"Test `plantuml-current-block-depth' level 0 at beginning of buffer."
(setq-local plantuml-jar-path plantuml-test-jar-path) (setq-local plantuml-jar-path plantuml-test-jar-path)
(plantuml-init-once) (plantuml-init-once)
(assert-block-depth 0 " (plantuml-test-assert-block-depth 0 "|
A |-> B") activate p1
activate p2
foo
deactivate p2
deactivate p1
")
)
(assert-block-depth 0 " (ert-deftest plantuml-test-current-block-depth_0 ()
pac|kage Foo { "Test `plantuml-current-block-depth' level 0 at beginning of first line."
A -> B (setq-local plantuml-jar-path plantuml-test-jar-path)
}") (plantuml-init-once)
(assert-block-depth 1 " (plantuml-test-assert-block-depth 0 "
package APackage { |activate p1
|A -> B activate p2
}") foo
deactivate p2
deactivate p1
")
)
(ert-deftest plantuml-test-current-block-depth_1 ()
"Test `plantuml-current-block-depth' level 0 at middle of first line."
(setq-local plantuml-jar-path plantuml-test-jar-path)
(plantuml-init-once)
(assert-block-depth 1 " (plantuml-test-assert-block-depth 0 "
alt choice 1 acti|vate p1
|A -> B activate p2
end foo
")) deactivate p2
deactivate p1
")
)
(ert-deftest plantuml-test-current-block-depth_2 ()
"Test `plantuml-current-block-depth' level 0 at end of first line"
(setq-local plantuml-jar-path plantuml-test-jar-path)
(plantuml-init-once)
(plantuml-test-assert-block-depth 0 "
activate p1|
activate p2
foo
deactivate p2
deactivate p1
")
)
(ert-deftest plantuml-test-current-block-depth_3 ()
"Test `plantuml-current-block-depth' level 1 at beginning of 2nd line."
(plantuml-test-assert-block-depth 1 "
activate p1
|activate p2
foo
deactivate p2
deactivate p1
")
)
(ert-deftest plantuml-test-current-block-depth_4 ()
"Test `plantuml-current-block-depth' level 2 at beginning of 3rd line."
(plantuml-test-assert-block-depth 2 "
activate p1
activate p2
|foo
deactivate p2
deactivate p1
")
)
(ert-deftest plantuml-test-current-block-depth_5 ()
"Test `plantuml-current-block-depth' level 1 at beginning of 4th line."
(plantuml-test-assert-block-depth 1 "
activate p1
activate p2
foo
|deactivate p2
deactivate p1
")
)
(ert-deftest plantuml-test-current-block-depth_6 ()
"Test `plantuml-current-block-depth' level 0 at beginning of 5th line."
(plantuml-test-assert-block-depth 0 "
activate p1
activate p2
foo
deactivate p2
|deactivate p1
")
)
(ert-deftest plantuml-test-current-block-depth_eob ()
"Test `plantuml-current-block-depth' level 0 at end of buffer."
(plantuml-test-assert-block-depth 0 "
activate p1
activate p2
foo
deactivate p2
deactivate p1
|")
)
;; This is taken from https://github.com/clojure-emacs/clojure-mode/blob/master/test/clojure-mode-indentation-test.el ;; This is taken from https://github.com/clojure-emacs/clojure-mode/blob/master/test/clojure-mode-indentation-test.el
(defmacro check-indentation (description before after &optional var-bindings) (defmacro plantuml-test-line-indentation (description before after &optional var-bindings)
"Declare an ert test for indentation behaviour. "Declare an ert test for line indentation behaviour.
The test will check that the swift indentation command changes the buffer The test will check that the swift indentation command changes the buffer
from one state to another. It will also test that point is moved to an from one state to another. It will also test that point is moved to an
expected position. expected position.
@ -61,8 +156,9 @@ AFTER is the expected buffer string after indenting, where a pipe (|)
represents the expected position of point. represents the expected position of point.
VAR-BINDINGS is an optional let-bindings list. It can be used to set the VAR-BINDINGS is an optional let-bindings list. It can be used to set the
values of customisable variables." values of customisable variables."
(declare (indent 1)) (declare (indent 1))
(let ((fname (intern (format "indentation/%s" description)))) (let ((fname (intern (format "plantuml-test-line-indentation/%s" description))))
`(ert-deftest ,fname () `(ert-deftest ,fname ()
(let* ((after ,after) (let* ((after ,after)
(expected-cursor-pos (1+ (s-index-of "|" after))) (expected-cursor-pos (1+ (s-index-of "|" after)))
@ -74,7 +170,7 @@ values of customisable variables."
(setq-local plantuml-jar-path plantuml-test-jar-path) (setq-local plantuml-jar-path plantuml-test-jar-path)
(plantuml-init-once) (plantuml-init-once)
(add-text-and-position-cursor ,before) (plantuml-test-add-text-and-position-cursor ,before)
(plantuml-mode) (plantuml-mode)
;; use 2 spaces instead of one tab for indentation ;; use 2 spaces instead of one tab for indentation
@ -85,19 +181,19 @@ values of customisable variables."
(should (equal expected-state (buffer-string))) (should (equal expected-state (buffer-string)))
(should (equal expected-cursor-pos (point)))))))) (should (equal expected-cursor-pos (point))))))))
(check-indentation toplevel-relationship (plantuml-test-line-indentation toplevel-relationship
"|Nobody -> [APIGateway]" "|Nobody -> [APIGateway]"
"|Nobody -> [APIGateway]") "|Nobody -> [APIGateway]")
(check-indentation package-block (plantuml-test-line-indentation package-block
"package APackage { "package APackage {
|A -> B |A -> B
}" }"
"package APackage { "package APackage {
|A -> B |A -> B
}") }")
(check-indentation nested-package (plantuml-test-line-indentation nested-package
"package APackage { "package APackage {
|package AnotherPackage { |package AnotherPackage {
} }
@ -107,11 +203,11 @@ values of customisable variables."
} }
}") }")
(check-indentation empty-package (plantuml-test-line-indentation empty-package
"|package Foo {}" "|package Foo {}"
"|package Foo {}") "|package Foo {}")
(check-indentation relative-indent (plantuml-test-line-indentation relative-indent
"package APackage { "package APackage {
database Foo database Foo
|A --> B |A --> B
@ -124,7 +220,7 @@ database Foo
}" }"
) )
(check-indentation note-as (plantuml-test-line-indentation note-as
"note as N1 "note as N1
|This is a note |This is a note
end note" end note"
@ -133,7 +229,7 @@ end note"
end note" end note"
) )
(check-indentation note-of (plantuml-test-line-indentation note-of
"note right of Foo "note right of Foo
|This is a note |This is a note
end note" end note"
@ -142,75 +238,169 @@ end note"
end note" end note"
) )
(check-indentation alt (plantuml-test-line-indentation alt
"alt choice 1 "alt choice 1
|A -> B |A -> B
end end
" "
"alt choice 1 "alt choice 1
|A -> B |A -> B
end end
") ")
(check-indentation alt-end (plantuml-test-line-indentation alt-end
"alt choice 1 "alt choice 1
A -> B A -> B
|end |end
" "
"alt choice 1 "alt choice 1
A -> B A -> B
|end |end
") ")
(check-indentation alt-else (plantuml-test-line-indentation alt-else
"alt choice 1 "alt choice 1
|else |else
end end
" "
"alt choice 1 "alt choice 1
|else |else
end end
") ")
(check-indentation alt-else-body (plantuml-test-line-indentation alt-else-body
"alt choice 1 "alt choice 1
else else
|A -> B |A -> B
end end
" "
"alt choice 1 "alt choice 1
else else
|A -> B |A -> B
end end
") ")
(check-indentation alt-else-end (plantuml-test-line-indentation alt-else-end
"alt choice 1 "alt choice 1
else else
|end |end
" "
"alt choice 1 "alt choice 1
else else
|end |end
") ")
(check-indentation opt (plantuml-test-line-indentation opt-body
"opt have fun "opt have fun
|some text |some text
end" end"
"opt have fun "opt have fun
|some text |some text
end") end")
(check-indentation activate-deactivate (plantuml-test-line-indentation opt-end
"activate participant_1 "opt have fun
|participant_1 -> participant_2 : f() some text
deactivate participant_1" |end"
"activate participant_1 "opt have fun
|participant_1 -> participant_2 : f() some text
deactivate participant_1") |end")
(plantuml-test-line-indentation activate-activate
"
|activate participant_1
"
"
|activate participant_1
")
(plantuml-test-line-indentation activate-body
"
activate participant_1
|participant_1 -> participant_2 : f()
"
"
activate participant_1
|participant_1 -> participant_2 : f()
")
(plantuml-test-line-indentation activate-deactivate
"
activate participant_1
participant_1 -> participant_2 : f()
|deactivate participant_1"
"
activate participant_1
participant_1 -> participant_2 : f()
|deactivate participant_1")
(plantuml-test-line-indentation activate-deactivate-2
"
activate participant_1
participant_1 -> participant_2 : f()
|deactivate participant_1"
"
activate participant_1
participant_1 -> participant_2 : f()
|deactivate participant_1")
(plantuml-test-line-indentation activate-deactivate-3
"
activate participant_1
participant_1 -> participant_2 : f()
deactivate| participant_1"
"
activate participant_1
participant_1 -> participant_2 : f()
deactivate| participant_1")
(defun plantuml-test-indent-block (textblock)
"Test helper for `plantuml-mode' indentation tests.
TEXTBLOCK will be inserted into a new temporary plantuml buffer. The
whole text will be indented according to the mode. Then, the buffer
contents is returned as a string."
(with-temp-buffer
;; fix the JAR location prior to mode initialization
;; for some reason, plantuml-mode disregards the setq-local
(setq-local plantuml-jar-path plantuml-test-jar-path)
(plantuml-init-once)
(insert textblock)
(goto-char (point-min))
(plantuml-mode)
;; use 2 spaces instead of one tab for indentation
(setq-local indent-tabs-mode nil)
(setq-local tab-width 2)
(indent-region (point-min) (point-max))
(buffer-string)
))
(ert-deftest plantuml-test-block-indentation/activate-deactivate-unindented ()
"test"
(should (equal (plantuml-test-indent-block "
activate participant_1
participant_1 -> participant_2 : f()
deactivate participant_1")
"
activate participant_1
participant_1 -> participant_2 : f()
deactivate participant_1")))
(ert-deftest plantuml-test-block-indentation/activate-deactivate-malformed-indent ()
"test"
(should (equal (plantuml-test-indent-block "
activate participant_1
participant_1 -> participant_2 : f()
deactivate participant_1")
"
activate participant_1
participant_1 -> participant_2 : f()
deactivate participant_1")))
(provide 'plantuml-indentation-test) (provide 'plantuml-indentation-test)
;;; plantuml-mode-preview-test.el ends here ;;; plantuml-indentation-test.el ends here