updated for version 7.0191
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 798262d..ec84844 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -3502,6 +3502,7 @@
case CMD_tag:
case CMD_stag:
case CMD_ptag:
+ case CMD_ltag:
case CMD_tselect:
case CMD_stselect:
case CMD_ptselect:
@@ -8801,6 +8802,16 @@
break;
}
+ if (name[0] == 'l')
+ {
+#ifndef FEAT_QUICKFIX
+ ex_ni(eap);
+ return;
+#else
+ cmd = DT_LTAG;
+#endif
+ }
+
do_tag(eap->arg, cmd, eap->addr_count > 0 ? (int)eap->line2 : 1,
eap->forceit, TRUE);
}
diff --git a/src/fileio.c b/src/fileio.c
index 868b649..2b0df67 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -6953,6 +6953,7 @@
{"QuickFixCmdPre", EVENT_QUICKFIXCMDPRE},
{"RemoteReply", EVENT_REMOTEREPLY},
{"SessionLoadPost", EVENT_SESSIONLOADPOST},
+ {"SpellFileMissing",EVENT_SPELLFILEMISSING},
{"StdinReadPost", EVENT_STDINREADPOST},
{"StdinReadPre", EVENT_STDINREADPRE},
{"Syntax", EVENT_SYNTAX},
@@ -8406,6 +8407,7 @@
if (event == EVENT_FILETYPE
|| event == EVENT_SYNTAX
|| event == EVENT_REMOTEREPLY
+ || event == EVENT_SPELLFILEMISSING
|| event == EVENT_QUICKFIXCMDPRE
|| event == EVENT_QUICKFIXCMDPOST)
fname = vim_strsave(fname);
diff --git a/src/spell.c b/src/spell.c
index b9f3727..8c82a7e 100644
--- a/src/spell.c
+++ b/src/spell.c
@@ -2229,6 +2229,9 @@
char_u fname_enc[85];
int r;
spelload_T sl;
+#ifdef FEAT_AUTOCMD
+ int round;
+#endif
/* Copy the language name to pass it to spell_load_cb() as a cookie.
* It's truncated when an error is detected. */
@@ -2236,24 +2239,41 @@
sl.sl_slang = NULL;
sl.sl_nobreak = FALSE;
- /*
- * Find the first spell file for "lang" in 'runtimepath' and load it.
- */
- vim_snprintf((char *)fname_enc, sizeof(fname_enc) - 5,
- "spell/%s.%s.spl", lang, spell_enc());
- r = do_in_runtimepath(fname_enc, FALSE, spell_load_cb, &sl);
-
- if (r == FAIL && *sl.sl_lang != NUL)
+#ifdef FEAT_AUTOCMD
+ /* We may retry when no spell file is found for the language, an
+ * autocommand may load it then. */
+ for (round = 1; round <= 2; ++round)
+#endif
{
- /* Try loading the ASCII version. */
+ /*
+ * Find the first spell file for "lang" in 'runtimepath' and load it.
+ */
vim_snprintf((char *)fname_enc, sizeof(fname_enc) - 5,
- "spell/%s.ascii.spl", lang);
+ "spell/%s.%s.spl", lang, spell_enc());
r = do_in_runtimepath(fname_enc, FALSE, spell_load_cb, &sl);
+
+ if (r == FAIL && *sl.sl_lang != NUL)
+ {
+ /* Try loading the ASCII version. */
+ vim_snprintf((char *)fname_enc, sizeof(fname_enc) - 5,
+ "spell/%s.ascii.spl", lang);
+ r = do_in_runtimepath(fname_enc, FALSE, spell_load_cb, &sl);
+
+#ifdef FEAT_AUTOCMD
+ if (r == FAIL && *sl.sl_lang != NUL && round == 1
+ && apply_autocmds(EVENT_SPELLFILEMISSING, lang,
+ curbuf->b_fname, FALSE, curbuf))
+ continue;
+ break;
+#endif
+ }
}
if (r == FAIL)
+ {
smsg((char_u *)_("Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""),
lang, spell_enc(), lang);
+ }
else if (sl.sl_slang != NULL)
{
/* At least one file was loaded, now load ALL the additions. */
diff --git a/src/tag.c b/src/tag.c
index a9d4d75..ed2889e 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -122,6 +122,7 @@
* type == DT_SELECT: ":tselect [tag]", select tag from a list of all matches
* type == DT_JUMP: ":tjump [tag]", jump to tag or select tag from a list
* type == DT_CSCOPE: use cscope to find the tag
+ * type == DT_LTAG: use location list for displaying tag matches
* type == DT_FREE: free cached matches
*
* for cscope, returns TRUE if we jumped to tag or aborted, FALSE otherwise
@@ -215,6 +216,9 @@
/* new pattern, add to the tag stack */
if (*tag && (type == DT_TAG || type == DT_SELECT || type == DT_JUMP
+#ifdef FEAT_QUICKFIX
+ || type == DT_LTAG
+#endif
#ifdef FEAT_CSCOPE
|| type == DT_CSCOPE
#endif
@@ -409,6 +413,9 @@
switch (type)
{
case DT_FIRST: cur_match = count - 1; break;
+#ifdef FEAT_QUICKFIX
+ case DT_LTAG: cur_match = 0; break;
+#endif
case DT_SELECT:
case DT_JUMP:
#ifdef FEAT_CSCOPE
@@ -748,6 +755,148 @@
}
ask_for_selection = TRUE;
}
+#if defined(FEAT_QUICKFIX) && defined(FEAT_EVAL)
+ else
+ if (type == DT_LTAG)
+ {
+ list_T *list;
+ char_u tag_name[128 + 1];
+ char_u fname[MAXPATHL + 1];
+ char_u cmd[CMDBUFFSIZE + 1];
+
+ /*
+ * Add the matching tags to the location list for the current
+ * window.
+ */
+
+ list = list_alloc();
+ if (list == NULL)
+ goto end_do_tag;
+
+ for (i = 0; i < num_matches; ++i)
+ {
+ int len, cmd_len;
+ long lnum;
+ dict_T *dict;
+
+ parse_match(matches[i], &tagp);
+
+ /* Save the tag name */
+ len = tagp.tagname_end - tagp.tagname;
+ if (len > 128)
+ len = 128;
+ vim_strncpy(tag_name, tagp.tagname, len);
+ tag_name[len] = NUL;
+
+ /* Save the tag file name */
+ p = tag_full_fname(&tagp);
+ if (p == NULL)
+ continue;
+ STRCPY(fname, p);
+ vim_free(p);
+
+ /*
+ * Get the line number or the search pattern used to locate
+ * the tag.
+ */
+ lnum = 0;
+ if (isdigit(*tagp.command))
+ /* Line number is used to locate the tag */
+ lnum = atol((char *)tagp.command);
+ else
+ {
+ char_u *cmd_start, *cmd_end;
+
+ /* Search pattern is used to locate the tag */
+
+ /* Locate the end of the command */
+ cmd_start = tagp.command;
+ cmd_end = tagp.command_end;
+ if (cmd_end == NULL)
+ {
+ for (p = tagp.command;
+ *p && *p != '\r' && *p != '\n'; ++p)
+ ;
+ cmd_end = p;
+ }
+ /*
+ * Now, cmd_end points to the character after the
+ * command. Adjust it to point to the last
+ * character of the command.
+ */
+ cmd_end--;
+
+ /*
+ * Skip the '/' and '?' characters at the
+ * beginning and end of the search pattern.
+ */
+ if (*cmd_start == '/' || *cmd_start == '?')
+ cmd_start++;
+
+ if (*cmd_end == '/' || *cmd_end == '?')
+ cmd_end--;
+
+ len = 0;
+ cmd[0] = NUL;
+
+ /*
+ * If "^" is present in the tag search pattern, then
+ * copy it first.
+ */
+ if (*cmd_start == '^')
+ {
+ STRCPY(cmd, "^");
+ cmd_start++;
+ len++;
+ }
+
+ /*
+ * Precede the tag pattern with \V to make it very
+ * nomagic.
+ */
+ STRCAT(cmd, "\\V");
+ len += 2;
+
+ cmd_len = cmd_end - cmd_start + 1;
+ if (cmd_len > (CMDBUFFSIZE - 5))
+ cmd_len = CMDBUFFSIZE - 5;
+ STRNCAT(cmd, cmd_start, cmd_len);
+ len += cmd_len;
+
+ if (cmd[len - 1] == '$')
+ {
+ /*
+ * Replace '$' at the end of the search pattern
+ * with '\$'
+ */
+ cmd[len - 1] = '\\';
+ cmd[len] = '$';
+ len++;
+ }
+
+ cmd[len] = NUL;
+ }
+
+ if ((dict = dict_alloc()) == NULL)
+ continue;
+ if (list_append_dict(list, dict) == FAIL)
+ {
+ vim_free(dict);
+ continue;
+ }
+
+ dict_add_nr_str(dict, "text", 0L, tag_name);
+ dict_add_nr_str(dict, "filename", 0L, fname);
+ dict_add_nr_str(dict, "lnum", lnum, NULL);
+ if (lnum == 0)
+ dict_add_nr_str(dict, "pattern", 0L, cmd);
+ }
+
+ set_errorlist(curwin, list, ' ');
+
+ list_free(list);
+ }
+#endif
if (ask_for_selection == TRUE)
{
diff --git a/src/vim.h b/src/vim.h
index bc0b334..7b79532 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -945,6 +945,7 @@
#define DT_HELP 8 /* like DT_TAG, but no wildcards */
#define DT_JUMP 9 /* jump to new tag or selection from list */
#define DT_CSCOPE 10 /* cscope find command (like tjump) */
+#define DT_LTAG 11 /* tag using location list */
#define DT_FREE 99 /* free cached matches */
/*
@@ -1104,6 +1105,7 @@
EVENT_FUNCUNDEFINED, /* if calling a function which doesn't exist */
EVENT_REMOTEREPLY, /* upon string reception from a remote vim */
EVENT_SWAPEXISTS, /* found existing swap file */
+ EVENT_SPELLFILEMISSING, /* spell file missing */
NUM_EVENTS /* MUST be the last one */
};