@@ -63,53 +63,73 @@ function M.update_selection(buf, node, selection_mode) -- rip from the old ts_ut
6363 vim .fn .setpos (" ." , { buf , end_row , end_col , 0 })
6464end -- }}}
6565
66- M . surf = function (direction , mode , move ) -- {{{
66+ local get_visual_node = function () -- {{{
6767 local node = ts_utils .get_node_at_cursor () -- declare node and bufnr
68- local bufnr = vim .api .nvim_get_current_buf ()
6968
7069 if node == nil then -- prevent errors
7170 return
7271 end
7372
74- if mode == " visual" then
75- local nodeA = node
76- vim .cmd (" normal! o" )
77- local nodeB = ts_utils .get_node_at_cursor ()
78- vim .cmd (" normal! o" )
79- local root = ts_utils .get_root_for_node (node )
80-
81- if nodeA :id () ~= nodeB :id () then -- > get the true node
82- local true_range = find_range_from_2nodes (nodeA , nodeB )
83- local parent = nodeA :parent ()
84- local start_row_P , start_col_P , end_row_P , end_col_P = parent :range ()
85-
86- while
87- start_row_P ~= true_range [1 ]
88- or start_col_P ~= true_range [2 ]
89- or end_row_P ~= true_range [3 ]
90- or end_col_P ~= true_range [4 ]
91- do
92- if parent :parent () == nil then
93- break
94- end
95- parent = parent :parent ()
96- start_row_P , start_col_P , end_row_P , end_col_P = parent :range ()
97- end
73+ local nodeA = node
74+ vim .cmd (" normal! o" )
75+ local nodeB = ts_utils .get_node_at_cursor ()
76+ vim .cmd (" normal! o" )
77+ local root = ts_utils .get_root_for_node (node )
78+
79+ if nodeA :id () ~= nodeB :id () then -- > get the true node
80+ local true_range = find_range_from_2nodes (nodeA , nodeB )
81+ local parent = nodeA :parent ()
82+ local start_row_P , start_col_P , end_row_P , end_col_P = parent :range ()
83+
84+ while
85+ start_row_P ~= true_range [1 ]
86+ or start_col_P ~= true_range [2 ]
87+ or end_row_P ~= true_range [3 ]
88+ or end_col_P ~= true_range [4 ]
89+ do
90+ if parent :parent () == nil then
91+ break
92+ end
93+ parent = parent :parent ()
94+ start_row_P , start_col_P , end_row_P , end_col_P = parent :range ()
95+ end
9896
99- node = parent
100- end
97+ node = parent
98+ end
10199
102- if node == root then -- catch some edge cases
103- node = nodeA
104- end
105- end
100+ if node == root then -- catch some edge cases
101+ node = nodeA
102+ end
106103
107104 local parent = node :parent () -- > if parent only has 1 child, move up the tree
108105 while parent ~= nil and parent :named_child_count () == 1 do
109106 node = parent
110107 parent = node :parent ()
111108 end
112109
110+ return node
111+
112+ end -- }}}
113+
114+ M .surf = function (direction , mode , move ) -- {{{
115+ local node = ts_utils .get_node_at_cursor () -- declare node and bufnr
116+ local bufnr = vim .api .nvim_get_current_buf ()
117+
118+ if node == nil then -- prevent errors
119+ return
120+ end
121+
122+ if mode == " visual" then -- {{{
123+ node = get_visual_node ()
124+ else
125+ local parent = node :parent ()
126+ while parent ~= nil and parent :named_child_count () == 1 do
127+ node = parent
128+ parent = node :parent ()
129+ end
130+ end -- }}}
131+
132+
113133 local target -- > setting the target, depending on the direction
114134 if direction == " parent" then
115135 target = node :parent ()
@@ -866,22 +886,22 @@ end, {})
866886
867887-- version 2.2
868888
889+
869890local held_node = nil -- store the held node internally
870- local function hold_focused_node () -- {{{
871- local new_node = ts_utils .get_node_at_cursor ()
891+ local function hold_node (node ) -- {{{
872892 local bufnr = vim .api .nvim_get_current_buf ()
873893
874- if new_node ~= nil then
875- local end_row , end_col = new_node :end_ ()
894+ if node ~= nil then
895+ local end_row , end_col = node :end_ ()
876896
877897 -- clear old extmark
878898 if held_node and held_node .extmark_id then
879- api .nvim_buf_del_extmark (0 , ns , held_node .extmark_id )
899+ -- api.nvim_buf_del_extmark(0, ns, held_node.extmark_id)
880900 end
881901
882902 -- store the held node with extra data for checks/extmark deletion
883903 held_node = {
884- node = new_node ,
904+ node = node ,
885905 bufnr = bufnr ,
886906 extmark_id = set_extmark_then_delete_it ( -- set the extmark and save it for deletion
887907 end_row ,
@@ -894,11 +914,11 @@ local function hold_focused_node() --{{{
894914 end
895915end -- }}}
896916
897- local function swap_held_and_focused_node ( ) -- {{{
917+ local function swap_held_node ( node ) -- {{{
898918 local bufnr = vim .api .nvim_get_current_buf ()
899919
900920 if held_node ~= nil and held_node .bufnr == bufnr then -- make sure we're swapping nodes in the same buffer
901- ts_utils .swap_nodes (held_node .node , ts_utils . get_node_at_cursor () , bufnr , true )
921+ ts_utils .swap_nodes (held_node .node , node , bufnr , true )
902922 api .nvim_buf_del_extmark (0 , ns , held_node .extmark_id ) -- clear the extmark, probably don't need it after this
903923 held_node = nil
904924 else
@@ -910,16 +930,28 @@ local function swap_held_and_focused_node() --{{{
910930 end
911931end -- }}}
912932
913- local function hold_or_swap () -- {{{
933+ local function hold_or_swap (visual_mode ) -- {{{
914934 if held_node == nil then
915- hold_focused_node ()
935+ if visual_mode then
936+ hold_node (get_visual_node ())
937+ else
938+ hold_node (ts_utils .get_node_at_cursor ())
939+ end
916940 else
917- swap_held_and_focused_node ()
941+ if visual_mode then
942+ swap_held_node (get_visual_node ())
943+ else
944+ swap_held_node (ts_utils .get_node_at_cursor ())
945+ end
918946 end
919947end -- }}}
920948
921949vim .api .nvim_create_user_command (" STSSwapOrHold" , function ()
922- hold_or_swap ()
950+ hold_or_swap (false )
951+ end , {})
952+
953+ vim .api .nvim_create_user_command (" STSSwapOrHoldVisual" , function ()
954+ hold_or_swap (true )
923955end , {})
924956
925957return M
0 commit comments