Skip to content

Commit

Permalink
Implement indentation
Browse files Browse the repository at this point in the history
  • Loading branch information
MoisMoshev committed Jun 8, 2024
1 parent cbe7b16 commit 80851ac
Showing 1 changed file with 153 additions and 5 deletions.
158 changes: 153 additions & 5 deletions d2-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -122,14 +122,161 @@
(org-babel-eval cmd "")
nil))

(defun d2--locate-declaration (str)
(defun d2--locate-declaration (str tag)
"Locate a certain declaration and return the line difference and indentation.
STR is the declaration."
STR is the declaration.
TAG is a symbol, which is prepended to the declaration data."
(let ((l (line-number-at-pos)))
(save-excursion
(if (re-search-backward str (point-min) t)
(cons (- l (line-number-at-pos)) (current-indentation))
(cons -1 -1)))))
(cons tag (cons (- l (line-number-at-pos)) (current-indentation)))
(cons tag (cons -1 -1))))))

(defun d2--combine-tokens-by-level (tokens)
"Combine TOKENS that are at the same level.
Collect the tags from both into a list.
Use the newer token's line and column."
(reverse
(cl-reduce (lambda (acc el)
(if (and (not (null acc))
(equal (d2--decl-line (car acc))
(d2--decl-line el)))
;; when tokens are on the same line, combine them
(progn
(setf (car acc)
;; we don't care about duplicate tags
(cons (cons (d2--decl-tag el) (d2--decl-tag (car acc)))
(cons (d2--decl-line el)
(d2--decl-column el))))
acc)
;; otherwise add a new token; set its tag to be a list
(cons (cons (list (d2--decl-tag el))
(cons (d2--decl-line el)
(d2--decl-column el)))
acc)))
tokens
:initial-value ())))

(defun d2--sort-tokens-by-line (tokens)
"Sort TOKENS by line number."
(sort tokens

Check failure on line 162 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 27.2)

sort called with 3 arguments, but accepts only 2

Check failure on line 162 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 28.2)

sort called with 3 arguments, but accepts only 2

Check failure on line 162 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (windows-latest, snapshot)

`sort' called with 3 arguments, but accepts only 2

Check failure on line 162 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (macos-latest, 28.2)

sort called with 3 arguments, but accepts only 2

Check failure on line 162 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (windows-latest, 26.3)

sort called with 3 arguments, but accepts only 2
:key (lambda (token)
(d2--decl-line token))))

(defun d2--filter-not-found-tokens (tokens)
"Filter TOKENS that were not detected.
They have a line number of -1"
(cl-remove-if
(lambda (token) (< (d2--decl-line token) 0))
tokens))

(defun d2--parse-from-line ()
"Parse by starting at current line and searching backward."
(let ((node (d2--locate-declaration
(rx (group (one-or-more (any alnum "_")))
(? (group ":"
(one-or-more space)))
(? (group
(one-or-more (not (any ?{ ?}))))))
'node))
(subnode-start (d2--locate-declaration
(rx (group (one-or-more (any alnum "_" "<->"
"->" "--" "<-"))
(? (group ":" (one-or-more space)))
(? (group (one-or-more (not (any ?{ ?})))))
"{"
))

Check failure on line 188 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, snapshot)

Closing parens should not be wrapped onto new lines.

Check failure on line 188 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 27.2)

Closing parens should not be wrapped onto new lines.

Check failure on line 188 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 28.2)

Closing parens should not be wrapped onto new lines.

Check failure on line 188 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (windows-latest, snapshot)

Closing parens should not be wrapped onto new lines.

Check failure on line 188 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (macos-latest, 28.2)

Closing parens should not be wrapped onto new lines.

Check failure on line 188 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (macos-latest, snapshot)

Closing parens should not be wrapped onto new lines.

Check failure on line 188 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (windows-latest, 26.3)

Closing parens should not be wrapped onto new lines.
'subnode))
(end (d2--locate-declaration "^ *} *$"
'end))
(connection (d2--locate-declaration
(rx (group (one-or-more (any alnum "_" "-"))
(any "->"
"<->"
"--"
"<-")
(? (seq
":"
(one-or-more space)))
(? (one-or-more graph))))
'connection)))
(list node subnode-start end connection)))

;;; declaration part handling
(defun d2--decl-tag (decl) (car decl))

Check failure on line 206 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, snapshot)

All variables and subroutines might as well have a documentation string

Check failure on line 206 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 27.2)

All variables and subroutines might as well have a documentation string

Check failure on line 206 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 28.2)

All variables and subroutines might as well have a documentation string

Check failure on line 206 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (windows-latest, snapshot)

All variables and subroutines might as well have a documentation string

Check failure on line 206 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (macos-latest, 28.2)

All variables and subroutines might as well have a documentation string

Check failure on line 206 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (macos-latest, snapshot)

All variables and subroutines might as well have a documentation string

Check failure on line 206 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (windows-latest, 26.3)

All variables and subroutines might as well have a documentation string
(defun d2--decl-line (decl) (cadr decl))

Check failure on line 207 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, snapshot)

All variables and subroutines might as well have a documentation string

Check failure on line 207 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 27.2)

All variables and subroutines might as well have a documentation string

Check failure on line 207 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 28.2)

All variables and subroutines might as well have a documentation string

Check failure on line 207 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (windows-latest, snapshot)

All variables and subroutines might as well have a documentation string

Check failure on line 207 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (macos-latest, 28.2)

All variables and subroutines might as well have a documentation string

Check failure on line 207 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (macos-latest, snapshot)

All variables and subroutines might as well have a documentation string

Check failure on line 207 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (windows-latest, 26.3)

All variables and subroutines might as well have a documentation string
(gv-define-setter d2--decl-line (val decl) `(setf (cadr ,decl) ,val))
(defun d2--decl-column (decl) (cddr decl))

