cursorless-dev / cursorless

Don't let the cursor slow you down
https://www.cursorless.org/
MIT License
1.13k stars 79 forks source link

neovim todo list #2281

Closed saidelike closed 4 months ago

saidelike commented 5 months ago

Pokey and I agreed to create a issue to list all the neovim issues for now. We will be able to create dedicated issues later for each of them.

pokey commented 5 months ago

as discussed, it might be worth trying to switch to terminal mode lazily, and set a flag when you do so so that you change back at the end. Eg don't switch at the beginning, but at the point that an action tries to set selection, do the switch then. Something like that

saidelike commented 5 months ago

We need to have a better handling of selection ranges. I noticed 2 problems.

recorded/marks/chuckNothing fails atm because of the way we set/get selection. When the selection is empty and at the end of the line, we currently don't get the same selection we would have previously set.

languageId: plaintext
command:
  version: 1
  spokenForm: chuck nothing
  action: remove
  targets:
    - type: primitive
      mark: {type: nothing}
initialState:
  documentContents: hello world
  selections:
    - anchor: {line: 0, character: 11}
      active: {line: 0, character: 11}
  marks: {}
finalState:
  documentContents: hello world
  selections:
    - anchor: {line: 0, character: 11}
      active: {line: 0, character: 11}
2024-04-05 20:27:12 WAR runTest(recorded/marks/chuckNothing)...
2024-04-05 20:27:12 WAR updateTextEditor(): window:1000, buffer:1, lines=["hello world"]
2024-04-05 20:27:12 WAR bufferGetSelections(): selections=(0, 0), (0, 0) neovim=(1,1),(1,1),reverse=true
2024-04-05 20:27:12 WAR windowGetVisibleRanges(): range=(0, 0), (0, 10)
2024-04-05 20:27:12 WAR toNeovimEditor(): updating document: buffer=1
2024-04-05 20:27:12 WAR toNeovimEditor(): updating editor: window=1000
2024-04-05 20:27:12 WAR bufferSetSelections() selections=(0,11),(0,11) luaCode="return require("talon.cursorless").select_range(1, 11, 1, 11)"
2024-04-05 20:27:12 WAR updateTextEditor(): window:1000, buffer:1, lines=["hello world"]
2024-04-05 20:27:12 WAR bufferGetSelections(): selections=(0, 10), (0, 11) neovim=(1,11),(1,12),reverse=false
2024-04-05 20:27:12 WAR windowGetVisibleRanges(): range=(0, 0), (0, 10)
 2024-04-05 20:27:12 WAR toNeovimEditor(): updating document: buffer=1
2024-04-05 20:27:12 WAR toNeovimEditor(): updating editor: window=1000
2024-04-05 20:27:18 WAR Failed test: recorded/marks/chuckNothing
2024-04-05 20:27:18 WAR Thrown error: Unexpected final state: expected { …(2) } to deeply equal { …(2) }
2024-04-05 20:27:18 WAR Expected: {
  "documentContents": "hello world",
  "selections": [
    {
      "anchor": {
        "line": 0,
        "character": 11
      },
      "active": {
        "line": 0,
        "character": 11
      }
    }
  ]
}
2024-04-05 20:27:18 WAR Actual: {
  "documentContents": "hello world",
  "selections": [
    {
      "anchor": {
        "line": 0,
        "character": 10
      },
      "active": {
        "line": 0,
        "character": 11
      }
    }
  ]
}

Atm when we read lines using the node-client API (buffer.getLines()). we get the utf-8 decoded data, which is nice. So typically we will get less characters than the actual bytes representing it. Then cursorless works on that data to modify it so typically if we chuck/change/etc. we would work on the decoded data.

However, atm when we want to get/set the selection, typically for a take action, we use the lua API (require("talon.cursorless").buffer_get_selection() or return require("talon.cursorless").select_range()) which typically has no clue of the utf-8 encoding. And so we will just use the number of decoded data which is the only one we know atm, instead of the encoded utf-8 bytes, and so the selection range will typically be less than the actual correct one.

