On Wed, Jul 29, 2015 at 10:17:25PM +0200, Bram Moolenaar wrote: > > > How about this alternative, use functions: > > > getcharsearch() returns a dict with the relevant info > > > setcharsearch() stores the relevant info > > > > > > It should be easier to save and restore the search, while all the > > > information is present in one place. > > > > Just to clarify, was that a suggested replacement for the last bullet in > > my description or for the entire interface? > > It would replace the register and variables.
Updated patch attached. Cheers, -- James GPG Key: 4096R/331BA3DB 2011-12-05 James McCoy <[email protected]> -- -- You received this message from the "vim_dev" maillist. Do not top-post! Type your reply below the text you are replying to. For more information, visit http://www.vim.org/maillist.php --- You received this message because you are subscribed to the Google Groups "vim_dev" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index d9f49ae..893624a 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1822,6 +1822,7 @@ getbufvar( {expr}, {varname} [, {def}])
any variable {varname} in buffer {expr}
getchar( [expr]) Number get one character from the user
getcharmod( ) Number modifiers for the last typed character
+getcharsearch() Dict last character search
getcmdline() String return the current command-line
getcmdpos() Number return cursor position in command-line
getcmdtype() String return current command-line type
@@ -1971,6 +1972,7 @@ server2client( {clientid}, {string})
Number send reply string
serverlist() String get a list of available servers
setbufvar( {expr}, {varname}, {val}) set {varname} in buffer {expr} to {val}
+setcharsearch( {dict}) Dict set character search from {dict}
setcmdpos( {pos}) Number set cursor position in command-line
setline( {lnum}, {line}) Number set line {lnum} to {line}
setloclist( {nr}, {list}[, {action}])
@@ -3361,6 +3363,26 @@ getcharmod() *getcharmod()*
character itself are obtained. Thus Shift-a results in "A"
without a modifier.
+getcharsearch() *getcharsearch()*
+ Return the current character search information as a {dict}
+ with the following entries:
+
+ char character previously used for a character
+ search (|t|, |f|, |T|, or |F|); empty string
+ if no character search has been performed
+ forward direction of character search; 1 for forward,
+ 0 for backward
+ until type of character search; 1 for a |t| or |T|
+ character search, 0 for an |f| or |F|
+ character search
+
+ This can be useful to always have |;| and |,| search
+ forward/backward regardless of the direction of the previous
+ character search: >
+ :nnoremap <expr> ; getcharsearch().forward ? ';' : ','
+ :nnoremap <expr> , getcharsearch().forward ? ',' : ';'
+< Also see |setcharsearch()|.
+
getcmdline() *getcmdline()*
Return the current command-line. Only works when the command
line is being edited, thus requires use of |c_CTRL-\_e| or
@@ -5397,6 +5419,26 @@ setbufvar({expr}, {varname}, {val}) *setbufvar()*
:call setbufvar("todo", "myvar", "foobar")
< This function is not available in the |sandbox|.
+setcharsearch() *setcharsearch()*
+ Set the current character search information to {dict},
+ which contains one or more of the following entries:
+
+ char character which will be used for a subsequent
+ |,| or |;| command; an empty string clears the
+ character search
+ forward direction of character search; 1 for forward,
+ 0 for backward
+ until type of character search; 1 for a |t| or |T|
+ character search, 0 for an |f| or |F|
+ character search
+
+ This can be useful to save/restore a user's character search
+ from a script: >
+ :let prevsearch = getcharsearch()
+ :" Perform a command which clobbers user's search
+ :call setcharsearch(prevsearch)
+< Also see |getcharsearch()|.
+
setcmdpos({pos}) *setcmdpos()*
Set the cursor position in the command line to byte position
{pos}. The first position is 1.
diff --git a/src/eval.c b/src/eval.c
index 0537c4e..6d883a6 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -555,6 +555,7 @@ static void f_getbufline __ARGS((typval_T *argvars, typval_T *rettv));
static void f_getbufvar __ARGS((typval_T *argvars, typval_T *rettv));
static void f_getchar __ARGS((typval_T *argvars, typval_T *rettv));
static void f_getcharmod __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_getcharsearch __ARGS((typval_T *argvars, typval_T *rettv));
static void f_getcmdline __ARGS((typval_T *argvars, typval_T *rettv));
static void f_getcmdpos __ARGS((typval_T *argvars, typval_T *rettv));
static void f_getcmdtype __ARGS((typval_T *argvars, typval_T *rettv));
@@ -688,6 +689,7 @@ static void f_searchpos __ARGS((typval_T *argvars, typval_T *rettv));
static void f_server2client __ARGS((typval_T *argvars, typval_T *rettv));
static void f_serverlist __ARGS((typval_T *argvars, typval_T *rettv));
static void f_setbufvar __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_setcharsearch __ARGS((typval_T *argvars, typval_T *rettv));
static void f_setcmdpos __ARGS((typval_T *argvars, typval_T *rettv));
static void f_setline __ARGS((typval_T *argvars, typval_T *rettv));
static void f_setloclist __ARGS((typval_T *argvars, typval_T *rettv));
@@ -8149,6 +8151,7 @@ static struct fst
{"getbufvar", 2, 3, f_getbufvar},
{"getchar", 0, 1, f_getchar},
{"getcharmod", 0, 0, f_getcharmod},
+ {"getcharsearch", 0, 0, f_getcharsearch},
{"getcmdline", 0, 0, f_getcmdline},
{"getcmdpos", 0, 0, f_getcmdpos},
{"getcmdtype", 0, 0, f_getcmdtype},
@@ -8285,6 +8288,7 @@ static struct fst
{"server2client", 2, 2, f_server2client},
{"serverlist", 0, 0, f_serverlist},
{"setbufvar", 3, 3, f_setbufvar},
+ {"setcharsearch", 1, 1, f_setcharsearch},
{"setcmdpos", 1, 1, f_setcmdpos},
{"setline", 2, 2, f_setline},
{"setloclist", 2, 3, f_setloclist},
@@ -11664,6 +11668,24 @@ f_getcharmod(argvars, rettv)
}
/*
+ * "getcharsearch()" function
+ */
+ static void
+f_getcharsearch(argvars, rettv)
+ typval_T *argvars UNUSED;
+ typval_T *rettv;
+{
+ if (rettv_dict_alloc(rettv) != FAIL)
+ {
+ dict_T *dict = rettv->vval.v_dict;
+
+ dict_add_nr_str(dict, "char", 0L, last_csearch());
+ dict_add_nr_str(dict, "forward", last_csearch_forward(), NULL);
+ dict_add_nr_str(dict, "until", last_csearch_until(), NULL);
+ }
+}
+
+/*
* "getcmdline()" function
*/
static void
@@ -17004,6 +17026,48 @@ f_setbufvar(argvars, rettv)
}
}
+ static void
+f_setcharsearch(argvars, rettv)
+ typval_T *argvars;
+ typval_T *rettv UNUSED;
+{
+ dict_T *d;
+ dictitem_T *di;
+
+ if (argvars[0].v_type != VAR_DICT)
+ {
+ EMSG(_(e_dictreq));
+ return;
+ }
+
+ if ((d = argvars[0].vval.v_dict) != NULL)
+ {
+ dictitem_T *di;
+ char_u *csearch;
+
+ csearch = get_dict_string(d, (char_u *)"char", FALSE);
+ if (csearch != NULL)
+ {
+ if (enc_utf8)
+ {
+ int pcc[MAX_MCO];
+ int c = utfc_ptr2char(csearch, pcc);
+ set_last_csearch(c, csearch, utfc_ptr2len(csearch));
+ }
+ else
+ set_last_csearch(mb_ptr2char(csearch), csearch, mb_ptr2len(csearch));
+ }
+
+ di = dict_find(d, "forward", -1);
+ if (di != NULL)
+ set_csearch_direction(get_tv_number(&di->di_tv) ? FORWARD : BACKWARD);
+
+ di = dict_find(d, "until", -1);
+ if (di != NULL)
+ set_csearch_until(!!get_tv_number(&di->di_tv));
+ }
+}
+
/*
* "setcmdpos()" function
*/
diff --git a/src/proto/search.pro b/src/proto/search.pro
index 07f6087..27d2016 100644
--- a/src/proto/search.pro
+++ b/src/proto/search.pro
@@ -8,6 +8,12 @@ void restore_search_patterns __ARGS((void));
void free_search_patterns __ARGS((void));
int ignorecase __ARGS((char_u *pat));
int pat_has_uppercase __ARGS((char_u *pat));
+char_u *last_csearch __ARGS((void));
+int last_csearch_forward __ARGS((void));
+int last_csearch_until __ARGS((void));
+void set_last_csearch __ARGS((int c, char_u *s, int len));
+void set_csearch_direction __ARGS((int cdir));
+void set_csearch_until __ARGS((int t_cmd));
char_u *last_search_pat __ARGS((void));
void reset_search_dir __ARGS((void));
void set_last_search_pat __ARGS((char_u *s, int idx, int magic, int setlast));
diff --git a/src/search.c b/src/search.c
index 238fc81..a4684d9 100644
--- a/src/search.c
+++ b/src/search.c
@@ -89,6 +89,14 @@ static struct spat spats[2] =
static int last_idx = 0; /* index in spats[] for RE_LAST */
+static char_u lastc[2] = { NUL, NUL }; /* last character searched for */
+static int lastcdir = FORWARD; /* last direction of character search */
+static int last_t_cmd = TRUE; /* last search t_cmd */
+#ifdef FEAT_MBYTE
+static char_u lastc_bytes[MB_MAXBYTES + 1];
+static int lastc_bytelen = 1; /* >1 for multi-byte char */
+#endif
+
#if defined(FEAT_AUTOCMD) || defined(FEAT_EVAL) || defined(PROTO)
/* copy of spats[], for keeping the search patterns while executing autocmds */
static struct spat saved_spats[2];
@@ -378,7 +386,7 @@ ignorecase(pat)
}
/*
- * Return TRUE if patter "pat" has an uppercase character.
+ * Return TRUE if pattern "pat" has an uppercase character.
*/
int
pat_has_uppercase(pat)
@@ -419,6 +427,58 @@ pat_has_uppercase(pat)
}
char_u *
+last_csearch()
+{
+#ifdef FEAT_MBYTE
+ return lastc_bytes;
+#else
+ return lastc;
+#endif
+}
+
+ int
+last_csearch_forward()
+{
+ return lastcdir == FORWARD;
+}
+
+ int
+last_csearch_until()
+{
+ return last_t_cmd == TRUE;
+}
+
+ void
+set_last_csearch(c, s, len)
+ int c;
+ char_u *s;
+ int len;
+{
+ *lastc = c;
+#ifdef FEAT_MBYTE
+ lastc_bytelen = len;
+ if (len)
+ memcpy(lastc_bytes, s, len);
+ else
+ vim_memset(lastc_bytes, 0, sizeof(lastc_bytes));
+#endif
+}
+
+ void
+set_csearch_direction(cdir)
+ int cdir;
+{
+ lastcdir = cdir;
+}
+
+ void
+set_csearch_until(t_cmd)
+ int t_cmd;
+{
+ last_t_cmd = t_cmd;
+}
+
+ char_u *
last_search_pat()
{
return spats[last_idx].pat;
@@ -1559,47 +1619,42 @@ searchc(cap, t_cmd)
int c = cap->nchar; /* char to search for */
int dir = cap->arg; /* TRUE for searching forward */
long count = cap->count1; /* repeat count */
- static int lastc = NUL; /* last character searched for */
- static int lastcdir; /* last direction of character search */
- static int last_t_cmd; /* last search t_cmd */
int col;
char_u *p;
int len;
int stop = TRUE;
-#ifdef FEAT_MBYTE
- static char_u bytes[MB_MAXBYTES + 1];
- static int bytelen = 1; /* >1 for multi-byte char */
-#endif
if (c != NUL) /* normal search: remember args for repeat */
{
if (!KeyStuffed) /* don't remember when redoing */
{
- lastc = c;
- lastcdir = dir;
- last_t_cmd = t_cmd;
+ *lastc = c;
+ set_csearch_direction(dir);
+ set_csearch_until(t_cmd);
#ifdef FEAT_MBYTE
- bytelen = (*mb_char2bytes)(c, bytes);
+ lastc_bytelen = (*mb_char2bytes)(c, lastc_bytes);
if (cap->ncharC1 != 0)
{
- bytelen += (*mb_char2bytes)(cap->ncharC1, bytes + bytelen);
+ lastc_bytelen += (*mb_char2bytes)(cap->ncharC1,
+ lastc_bytes + lastc_bytelen);
if (cap->ncharC2 != 0)
- bytelen += (*mb_char2bytes)(cap->ncharC2, bytes + bytelen);
+ lastc_bytelen += (*mb_char2bytes)(cap->ncharC2,
+ lastc_bytes + lastc_bytelen);
}
#endif
}
}
else /* repeat previous search */
{
- if (lastc == NUL)
+ if (*lastc == NUL)
return FAIL;
if (dir) /* repeat in opposite direction */
dir = -lastcdir;
else
dir = lastcdir;
t_cmd = last_t_cmd;
- c = lastc;
- /* For multi-byte re-use last bytes[] and bytelen. */
+ c = *lastc;
+ /* For multi-byte re-use last lastc_bytes[] and lastc_bytelen. */
/* Force a move of at least one char, so ";" and "," will move the
* cursor, even if the cursor is right in front of char we are looking
@@ -1636,14 +1691,14 @@ searchc(cap, t_cmd)
return FAIL;
col -= (*mb_head_off)(p, p + col - 1) + 1;
}
- if (bytelen == 1)
+ if (lastc_bytelen == 1)
{
if (p[col] == c && stop)
break;
}
else
{
- if (vim_memcmp(p + col, bytes, bytelen) == 0 && stop)
+ if (vim_memcmp(p + col, lastc_bytes, lastc_bytelen) == 0 && stop)
break;
}
stop = TRUE;
@@ -1671,8 +1726,8 @@ searchc(cap, t_cmd)
if (has_mbyte)
{
if (dir < 0)
- /* Landed on the search char which is bytelen long */
- col += bytelen - 1;
+ /* Landed on the search char which is lastc_bytelen long */
+ col += lastc_bytelen - 1;
else
/* To previous char, which may be multi-byte. */
col -= (*mb_head_off)(p, p + col);
signature.asc
Description: Digital signature
