cursorless
cursorless copied to clipboard
`head/tail` and `word` tokens are not selecting correctly.
Sample Code
const shouldDisableTableUpdate = true;
Assume there is a hat over the u
in should
Command | Expected Result | Actual Result |
---|---|---|
chuck tail second word urge |
const should = true; |
const TableUpdate = true |
chuck head second word urge |
const TableUpdate = true; |
const should = true |
Essentially the result of using a word target and tail
and head
are reversed from what I expected in this situation.
Workarounds
- Defining the range
second past last word urge
orsecond past first word urge
- Using the opposite command from what you want (not really recommended as it promotes bad muscle memory)
The reason for this behavior is that you give it a second modified after head or tail that will be used as the constraint/limit instead of the current line.
"take tail urge"
=> Set selection from start of urge to end of line
"take tail line urge"
=> Set selection from start of urge to end of line
"take tail string urge"
=> Set selection from start of urge to end of string
"take tail second word urge"
=> Set selection from start of urge to end of second sub word
So the behavior you are seeing is consistent with the intended implementation. We might need to rethink this. @pokey
Oh actually @SimeonC I just realised, I was wrong on Slack. I believe what you're looking for is "take tail token second word urge"
and "take head token second word urge"
. The use case for "take tail second word"
would be as follows:
shouldDis|ableTableUpdate
Assume the |
is your cursor. If you say "take tail second word"
, it should select able
. Ideally you'd be able to say just "take tail word"
in this case as well, but "word"
isn't yet a proper scope type
Fwiw "tail <modifier>"
is shorthand for "past end of <modifier>"
. So in your case, "tail second word urge"
is shorthand for "urge past end of second word"
, which is kind of an odd thing. The modifier after "tail"
is generally expected to result in something bigger, and then we only take the part of it starting with the thing it's modifying. So for example, "tail file line air"
starts with "line air"
, expands to the file, and then only takes the part of the file starting from "line air"
.
In your example, we start with "urge"
, and then "expand" to "second word"
, but since that's actually smaller than "urge"
, the behaviour isn't really well defined imo.
Tbh I'd be tempted to error if the modifier results in something smaller
Thanks for the explanations, It does make sense why it wasn't working and the take head token second word urge
does work like I expected. (I often find myself saying cursorless commands in the wrong order still!)
So it sounds like this is an edge case where the "expansion" target is smaller than the main "target". I was thinking maybe it would be possible to just invert the target and modifier if the modifier results in something smaller, but erroring is probably a cleaner solution.
To me it's a bit inconsistent that we have tail <modifier>
and <modifier> <scope>
. This leads to my difficulty in reading and understanding in tail <modifier> <scope>
which one does the modifier belong to - cursorless obviously doesn't have the issue, but it does seem kinda arbritrary.
Maybe this could be avoided by always having the modifier before to give a good separation between which one the modifier is being applied to? though that could be a huge change so feel free to reject that idea!). (below is me thinking out loud about it)
-
take tail second word urge
(would take whole line from second word of urge - as per implicit definition) -
take token tail second word urge
(would take from second word of urge to end of containing token) -
take line tail urge
(would take the line from urge till the end) -
take file tail line urge
(would take from line urge to end of file)
Yeah we went back and forth a bunch on the order. I'm not sure why swapping the order makes things more consistent, though. You still need to know that <modifier> tail
is different from <modifier>
by itself, and there is still the same ambiguity, it's just on the other side. Eg if you say "second word token tail urge"
, how do you know that "tail"
stops at "token"
and doesn't include "second word"
? It's just the same problem in the other direction
Hmm, In my head it seems more consistent. second word token tail urge
is unambiguous to me as to me it follows the same reading order - second word
applies to token
, then second word token
applies to tail
, then second word token tail
is applied to urge
. In that one tail would always include second word as we're combining from left to right.
Whereas in the current one we have overlap/reversion of order tail <modifier> <target>
does the modifier belong to the tail
or the target
? (I'm talking very much just from a reading comprehension point of view, naieve of how the code works)
I'm not sure your reading there is correct. Cursorless commands form a pipeline that runs from right to left. So the first stage is "urge"
, the second stage is "token tail"
, and the third stage is "second word"
. So you'd still need to know that "tail"
affects only the "token"
modifier
Interesting, the right-to-left pipeline did throw me off a bit 😅 . I'm still reading and constructing cursorless commands like an english sentence, "take from the second word of the token past the end of the line of urge" (implicitly: where the token is urge). Which I guess is why it makes more sense to me that way. I think my example got a bit jumbled - I went from this threads case to a bit more general case, my bad.
So to fix my previous comment to be inline with the original point of the thread would be, second word tail token urge
as the consistent way.
It does sound a bit like the logic path I'm going down may be a bit too far removed from the current cursorless way of thinking so probably not too desirable a change so I'm happy if this just ends up being an academic discussion, I can try write some kind of docs up to try help others adjust to the cursorless way of thinking out of it 😁
I'll ask you about this again in the next meetup I manage to attend as I feel like this is possibly me being a bit lost and confusing the issue here more than I should.
Yeah let's discuss at the next meetup; I think we're reaching the limits of text 😊
I believe this one is superseded by #972, right?