@@ -119,6 +119,59 @@ find_win_for_curbuf(void)
119119 }
120120}
121121
122+ typedef struct {
123+ win_T * cob_curwin_save ;
124+ aco_save_T cob_aco ;
125+ int cob_using_aco ;
126+ int cob_save_VIsual_active ;
127+ } cob_T ;
128+
129+ /*
130+ * Used before making a change in "buf", which is not the current one: Make
131+ * "buf" the current buffer and find a window for this buffer, so that side
132+ * effects are done correctly (e.g., adjusting marks).
133+ *
134+ * Information is saved in "cob" and MUST be restored by calling
135+ * change_other_buffer_restore().
136+ */
137+ static void
138+ change_other_buffer_prepare (cob_T * cob , buf_T * buf )
139+ {
140+ CLEAR_POINTER (cob );
141+
142+ // Set "curbuf" to the buffer being changed. Then make sure there is a
143+ // window for it to handle any side effects.
144+ cob -> cob_save_VIsual_active = VIsual_active ;
145+ VIsual_active = FALSE;
146+ cob -> cob_curwin_save = curwin ;
147+ curbuf = buf ;
148+ find_win_for_curbuf (); // simplest: find existing window for "buf"
149+
150+ if (curwin -> w_buffer != buf )
151+ {
152+ // No existing window for this buffer. It is dangerous to have
153+ // curwin->w_buffer differ from "curbuf", use the autocmd window.
154+ curbuf = curwin -> w_buffer ;
155+ aucmd_prepbuf (& cob -> cob_aco , buf );
156+ cob -> cob_using_aco = TRUE;
157+ }
158+ }
159+
160+ static void
161+ change_other_buffer_restore (cob_T * cob )
162+ {
163+ if (cob -> cob_using_aco )
164+ {
165+ aucmd_restbuf (& cob -> cob_aco );
166+ }
167+ else
168+ {
169+ curwin = cob -> cob_curwin_save ;
170+ curbuf = curwin -> w_buffer ;
171+ }
172+ VIsual_active = cob -> cob_save_VIsual_active ;
173+ }
174+
122175/*
123176 * Set line or list of lines in buffer "buf" to "lines".
124177 * Any type is allowed and converted to a string.
@@ -137,10 +190,6 @@ set_buffer_lines(
137190 listitem_T * li = NULL ;
138191 long added = 0 ;
139192 linenr_T append_lnum ;
140- win_T * curwin_save = NULL ;
141- aco_save_T aco ;
142- int using_aco = FALSE;
143- int save_VIsual_active = VIsual_active ;
144193
145194 // When using the current buffer ml_mfp will be set if needed. Useful when
146195 // setline() is used on startup. For other buffers the buffer must be
@@ -154,24 +203,11 @@ set_buffer_lines(
154203 return ;
155204 }
156205
206+ // After this don't use "return", goto "cleanup"!
207+ cob_T cob ;
157208 if (!is_curbuf )
158- {
159- // Set "curbuf" to the buffer being changed. Then make sure there is a
160- // window for it to handle any side effects.
161- VIsual_active = FALSE;
162- curwin_save = curwin ;
163- curbuf = buf ;
164- find_win_for_curbuf (); // simplest: find existing window for "buf"
165-
166- if (curwin -> w_buffer != buf )
167- {
168- // No existing window for this buffer. It is dangerous to have
169- // curwin->w_buffer differ from "curbuf", use the autocmd window.
170- curbuf = curwin -> w_buffer ;
171- aucmd_prepbuf (& aco , buf );
172- using_aco = TRUE;
173- }
174- }
209+ // set "curbuf" to "buf" and find a window for this buffer
210+ change_other_buffer_prepare (& cob , buf );
175211
176212 if (append )
177213 // appendbufline() uses the line number below which we insert
@@ -272,18 +308,7 @@ set_buffer_lines(
272308
273309done :
274310 if (!is_curbuf )
275- {
276- if (using_aco )
277- {
278- aucmd_restbuf (& aco );
279- }
280- else
281- {
282- curwin = curwin_save ;
283- curbuf = curwin -> w_buffer ;
284- }
285- VIsual_active = save_VIsual_active ;
286- }
311+ change_other_buffer_restore (& cob );
287312}
288313
289314/*
@@ -521,12 +546,9 @@ f_deletebufline(typval_T *argvars, typval_T *rettv)
521546 linenr_T lnum ;
522547 long count ;
523548 int is_curbuf ;
524- buf_T * curbuf_save = NULL ;
525- win_T * curwin_save = NULL ;
526549 tabpage_T * tp ;
527550 win_T * wp ;
528551 int did_emsg_before = did_emsg ;
529- int save_VIsual_active = VIsual_active ;
530552
531553 rettv -> vval .v_number = 1 ; // FAIL by default
532554
@@ -539,7 +561,6 @@ f_deletebufline(typval_T *argvars, typval_T *rettv)
539561 buf = tv_get_buf (& argvars [0 ], FALSE);
540562 if (buf == NULL )
541563 return ;
542- is_curbuf = buf == curbuf ;
543564
544565 first = tv_get_lnum_buf (& argvars [1 ], buf );
545566 if (did_emsg > did_emsg_before )
@@ -554,14 +575,12 @@ f_deletebufline(typval_T *argvars, typval_T *rettv)
554575 return ;
555576
556577 // After this don't use "return", goto "cleanup"!
578+ is_curbuf = buf == curbuf ;
579+ cob_T cob ;
557580 if (!is_curbuf )
558- {
559- VIsual_active = FALSE;
560- curbuf_save = curbuf ;
561- curwin_save = curwin ;
562- curbuf = buf ;
563- find_win_for_curbuf ();
564- }
581+ // set "curbuf" to "buf" and find a window for this buffer
582+ change_other_buffer_prepare (& cob , buf );
583+
565584 if (last > curbuf -> b_ml .ml_line_count )
566585 last = curbuf -> b_ml .ml_line_count ;
567586 count = last - first + 1 ;
@@ -599,11 +618,7 @@ f_deletebufline(typval_T *argvars, typval_T *rettv)
599618
600619cleanup :
601620 if (!is_curbuf )
602- {
603- curbuf = curbuf_save ;
604- curwin = curwin_save ;
605- VIsual_active = save_VIsual_active ;
606- }
621+ change_other_buffer_restore (& cob );
607622}
608623
609624/*
0 commit comments