Mercurial > vim
comparison src/main.c @ 18116:7f57ea9a4ba8 v8.1.2053
patch 8.1.2053: SafeStateAgain not triggered if callback uses feedkeys()
Commit: https://github.com/vim/vim/commit/d103ee78432f9036d243b18dd5aac1263d3b7dc9
Author: Bram Moolenaar <Bram@vim.org>
Date: Wed Sep 18 21:15:31 2019 +0200
patch 8.1.2053: SafeStateAgain not triggered if callback uses feedkeys()
Problem: SafeStateAgain not triggered if callback uses feedkeys().
Solution: Check for safe state in the input loop. Make log messages easier
to find. Add 'S' flag to state().
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Wed, 18 Sep 2019 21:30:03 +0200 |
parents | 76126690dd92 |
children | 1868ec23360e |
comparison
equal
deleted
inserted
replaced
18115:bd18e9db370e | 18116:7f57ea9a4ba8 |
---|---|
1047 && current_oap->op_type == OP_NOP | 1047 && current_oap->op_type == OP_NOP |
1048 && current_oap->regname == NUL); | 1048 && current_oap->regname == NUL); |
1049 } | 1049 } |
1050 | 1050 |
1051 /* | 1051 /* |
1052 * Return whether currently it is safe, assuming it was safe before (high level | |
1053 * state didn't change). | |
1054 */ | |
1055 static int | |
1056 is_safe_now(void) | |
1057 { | |
1058 return stuff_empty() | |
1059 && typebuf.tb_len == 0 | |
1060 && scriptin[curscript] == NULL | |
1061 && !global_busy; | |
1062 } | |
1063 | |
1064 /* | |
1052 * Trigger SafeState if currently in s safe state, that is "safe" is TRUE and | 1065 * Trigger SafeState if currently in s safe state, that is "safe" is TRUE and |
1053 * there is no typeahead. | 1066 * there is no typeahead. |
1054 */ | 1067 */ |
1055 void | 1068 void |
1056 may_trigger_safestate(int safe) | 1069 may_trigger_safestate(int safe) |
1057 { | 1070 { |
1058 int is_safe = safe | 1071 int is_safe = safe && is_safe_now(); |
1059 && stuff_empty() | |
1060 && typebuf.tb_len == 0 | |
1061 && scriptin[curscript] == NULL | |
1062 && !global_busy; | |
1063 | 1072 |
1064 #ifdef FEAT_JOB_CHANNEL | 1073 #ifdef FEAT_JOB_CHANNEL |
1065 if (was_safe != is_safe) | 1074 if (was_safe != is_safe) |
1066 // Only log when the state changes, otherwise it happens at nearly | 1075 // Only log when the state changes, otherwise it happens at nearly |
1067 // every key stroke. | 1076 // every key stroke. |
1068 ch_log(NULL, is_safe ? "Start triggering SafeState" | 1077 ch_log(NULL, is_safe ? "SafeState: Start triggering" |
1069 : "Stop triggering SafeState"); | 1078 : "SafeState: Stop triggering"); |
1070 #endif | 1079 #endif |
1071 if (is_safe) | 1080 if (is_safe) |
1072 apply_autocmds(EVENT_SAFESTATE, NULL, NULL, FALSE, curbuf); | 1081 apply_autocmds(EVENT_SAFESTATE, NULL, NULL, FALSE, curbuf); |
1073 was_safe = is_safe; | 1082 was_safe = is_safe; |
1074 } | 1083 } |
1077 * Something changed which causes the state possibly to be unsafe, e.g. a | 1086 * Something changed which causes the state possibly to be unsafe, e.g. a |
1078 * character was typed. It will remain unsafe until the next call to | 1087 * character was typed. It will remain unsafe until the next call to |
1079 * may_trigger_safestate(). | 1088 * may_trigger_safestate(). |
1080 */ | 1089 */ |
1081 void | 1090 void |
1082 state_no_longer_safe(void) | 1091 state_no_longer_safe(char *reason UNUSED) |
1083 { | 1092 { |
1084 #ifdef FEAT_JOB_CHANNEL | 1093 #ifdef FEAT_JOB_CHANNEL |
1085 if (was_safe) | 1094 if (was_safe) |
1086 ch_log(NULL, "safe state reset"); | 1095 ch_log(NULL, "SafeState: reset: %s", reason); |
1087 #endif | 1096 #endif |
1088 was_safe = FALSE; | 1097 was_safe = FALSE; |
1098 } | |
1099 | |
1100 int | |
1101 get_was_safe_state(void) | |
1102 { | |
1103 return was_safe; | |
1089 } | 1104 } |
1090 | 1105 |
1091 /* | 1106 /* |
1092 * Invoked when leaving code that invokes callbacks. Then trigger | 1107 * Invoked when leaving code that invokes callbacks. Then trigger |
1093 * SafeStateAgain, if it was safe when starting to wait for a character. | 1108 * SafeStateAgain, if it was safe when starting to wait for a character. |
1094 */ | 1109 */ |
1095 void | 1110 void |
1096 may_trigger_safestateagain(void) | 1111 may_trigger_safestateagain(void) |
1097 { | 1112 { |
1113 if (!was_safe) | |
1114 { | |
1115 // If the safe state was reset in state_no_longer_safe(), e.g. because | |
1116 // of calling feedkeys(), we check if it's now safe again (all keys | |
1117 // were consumed). | |
1118 was_safe = is_safe_now(); | |
1119 #ifdef FEAT_JOB_CHANNEL | |
1120 if (was_safe) | |
1121 ch_log(NULL, "SafeState: undo reset"); | |
1122 #endif | |
1123 } | |
1098 if (was_safe) | 1124 if (was_safe) |
1099 { | 1125 { |
1100 #ifdef FEAT_JOB_CHANNEL | 1126 #ifdef FEAT_JOB_CHANNEL |
1101 ch_log(NULL, "Leaving unsafe area, triggering SafeStateAgain"); | 1127 ch_log(NULL, "SafeState: back to waiting, triggering SafeStateAgain"); |
1102 #endif | 1128 #endif |
1103 apply_autocmds(EVENT_SAFESTATEAGAIN, NULL, NULL, FALSE, curbuf); | 1129 apply_autocmds(EVENT_SAFESTATEAGAIN, NULL, NULL, FALSE, curbuf); |
1104 } | 1130 } |
1105 #ifdef FEAT_JOB_CHANNEL | 1131 #ifdef FEAT_JOB_CHANNEL |
1106 else | 1132 else |
1107 ch_log(NULL, "Leaving unsafe area, not triggering SafeStateAgain"); | 1133 ch_log(NULL, |
1134 "SafeState: back to waiting, not triggering SafeStateAgain"); | |
1108 #endif | 1135 #endif |
1109 } | 1136 } |
1110 | 1137 |
1111 | 1138 |
1112 /* | 1139 /* |