Fork me on GitHub
#calva
<
2019-12-04
>
filipematossilva11:12:42

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

filipematossilva11:12:46

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

filipematossilva11: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

filipematossilva11:12:53

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

filipematossilva11:12:35

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

filipematossilva11:12:18

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

filipematossilva11:12:42

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

filipematossilva12:12:59

I'll capture this in an issue

pez12:12:18

Agree about the distinction between ; and #_.

pez12:12:58

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.

filipematossilva12:12:27

can you give me an example of a plain symbol?

filipematossilva12:12:47

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

pez12:12:49

Yes, and inc .

filipematossilva12:12:02

I guess the real question is if that's valid

filipematossilva12:12:18

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

filipematossilva12:12:29

this code has a compilation error but only because of arity

filipematossilva12: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 |
--------------------------------------------------------------------------------

filipematossilva12:12:01

(+ 1 #_2 3) is valid

filipematossilva12:12:15

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

pez12:12:45

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

filipematossilva12:12:54

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

pez12:12:58

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

pez12:12:16

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

filipematossilva12:12:37

oh I have a good example!

filipematossilva12:12:07

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

filipematossilva12:12:12

but I needed to save all the time

filipematossilva12:12:35

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

pez12:12:46

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

filipematossilva12: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

filipematossilva12: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

filipematossilva12:12:05

but that's a very specific case

filipematossilva12:12:07

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

filipematossilva12:12:16

so I guess the information is there

filipematossilva12: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

pez12:12:15

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

sasho.popov12:12:19

> 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.

sasho.popov12:12:47

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

filipematossilva12: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)

pez12:12:24

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

sasho.popov12:12:07

🤔 thinking…

filipematossilva12:12:33

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

pez12:12:48

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

filipematossilva12:12:14

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

pez12:12:38

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

pez12:12:19

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

pez12:12:02

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

filipematossilva12:12:17

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

sasho.popov12:12:44

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

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

pez12:12:03

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

pez12:12:25

Multi selections are not supported by anything in Calva anyway.

filipematossilva12:12:59

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

pez12:12:38

We can choose to make it

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

sasho.popov12:12:49

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

filipematossilva12:12:09

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

pez12:12:45

So rather

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

pez12:12:30

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

sasho.popov12:12:40

For example:

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

sasho.popov12:12:26

And if w select rows 3 and 4, then:

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

pez12:12:36

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

pez12:12:56

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

sasho.popov12:12:15

I don’t understand this. 🙂

pez12:12:51

lateral selection = siblings

pez12:12:54

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

pez12:12:01

top level siblings.

sasho.popov12:12:49

Ah, now I see.

filipematossilva12:12:27

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

pez12:12:14

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

filipematossilva12:12:31

but that's not the important part

filipematossilva12:12:38

it's the existing comment semantics

filipematossilva12: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

filipematossilva12:12:15

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

filipematossilva12:12:30

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

filipematossilva12:12:50

but if we add double ignore these semantics are not maintained

pez12:12:13

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.

filipematossilva12:12:02

I think currently something else is shown

sasho.popov12:12:45

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

pez12:12:05

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

filipematossilva12:12:11

An example.

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

pez12:12:20

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).

pez12:12:08

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

filipematossilva12: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?

sasho.popov12:12:02

It’s AlexVPopov

pez12:12:20

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

pez12:12:32

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

sasho.popov12:12:53

Sure, I’m willing to do this. 🙂

sasho.popov12:12:17

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

pez12:12:04

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

sasho.popov13:12:24

Very well described!

filipematossilva13:12:47

mostly copy paste, the good discussion already happened here 😛

pez12:12:56

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.

filipematossilva12: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`).

pez12:12:35

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

pez12:12:02

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.

dennisa14:12:52

I guess you have seen this already ?

dennisa14:12:23

Calva is doing fairly wel : ) !

pez14:12:28

@dennisa is that from this spring?

dennisa14:12:14

surely before May

pez14:12:24

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

dennisa14:12:25

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

pez14:12:39

I wonder how many are using Lisin's extension.

davidbrear0416:12:55

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

pez16:12:59

You just made my day. Thanks!

gkhasel121: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!!

pez21:12:34

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.

gkhasel121: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?

pez22:12:47

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.

gkhasel122:12:01

right right that totally makes sense

pez22:12:10

Here are some of my thoughts around zprint: https://github.com/kkinnear/zprint/issues/119

pez22:12:27

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.

pez22:12:12

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. 😃 )

gkhasel122:12:38

ok, im following along so far!

pez22:12:22

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.)

pez22:12:15

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.

gkhasel122:12:55

:+1: really appreciate the jumpstart!

pez22:12:14

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.

gkhasel122:12:37

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

pez22:12:56

Totally appreciate that you want to help out with this!

pez22:12:52

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.

pez22:12:06

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).