Fork me on GitHub
Filipe Silva11:12:42

I've always wondered if there was a #_ shortcut too 😄

Filipe Silva11:12:46

atm I move around with the paredit shortcuts to go the the right sexp start, then manually input #_

Filipe Silva11:12:05

so I guess the ergonomic approach is to make such a shortcut apply #_ to the expression that the paredit move keybinds leave me in

Filipe Silva11:12:53

personally I use ; and #_ with different intents: the first is mostly for text comments, the latter for disabling code

Filipe Silva11:12:35

whenever I use ; to disable code I feel I'm only doing it because it's easier (via VSCode shortcuts) than using #_

Filipe Silva11:12:18

but #_ is what I really want for code... because it applies correctly to the whole expression, instead of applying to lines

Filipe Silva11:12:42

when I use ; to comment code I must think about start line, end line, and expression delimiters

Filipe Silva12:12:59

I'll capture this in an issue


Agree about the distinction between ; and #_.


My questions about where the cursor is when the shortcut is issued remains. Calva has a notion about current form today, but that doesn't distinguish between list forms or ”plain” symbols.

Filipe Silva12:12:27

can you give me an example of a plain symbol?

Filipe Silva12:12:47

do you mean something like 2 in (inc 2)?


Yes, and inc .

Filipe Silva12:12:02

I guess the real question is if that's valid

Filipe Silva12:12:18