saidelike commented 5 months ago
saidelike commented 5 months ago

as discussed, it might be worth trying to switch to terminal mode lazily, and set a flag when you do so so that you change back at the end. Eg don't switch at the beginning, but at the point that an action tries to set selection, do the switch then. Something like that

Done

saidelike commented 5 months ago

For the UTF8 bug, we could possibly special case using https://github.com/uga-rosa/utf8.nvim/blob/main/doc/utf8.txt but it seems a bit annoying. We have to use an external lib because they don't expose utf8 support in neovim apis atm https://github.com/neovim/neovim/issues/14281

It would be based on detecting that utf8 is used with set fileencoding https://superuser.com/questions/28779/how-do-i-find-the-encoding-of-the-current-buffer-in-vim

pokey commented 5 months ago
  • [ ] atm when we double click some text, it "visually" selects exactly the word (and not one more character like what we do with visual mode in cursorless). and so when we issue copy this, it copies one less character than it is supposed to. I am tempted to move to selecting visually one less character in visual mode / cursorless so it shows better, but then it means we would have to copy one more character than the actual selection.

can you elaborate? or maybe you can show me at next meet-up. Not sure I'm following

pokey commented 5 months ago

For the UTF8 bug, we could possibly special case using https://github.com/uga-rosa/utf8.nvim/blob/main/doc/utf8.txt but it seems a bit annoying. We have to use an external lib because they don't expose utf8 support in neovim apis atm neovim/neovim#14281

It would be based on detecting that utf8 is used with set fileencoding https://superuser.com/questions/28779/how-do-i-find-the-encoding-of-the-current-buffer-in-vim

I think we could use https://neovim.io/doc/user/lua.html#vim.str_byteindex(), no? I believe the stuff still unresolved in https://github.com/neovim/neovim/issues/14281 is just grapheme cluster stuff, which we don't need

saidelike commented 5 months ago

I know that sometimes in the cursorless vscode extension that if an exception occurs, it is propagated to Talon and it is shown in debug logs. It would be nice to do the same, for instance assuming a typo in the lua require(), atm we get this exception in typescript but not shown in Talon:

2024-04-25 10:29:57 INF updateTextEditor(): window:1000, buffer:1, lines=["0123 5678","01 345 789abcdef","aaaa bbbb cccc"]
2024-04-25 10:29:57 ERR failed request to "nvim_execute_lua": Error: nvim_execute_lua: Error executing lua: [string "<nvim>"]:1: module 'talon.cursorless' not found:
        no field package.preload['talon.cursorless']
cache_loader: module talon.cursorless not found
cache_loader_lib: module talon.cursorless not found
        no file '.\talon\cursorless.lua'
        no file 'C:\Program Files\Neovim\bin\lua\talon\cursorless.lua'
        no file 'C:\Program Files\Neovim\bin\lua\talon\cursorless\init.lua'
        no file '.\talon\cursorless.dll'
        no file 'C:\Program Files\Neovim\bin\talon\cursorless.dll'
        no file 'C:\Program Files\Neovim\bin\loadall.dll'
        no file '.\talon.dll'
        no file 'C:\Program Files\Neovim\bin\talon.dll'
        no file 'C:\Program Files\Neovim\bin\loadall.dll'
stack traceback:
        [C]: in function 'require'
        [string "<nvim>"]:1: in main chunk
pokey commented 5 months ago

propagate exception to talon debug output? [ ]

This should work out of the box in the command server, so yeah def looking into why it doesn't work. The command server just wraps running the command in a try-catch and returns an error payload if it catches an exception. I would be tempted to get this working as part of v0. I thought this issue was for tracking follow-up tasks?

saidelike commented 4 months ago

closing because I'm not tracking all them in seperate issues