-
-
Notifications
You must be signed in to change notification settings - Fork 219
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Help beta test multi-cursor Calva Paredit, please ❤️ 🙏 #1662
Comments
Hi! Thanks @riotrah for working on this awesome feature! ❤️ Of course I love to help with testing. Here's an issue I found: Delete Forward to End of List only deletes for the first cursor, and loses the other cursors Before
Delete Forward to End of List Expected
Actual
As this is also an example of the report format, let me elaborate some:
The command is written like |
I'm having a great time testing this! Thanks again! 🙏 Delete Backward to Start of List only deletes for the first cursor, and loses the other cursors Before
Delete Backward to Start of List Expected
Actual
|
Here's an interesting one. The edits are correct, then all but the leftmost cursor get offset. I've tried it on some more cases then below, and I think the offset is related to how much text is deleted by leftwards cursors. Raise sexp wrong placement of cursor after the edit Before 1 ;; 1. Start two cursors left->right
(a (b|)) (a (b|1)) (a (b)) Raise sexp Expect 1 (a b|) (a b|1) (a (b)) Actual 1 (a b|) (a b) |1(a (b)) Before 2 ;; 1. Start two cursors left->right
(a (b|1)) (a (b|)) (a (b)) Raise sexp Expect 2 (a b|1) (a b|) (a (b)) Actual 2 (not sure if it keeps the cursor order) (a b|1) (a b) |(a (b)) |
Delete Sexp Forwards only deletes at primary cursor, loses the others Before (|2a) (|1a) (|a) (a) Delete Sexp Forwards Expect (|2) (|1) (|) (a) Actual (a) (a) (|) (a) |
Delete Sexp Backwards only deletes at primary cursor, loses the others Before (a|2) (a|1) (a|) (a) Delete Sexp Backwards Expect (|2) (|1) (|) (a) Actual (a) (a) (|) (a) |
Almost done with the ones posted so far. The text notation format in which you've posted these has made it very easy to test driven develop. Along the way I learned:
|
Update: Made the above pass. Added a Now just making sure the changes I made are actually legible lol. It's been interesting having to calculate these offsets and stuff, haven't done much like this before. A question for @PEZ et al.: Multicursor copy or "kill while adding to clipboard" is tricky. I'm not exactly sure how vscode does it natively, but if you have n cursors and copy text per cursor, and then paste at a later point with exactly n cursors, the cursors paste according to the original corresponding cursor's location. However, if you do not have exactly n cursors, the total sum of copied text is pasted at each cursor. For now I'm copying only the first (primary) cursor's content. Will have to see how that goes after |
Stellar work, @riotrah! I can't thank you enough. 🙏 ❤️
So awesome! I made a user command from it. See updated issue description.
😄 Happy you have discovered that it is easier if you work from the end of the document. (Not saying that it gets easy, but anyway.) The next level of this is when edits overlap, like: (|(a :a) (|1b :b)) Raise sexp Now what? In the latest build nothing happens, which might be the right call, and mean that you have thought of this.
Indeed! I think what you do makes sense for now. Add the behaviour to the |
Used this build all day at work today. Totally useful, even though some quirks remain of course. Here's one. Expand selection when all text in a list is selected, doesn't select the list. It selects the opening paren: Before (|a|) Expand Selection Expected |(a)| Actual |(|a) This bug is now famous from this video: https://www.youtube.com/watch?v=Sy3arG-Degw 😄 |
Can TokenCursors (or any other API) tell us how "deep" a cursor or the form it's in is? That way, for Raise, we should go in order of cursor depth. It's not as efficient as short circuiting by doing shallower overlapping form raises first, but it's easier to implement and read, and is logically accurate. For example, in the given example, the deepest symbol/form to raise is the |
Calva Highlight is doing this kind of work continuously. But only on visible forms, so maybe it's not the place to look... Maybe just do cursorUp until at the top, with each cursor? |
Maybe we can factor out the thing from Calva Highlight and run it on demand... |
Paredit Delete Backward does not move cursor inside list when used from adjacent after the list: Before ()| Paredit Delete Backward Expected (|) Actual ()| We have the same error with Delete Forward. |
@riotrah Did you remove the cursor contexts without updating the Paredit commands to handle it instead? 😄 Forward Sexp moves cursor out of line comment instead of moving by word: Before a§|; a b c§d e Forward Sexp Expected a§;| a b c§d e Actual a§; a b c§d| e |
Multi-cursor Paredit Delete Backward destroys structure when a cursor is at the beginning of a list: Before (a|)§(|1) Paredit Delete Backward Expected (|)§|1 Actual (|)§|1) As well as: Before (|)§(|1) Paredit Delete Backward Expected |§|1 Actual |)§|1) We have the same error with Delete Forward. |
Now we are entering into tricky territory, indeed. Post-edit formatting! Paredit editing commands "spawns of” a formatting of the text after the editing has happened. But the formatter is not multi-cursor aware, so we loose all but the primary cursor after an edit. Illustrating here with Barf forward: With formattingMulti-cursor.barf.post-formatting.mov-processed.mp4Copying the before, expected, actual text-notation in here. Note that they can't be straightforwardly translated to unit tests because currently our Paredit unit tests do not capture the post-formatting step. Before ([|a§ b])§([|1a§ b]) Barf forward Expected ([|a]§ b)§([|1a]§ b) Actual ([|a]§ b)§([a]§ b) Without formattingCalva checks if the formatter has changed the document and won't apply the changes if there is no change, so this retains the cursors: multi-cursor-barf-no-formatting.mp4Before ([|a b])§([|1a b]) Barf forward Expected ([|a] b)§([|1a] b) ✅ |
Some options for the formatting problem:
|
Splice sexp misplaces cursors when there more than one Before (|a)§(|1b) Splice sexp Expected |a§|1b Actual |a§b|1 That is what I see in VS Code when I do this. In the unit tests I get even weirder results... And it get's weirder (with some pattern to it) with increasing amount of cursors. I've added failing tests and pointed out the weirdness I see in comments. |
Wrap around commands only wraps primary cursor and loses the other cursors Before |a§|1b Wrap around () Expected (|a)§(|1b) Actual (|a)§b Again there is a weird difference between what happens in VS Code and what I see in the unit tests... |
Some interesting stuff in here, we are indeed entering tricky territory haha! Will look into |
Delete backward does not move into list from behind closing bracket Before ()| Delete backward Expected (|) Actual ()| The unit tests for this pass, though... |
@riotrah , I notice that the failing tests I have been adding, now pass. Does that mean that some checkboxes should potentially be ticked in the issue description here. It takes me a lot of time to test things blindly, so some update on what I should be re-testing would be nice! |
@PEZ I think I've updated the desc to reflect current local branch. Will push them shortly. Some of them are very strange as you've noted 😅 |
Hi @PEZ, I wonder if the cursors in the first Expected are swapped? |
What does **We have the same error with Delete Forward mean here? Can you give me a unit test case? |
What is the "delete forward" equivalent of this test/feature? |
Yes, I've updated the comment now.
It means that the general problem of destroying structure goes for both deleting backwards and forwards. So if I pick your last question about this, it would be: Before |() Paredit Delete Forward Expected (|) Actual |() |
@riotrah is bringing something wonderful to Calva, multi cursor support to Paredit!
The way this beta test will work is that Calva Team members will maintain a checklist of known issues right here and all who participate in the testing can report findings in the comments. See How to test custom VSIX packaged on the Calva wiki if this is unfamiliar to you. (TL;DR: It is super easy.)
This is recorded April 3, 2022, with the build: calva-2.0.263-pull-1606-298af21c.vsix
multi-cursor-paredit-beta-1.mp4
As you can see it is largely working! As you also can see, sometimes it doesn't do the right thing. So this is a call for help testing this to help us find bugs and to help us discover what is the right thing for certain cases.
See Paredit, a Visual Guide for how Calva Paredit works for a single cursor (and to appreciate what an effort this is for @riotrah to pull off, and why the rest of us should help with testing.
Test notation
In the Calva tests for structural navigation and editing we use a special document notation, which is easy to read for both the machine and for us humans:
See this CalvaTV video for tutorial: https://www.youtube.com/watch?v=Sy3arG-Degw
A typical report has
We try to keep the document descriptions as minimal as possible. See the first report in the comments for an example.
There's a command for it
The test VSIX has a command for printing the text notation from the state of the current document.
Which makes creating a report involve these steps:
Now you have the Before and Actual texts in the Output channel Calva says. You only need to add the Expected texts yoursefl.
Reported issues
The text was updated successfully, but these errors were encountered: