Fork me on GitHub
#calva
<
2022-03-31
>
JAtkins06:03:12

Hi all, quick question about paredit.[forward/backward]UpSexp . I'm able to successfully move from

(def x (inc |3))
to
(def x (inc 3))|
But, if there are multiple top level s-exprs, forward and backward do not navigate further.
(def x 1)|
(def y 2)
I'd expect forwardUpSexp to move
(def x 1)
(def y 2)|
but instead the cursor does not move. Is this intended? Can it be changed?

pez07:03:36

It's supposed to work as you want it to. Is that the only code in the file?

JAtkins07:03:07

(ns test)

(def x 1)|
(def y 2)
Opening a file with only these contents has the same behavior

pez08:03:32

Very strange. Which version of Calva are you using?

JAtkins08:03:17

Latest - just installed VS code and calva today. Not sure if this is the place to find the extension version, but the Calva extension homepage says v2.0.060

pez08:03:15

THat should be v2.0.260, right?

JAtkins08:03:15

I knew I should've copied and pasted 😛

😂 1
pez08:03:10

This is how it behaves when I try it. What OS are you on?

JAtkins08:03:47

Ubuntu 20.04

pez08:03:36

When it has failed moving there, does it still work to move by sexp inside the forms?

JAtkins08:03:18

Hopefully this answers your q

pez08:03:04

Yes, and I know what it is now. VIM. Calva things that cursor is inside the paren. At least I think that's what's going on. You should be able to confirm by moving backwards sexp from that position. It should move inside the form then.

JAtkins08:03:05

that explains it

pez09:03:20

I have not figured out a way to solve it. At one level it is about not knowing that VIM is in COMMAND mode. At another level it is about knowing where the user thinks the cursors is. Because it is not where you thought it was. 😃

JAtkins09:03:38

Actually, if I put the cursor on a blank line calva is still confused about what to do

JAtkins09:03:46

(when in Normal mode)

pez12:03:52

That's weird. Can you explain the confusion with an example?

JAtkins14:03:53

You can actually see it in the gif when my cursor is on ln 37 - I tried to go back and forward and nothing happens

JAtkins14:03:10

(bottom right showing last action performed)

pez14:03:58

That is totally unexpected to me. Are you using vscodevim?

JAtkins14:03:31

actually, a/b testing forwardSexp works at root level in Normal mode, but forwardUpSexp doesn't

pez14:03:05

I get this. Didn't try forwardUp though.

JAtkins14:03:55

That matches what I get

pez14:03:14

Then I'm not following about what is not working. 😃 forwardup works for me too.

JAtkins14:03:25

How do I get that little popup?

pez14:03:05

Enable Screencast mode.

pez14:03:34

These are my Screencast Mode settings:

👍 1
pez14:03:49

If you think the feature with showing the command name is neat, you can tell me, because I added that. 😃

JAtkins14:03:42

Best thing about that feature 😛. Otherwise you wouldn't know what I'm doing cuz I've got one off keybindings so I can remember them all.

JAtkins14:03:06

As a fun bonus, that exact behavior is matched when in INSERT mode too

JAtkins14:03:48

(and when vim is disabled....)

pez14:03:15

It is all happening too fast for me to follow. 😃

JAtkins14:03:37

take 2 upcoming 😛

JAtkins14:03:52

as mp4 so you can .5x if needed

pez15:03:39

Thanks. That looks like it work exactly as intended. Where does it not do what you expect?

JAtkins15:03:15

I would expect forward up to continue around the next top level sexp

pez15:03:09

I now re-read your original question. When at the top level, there is no up, right?

JAtkins15:03:13

Tis true. I'm trying to match my cursive settings where I use forwardSexp to nav within sexp, when at the end of the sexp go up, and nav around top level

JAtkins15:03:27

calva forwardSexp is contained to the sexp, so I'm trying to get a best fit with forwardUp

pez15:03:29

Sounds a bit like this one, even if it is not this one https://github.com/BetterThanTomorrow/calva/issues/1487

pez15:03:25

Does Cursive forwardSexp go past the enclosing form?

JAtkins15:03:45

(def x (inc |1))
(def x (inc 1|))
(def x (inc 1)|)
(def x (inc 1))|

JAtkins15:03:42

It'll move out at the end - I assume that's what "past the enclosing form means"

pez15:03:57

Interesting. I rely on that I am guaranteed to not slip out of the form. 😃

pez15:03:33

Is it a setting in Cursive or does it do that crazy thing unconditionally? 😃

JAtkins15:03:07

there's a strict version I think. I use this to quickly jump around and out. I have this bound to J, K , but line absolute up/down/left/right commands bound to hjlk still. I get a little absolute and a little ast behavior at once 🙂

pez15:03:40

Did you check out the video on that ticket I posted? Seems like a super quick way to move around.

JAtkins15:03:17

I did. pretty cool

JAtkins15:03:40

I've found after alot of iteration that for me fewer more general commands get me around much quicker than actually remembering all the specific commands. That might fit the bill as well, but I've rewired my brain over the past year or two to this setup

pez15:03:34

We could maybe add some when contexts that informs about the cursor being at the beginning/end of a list and then you could bind the same keys to forward/backwardUp in that context as with forward/backwardSexp in the context where it is not at the boundaries.

JAtkins15:03:49

:thinking_face: that's a pretty good idea. I don't think that would work with vim though? Unless it respects action whens and I've not seen it yet

pez15:03:47

The potentially problematic thing with that is that @U037TPXKBGS is working on adding multicursor support and we've already seen that break havoc with some existing cursor when contexts.

pez15:03:56

I don't know anything about how the vim extension binds keys. Maybe it doesn't make when contexts available. Sound boring if it doesn't.

JAtkins15:03:11

would you accept a forward/backwardSexpLax command pr?

pez15:03:32

Oh, yes I would.

JAtkins15:03:42

Weekend task 😛

pez15:03:56

I was thinking in terms of settings and I don't fancy those. But a separate command makes perfect sense.

pez15:03:35

A fun task. I love working with Paredit stuff. 😃

pez15:03:10

Sorry for derailing this issue for so long, not having read your original question properly!

JAtkins15:03:11

Thanks for taking a look at this with me 🙂. Glad to know calva paredit is working as expected across oses at least 😛

JAtkins15:03:32

(and now about the presenter mode 👀 nice )

pez16:03:10

Also good to know that Paredit mostly works in Vim NORMAL mode.

pez16:03:11

How about naming the commands forward/backwardSexpOrUp. I'm thinking that ”lax” is a bit too open for interpretation.

💯 1
JAtkins10:04:41

Needs some help - see checklist I added at the bottom

pez10:04:14

That was fast! I'll have a look in a minute.

JAtkins10:04:10

LMK if you'd like me to refactor out the common bits between the fwd, fwdUp, and fwdSexpOrUp versions. I don't use typescript regularly so wasn't sure how to write that. (though I can figure it out 🙂 )

pez11:04:42

I'm lacking some tests 😃

JAtkins11:04:48

You are, or I didn't write them?

JAtkins11:04:21

I didn't see any existing ones for fwdSexp & friends - can add if those exist

JAtkins11:04:34

ah, I see - you tested forwardSexpRange - not forwardSexp

JAtkins11:04:44

I'll add those and @ you then

pez11:04:36

Left some comments on the PR too.

👍 1
pez11:04:14

Now thinking about what might be the best approach for avoiding the duplication... Maybe something like so?

function _forwardSexpRange(
  doc: EditableDocument,
  offset = Math.max(doc.selection.anchor, doc.selection.active),
  goPastWhitespace = false,
  goPastClosingBracket = false
): [number, number] {
  const cursor = doc.getTokenCursor(offset);
  cursor.forwardWhitespace();
  if (cursor.forwardSexp(true, true)) {
    if (goPastWhitespace) {
      cursor.forwardWhitespace();
    }
    return [offset, cursor.offsetStart];
  } else {
    if (goPastClosingBracket && cursor.upList()) {
      return [offset, cursor.offsetStart];
    }
    return [offset, offset];
  }
}

export function forwardSexpRange(
  doc: EditableDocument,
  offset = Math.max(doc.selection.anchor, doc.selection.active),
  goPastWhitespace = false
): [number, number] {
  return _forwardSexpRange(doc, offset, goPastWhitespace, false)
}

export function forwardSexpOrUpRange(
  doc: EditableDocument,
  offset = Math.max(doc.selection.anchor, doc.selection.active),
  goPastWhitespace = false
): [number, number] {
  return _forwardSexpRange(doc, offset, goPastWhitespace, true);
}
(Not tested)

JAtkins11:04:14

That could maybe also simplify the tests - just 1 instead of 2 or 3 that I was planning

JAtkins11:04:48

(1 per fwd/back)

pez11:04:35

It's good to document how it behaves on top level as well, I think. 😃

pez11:04:35

I've tried the commands manually now. Could almost get used to them!

pez15:04:40

Thanks for the changes, @U5P29DSUS!

👍 1
Yuner Bekir08:03:58

Hi. Is there a way to tell calva to preload the namespaces of different projects? When I press f12 to navigate to the implementation of something it always opens bytecode (which is unchangable) and I have to manually open the file eval the namespace and then everything starts working as expected.

pez08:03:30

Never seen bytecode show. 😃 Does it work to first use the command Calva: Load current file and dependencies?

Yuner Bekir09:03:38

Doesn't help. By bytecode :rolling_on_the_floor_laughing: I mean that it opens a file in read-only mode

😂 1
Yuner Bekir14:03:22

Some clarification. The product I am working on is made up from a whole bunch of separate projects.

pez14:03:10

Are you depending on the other projects via maven or something?

rayat16:03:25

Yeah this happens to me too, always thought this was just an accepted limitation. For me, if I hover over the editor tab it reveals that the filepath of the readonly file is within what I assume is the local maven cache. I'm not at my computer currently, but that's more or less what I recall it being. It doesn't open the actual file in my monorepo.

pez16:03:21

Could rearranging the classpath help?

Yuner Bekir10:04:48

I am depending on the other projects. What I have seen colleagues using intellij do is that they import all projects separately via the editor somehow.