diff src/misc1.c @ 25790:16a7d1154be8 v8.2.3430

patch 8.2.3430: no generic way to trigger an autocommand on mode change Commit: https://github.com/vim/vim/commit/f1e8876fa2359b572d262772747405d3616db670 Author: =?UTF-8?q?Magnus=20Gro=C3=9F?= <magnus.gross@rwth-aachen.de> Date: Sun Sep 12 13:39:55 2021 +0200 patch 8.2.3430: no generic way to trigger an autocommand on mode change Problem: No generic way to trigger an autocommand on mode change. Solution: Add the ModeChanged autocommand event. (Magnus Gross, closes https://github.com/vim/vim/issues/8856)
author Bram Moolenaar <Bram@vim.org>
date Sun, 12 Sep 2021 13:45:05 +0200
parents 4101d78f78e2
children 2d0bea8aed33
line wrap: on
line diff
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -630,7 +630,7 @@ ask_yesno(char_u *str, int direct)
     void
 f_mode(typval_T *argvars, typval_T *rettv)
 {
-    char_u	buf[4];
+    char_u	buf[MODE_MAX_LENGTH];
 
     if (in_vim9script() && check_for_opt_bool_arg(argvars, 0) == FAIL)
 	return;
@@ -2643,3 +2643,42 @@ path_with_url(char_u *fname)
     // "://" or ":\\" must follow
     return path_is_url(p);
 }
+
+/*
+ * Fires a ModeChanged autocmd
+ */
+    void
+trigger_modechanged()
+{
+#if defined(FEAT_EVAL) || defined(PROTO)
+    dict_T	    *v_event;
+    typval_T	    rettv;
+    typval_T	    tv;
+    char_u	    *pat_pre;
+    char_u	    *pat;
+
+    if (!has_modechanged())
+	return;
+
+    v_event = get_vim_var_dict(VV_EVENT);
+
+    tv.v_type = VAR_UNKNOWN;
+    f_mode(&tv, &rettv);
+    (void)dict_add_string(v_event, "new_mode", rettv.vval.v_string);
+    (void)dict_add_string(v_event, "old_mode", last_mode);
+    dict_set_items_ro(v_event);
+
+    // concatenate modes in format "old_mode:new_mode"
+    pat_pre = concat_str(last_mode, (char_u*)":");
+    pat = concat_str(pat_pre, rettv.vval.v_string);
+    vim_free(pat_pre);
+
+    apply_autocmds(EVENT_MODECHANGED, pat, NULL, FALSE, curbuf);
+    STRCPY(last_mode, rettv.vval.v_string);
+
+    vim_free(rettv.vval.v_string);
+    vim_free(pat);
+    dict_free_contents(v_event);
+    hash_init(&v_event->dv_hashtab);
+#endif
+}