Replies: 6 comments 9 replies
-
Thanks for converting this to a discussion, I didn't even see that there's that tab on the repo. I've been experimenting with more variations of that snippet in rust-ts-mode, and none of them seem to indent the "bar" token: (foo "{" n> "bar" n> "}")
(foo "{" n "bar" > n "}")
(foo "{" n> "bar" n> "}" >)
(foo "{" n "bar" n "}") When invoked on column 0, all of these put "bar" on column zero (and you can probably tell that I was getting pretty desparate towards the end)... However, this one works when invoked outside column 0, inside a block (that's the third from the top above): (foo "{" n> "bar" n> "}" >) on column zero: {
bar
} inside a block: {
// below is the expansion of foo on the base indent level:
{
bar
}
} |
Beta Was this translation helpful? Give feedback.
-
Update: It looks like indent-according-to-mode doesn't work correctly at all with treesit modes. In rust-ts-mode, running |
Beta Was this translation helpful? Give feedback.
-
So given that tempel needs can only do indentation on a line-by-line basis, while it's inserting characters (creating syntax errors along the way, which sometimes cause treesit modes to be unable to correctly indent), I think the only way to get indentation of column-0 based forms to work is to wrap them in "indent this region, please" code. Here's what I have, but it feels really dirty (note that this doesn't use rust-mode rust-ts-mode
(test (p (point) template-start t)
"#[test]" > n "fn " (p "test_name") "() {" n
> (p "test_body") n
"}"
(progn (indent-region template-start (point)) nil)) The I'm somewhat dissatisfied with this; would this warrant and |
Beta Was this translation helpful? Give feedback.
-
Think we can do even better, in fact: (defun asf--tempel-indent-template (elt)
(when (eq '>> (car-safe elt))
(let ((template-start (gensym)))
`(l (p (point) ,template-start t)
,@(cdr elt)
(progn (indent-region ,template-start (point)) nil)))))
(add-to-list 'tempel-user-elements 'asf--tempel-indent-template) This defines a template sigil rust-mode rust-ts-mode
(test (>>
"#[test]" n "fn " (p "test_name") "() {" n
(p "test_body") n
"}")) ...which properly indents the inserted template, but THEN, when I edit the |
Beta Was this translation helpful? Give feedback.
-
Hrm, yeah, so it seems that two things don't interact nicely with each other:
I'm not completely sure how to go about debugging this. Maybe I'll have to introduce a new variable to the |
Beta Was this translation helpful? Give feedback.
-
I stumbled upon this thread while debugging a different indentation issue (which I solved by tinkering with my template definition). Anyway, I got curious and found what I believe to be the core issue – the variable (defvar rust-ts-mode--indent-rules
`((rust
((parent-is "source_file") column-0 0) ;; <== Curious ==========
((node-is ")") parent-bol 0)
((node-is "]") parent-bol 0)
((node-is "}") (and parent parent-bol) 0)
((and (parent-is "comment") c-ts-common-looking-at-star)
c-ts-common-comment-start-after-first-star -1)
((parent-is "comment") prev-adaptive-prefix 0)
((parent-is "arguments") parent-bol rust-ts-mode-indent-offset)
...
((parent-is "block") parent-bol rust-ts-mode-indent-offset)
...
) Immediately, we see that at the top-level of the AST the anchor is column zero and offset is zero. As a result, everything is reset to column zero (by tree sitter). Changing the offset to something like Next, considering that at some point the indentation level has to change, I examined the AST with malformed code blocks:
Notice that in the second case the error is relegated to the top-level (as the top-most brace is now unmatched), while the 'inside' can be an indent-able structure (wrt. to the indent rules). Hence, to solve the core of this issue, you would have to either:
Of course, we are using Emacs, so we can possibly tackle this at a higher level, such as:
I agree with minad that modifying Tempel to indent the whole template at any point is not the best idea, mainly because that will introduce a heap of other issues. Having said that, a possible middle ground could be for Tempel to track the first and last line of the template and also provide a pre and/or post template insertion hook to allow users to hack away at it. I am not sure how easy it would be to track the first and last lines, but this is the best I could come up with at the moment. I think any of the listed solutions are much safer than any modification to Tempel could do. |
Beta Was this translation helpful? Give feedback.
-
I have to add my voice to the chorus of issues (e.g. #73 and #80): I've not managed to create a snippet yet for rust or nix modes that indents its literal or prompted contents to a column other than 0.
I use rust-ts-mode and nix-ts-mode, with active eglot LSP connections, if that indicates anything
This rust snippet:
In rust-ts-mode, entering "test" on column zero and M-x tempel-expand, results in:
I've tried all sorts of combinations on that "body" prompt, using
r>
, plain>
,n>
before it or not, none of these things result in an indented text.Similar with this nix snippet:
And again, "darwinmod" in nix-ts-mode, on column zero, results in:
...which is even weirder, because some parts are indented!
I tried doing the same thing tempel is doing, with
M-: (progn (insert "\n") (tempel--protect (indent-according-to-mode)))
- and that does result in the correct indentation. So something must be going on, but I'm not sure what.Can you tell me what's happening there?
Beta Was this translation helpful? Give feedback.
All reactions