(inc #_1)
(+ 1 #_2 3)

Filipe Silva12:12:29

this code has a compilation error but only because of arity

Filipe Silva12:12:44

------ ERROR -------------------------------------------------------------------
 File: D:\work\self-managed\src\self_managed\db.cljs:107:1
 106 |
 107 | (inc #_1)
Error in phase :compilation
Wrong number of args (0) passed to: cljs.core/inc
 108 | (+ 1 #_2 3)
 109 |

Filipe Silva12:12:01

(+ 1 #_2 3) is valid

Filipe Silva12:12:15

so it wouldn't make sense for Calva to prevent that from happening


Yeah. and (inc #_1) can be valid inside a thread macro.

Filipe Silva12:12:54

(println "one" #_"two" "three #_four") is fine-ish as well, it would just be printed


If you use the Expand Selection command, without a previous selection, then what is selected first is what Calva considers being the current form.


My question then is if that is what we want to be ignored using the #_ shortcut. The gain with the shortcut then seems limited. 😃

Filipe Silva12:12:37

oh I have a good example!

Filipe Silva12:12:07

this weekend I was trying to experiment with some code that I didn't understand, and kept using the repl commands

Filipe Silva12:12:12

but I needed to save all the time

Filipe Silva12:12:35

because these were re-frame subscriptions, and I needed them to be registered and loaded


Here a fun thing to try. (println #_ #_ #_ "one" "two" "three" "four") 😃

Filipe Silva12:12:52

my workflow ended up being this: • make a subs • make some code that I evaluated to a comment • select that code, use the vscode comment shortcut • edit the subs • repeat

Filipe Silva12:12:52

I kept wishing I had a #_ shortcut all the while because every time I made a wrong selection I would get either a compile time or runtime error

Filipe Silva12:12:05

but that's a very specific case

Filipe Silva12:12:07

on that case you presented, calva seem to highlight it correctly

Filipe Silva12:12:16

so I guess the information is there

Filipe Silva12:12:54

now that I read your question again I think I mis-read it... I think now you were only asking about what we want ignored specifically with an expanded selection, not in general


My question is what we want ignored generally. However, if we have a selection it makes sense to ignore that.


> Where is the cursor when you want to disable the form? @pez This could follow the same logic as selecting a form with Ctrl+w . So if we have (inc 2) and want to get #_(inc 2) , then the cursor should be either before the opening paren or behind the closing one.


If the cursor is, say, right behind inc , then we will get (#_inc 2) .

Filipe Silva12:12:13

selections are weird with #_, because it specifically ignores the next expression but a selection can contain many expressions, or even ranges that can be invalid expressions (e.g. 2) in (inc 2) is not a valid expression)


Is it worth it then? It would be saving you the typing of the #_...


:thinking_face: thinking…

Filipe Silva12:12:33

I think it's worth it for the same reasons the comment shortcut is worth it


If we have a selection it makes sense, because typing #_ would then replace the selection.

Filipe Silva12:12:14

yeah the selection case is one where the comment shortcut is very helpful


So if we make it such that the shortcut ignores out either the current form or the selection, that would help?


I guess that if several forms are selected, we put that number of #_ in front of them...


And if something unbalanced is selected we don't do anything.

Filipe Silva12:12:17

I think the intuitive semantics would then be "ignore expression at cursor/start of range"


O.K., how feasable is the following scenario:

  (inc 1)
  (inc 2))
We select everything from line 2 and line 3. If we use a normal comment, we’d get:
  ; (inc 1)
  ; (inc 2))
If we use #_ , we’d get:
  #_(inc 1)
  #_(inc 2))
Bear in mind, I’m talking about a single selection of rows 2 and 3, and not a multi-selection.


It will need to correspond to all other commands dealing with the current form.


Multi selections are not supported by anything in Calva anyway.

👍 4
Filipe Silva12:12:59

so this would ignore all toplevel expressions within the selection... doing the "right" thing for the equivalent comment shortcut


We can choose to make it

  #_#_(inc 1)
  (inc 2))


I guess, the expected behavior would be -> comment all top-level forms within the section with #_ .

Filipe Silva12:12:09

but if matching comment shortcut semantics then the "uncomment commented stuff" aspect of it would be expected as well...


So rather

  #_(inc 1)
  #_(inc 2))


Cool. Now it is starting to get ready for an issue. 😃


For example:

    (inc 1)
    (inc 2)))
If we select rows 2, 3, and 4, we should get:
    (inc 1)
    (inc 2)))
and not
    #_(inc 1)
    #_(inc 2)))


And if w select rows 3 and 4, then:

    #_(inc 1)
    #_(inc 2)))

Filipe Silva12:12:50

yes I think so


Indeed. We just need the ”special” handling for lateral selections.


Even if one form could be thought of as a lateral selection of one form.


I don’t understand this. 🙂


lateral selection = siblings


So the rule would be that we put an ignore before all siblings in a selection.


top level siblings.


Ah, now I see.

Filipe Silva12:12:27

important to note that ignore semantics mean that existing ignore symbols should not be kept (because they stack)


Well, Calva will show you if you have stacked them.

Filipe Silva12:12:31

but that's not the important part

Filipe Silva12:12:38

it's the existing comment semantics

Filipe Silva12:12:05

if you select two lines, one with a comment and one without, and press the comment keybind, both will get a comment symbol

Filipe Silva12:12:15

then if you press it again, the new comment symbol will go away but the original one wont

Filipe Silva12:12:30

and this is ok because double comment still just means "this line is commented"

Filipe Silva12:12:50

but if we add double ignore these semantics are not maintained


The semantics of whatever you put ignore forms in front get ignored, are kept. 😃 But we'll see how hard it would be to ignore to ignore already ignored forms.

Filipe Silva12:12:02

I think currently something else is shown


@pez just out of curiosity - when working on a feature like this -> how much does it require Clojure knowledge and how much -> TypeScript knowledge?


@filipematossilva Yeah, I am aware that they stack. That's why I highlight it like that. 😃

Filipe Silva12:12:11

An example.

    (inc 1)
    #_(inc 2)))
Selecting 3, and 4, and pressing the ignore shortcut:
    #_(inc 1)
    #_(inc 2)))
Pressing it again:
    (inc 1)
    (inc 2)))


This particular feature takes some TS knowledge to implement and some (more) Clojure knowledge to design. (The latter of which we are doing right now).


Mostly it will take some knowledge with Calva's Paredit and Token Cursor.

Filipe Silva12:12:18

I'll open an issue and add the selection examples. @sasho.popov what's your github handle for me to link you there?


It’s AlexVPopov


I'm happy with that design, @filipematossilva, even if I think it is not exactly matching the text based comment selection semantics.


If we can find some time to pair it, @sasho.popov, I'd be delighted to.


Sure, I’m willing to do this. 🙂


Not sure how much of help I might be, though, but I’ll help with whatever I can. 🙂


Awesome. we are almost in the same time zone. I work with Calva from about, 21:30 your time, on weekdays.

👍 4

Sounds good!


Very well described!

Filipe Silva13:12:47

mostly copy paste, the good discussion already happened here 😛


