Closed gilch closed 2 years ago
Thank you for another non-clojure example. I’m not yet sure what kind of abstraction I could wrap parinfer in to make it respect arbitrary rules in different dialects.
Seems to come down to distinguishing atoms from brackets, and knowing which opening bracket types pair with which closing brackets. A config file taking some regex could almost do it, and is maybe the Pareto 80/20 solution, but there are a few difficult cases, like the nested #| |#
, although some enhanced engines (like PCRE) could probably handle those too.
A config file with callback functions should be powerful enough, but I'm not sure how that would work with the e.g. Rust implementation if callbacks are written in JavaScript. Maybe each implementation would be configured using its own language?
Various text editors have customizable syntax highlighting. There might be some good ideas there. A parser that only distinguishes brackets from atoms is probably not going to be very complex.
Right, parinfer’s parser only watches for delimiters to note when it has crossed a context boundary (to rule brackets found in strings or comments), and only tracks them insofar as it matters to finding structural parens to do its inference.
And actually, for your case, it seems like just having an option to process parens-only (ignoring []
and {}
) would be sufficient. Sorry I missed that on first read.
For the larger set of dialect-specific delimiters, we would need some subset of the language parser that allows us to know precisely when we’ve reached the end of it. I would avoid regex here. And maybe it’s best for now to support a set of dialect options rather than allowing customizable parsers—assuming there are only a handful of dialects with simple enough block comments and/or heredoc strings.
I added options for openParenChars
and closeParenChars
, and was able to test that your case works with it:
const parinfer = require('./parinfer.js')
const text = `
(let ((}{ 2)
(]]] 5))
(- }{ }} ]]]))
`
const opts = {openParenChars:'(', closeParenChars:')'}
const result = parinfer.indentMode(text,opts)
console.log(result)
console.log(result.text)
$ node scratch.js
SUCCESS:
(let ((}{ 2)
(]]] 5))
(- }{ }} ]]]))
I will increment and publish a version with these changes after some more non-clojure dialect changes.
This is obvious nonsense in Clojure, but perfectly valid Common Lisp (sbcl repl):
The symbols here are
}{
and]]]
.In this case, Parinfer should be managing parentheses only, not other bracket types, but it has to work the way it does for Clojure. So maybe a config option?
The workaround seems to be to escape any unbalanced brackets with a backslash, so like
\}\{
, probably because Parinfer is recognizing it like two Clojure character literals. I think Parinfer handles balanced brackets in symbols OK? It could theoretically move one at the end of a line, but I can't think of an otherwise well-formatted case where this would happen.