/* Last string searched for from `/' or `?'. */
static char *vi_last_search = (char *)NULL;
static int vi_histpos;
/* Non-zero means enter insertion mode. */
int vi_doing_insert = 0;
/* *** UNCLEAN *** */
/* Command keys which do movement for xxx_to commands. */
static char *vi_motion = " hl^$0ftFt;,%wbeWBE|";
/* Keymap used for vi replace characters. Created dynamically since
rarely used. */
static Keymap vi_replace_map = (Keymap)NULL;
/* The number of characters inserted in the last replace operation. */
static vi_replace_count = 0;
/* Yank the nth arg from the previous line into this line at point. */
rl_vi_yank_arg (count)
int count;
{
rl_yank_nth_arg (count, 0);
}
/* Search again for the last thing searched for. */
rl_vi_search_again (ignore, key)
int ignore, key;
{
switch (key)
{
case 'n':
rl_vi_dosearch (vi_last_search, -1);
break;
case 'N':
rl_vi_dosearch (vi_last_search, 1);
break;
}
}
/* Do a vi style search. */
rl_vi_search (count, key)
int count, key;
{
int dir, c, save_pos;
char *p;
/* Completion, from vi's point of view. */
rl_vi_complete (ignore, key)
int ignore, key;
{
if ((rl_point < rl_end) && (!whitespace (the_line[rl_point])))
{
if (!whitespace (the_line[rl_point + 1]))
rl_vi_end_word (1, 'E');
rl_point++;
}
if (key == '*')
rl_complete_internal ('*');
else
rl_complete (0, key);
rl_vi_insertion_mode ();
}
/* Previous word in vi mode. */
rl_vi_prev_word (count, key)
int count, key;
{
if (count < 0)
{
rl_vi_next_word (-count, key);
return;
}
if (uppercase_p (key))
rl_vi_bWord (count);
else
rl_vi_bword (count);
}
/* Next word in vi mode. */
rl_vi_next_word (count, key)
int count;
{
if (count < 0)
{
rl_vi_prev_word (-count, key);
return;
}
if (uppercase_p (key))
rl_vi_fWord (count);
else
rl_vi_fword (count);
}
/* Move to the end of the ?next? word. */
rl_vi_end_word (count, key)
int count, key;
{
if (count < 0)
{
ding ();
return;
}
if (uppercase_p (key))
rl_vi_eWord (count);
else
rl_vi_eword (count);
}
/* Move forward a word the way that 'W' does. */
/* Move forward a word the way that 'W' does. */
rl_vi_fWord (count)
int count;
{
while (count-- && rl_point < (rl_end - 1))
{
/* Skip until whitespace. */
while (!whitespace (the_line[rl_point]) && rl_point < rl_end)
rl_point++;
/* Now skip whitespace. */
while (whitespace (the_line[rl_point]) && rl_point < rl_end)
rl_point++;
}
}
rl_vi_bWord (count)
int count;
{
while (count-- && rl_point > 0)
{
/* If we are at the start of a word, move back to whitespace so
we will go back to the start of the previous word. */
if (!whitespace (the_line[rl_point]) &&
whitespace (the_line[rl_point - 1]))
rl_point--;
while (rl_point > 0 && whitespace (the_line[rl_point]))
rl_point--;
if (rl_point > 0)
{
while (--rl_point >= 0 && !whitespace (the_line[rl_point]));
rl_point++;
}
}
}
rl_vi_eWord (count)
int count;
{
while (count-- && rl_point < (rl_end - 1))
{
/* Move to white space. */
while (++rl_point < rl_end && whitespace (the_line[rl_point]))
;
if (rl_point && rl_point < rl_end)
{
/* Skip whitespace. */
while (rl_point < rl_end && whitespace (the_line[rl_point]))
rl_point++;
/* Skip until whitespace. */
while (rl_point < rl_end && !whitespace (the_line[rl_point]))
rl_point++;
/* Move back to the last character of the word. */
rl_point--;
}
}
}
rl_vi_fword (count)
int count;
{
while (count-- && rl_point < (rl_end - 1))
{
/* Move to white space (really non-identifer). */
if (isident (the_line[rl_point]))
{
while (isident (the_line[rl_point]) && rl_point < rl_end)
rl_point++;
}
else /* if (!whitespace (the_line[rl_point])) */
{
while (!isident (the_line[rl_point]) &&
!whitespace (the_line[rl_point]) && rl_point < rl_end)
rl_point++;
}
/* Move past whitespace. */
while (whitespace (the_line[rl_point]) && rl_point < rl_end)
rl_point++;
}
}
rl_vi_bword (count)
int count;
{
while (count-- && rl_point > 0)
{
int last_is_ident;
/* If we are at the start of a word, move back to a non-identifier
so we will go back to the start of the previous word. */
if (isident (the_line[rl_point]) && !isident (the_line[rl_point - 1]))
rl_point--;
/* If this character and the previous character are `opposite', move
back so we don't get messed up by the rl_point++ down there in
the while loop. Without this code, words like `l;' screw up the
function. */
last_is_ident = isident (the_line[rl_point - 1]);
if ((isident (the_line[rl_point]) && !last_is_ident) ||
(!isident (the_line[rl_point]) && last_is_ident))
rl_point--;
while (rl_point > 0 && whitespace (the_line[rl_point]))
rl_point--;
if (rl_point > 0)
{
if (isident (the_line[rl_point]))
while (--rl_point >= 0 && isident (the_line[rl_point]));
else
while (--rl_point >= 0 && !isident (the_line[rl_point]) &&
!whitespace (the_line[rl_point]));
rl_point++;
}
}
}
rl_vi_eword (count)
int count;
{
while (count-- && rl_point < rl_end - 1)
{
while (++rl_point < rl_end && whitespace (the_line[rl_point]))
;
if (rl_point < rl_end)
{
if (isident (the_line[rl_point]))
while (++rl_point < rl_end && isident (the_line[rl_point]));
else
while (++rl_point < rl_end && !isident (the_line[rl_point])
&& !whitespace (the_line[rl_point]));
rl_point--;
}
}
}
/* Turn the current line into a comment in shell history.
A K*rn shell style function. */
rl_vi_comment ()
{
rl_beg_of_line ();
rl_insert_text (": "); /* `#' doesn't work in interactive mode */
rl_redisplay ();
rl_newline (1, '\010');
}
rl_vi_first_print ()
{
rl_back_to_indent ();
}
rl_back_to_indent (ignore1, ignore2)
int ignore1, ignore2;
{
rl_beg_of_line ();
while (rl_point < rl_end && whitespace (the_line[rl_point]))
rl_point++;
}
/* NOTE: it is necessary that opposite directions are inverses */
#define FTO 1 /* forward to */
#define BTO -1 /* backward to */
#define FFIND 2 /* forward find */
#define BFIND -2 /* backward find */
rl_vi_char_search (count, key)
int count, key;
{
static char target;
static int orig_dir, dir;
int pos;
if (brack < 0)
{
while (count)
{
if (--pos >= 0)
{
int b = rl_vi_bracktype (the_line[pos]);
if (b == -brack)
count--;
else if (b == brack)
count++;
}
else
{
ding ();
return;
}
}
}
else
{ /* brack > 0 */
while (count)
{
if (++pos < rl_end)
{
int b = rl_vi_bracktype (the_line[pos]);
if (b == -brack)
count--;
else if (b == brack)
count++;
}
else
{
ding ();
return;
}
}
}
rl_point = pos;
}
int
rl_vi_bracktype (c)
int c;
{
switch (c)
{
case '(': return 1;
case ')': return -1;
case '[': return 2;
case ']': return -2;
case '{': return 3;
case '}': return -3;
default: return 0;
}
}
/*
* Try to complete the word we are standing on or the word that ends with
* the previous character. A space matches everything.
* Word delimiters are space and ;.
*/
rl_vi_possible_completions()
{
int save_pos = rl_point;
if (!index (" ;", the_line[rl_point]))
{
while (!index(" ;", the_line[++rl_point]))
;
}
else if (the_line[rl_point-1] == ';')
{
ding ();
return (0);
}