comparison src/quickfix.c @ 24590:2818f846f099 v8.2.2834

patch 8.2.2834: Vim9: :cexpr does not work with local variables Commit: https://github.com/vim/vim/commit/5f7d4c049e934dbc8d2c3f2720797c10ee3c55c2 Author: Bram Moolenaar <Bram@vim.org> Date: Wed May 5 21:31:39 2021 +0200 patch 8.2.2834: Vim9: :cexpr does not work with local variables Problem: Vim9: :cexpr does not work with local variables. Solution: Compile :cexpr.
author Bram Moolenaar <Bram@vim.org>
date Wed, 05 May 2021 21:45:04 +0200
parents 3a3d5ee00574
children 7334bf933510
comparison
equal deleted inserted replaced
24589:c770bde164ea 24590:2818f846f099
7862 7862
7863 #if defined(FEAT_EVAL) || defined(PROTO) 7863 #if defined(FEAT_EVAL) || defined(PROTO)
7864 /* 7864 /*
7865 * Return the autocmd name for the :cexpr Ex commands. 7865 * Return the autocmd name for the :cexpr Ex commands.
7866 */ 7866 */
7867 static char_u * 7867 char_u *
7868 cexpr_get_auname(cmdidx_T cmdidx) 7868 cexpr_get_auname(cmdidx_T cmdidx)
7869 { 7869 {
7870 switch (cmdidx) 7870 switch (cmdidx)
7871 { 7871 {
7872 case CMD_cexpr: return (char_u *)"cexpr"; 7872 case CMD_cexpr: return (char_u *)"cexpr";
7877 case CMD_laddexpr: return (char_u *)"laddexpr"; 7877 case CMD_laddexpr: return (char_u *)"laddexpr";
7878 default: return NULL; 7878 default: return NULL;
7879 } 7879 }
7880 } 7880 }
7881 7881
7882 int
7883 trigger_cexpr_autocmd(int cmdidx)
7884 {
7885 char_u *au_name = cexpr_get_auname(cmdidx);
7886
7887 if (au_name != NULL && apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name,
7888 curbuf->b_fname, TRUE, curbuf))
7889 {
7890 if (aborting())
7891 return FAIL;
7892 }
7893 return OK;
7894 }
7895
7896 int
7897 cexpr_core(exarg_T *eap, typval_T *tv)
7898 {
7899 qf_info_T *qi;
7900 win_T *wp = NULL;
7901
7902 qi = qf_cmd_get_or_alloc_stack(eap, &wp);
7903 if (qi == NULL)
7904 return FAIL;
7905
7906 if ((tv->v_type == VAR_STRING && tv->vval.v_string != NULL)
7907 || (tv->v_type == VAR_LIST && tv->vval.v_list != NULL))
7908 {
7909 int res;
7910 int_u save_qfid;
7911 char_u *au_name = cexpr_get_auname(eap->cmdidx);
7912
7913 incr_quickfix_busy();
7914 res = qf_init_ext(qi, qi->qf_curlist, NULL, NULL, tv, p_efm,
7915 (eap->cmdidx != CMD_caddexpr
7916 && eap->cmdidx != CMD_laddexpr),
7917 (linenr_T)0, (linenr_T)0,
7918 qf_cmdtitle(*eap->cmdlinep), NULL);
7919 if (qf_stack_empty(qi))
7920 {
7921 decr_quickfix_busy();
7922 return FAIL;
7923 }
7924 if (res >= 0)
7925 qf_list_changed(qf_get_curlist(qi));
7926
7927 // Remember the current quickfix list identifier, so that we can
7928 // check for autocommands changing the current quickfix list.
7929 save_qfid = qf_get_curlist(qi)->qf_id;
7930 if (au_name != NULL)
7931 apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name,
7932 curbuf->b_fname, TRUE, curbuf);
7933
7934 // Jump to the first error for a new list and if autocmds didn't
7935 // free the list.
7936 if (res > 0 && (eap->cmdidx == CMD_cexpr || eap->cmdidx == CMD_lexpr)
7937 && qflist_valid(wp, save_qfid))
7938 // display the first error
7939 qf_jump_first(qi, save_qfid, eap->forceit);
7940 decr_quickfix_busy();
7941 return OK;
7942 }
7943
7944 emsg(_("E777: String or List expected"));
7945 return FAIL;
7946 }
7947
7882 /* 7948 /*
7883 * ":cexpr {expr}", ":cgetexpr {expr}", ":caddexpr {expr}" command. 7949 * ":cexpr {expr}", ":cgetexpr {expr}", ":caddexpr {expr}" command.
7884 * ":lexpr {expr}", ":lgetexpr {expr}", ":laddexpr {expr}" command. 7950 * ":lexpr {expr}", ":lgetexpr {expr}", ":laddexpr {expr}" command.
7951 * Also: ":caddexpr", ":cgetexpr", "laddexpr" and "laddexpr".
7885 */ 7952 */
7886 void 7953 void
7887 ex_cexpr(exarg_T *eap) 7954 ex_cexpr(exarg_T *eap)
7888 { 7955 {
7889 typval_T *tv; 7956 typval_T *tv;
7890 qf_info_T *qi; 7957
7891 char_u *au_name = NULL; 7958 if (trigger_cexpr_autocmd(eap->cmdidx) == FAIL)
7892 int res;
7893 int_u save_qfid;
7894 win_T *wp = NULL;
7895
7896 au_name = cexpr_get_auname(eap->cmdidx);
7897 if (au_name != NULL && apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name,
7898 curbuf->b_fname, TRUE, curbuf))
7899 {
7900 #ifdef FEAT_EVAL
7901 if (aborting())
7902 return;
7903 #endif
7904 }
7905
7906 qi = qf_cmd_get_or_alloc_stack(eap, &wp);
7907 if (qi == NULL)
7908 return; 7959 return;
7909 7960
7910 // Evaluate the expression. When the result is a string or a list we can 7961 // Evaluate the expression. When the result is a string or a list we can
7911 // use it to fill the errorlist. 7962 // use it to fill the errorlist.
7912 tv = eval_expr(eap->arg, eap); 7963 tv = eval_expr(eap->arg, eap);
7913 if (tv != NULL) 7964 if (tv != NULL)
7914 { 7965 {
7915 if ((tv->v_type == VAR_STRING && tv->vval.v_string != NULL) 7966 (void)cexpr_core(eap, tv);
7916 || (tv->v_type == VAR_LIST && tv->vval.v_list != NULL))
7917 {
7918 incr_quickfix_busy();
7919 res = qf_init_ext(qi, qi->qf_curlist, NULL, NULL, tv, p_efm,
7920 (eap->cmdidx != CMD_caddexpr
7921 && eap->cmdidx != CMD_laddexpr),
7922 (linenr_T)0, (linenr_T)0,
7923 qf_cmdtitle(*eap->cmdlinep), NULL);
7924 if (qf_stack_empty(qi))
7925 {
7926 decr_quickfix_busy();
7927 goto cleanup;
7928 }
7929 if (res >= 0)
7930 qf_list_changed(qf_get_curlist(qi));
7931
7932 // Remember the current quickfix list identifier, so that we can
7933 // check for autocommands changing the current quickfix list.
7934 save_qfid = qf_get_curlist(qi)->qf_id;
7935 if (au_name != NULL)
7936 apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name,
7937 curbuf->b_fname, TRUE, curbuf);
7938
7939 // Jump to the first error for a new list and if autocmds didn't
7940 // free the list.
7941 if (res > 0 && (eap->cmdidx == CMD_cexpr
7942 || eap->cmdidx == CMD_lexpr)
7943 && qflist_valid(wp, save_qfid))
7944 // display the first error
7945 qf_jump_first(qi, save_qfid, eap->forceit);
7946 decr_quickfix_busy();
7947 }
7948 else
7949 emsg(_("E777: String or List expected"));
7950 cleanup:
7951 free_tv(tv); 7967 free_tv(tv);
7952 } 7968 }
7953 } 7969 }
7954 #endif 7970 #endif
7955 7971