I'm writing a simple mode for a Lisp-like language, and am having trouble setting up indentation. I've been following the emacswiki mode tutorial.
However, I can't figure out how to adapt their example indentation to my needs because they don't do any form of counting.
Basically, I just need to add 2 spaces to my indentation count every time I see a {
or (
, even if there are multiple on the same line, and subtract 2 spaces when I see closures of the above. I'm new to elisp; how can I adapt their example to count braces and brackets?
For convenience, here is the code they are using (for a non-bracket language):
(defun wpdl-indent-line ()
"Indent current line as WPDL code"
(interactive)
(beginning-of-line)
(if (bobp) ; Check for rule 1
(indent-line-to 0)
(let ((not-indented t) cur-indent)
(if (looking-at "^[ \t]*END_") ; Check for rule 2
(progn
(save-excursion
(forward-line -1)
(setq cur-indent (- (current-indentation) default-tab-width)))
(if (< cur-indent 0)
(setq cur-indent 0)))
(save-excursion
(while not-indented
(forward-line -1)
(if (looking-at "^[ \t]*END_") ; Check for rule 3
(progn
(setq cur-indent (current-indentation))
(setq not-indented nil))
; Check for rule 4
(if (looking-at "^[ \t]*\\(PARTICIPANT\\|MODEL\\|APPLICATION\\|WORKFLOW\\|ACTIVITY\\|DATA\\|TOOL_LIST\\|TRANSITION\\)")
(progn
(setq cur-indent (+ (current-indentation) default-tab-width))
(setq not-indented nil))
(if (bobp) ; Check for rule 5
(setq not-indented nil)))))))
(if cur-indent
(indent-line-to cur-indent)
(indent-line-to 0))))) ; If we didn't see an indentation hint, then allow no indentation
How can I just implement lisp-like indentation (but also with curly braces)?
If you want something simple for a Lisp-style language, I suggest you start with (syntax-ppss)
which returns the "parsing state" at point. The first element of that state is the current paren-nesting depth. While I used the word "paren", this doesn't really count parens but counts those chars which the syntax-table defines as paren-like, so if you set your syntax-table such that { and } are declared as paren-like, then those will also be counted.
So you could start with something like
(defun foo-indent-function ()
(save-excursion
(beginning-of-line)
(indent-line-to (* 2 (car (syntax-ppss))))))
Do not define this as interactive, since the way to use it is by adding
(set (make-local-variable 'indent-line-function) #'foo-indent-function)
in your major-mode function.
But maybe a better option is to simply do:
(require 'smie)
...
(define-derived-mode foo-mode "Foo"
...
(smie-setup nil #'ignore)
...)
This will use an indentation step of 4 (configured in smie-indent-basic
).