Thanks! If you can mention that Calva's current form concept can be explored by pressing ctrl+w, I think it is easer for readers to figure it out.

Filipe Silva12:12:03

added this now > Calva has a concept of current form. This is the selected form when using the "expand selection" shortcut (`ctrl+w`).

metal 4

And I now realize that the command Select Current Form selects something different that ctrl+w in some situations....


No. maybe I was confused there. I now can't find where they behaved differently. Which is good, because then I can remove the Select Current Form command.


I guess you have seen this already ?

calva 4

Calva is doing fairly wel : ) !


@dennisa is that from this spring?


surely before May


I hope they will make one next year as well. And how VS Code might have moved then.


this year, but I there's no exact date ..


I wonder how many are using Lisin's extension.

David Brear16:12:55

Been using Calva for about a month now and I can't imagine not having it! Great addition!

❤️ 4
calva 4

You just made my day. Thanks!

Gabriel Khaselev21:12:56

hey calva friends, looking for some advice on custom formatting. two questions in mind: (1) i have a macro my-let that syntactically is exactly like let . is there a way to tell calva to format my-let just like let? alternatively, is there a way to write a custom formatter for this? (2) can i tell calva to respect , in map literals and only linebreak after , when any , are present in the map? alternatively, is there a way to write a custom formatter for this? thank you!!


Hi there, @gkhasel1! Currently there is no way to configure Calva’s formatting beyond some options regarding whitespace. However, it is not all that much work that needs to be done to make it respect cljfmt indent maps, because it is cljfmt we are using. If you want to explore that, I’d be happy to show you around the code in question and have a general chat about it. That would take care of 1. For 2 , I am not sure. if cljfmt supports it, then that is easy to add support for. If not, we would need to either do some work on the text ourselves, before or after cljfmt does it work. Or use another formatter. That shouldn’t be too hard to do, I have been talking some with Kim Kinnear about using zprint and that is pretty much within reach. All in all it is a matter of time and priorities, really, but not eons of time, and I am quite interested in at least solving 1 in something like a short term.

Gabriel Khaselev21:12:33

hey @pez thanks for the quick response! definitely interested in tackling problem 1, took a quick glance at cljfmt and using :indents seems straightforward to me. can you point me to some files in calva that apply cljfmt rules? for problem 2, a quick glance at zprint makes it seem really promising, and potentially more feature rich that cljfmt. what are your thoughts on how youd integrate that into calva? do you think its worth looking into supporting cljfmt indent rules if theres a pending switch to zprint?


I want to support both cljfmt and zprint. The rationale there is that Calva is not suitable for some projects as long as it doesn’t support those projects’ formatters, and config files.

Gabriel Khaselev22:12:01

right right that totally makes sense


Here are some of my thoughts around zprint:

👍 4

But, leaving zprint aside for a while. For 1, we need to support the :indents option of cljfmt, as you have already figured out. In format.ts there are _formatIndex and _formatRange that call the formatter (which is written in ClojureScript) and pass in the config. I think it makes sense to support reading configs from a .`cljfmt` file and from project.clj.


I don’t remember if the :`indents` go in the :`config` , but I would guess they do. So then it would possibly be zero changes to the ClojureScript formatter stuff. (Which isn’t a selling point, I know, but anyway. 😃 )

Gabriel Khaselev22:12:38

ok, im following along so far!


We also need to make sure our second indent engine gets the indents from the same config. It uses a cljfmt compatible dictionary, so shouldn’t be a stumble block. That lives in indent.ts. (The plan is that all on-type indenting should be done by this second indenter, because doing it via the full formatters is a bit too slow for full comfort.)


I think that’s about it. I’ll be off to get some sleep now, so won’t be available a while, but roam around a bit in those files. It is not all that much code, actually.

Gabriel Khaselev22:12:55

👍 really appreciate the jumpstart!


The cljs formatter is a bit of a hack, so if you end up needing to fix stuff there, I will be happy to have a zoom session and try explain some of my sins.

Gabriel Khaselev22:12:37

🙏 ill keep you posted on that once I'm more familiar with the file


Totally appreciate that you want to help out with this!


Please see what issues there are on the repo regarding this, and feel free to file a new one if you don’t find one that fits.


Also, earlier today I added some first unit tests to the project so please have a look at that setup when you feel ready to start implementing something. (It’s in the directory src/extension-test/unit).

👍 4