@@ -7,118 +7,44 @@ local M = {}
7
7
-- window_get_visible_lines
8
8
-- { [1] = 28, [2] = 74 }
9
9
function M .window_get_visible_lines ()
10
- -- print('window_get_visible_lines()')
11
- return { vim .fn .line (" w0" ), vim .fn .line (" w$" ) }
10
+ -- print('window_get_visible_lines()')
11
+ return { vim .fn .line (" w0" ), vim .fn .line (" w$" ) }
12
12
end
13
13
14
- -- https://www.reddit.com/r/neovim/comments/p4u4zy/how_to_pass_visual_selection_range_to_lua_function/
15
- -- https://neovim.io/doc/user/api.html#nvim_win_get_cursor()
14
+ -- Get the coordinates of the current selection
15
+ -- To manually test follow these steps:
16
+ -- 1. In command mode :vmap <c-a> <Cmd>lua print(vim.inspect(require('cursorless').buffer_get_selection()))<Cr>
17
+ -- 2. type "hello" on the first line and "world" on the second line
18
+ -- 3. Enter visual mode and select "hello" on the first line and continue selection with "world"
19
+ -- on the second line.
20
+ -- 4. Hit ctrl+a to show the selection: {1, 1, 2, 5, false}
21
+ -- 5. Hit 'o' to swap the cursor position and hit ctrl+a again: {1, 1, 2, 5, true}
16
22
--
17
- -- luacheck:ignore 631
18
- -- e.g. run in command mode :vmap <c-a> <Cmd>lua print(vim.inspect(require('cursorless').buffer_get_selection()))<Cr>
19
- -- then go in visual mode with "v" and select "hello" on the first line and continue selection with "air"
20
- -- on the second line.
21
- -- Then hit ctrl+b and it will show the selection
22
- -- cline=2, ccol=2, vline=1, vcol=1
23
- -- sline=1, scol=1, eline=2, ecol=3, reverse=false
24
- -- { 1, 1, 2, 3, false }
25
- --
26
- -- if instead you select from the end of the "air" word on the second line
27
- -- and select up to the beginning of "hello" on the first line
28
- -- cline=1, ccol=0, vline=3, vcol=3
29
- -- sline=1, scol=1, eline=2, ecol=3, reverse=true
30
- -- { 1, 1, 2, 3, true }
31
- --
32
- -- if you want to directly see how it is parsed in the node extension, you can use the below:
33
- -- e.g. run in command mode :vmap <c-a> <Cmd>:call CursorlessLoadExtension()<Cr>
34
- -- and again use ctrl+a after selecting the text
23
+ -- If you want to directly see how it is parsed in the node extension:
24
+ -- 1. run in command mode :vmap <c-a> <Cmd>:call CursorlessLoadExtension()<Cr>
25
+ -- 2. Select some text and hit ctrl+a
35
26
function M .buffer_get_selection ()
36
- -- print('buffer_get_selection()')
37
- local modeInfo = vim .api .nvim_get_mode ()
38
- local mode = modeInfo .mode
39
-
40
- local cursor = vim .api .nvim_win_get_cursor (0 )
41
- local cline , ccol = cursor [1 ], cursor [2 ]
42
- local vline , vcol = vim .fn .line (" v" ), vim .fn .col (" v" )
43
- -- print(('cline=%d, ccol=%d, vline=%d, vcol=%d'):format(cline, ccol, vcol, vcol))
44
-
45
- local sline , scol
46
- local eline , ecol
47
- local reverse
48
- if cline == vline then
49
- -- if ccol <= vcol then
50
- if ccol < vcol then
51
- sline , scol = cline , ccol
52
- eline , ecol = vline , vcol
53
- scol = scol + 1
54
- reverse = true
55
- else
56
- sline , scol = vline , vcol
57
- eline , ecol = cline , ccol
58
- ecol = ecol + 1
59
- reverse = false
60
- end
61
- elseif cline < vline then
62
- sline , scol = cline , ccol
63
- eline , ecol = vline , vcol
64
- scol = scol + 1
65
- reverse = true
66
- else
67
- sline , scol = vline , vcol
68
- eline , ecol = cline , ccol
69
- ecol = ecol + 1
70
- reverse = false
71
- end
72
-
73
- if mode == " V" or mode == " CTRL-V" or mode == " \22 " then
74
- scol = 1
75
- ecol = nil
76
- end
77
-
78
- -- print(
79
- -- ('sline=%d, scol=%d, eline=%d, ecol=%d, reverse=%s'):format(
80
- -- sline,
81
- -- scol,
82
- -- eline,
83
- -- ecol,
84
- -- tostring(reverse)
85
- -- )
86
- -- )
87
- return { sline , scol , eline , ecol , reverse }
88
- end
89
-
90
- -- https://www.reddit.com/r/neovim/comments/p4u4zy/how_to_pass_visual_selection_range_to_lua_function/
91
- -- luacheck:ignore 631
92
- -- e.g. run in command mode :vmap <c-b> <Cmd>lua print(vim.inspect(require('cursorless').buffer_get_selection_text()))<Cr>
93
- -- then go in visual mode with "v" and select "hello" on the first line and continue selection with "air"
94
- -- on the second line.
95
- -- Then hit ctrl+b and it will show the selection
96
- -- { "hello", "air" }
97
- function M .buffer_get_selection_text ()
98
- -- print('buffer_get_selection_text()')
99
- local sline , scol , eline , ecol , _ =
100
- unpack (require (" talon.cursorless" ).buffer_get_selection ())
101
-
102
- local lines = vim .api .nvim_buf_get_lines (0 , sline - 1 , eline , 0 )
103
- if # lines == 0 then
104
- return
105
- end
27
+ local start_pos = vim .fn .getpos (" v" ) -- start of visual selection
28
+ local start_line , start_col = start_pos [2 ], start_pos [3 ]
29
+ local end_pos = vim .fn .getpos (" ." ) -- end of visual selection (cursor position)
30
+ local end_line , end_col = end_pos [2 ], end_pos [3 ]
31
+ local reverse = false
32
+ local mode = vim .api .nvim_get_mode ().mode
106
33
107
- local startText , endText
108
- if # lines == 1 then
109
- startText = string.sub (lines [1 ], scol , ecol )
110
- else
111
- startText = string.sub (lines [1 ], scol )
112
- endText = string.sub (lines [# lines ], 1 , ecol )
113
- end
34
+ -- Invert the values depending on if the cursor is before the start
35
+ if end_line < start_line or end_col < start_col then
36
+ start_line , start_col , end_line , end_col = end_line , end_col , start_line , start_col
37
+ reverse = true
38
+ end
114
39
115
- local selection = { startText }
116
- if # lines > 2 then
117
- vim .list_extend (selection , vim .list_slice (lines , 2 , # lines - 1 ))
118
- end
119
- table.insert (selection , endText )
40
+ -- See https://github.com/cursorless-dev/cursorless/issues/2537 if you want to add more modes
41
+ if mode == " V" then
42
+ -- Line and block-based visual modes are line-based, so we don't need to track the columns
43
+ start_col = 1
44
+ end_col = nil
45
+ end
120
46
121
- return selection
47
+ return { start_line , start_col , end_line , end_col , reverse }
122
48
end
123
49
124
50
-- https://github.com/nvim-treesitter/nvim-treesitter/blob/master/lua/nvim-treesitter/ts_utils.lua#L278
131
57
-- for example it will highlight the last function name (nvim_win_set_cursor).
132
58
-- another example is :tmap <c-b> <Cmd>lua require("talon.cursorless").select_range(4, 0, 4, 38)<Cr>
133
59
-- NOTE: works for any mode (n,i,v,nt) except in t mode
134
- function M .select_range (start_x , start_y , end_x , end_y )
135
- vim .cmd ([[ normal! :noh]] )
136
- vim .api .nvim_win_set_cursor (0 , { start_x , start_y })
137
- vim .cmd ([[ normal v]] )
138
- vim .api .nvim_win_set_cursor (0 , { end_x , end_y })
60
+ function M .select_range (start_line , start_col , end_line , end_col )
61
+ vim .cmd ([[ normal! :noh]] )
62
+ vim .api .nvim_win_set_cursor (0 , { start_line , start_col })
63
+ vim .cmd ([[ normal v]] )
64
+ vim .api .nvim_win_set_cursor (0 , { end_line , end_col })
139
65
end
140
66
141
67
return M
0 commit comments