Check failure on line 209 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, snapshot)

All variables and subroutines might as well have a documentation string

Check failure on line 209 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 27.2)

All variables and subroutines might as well have a documentation string

Check failure on line 209 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 28.2)

All variables and subroutines might as well have a documentation string

Check failure on line 209 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (windows-latest, snapshot)

All variables and subroutines might as well have a documentation string

Check failure on line 209 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (macos-latest, 28.2)

All variables and subroutines might as well have a documentation string

Check failure on line 209 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (macos-latest, snapshot)

All variables and subroutines might as well have a documentation string

Check failure on line 209 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (windows-latest, 26.3)

All variables and subroutines might as well have a documentation string
(defun d2--decl-tags-contain (decl tag)
(seq-find (lambda (tag2)

Check failure on line 211 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, snapshot)

All variables and subroutines might as well have a documentation string

Check failure on line 211 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 27.2)

All variables and subroutines might as well have a documentation string

Check failure on line 211 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 28.2)

All variables and subroutines might as well have a documentation string

Check failure on line 211 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (windows-latest, snapshot)

All variables and subroutines might as well have a documentation string

Check failure on line 211 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (macos-latest, 28.2)

All variables and subroutines might as well have a documentation string

Check failure on line 211 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (macos-latest, snapshot)

All variables and subroutines might as well have a documentation string

Check failure on line 211 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (windows-latest, 26.3)

All variables and subroutines might as well have a documentation string
(equal tag2 tag))
(d2--decl-tag decl)))

(defun d2--calculate-desired-indentation ()
(save-excursion

Check failure on line 216 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, snapshot)

All variables and subroutines might as well have a documentation string

Check failure on line 216 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 27.2)

All variables and subroutines might as well have a documentation string

Check failure on line 216 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 28.2)

All variables and subroutines might as well have a documentation string

Check failure on line 216 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (windows-latest, snapshot)

All variables and subroutines might as well have a documentation string

Check failure on line 216 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (macos-latest, 28.2)

All variables and subroutines might as well have a documentation string

Check failure on line 216 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (macos-latest, snapshot)

All variables and subroutines might as well have a documentation string

Check failure on line 216 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (windows-latest, 26.3)

