@@ -104,89 +104,74 @@ local function bytecol_to_utfcol(pos)
104104 return { pos [1 ], vim .str_utfindex (line [1 ] or " " , pos [2 ]) }
105105end
106106
107- local function normal_move_before (new_cur_pos )
108- -- +1: indexing
109- if new_cur_pos [2 ] - 1 > 0 then
110- local keys = vim .api .nvim_replace_termcodes (
111- tostring (new_cur_pos [1 ] + 1 )
112- .. " G0"
113- .. tostring (new_cur_pos [2 ] - 1 )
114- .. " <Right>" ,
115- true ,
116- false ,
117- true
118- )
119- -- passing only "n" doesn't open folds (:h feedkeys).
120- vim .api .nvim_feedkeys (keys , " nt" , true )
121- elseif new_cur_pos [2 ] - 1 == 0 then
122- vim .api .nvim_feedkeys (tostring (new_cur_pos [1 ] + 1 ) .. " G0" , " nt" , true )
123- else
124- -- column is 0, includes end of previous line. Move there.
125- vim .api .nvim_feedkeys (tostring (new_cur_pos [1 ]) .. " G$" , " nt" , true )
126- end
107+ local function replace_feedkeys (keys , opts )
108+ vim .api .nvim_feedkeys (
109+ vim .api .nvim_replace_termcodes (keys , true , false , true ),
110+ -- folds are opened manually now, no need to pass t.
111+ -- n prevents langmap from interfering.
112+ opts or " n" ,
113+ true
114+ )
127115end
128116
129- local function normal_move_on ( new_cur_pos )
130- if new_cur_pos [ 2 ] ~= 0 then
131- local keys = vim . api . nvim_replace_termcodes (
132- tostring ( new_cur_pos [ 1 ] + 1 )
133- .. " G0 "
134- .. tostring ( new_cur_pos [ 2 ])
135- -- open folds!
136- .. " <Right> " ,
137- true ,
138- false ,
139- true
140- )
141- -- passing only "n" doesn't open folds (:h feedkeys).
142- vim . api . nvim_feedkeys ( keys , " nt " , true )
143- else
144- vim . api . nvim_feedkeys ( tostring ( new_cur_pos [ 1 ] + 1 ) .. " G0 " , " nt " , true )
117+ -- pos: (0,0)-indexed.
118+ local function cursor_set_keys ( pos , before )
119+ if before then
120+ if pos [ 2 ] == 0 then
121+ pos [ 1 ] = pos [ 1 ] - 1
122+ -- pos2 is set to last columnt of previous line.
123+ -- # counts bytes, but win_set_cursor expects bytes, so all's good.
124+ pos [ 2 ] = # vim . api . nvim_buf_get_lines (
125+ 0 ,
126+ pos [ 1 ] ,
127+ pos [ 1 ] + 1 ,
128+ false
129+ )[ 1 ]
130+ else
131+ pos [ 2 ] = pos [ 2 ] - 1
132+ end
145133 end
134+
135+ return " <cmd>lua vim.api.nvim_win_set_cursor(0,{"
136+ -- +1, win_set_cursor starts at 1.
137+ .. pos [1 ] + 1
138+ .. " ,"
139+ -- -1 works for multibyte because of rounding, apparently.
140+ .. pos [2 ]
141+ .. " })"
142+ .. " <cr><cmd>:silent! foldopen!<cr>"
143+ end
144+
145+ -- any for any mode.
146+ -- other functions prefixed with eg. normal have to be in that mode, the
147+ -- initial esc removes that need.
148+ local function any_select (b , e )
149+ -- stylua: ignore
150+ replace_feedkeys (
151+ -- this esc -> movement sometimes leads to a slight flicker
152+ -- TODO: look into preventing that reliably.
153+ -- simple move -> <esc>v isn't possible, leaving insert moves the
154+ -- cursor, maybe do check for mode beforehand.
155+ " <esc>"
156+ .. cursor_set_keys (b )
157+ .. " v"
158+ .. (vim .o .selection == " exclusive" and
159+ cursor_set_keys (e ) or
160+ -- set before
161+ cursor_set_keys (e , true ))
162+ .. " o<C-G>" )
146163end
147164
148165local function normal_move_on_insert (new_cur_pos )
149- local keys = vim .api .nvim_replace_termcodes (
150- tostring (new_cur_pos [1 ] + 1 )
151- -- open folds!
152- .. " G0i"
153- .. string.rep (" <Right>" , new_cur_pos [2 ]),
154- true ,
155- false ,
156- true
157- )
158- -- passing only "n" doesn't open folds (:h feedkeys).
159- vim .api .nvim_feedkeys (keys , " nt" , true )
166+ -- moving in normal and going into insert is kind of annoying, eg. when the
167+ -- cursor is, in normal, on a tab, i will set it on the beginning of the
168+ -- tab. There's more problems, but this is very safe.
169+ replace_feedkeys (" i" .. cursor_set_keys (new_cur_pos ))
160170end
161171
162172local function insert_move_on (new_cur_pos )
163- local current_line = get_cursor_0ind ()[1 ]
164-
165- -- only compute diff for lines, seems safer and may even be faster because
166- -- the current column isn't required (cursor returns in bytes, calculating
167- -- columns from bytes costs too).
168- local direction , count
169- if current_line > new_cur_pos [1 ] then
170- -- current line is lower on screen, we need to move up.
171- direction = " <Up>"
172- count = current_line - new_cur_pos [1 ]
173- else
174- direction = " <Down>"
175- count = new_cur_pos [1 ] - current_line
176- end
177-
178- -- stylua: ignore
179- local try =
180- -- move cursor to first column
181- " <Home>"
182- -- move to correct line.
183- .. direction :rep (count )
184- -- move to correct column
185- .. string.rep (" <Right>" , new_cur_pos [2 ])
186-
187- local keys = vim .api .nvim_replace_termcodes (try , true , false , true )
188- -- passing only "n" doesn't open folds (:h feedkeys).
189- vim .api .nvim_feedkeys (keys , " nt" , true )
173+ -- maybe feedkeys this too.
174+ set_cursor_0ind (new_cur_pos )
190175end
191176
192177local function multiline_equal (t1 , t2 )
@@ -569,10 +554,9 @@ return {
569554 get_cursor_0ind = get_cursor_0ind ,
570555 set_cursor_0ind = set_cursor_0ind ,
571556 move_to_mark = move_to_mark ,
572- normal_move_before = normal_move_before ,
573- normal_move_on = normal_move_on ,
574557 normal_move_on_insert = normal_move_on_insert ,
575558 insert_move_on = insert_move_on ,
559+ any_select = any_select ,
576560 remove_n_before_cur = remove_n_before_cur ,
577561 get_current_line_to_cursor = get_current_line_to_cursor ,
578562 mark_pos_equal = mark_pos_equal ,
0 commit comments