• R/O
  • SSH

vim: Commit

Mirror of the Vim source from https://github.com/vim/vim


Commit MetaInfo

Revisiona2870e6f5b453631c7946ce0617b92043ea3be83 (tree)
Time2019-09-16 06:15:03
AuthorBram Moolenaar <Bram@vim....>
CommiterBram Moolenaar

Log Message

patch 8.1.2044: no easy way to process postponed work

Commit: https://github.com/vim/vim/commit/8aeec40207b5adcd3a155277dc4f29189343b963
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Sep 15 23:02:04 2019 +0200

patch 8.1.2044: no easy way to process postponed work
Problem: No easy way to process postponed work. (Paul Jolly)
Solution: Add the SafeState autocommand event.

Change Summary

Incremental Difference

diff -r 1608410ff8f3 -r a2870e6f5b45 runtime/doc/autocmd.txt
--- a/runtime/doc/autocmd.txt Sun Sep 15 21:15:04 2019 +0200
+++ b/runtime/doc/autocmd.txt Sun Sep 15 23:15:03 2019 +0200
@@ -355,6 +355,9 @@
355355 when popup menu visible
356356 |TextYankPost| after text has been yanked or deleted
357357
358+|SafeState| nothing pending, going to wait for the user to type a
359+ character
360+
358361 |ColorSchemePre| before loading a color scheme
359362 |ColorScheme| after loading a color scheme
360363
@@ -955,6 +958,27 @@
955958 Note that even if an autocommand is defined,
956959 the reply should be read with |remote_read()|
957960 to consume it.
961+ *SafeState*
962+SafeState When nothing is pending, going to wait for the
963+ user to type a character.
964+ This will not be triggered when:
965+ - an operator is pending
966+ - a register was entered with "r
967+ - halfway executing a command
968+ - executing a mapping
969+ - there is typeahead
970+ - Insert mode completion is active
971+ - Command line completion is active
972+ You can use `mode()` to find out what state
973+ Vim is in. That may be:
974+ - VIsual mode
975+ - Normal mode
976+ - Insert mode
977+ - Command-line mode
978+ Depending on what you want to do, you may also
979+ check more with `state()`, e.g. whether the
980+ screen was scrolled for messages.
981+
958982 *SessionLoadPost*
959983 SessionLoadPost After loading the session file created using
960984 the |:mksession| command.
diff -r 1608410ff8f3 -r a2870e6f5b45 src/autocmd.c
--- a/src/autocmd.c Sun Sep 15 21:15:04 2019 +0200
+++ b/src/autocmd.c Sun Sep 15 23:15:03 2019 +0200
@@ -155,6 +155,7 @@
155155 {"QuickFixCmdPre", EVENT_QUICKFIXCMDPRE},
156156 {"QuitPre", EVENT_QUITPRE},
157157 {"RemoteReply", EVENT_REMOTEREPLY},
158+ {"SafeState", EVENT_SAFESTATE},
158159 {"SessionLoadPost", EVENT_SESSIONLOADPOST},
159160 {"ShellCmdPost", EVENT_SHELLCMDPOST},
160161 {"ShellFilterPost", EVENT_SHELLFILTERPOST},
diff -r 1608410ff8f3 -r a2870e6f5b45 src/channel.c
--- a/src/channel.c Sun Sep 15 21:15:04 2019 +0200
+++ b/src/channel.c Sun Sep 15 23:15:03 2019 +0200
@@ -3589,10 +3589,17 @@
35893589 sock_T fd;
35903590 int timeout;
35913591 chanpart_T *chanpart = &channel->ch_part[part];
3592+ int retval = FAIL;
35923593
35933594 ch_log(channel, "Blocking read JSON for id %d", id);
3595+
3596+ // Not considered a safe state here, since we are processing a JSON message
3597+ // and parsing other messages while waiting.
3598+ enter_unsafe_state();
3599+
35943600 if (id >= 0)
35953601 channel_add_block_id(chanpart, id);
3602+
35963603 for (;;)
35973604 {
35983605 more = channel_parse_json(channel, part);
@@ -3600,10 +3607,9 @@
36003607 // search for message "id"
36013608 if (channel_get_json(channel, part, id, TRUE, rettv) == OK)
36023609 {
3603- if (id >= 0)
3604- channel_remove_block_id(chanpart, id);
36053610 ch_log(channel, "Received JSON for id %d", id);
3606- return OK;
3611+ retval = OK;
3612+ break;
36073613 }
36083614
36093615 if (!more)
@@ -3659,7 +3665,11 @@
36593665 }
36603666 if (id >= 0)
36613667 channel_remove_block_id(chanpart, id);
3662- return FAIL;
3668+
3669+ // This may trigger a SafeState autocommand.
3670+ leave_unsafe_state();
3671+
3672+ return retval;
36633673 }
36643674
36653675 /*
@@ -4195,9 +4205,9 @@
41954205 free_job_options(&opt);
41964206 }
41974207
4198-# define KEEP_OPEN_TIME 20 /* msec */
4199-
4200-# if (defined(UNIX) && !defined(HAVE_SELECT)) || defined(PROTO)
4208+#define KEEP_OPEN_TIME 20 /* msec */
4209+
4210+#if (defined(UNIX) && !defined(HAVE_SELECT)) || defined(PROTO)
42014211 /*
42024212 * Add open channels to the poll struct.
42034213 * Return the adjusted struct index.
@@ -4288,9 +4298,9 @@
42884298
42894299 return ret;
42904300 }
4291-# endif /* UNIX && !HAVE_SELECT */
4292-
4293-# if (!defined(MSWIN) && defined(HAVE_SELECT)) || defined(PROTO)
4301+#endif /* UNIX && !HAVE_SELECT */
4302+
4303+#if (!defined(MSWIN) && defined(HAVE_SELECT)) || defined(PROTO)
42944304
42954305 /*
42964306 * The "fd_set" type is hidden to avoid problems with the function proto.
@@ -4381,7 +4391,7 @@
43814391 if (ret > 0 && in_part->ch_fd != INVALID_FD
43824392 && FD_ISSET(in_part->ch_fd, wfds))
43834393 {
4384- /* Clear the flag first, ch_fd may change in channel_write_input(). */
4394+ // Clear the flag first, ch_fd may change in channel_write_input().
43854395 FD_CLR(in_part->ch_fd, wfds);
43864396 channel_write_input(channel);
43874397 --ret;
@@ -4390,11 +4400,12 @@
43904400
43914401 return ret;
43924402 }
4393-# endif /* !MSWIN && HAVE_SELECT */
4403+#endif // !MSWIN && HAVE_SELECT
43944404
43954405 /*
43964406 * Execute queued up commands.
4397- * Invoked from the main loop when it's safe to execute received commands.
4407+ * Invoked from the main loop when it's safe to execute received commands,
4408+ * and during a blocking wait for ch_evalexpr().
43984409 * Return TRUE when something was done.
43994410 */
44004411 int
diff -r 1608410ff8f3 -r a2870e6f5b45 src/edit.c
--- a/src/edit.c Sun Sep 15 21:15:04 2019 +0200
+++ b/src/edit.c Sun Sep 15 23:15:03 2019 +0200
@@ -1509,6 +1509,11 @@
15091509 (linenr_T)(curwin->w_cursor.lnum + 1));
15101510 }
15111511
1512+ // Trigger SafeState if nothing is pending.
1513+ may_trigger_safestate(ready
1514+ && !ins_compl_active()
1515+ && !pum_visible());
1516+
15121517 #if defined(FEAT_CONCEAL)
15131518 if ((conceal_update_lines
15141519 && (conceal_old_cursor_line != conceal_new_cursor_line
diff -r 1608410ff8f3 -r a2870e6f5b45 src/ex_getln.c
--- a/src/ex_getln.c Sun Sep 15 21:15:04 2019 +0200
+++ b/src/ex_getln.c Sun Sep 15 23:15:03 2019 +0200
@@ -971,6 +971,9 @@
971971 that occurs while typing a command should
972972 cause the command not to be executed. */
973973
974+ // Trigger SafeState if nothing is pending.
975+ may_trigger_safestate(xpc.xp_numfiles <= 0);
976+
974977 cursorcmd(); /* set the cursor on the right spot */
975978
976979 /* Get a character. Ignore K_IGNORE and K_NOP, they should not do
diff -r 1608410ff8f3 -r a2870e6f5b45 src/main.c
--- a/src/main.c Sun Sep 15 21:15:04 2019 +0200
+++ b/src/main.c Sun Sep 15 23:15:03 2019 +0200
@@ -1028,6 +1028,64 @@
10281028 return params.not_a_term;
10291029 }
10301030
1031+
1032+static int was_safe = FALSE;
1033+static int not_safe_now = 0;
1034+
1035+/*
1036+ * Trigger SafeState if currently in a safe state for main_loop().
1037+ */
1038+ static void
1039+may_trigger_safestate_main(oparg_T *oap)
1040+{
1041+ may_trigger_safestate(
1042+ !finish_op
1043+ && oap->prev_opcount > 0
1044+ && oap->prev_count0 == 0
1045+ && oap->op_type == OP_NOP
1046+ && oap->regname == NUL
1047+ && restart_edit == 0);
1048+}
1049+
1050+/*
1051+ * Trigger SafeState if currently in s safe state, that is "safe" is TRUE and
1052+ * there is no typeahead.
1053+ */
1054+ void
1055+may_trigger_safestate(int safe)
1056+{
1057+ int is_safe = safe
1058+ && stuff_empty()
1059+ && typebuf.tb_len == 0
1060+ && !global_busy;
1061+
1062+ if (is_safe)
1063+ apply_autocmds(EVENT_SAFESTATE, NULL, NULL, FALSE, curbuf);
1064+ was_safe = is_safe;
1065+}
1066+
1067+/*
1068+ * Entering a not-safe state.
1069+ */
1070+ void
1071+enter_unsafe_state(void)
1072+{
1073+ ++not_safe_now;
1074+}
1075+
1076+/*
1077+ * Leaving a not-safe state. Trigger SafeState if we were in a safe state
1078+ * before first calling enter_not_safe_state().
1079+ */
1080+ void
1081+leave_unsafe_state(void)
1082+{
1083+ --not_safe_now;
1084+ if (not_safe_now == 0 && was_safe)
1085+ apply_autocmds(EVENT_SAFESTATE, NULL, NULL, FALSE, curbuf);
1086+}
1087+
1088+
10311089 /*
10321090 * Main loop: Execute Normal mode commands until exiting Vim.
10331091 * Also used to handle commands in the command-line window, until the window
@@ -1133,6 +1191,9 @@
11331191 msg_scroll = FALSE;
11341192 quit_more = FALSE;
11351193
1194+ // it's not safe unless may_trigger_safestate_main() is called
1195+ was_safe = FALSE;
1196+
11361197 /*
11371198 * If skip redraw is set (for ":" in wait_return()), don't redraw now.
11381199 * If there is nothing in the stuff_buffer or do_redraw is TRUE,
@@ -1211,6 +1272,10 @@
12111272 curbuf->b_last_changedtick = CHANGEDTICK(curbuf);
12121273 }
12131274
1275+ // If nothing is pending and we are going to wait for the user to
1276+ // type a character, trigger SafeState.
1277+ may_trigger_safestate_main(&oa);
1278+
12141279 #if defined(FEAT_DIFF)
12151280 // Updating diffs from changed() does not always work properly,
12161281 // esp. updating folds. Do an update just before redrawing if
diff -r 1608410ff8f3 -r a2870e6f5b45 src/proto/main.pro
--- a/src/proto/main.pro Sun Sep 15 21:15:04 2019 +0200
+++ b/src/proto/main.pro Sun Sep 15 23:15:03 2019 +0200
@@ -2,6 +2,9 @@
22 int vim_main2(void);
33 void common_init(mparm_T *paramp);
44 int is_not_a_term(void);
5+void may_trigger_safestate(int safe);
6+void enter_unsafe_state(void);
7+void leave_unsafe_state(void);
58 void main_loop(int cmdwin, int noexmode);
69 void getout_preserve_modified(int exitval);
710 void getout(int exitval);
diff -r 1608410ff8f3 -r a2870e6f5b45 src/version.c
--- a/src/version.c Sun Sep 15 21:15:04 2019 +0200
+++ b/src/version.c Sun Sep 15 23:15:03 2019 +0200
@@ -758,6 +758,8 @@
758758 static int included_patches[] =
759759 { /* Add new patch number below this line */
760760 /**/
761+ 2044,
762+/**/
761763 2043,
762764 /**/
763765 2042,
diff -r 1608410ff8f3 -r a2870e6f5b45 src/vim.h
--- a/src/vim.h Sun Sep 15 21:15:04 2019 +0200
+++ b/src/vim.h Sun Sep 15 23:15:03 2019 +0200
@@ -1315,6 +1315,7 @@
13151315 EVENT_QUICKFIXCMDPRE, // before :make, :grep etc.
13161316 EVENT_QUITPRE, // before :quit
13171317 EVENT_REMOTEREPLY, // upon string reception from a remote vim
1318+ EVENT_SAFESTATE, // going to wait for a character
13181319 EVENT_SESSIONLOADPOST, // after loading a session file
13191320 EVENT_SHELLCMDPOST, // after ":!cmd"
13201321 EVENT_SHELLFILTERPOST, // after ":1,2!cmd", ":w !cmd", ":r !cmd".
Show on old repository browser