Skip to content

Commit 3d0d9f9

Browse files
committed
Merge remote-tracking branch 'vim/master'
2 parents 6739711 + 98aff65 commit 3d0d9f9

16 files changed

Lines changed: 411 additions & 204 deletions

src/channel.c

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3615,6 +3615,24 @@ channel_free_all(void)
36153615
// Buffer size for reading incoming messages.
36163616
#define MAXMSGSIZE 4096
36173617

3618+
/*
3619+
* Check if there are remaining data that should be written for "in_part".
3620+
*/
3621+
static int
3622+
is_channel_write_remaining(chanpart_T *in_part)
3623+
{
3624+
buf_T *buf = in_part->ch_bufref.br_buf;
3625+
3626+
if (in_part->ch_writeque.wq_next != NULL)
3627+
return TRUE;
3628+
if (buf == NULL)
3629+
return FALSE;
3630+
return in_part->ch_buf_append
3631+
? (in_part->ch_buf_bot < buf->b_ml.ml_line_count)
3632+
: (in_part->ch_buf_top <= in_part->ch_buf_bot
3633+
&& in_part->ch_buf_top <= buf->b_ml.ml_line_count);
3634+
}
3635+
36183636
#if defined(HAVE_SELECT)
36193637
/*
36203638
* Add write fds where we are waiting for writing to be possible.
@@ -3630,8 +3648,7 @@ channel_fill_wfds(int maxfd_arg, fd_set *wfds)
36303648
chanpart_T *in_part = &ch->ch_part[PART_IN];
36313649

36323650
if (in_part->ch_fd != INVALID_FD
3633-
&& (in_part->ch_bufref.br_buf != NULL
3634-
|| in_part->ch_writeque.wq_next != NULL))
3651+
&& is_channel_write_remaining(in_part))
36353652
{
36363653
FD_SET((int)in_part->ch_fd, wfds);
36373654
if ((int)in_part->ch_fd >= maxfd)
@@ -3655,8 +3672,7 @@ channel_fill_poll_write(int nfd_in, struct pollfd *fds)
36553672
chanpart_T *in_part = &ch->ch_part[PART_IN];
36563673

36573674
if (in_part->ch_fd != INVALID_FD
3658-
&& (in_part->ch_bufref.br_buf != NULL
3659-
|| in_part->ch_writeque.wq_next != NULL))
3675+
&& is_channel_write_remaining(in_part))
36603676
{
36613677
in_part->ch_poll_idx = nfd;
36623678
fds[nfd].fd = in_part->ch_fd;
@@ -3891,8 +3907,6 @@ channel_read(channel_T *channel, ch_part_T part, char *func)
38913907
// Store the read message in the queue.
38923908
channel_save(channel, part, buf, len, FALSE, "RECV ");
38933909
readlen += len;
3894-
if (len < MAXMSGSIZE)
3895-
break; // did read everything that's available
38963910
}
38973911

38983912
// Reading a disconnection (readlen == 0), or an error.

src/eval.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,8 +263,9 @@ eval_expr_typval(typval_T *expr, typval_T *argv, int argc, typval_T *rettv)
263263
if (partial->pt_func != NULL
264264
&& partial->pt_func->uf_def_status != UF_NOT_COMPILED)
265265
{
266+
// FIXME: should create a funccal and link it in current_funccal.
266267
if (call_def_function(partial->pt_func, argc, argv,
267-
partial, rettv) == FAIL)
268+
partial, NULL, rettv) == FAIL)
268269
return FAIL;
269270
}
270271
else

src/evalvars.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3393,7 +3393,8 @@ find_var_ht(char_u *name, char_u **varname)
33933393
if (*name == 'v') // v: variable
33943394
return &vimvarht;
33953395
if (get_current_funccal() != NULL
3396-
&& get_current_funccal()->func->uf_def_status == UF_NOT_COMPILED)
3396+
&& get_current_funccal()->fc_func->uf_def_status
3397+
== UF_NOT_COMPILED)
33973398
{
33983399
// a: and l: are only used in functions defined with ":function"
33993400
if (*name == 'a') // a: function argument

src/gui.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5416,8 +5416,10 @@ gui_do_findrepl(
54165416
if (type == FRD_REPLACEALL)
54175417
{
54185418
ga_concat(&ga, (char_u *)"/");
5419-
// escape slash and backslash
5420-
p = vim_strsave_escaped(repl_text, (char_u *)"/\\");
5419+
// Escape slash and backslash.
5420+
// Also escape tilde and ampersand if 'magic' is set.
5421+
p = vim_strsave_escaped(repl_text,
5422+
p_magic ? (char_u *)"/\\~&" : (char_u *)"/\\");
54215423
if (p != NULL)
54225424
ga_concat(&ga, p);
54235425
vim_free(p);

src/main.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1659,6 +1659,11 @@ getout(int exitval)
16591659
if (!is_not_a_term_or_gui())
16601660
windgoto((int)Rows - 1, 0);
16611661

1662+
#ifdef FEAT_EVAL
1663+
// Invoked all deferred functions in the function stack.
1664+
invoke_all_defer();
1665+
#endif
1666+
16621667
#if defined(FEAT_EVAL) || defined(FEAT_SYN_HL)
16631668
// Optionally print hashtable efficiency.
16641669
hash_debug_results();

src/profiler.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -718,8 +718,8 @@ prof_child_enter(
718718
{
719719
funccall_T *fc = get_current_funccal();
720720

721-
if (fc != NULL && fc->func->uf_profiling)
722-
profile_start(&fc->prof_child);
721+
if (fc != NULL && fc->fc_func->uf_profiling)
722+
profile_start(&fc->fc_prof_child);
723723
script_prof_save(tm);
724724
}
725725

@@ -733,12 +733,12 @@ prof_child_exit(
733733
{
734734
funccall_T *fc = get_current_funccal();
735735

736-
if (fc != NULL && fc->func->uf_profiling)
736+
if (fc != NULL && fc->fc_func->uf_profiling)
737737
{
738-
profile_end(&fc->prof_child);
739-
profile_sub_wait(tm, &fc->prof_child); // don't count waiting time
740-
profile_add(&fc->func->uf_tm_children, &fc->prof_child);
741-
profile_add(&fc->func->uf_tml_children, &fc->prof_child);
738+
profile_end(&fc->fc_prof_child);
739+
profile_sub_wait(tm, &fc->fc_prof_child); // don't count waiting time
740+
profile_add(&fc->fc_func->uf_tm_children, &fc->fc_prof_child);
741+
profile_add(&fc->fc_func->uf_tml_children, &fc->fc_prof_child);
742742
}
743743
script_prof_restore(tm);
744744
}
@@ -753,7 +753,7 @@ prof_child_exit(
753753
func_line_start(void *cookie, long lnum)
754754
{
755755
funccall_T *fcp = (funccall_T *)cookie;
756-
ufunc_T *fp = fcp->func;
756+
ufunc_T *fp = fcp->fc_func;
757757

758758
if (fp->uf_profiling && lnum >= 1 && lnum <= fp->uf_lines.ga_len)
759759
{
@@ -775,7 +775,7 @@ func_line_start(void *cookie, long lnum)
775775
func_line_exec(void *cookie)
776776
{
777777
funccall_T *fcp = (funccall_T *)cookie;
778-
ufunc_T *fp = fcp->func;
778+
ufunc_T *fp = fcp->fc_func;
779779

780780
if (fp->uf_profiling && fp->uf_tml_idx >= 0)
781781
fp->uf_tml_execed = TRUE;
@@ -788,7 +788,7 @@ func_line_exec(void *cookie)
788788
func_line_end(void *cookie)
789789
{
790790
funccall_T *fcp = (funccall_T *)cookie;
791-
ufunc_T *fp = fcp->func;
791+
ufunc_T *fp = fcp->fc_func;
792792

793793
if (fp->uf_profiling && fp->uf_tml_idx >= 0)
794794
{

src/proto/userfunc.pro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ void func_ref(char_u *name);
5959
void func_ptr_ref(ufunc_T *fp);
6060
void ex_return(exarg_T *eap);
6161
int add_defer(char_u *name, int argcount_arg, typval_T *argvars);
62-
void handle_defer(void);
62+
void invoke_all_defer(void);
6363
void ex_call(exarg_T *eap);
6464
int do_return(exarg_T *eap, int reanimate, int is_cmd, void *rettv);
6565
void discard_pending_return(void *rettv);

src/proto/vim9execute.pro

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ void update_has_breakpoint(ufunc_T *ufunc);
44
void funcstack_check_refcount(funcstack_T *funcstack);
55
int set_ref_in_funcstacks(int copyID);
66
int in_def_function(void);
7+
ectx_T *clear_currrent_ectx(void);
8+
void restore_current_ectx(ectx_T *ectx);
79
int add_defer_function(char_u *name, int argcount, typval_T *argvars);
810
char_u *char_from_string(char_u *str, varnumber_T index);
911
char_u *string_slice(char_u *str, varnumber_T first, varnumber_T last, int exclusive);
@@ -13,7 +15,9 @@ typval_T *lookup_debug_var(char_u *name);
1315
int may_break_in_function(ufunc_T *ufunc);
1416
int exe_typval_instr(typval_T *tv, typval_T *rettv);
1517
char_u *exe_substitute_instr(void);
16-
int call_def_function(ufunc_T *ufunc, int argc_arg, typval_T *argv, partial_T *partial, typval_T *rettv);
18+
int call_def_function(ufunc_T *ufunc, int argc_arg, typval_T *argv, partial_T *partial, funccall_T *funccal, typval_T *rettv);
19+
void unwind_def_callstack(ectx_T *ectx);
20+
void may_invoke_defer_funcs(ectx_T *ectx);
1721
void set_context_in_disassemble_cmd(expand_T *xp, char_u *arg);
1822
char_u *get_disassemble_argument(expand_T *xp, int idx);
1923
void ex_disassemble(exarg_T *eap);

src/structs.h

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1735,36 +1735,40 @@ typedef struct
17351735
*/
17361736
struct funccall_S
17371737
{
1738-
ufunc_T *func; // function being called
1739-
int linenr; // next line to be executed
1740-
int returned; // ":return" used
1738+
ufunc_T *fc_func; // function being called
1739+
int fc_linenr; // next line to be executed
1740+
int fc_returned; // ":return" used
17411741
struct // fixed variables for arguments
17421742
{
17431743
dictitem_T var; // variable (without room for name)
17441744
char_u room[VAR_SHORT_LEN]; // room for the name
1745-
} fixvar[FIXVAR_CNT];
1746-
dict_T l_vars; // l: local function variables
1747-
dictitem_T l_vars_var; // variable for l: scope
1748-
dict_T l_avars; // a: argument variables
1749-
dictitem_T l_avars_var; // variable for a: scope
1750-
list_T l_varlist; // list for a:000
1751-
listitem_T l_listitems[MAX_FUNC_ARGS]; // listitems for a:000
1752-
typval_T *rettv; // return value
1753-
linenr_T breakpoint; // next line with breakpoint or zero
1754-
int dbg_tick; // debug_tick when breakpoint was set
1755-
int level; // top nesting level of executed function
1745+
} fc_fixvar[FIXVAR_CNT];
1746+
dict_T fc_l_vars; // l: local function variables
1747+
dictitem_T fc_l_vars_var; // variable for l: scope
1748+
dict_T fc_l_avars; // a: argument variables
1749+
dictitem_T fc_l_avars_var; // variable for a: scope
1750+
list_T fc_l_varlist; // list for a:000
1751+
listitem_T fc_l_listitems[MAX_FUNC_ARGS]; // listitems for a:000
1752+
typval_T *fc_rettv; // return value
1753+
linenr_T fc_breakpoint; // next line with breakpoint or zero
1754+
int fc_dbg_tick; // debug_tick when breakpoint was set
1755+
int fc_level; // top nesting level of executed function
1756+
17561757
garray_T fc_defer; // functions to be called on return
1758+
ectx_T *fc_ectx; // execution context for :def function, NULL
1759+
// otherwise
1760+
17571761
#ifdef FEAT_PROFILE
1758-
proftime_T prof_child; // time spent in a child
1762+
proftime_T fc_prof_child; // time spent in a child
17591763
#endif
1760-
funccall_T *caller; // calling function or NULL; or next funccal in
1764+
funccall_T *fc_caller; // calling function or NULL; or next funccal in
17611765
// list pointed to by previous_funccal.
17621766

17631767
// for closure
17641768
int fc_refcount; // number of user functions that reference this
17651769
// funccal
17661770
int fc_copyID; // for garbage collection
1767-
garray_T fc_funcs; // list of ufunc_T* which keep a reference to
1771+
garray_T fc_ufuncs; // list of ufunc_T* which keep a reference to
17681772
// "func"
17691773
};
17701774

src/testdir/test_gui.vim

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1587,6 +1587,12 @@ func Test_gui_findrepl()
15871587
call test_gui_event('findrepl', args)
15881588
call assert_equal(['ONE two ONE', 'Twoo ONE two ONEo'], getline(1, '$'))
15891589

1590+
" Replace all instances with sub-replace specials
1591+
call cursor(1, 1)
1592+
let args = #{find_text: 'ONE', repl_text: '&~&', flags: 0x4, forward: 1}
1593+
call test_gui_event('findrepl', args)
1594+
call assert_equal(['&~& two &~&', 'Twoo &~& two &~&o'], getline(1, '$'))
1595+
15901596
" Invalid arguments
15911597
call assert_false(test_gui_event('findrepl', {}))
15921598
let args = #{repl_text: 'a', flags: 1, forward: 1}

0 commit comments

Comments
 (0)