All variables and subroutines might as well have a documentation string
(end-of-line)
;; sort tokens by line number (distance from current line)
;; and calculate the final indentation
(let* ((ordered-tokens (d2--combine-tokens-by-level
(d2--sort-tokens-by-line
(append (d2--filter-not-found-tokens (d2--parse-from-line))
;; also collect tokens starting at previous line
;; otherwise successive tokens of the same type
;; may not be detected
(if (equal (line-number-at-pos) 1)
()
(progn (forward-line -1)
(end-of-line)
(mapcar (lambda (token)
;; increment line number
;; to make it relative to starting line
(cl-incf (d2--decl-line token))
token)
(d2--filter-not-found-tokens
(d2--parse-from-line)))))))))
(current-token (car ordered-tokens))
(previous-token (cadr ordered-tokens)))
(message "tokens %s" ordered-tokens)
(cond ((and (d2--decl-tags-contain current-token 'node)
(null previous-token))
0)

((and (d2--decl-tags-contain current-token 'node)
(d2--decl-tags-contain previous-token 'subnode))
(+ 4 (d2--decl-column previous-token)))

((and (d2--decl-tags-contain current-token 'subnode)
(d2--decl-tags-contain previous-token 'subnode))
(+ 4 (d2--decl-column previous-token)))


((and (d2--decl-tags-contain current-token 'node)
(d2--decl-tags-contain previous-token 'node))
(d2--decl-column previous-token))

((and (d2--decl-tags-contain current-token 'node)
(d2--decl-tags-contain previous-token 'end))
(d2--decl-column previous-token))

((and (d2--decl-tags-contain current-token 'end)
(d2--decl-tags-contain previous-token 'end))
(max (- (d2--decl-column previous-token) 4) 0))

((and (d2--decl-tags-contain current-token 'end)
(d2--decl-tags-contain previous-token 'subnode))
(d2--decl-column previous-token))

((and (d2--decl-tags-contain current-token 'end)
(d2--decl-tags-contain previous-token 'node))
(max (- (d2--decl-column previous-token) 4) 0))

(t (progn (message "uknown syntax %s" current-token)
(d2--decl-column current-token)))
))))

Check failure on line 275 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, snapshot)

Closing parens should not be wrapped onto new lines.

Check failure on line 275 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 27.2)

Closing parens should not be wrapped onto new lines.

Check failure on line 275 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 28.2)

Closing parens should not be wrapped onto new lines.

Check failure on line 275 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (windows-latest, snapshot)

Closing parens should not be wrapped onto new lines.

Check failure on line 275 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (macos-latest, 28.2)

Closing parens should not be wrapped onto new lines.

Check failure on line 275 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (macos-latest, snapshot)

Closing parens should not be wrapped onto new lines.

Check failure on line 275 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (windows-latest, 26.3)

Closing parens should not be wrapped onto new lines.

(defun d2-indent-line ()
(interactive)

Check failure on line 278 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, snapshot)

All interactive functions should have documentation

Check failure on line 278 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 27.2)

All interactive functions should have documentation

Check failure on line 278 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 28.2)

All interactive functions should have documentation

Check failure on line 278 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (windows-latest, snapshot)

All interactive functions should have documentation

Check failure on line 278 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (macos-latest, 28.2)

All interactive functions should have documentation

Check failure on line 278 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (macos-latest, snapshot)

All interactive functions should have documentation

Check failure on line 278 in d2-mode.el

View workflow job for this annotation

GitHub Actions / build (windows-latest, 26.3)

All interactive functions should have documentation
(indent-line-to (d2--calculate-desired-indentation)))

(defun d2-compile ()
"Compile the current d2 file using d2."
Expand Down Expand Up @@ -220,7 +367,8 @@ Optional argument BROWSE whether to open the browser."
(setq-local font-lock-defaults '(d2-font-lock-keywords))
(setq-local comment-start "#")
(setq-local comment-end "")
(setq-local comment-start-skip "#"))
(setq-local comment-start-skip "#")
(setq-local indent-line-function 'd2-indent-line))

(provide 'd2-mode)

Expand Down

0 comments on commit 80851ac

Please sign in to comment.