mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-12 15:45:18 +00:00
Add ability to use system libedit and update bundled libedit.
The version of libedit that is bundled with asterisk is old and has some bugs. This patch updates the bundled version of libedit within asterisk, and also updates asterisk to use the system libedit instead if one is available (and pkg-config is available). This review integrates several patches from other users specifically kkm and tzafrir. (closes issue #15929) Reported by: kkm Patches: 015929-astcli-editrc-trunk.240324.diff uploaded by kkm (license 888) (issue #16858) Reported by: jw-asterisk (closes issue #17039) Reported by: tzafrir Patches: 0001-allow-using-system-copy-of-libedit.patch uploaded by tzafrir (license 46) Review: https://reviewboard.asterisk.org/r/807/ git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8@280019 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -1,941 +0,0 @@
|
||||
/* $NetBSD: vi.c,v 1.9 2002/03/18 16:01:01 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Christos Zoulas of Cornell University.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#if !defined(lint) && !defined(SCCSID)
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)vi.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: vi.c,v 1.9 2002/03/18 16:01:01 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint && not SCCSID */
|
||||
|
||||
/*
|
||||
* vi.c: Vi mode commands.
|
||||
*/
|
||||
#include "el.h"
|
||||
|
||||
private el_action_t cv_action(EditLine *, int);
|
||||
private el_action_t cv_paste(EditLine *, int);
|
||||
|
||||
/* cv_action():
|
||||
* Handle vi actions.
|
||||
*/
|
||||
private el_action_t
|
||||
cv_action(EditLine *el, int c)
|
||||
{
|
||||
char *cp, *kp;
|
||||
|
||||
if (el->el_chared.c_vcmd.action & DELETE) {
|
||||
el->el_chared.c_vcmd.action = NOP;
|
||||
el->el_chared.c_vcmd.pos = 0;
|
||||
|
||||
el->el_chared.c_undo.isize = 0;
|
||||
el->el_chared.c_undo.dsize = 0;
|
||||
kp = el->el_chared.c_undo.buf;
|
||||
for (cp = el->el_line.buffer; cp < el->el_line.lastchar; cp++) {
|
||||
*kp++ = *cp;
|
||||
el->el_chared.c_undo.dsize++;
|
||||
}
|
||||
|
||||
el->el_chared.c_undo.action = INSERT;
|
||||
el->el_chared.c_undo.ptr = el->el_line.buffer;
|
||||
el->el_line.lastchar = el->el_line.buffer;
|
||||
el->el_line.cursor = el->el_line.buffer;
|
||||
if (c & INSERT)
|
||||
el->el_map.current = el->el_map.key;
|
||||
|
||||
return (CC_REFRESH);
|
||||
}
|
||||
el->el_chared.c_vcmd.pos = el->el_line.cursor;
|
||||
el->el_chared.c_vcmd.action = c;
|
||||
return (CC_ARGHACK);
|
||||
|
||||
#ifdef notdef
|
||||
/*
|
||||
* I don't think that this is needed. But we keep it for now
|
||||
*/
|
||||
else
|
||||
if (el_chared.c_vcmd.action == NOP) {
|
||||
el->el_chared.c_vcmd.pos = el->el_line.cursor;
|
||||
el->el_chared.c_vcmd.action = c;
|
||||
return (CC_ARGHACK);
|
||||
} else {
|
||||
el->el_chared.c_vcmd.action = 0;
|
||||
el->el_chared.c_vcmd.pos = 0;
|
||||
return (CC_ERROR);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* cv_paste():
|
||||
* Paste previous deletion before or after the cursor
|
||||
*/
|
||||
private el_action_t
|
||||
cv_paste(EditLine *el, int c)
|
||||
{
|
||||
char *ptr;
|
||||
c_undo_t *un = &el->el_chared.c_undo;
|
||||
|
||||
#ifdef DEBUG_PASTE
|
||||
(void) fprintf(el->el_errfile, "Paste: %x \"%s\" +%d -%d\n",
|
||||
un->action, un->buf, un->isize, un->dsize);
|
||||
#endif
|
||||
if (un->isize == 0)
|
||||
return (CC_ERROR);
|
||||
|
||||
if (!c && el->el_line.cursor < el->el_line.lastchar)
|
||||
el->el_line.cursor++;
|
||||
ptr = el->el_line.cursor;
|
||||
|
||||
c_insert(el, (int) un->isize);
|
||||
if (el->el_line.cursor + un->isize > el->el_line.lastchar)
|
||||
return (CC_ERROR);
|
||||
(void) memcpy(ptr, un->buf, un->isize);
|
||||
return (CC_REFRESH);
|
||||
}
|
||||
|
||||
|
||||
/* vi_paste_next():
|
||||
* Vi paste previous deletion to the right of the cursor
|
||||
* [p]
|
||||
*/
|
||||
protected el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_paste_next(EditLine *el, int c)
|
||||
{
|
||||
|
||||
return (cv_paste(el, 0));
|
||||
}
|
||||
|
||||
|
||||
/* vi_paste_prev():
|
||||
* Vi paste previous deletion to the left of the cursor
|
||||
* [P]
|
||||
*/
|
||||
protected el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_paste_prev(EditLine *el, int c)
|
||||
{
|
||||
|
||||
return (cv_paste(el, 1));
|
||||
}
|
||||
|
||||
|
||||
/* vi_prev_space_word():
|
||||
* Vi move to the previous space delimited word
|
||||
* [B]
|
||||
*/
|
||||
protected el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_prev_space_word(EditLine *el, int c)
|
||||
{
|
||||
|
||||
if (el->el_line.cursor == el->el_line.buffer)
|
||||
return (CC_ERROR);
|
||||
|
||||
el->el_line.cursor = cv_prev_word(el, el->el_line.cursor,
|
||||
el->el_line.buffer,
|
||||
el->el_state.argument,
|
||||
cv__isword);
|
||||
|
||||
if (el->el_chared.c_vcmd.action & DELETE) {
|
||||
cv_delfini(el);
|
||||
return (CC_REFRESH);
|
||||
}
|
||||
return (CC_CURSOR);
|
||||
}
|
||||
|
||||
|
||||
/* vi_prev_word():
|
||||
* Vi move to the previous word
|
||||
* [B]
|
||||
*/
|
||||
protected el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_prev_word(EditLine *el, int c)
|
||||
{
|
||||
|
||||
if (el->el_line.cursor == el->el_line.buffer)
|
||||
return (CC_ERROR);
|
||||
|
||||
el->el_line.cursor = cv_prev_word(el, el->el_line.cursor,
|
||||
el->el_line.buffer,
|
||||
el->el_state.argument,
|
||||
ce__isword);
|
||||
|
||||
if (el->el_chared.c_vcmd.action & DELETE) {
|
||||
cv_delfini(el);
|
||||
return (CC_REFRESH);
|
||||
}
|
||||
return (CC_CURSOR);
|
||||
}
|
||||
|
||||
|
||||
/* vi_next_space_word():
|
||||
* Vi move to the next space delimited word
|
||||
* [W]
|
||||
*/
|
||||
protected el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_next_space_word(EditLine *el, int c)
|
||||
{
|
||||
|
||||
if (el->el_line.cursor == el->el_line.lastchar)
|
||||
return (CC_ERROR);
|
||||
|
||||
el->el_line.cursor = cv_next_word(el, el->el_line.cursor,
|
||||
el->el_line.lastchar,
|
||||
el->el_state.argument,
|
||||
cv__isword);
|
||||
|
||||
if (el->el_map.type == MAP_VI)
|
||||
if (el->el_chared.c_vcmd.action & DELETE) {
|
||||
cv_delfini(el);
|
||||
return (CC_REFRESH);
|
||||
}
|
||||
return (CC_CURSOR);
|
||||
}
|
||||
|
||||
|
||||
/* vi_next_word():
|
||||
* Vi move to the next word
|
||||
* [w]
|
||||
*/
|
||||
protected el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_next_word(EditLine *el, int c)
|
||||
{
|
||||
|
||||
if (el->el_line.cursor == el->el_line.lastchar)
|
||||
return (CC_ERROR);
|
||||
|
||||
el->el_line.cursor = cv_next_word(el, el->el_line.cursor,
|
||||
el->el_line.lastchar,
|
||||
el->el_state.argument,
|
||||
ce__isword);
|
||||
|
||||
if (el->el_map.type == MAP_VI)
|
||||
if (el->el_chared.c_vcmd.action & DELETE) {
|
||||
cv_delfini(el);
|
||||
return (CC_REFRESH);
|
||||
}
|
||||
return (CC_CURSOR);
|
||||
}
|
||||
|
||||
|
||||
/* vi_change_case():
|
||||
* Vi change case of character under the cursor and advance one character
|
||||
* [~]
|
||||
*/
|
||||
protected el_action_t
|
||||
vi_change_case(EditLine *el, int c)
|
||||
{
|
||||
|
||||
if (el->el_line.cursor < el->el_line.lastchar) {
|
||||
c = *el->el_line.cursor;
|
||||
if (isupper(c))
|
||||
*el->el_line.cursor++ = tolower(c);
|
||||
else if (islower(c))
|
||||
*el->el_line.cursor++ = toupper(c);
|
||||
else
|
||||
el->el_line.cursor++;
|
||||
re_fastaddc(el);
|
||||
return (CC_NORM);
|
||||
}
|
||||
return (CC_ERROR);
|
||||
}
|
||||
|
||||
|
||||
/* vi_change_meta():
|
||||
* Vi change prefix command
|
||||
* [c]
|
||||
*/
|
||||
protected el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_change_meta(EditLine *el, int c)
|
||||
{
|
||||
|
||||
/*
|
||||
* Delete with insert == change: first we delete and then we leave in
|
||||
* insert mode.
|
||||
*/
|
||||
return (cv_action(el, DELETE | INSERT));
|
||||
}
|
||||
|
||||
|
||||
/* vi_insert_at_bol():
|
||||
* Vi enter insert mode at the beginning of line
|
||||
* [I]
|
||||
*/
|
||||
protected el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_insert_at_bol(EditLine *el, int c)
|
||||
{
|
||||
|
||||
el->el_line.cursor = el->el_line.buffer;
|
||||
el->el_chared.c_vcmd.ins = el->el_line.cursor;
|
||||
|
||||
el->el_chared.c_undo.ptr = el->el_line.cursor;
|
||||
el->el_chared.c_undo.action = DELETE;
|
||||
|
||||
el->el_map.current = el->el_map.key;
|
||||
return (CC_CURSOR);
|
||||
}
|
||||
|
||||
|
||||
/* vi_replace_char():
|
||||
* Vi replace character under the cursor with the next character typed
|
||||
* [r]
|
||||
*/
|
||||
protected el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_replace_char(EditLine *el, int c)
|
||||
{
|
||||
|
||||
el->el_map.current = el->el_map.key;
|
||||
el->el_state.inputmode = MODE_REPLACE_1;
|
||||
el->el_chared.c_undo.action = CHANGE;
|
||||
el->el_chared.c_undo.ptr = el->el_line.cursor;
|
||||
el->el_chared.c_undo.isize = 0;
|
||||
el->el_chared.c_undo.dsize = 0;
|
||||
return (CC_NORM);
|
||||
}
|
||||
|
||||
|
||||
/* vi_replace_mode():
|
||||
* Vi enter replace mode
|
||||
* [R]
|
||||
*/
|
||||
protected el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_replace_mode(EditLine *el, int c)
|
||||
{
|
||||
|
||||
el->el_map.current = el->el_map.key;
|
||||
el->el_state.inputmode = MODE_REPLACE;
|
||||
el->el_chared.c_undo.action = CHANGE;
|
||||
el->el_chared.c_undo.ptr = el->el_line.cursor;
|
||||
el->el_chared.c_undo.isize = 0;
|
||||
el->el_chared.c_undo.dsize = 0;
|
||||
return (CC_NORM);
|
||||
}
|
||||
|
||||
|
||||
/* vi_substitute_char():
|
||||
* Vi replace character under the cursor and enter insert mode
|
||||
* [r]
|
||||
*/
|
||||
protected el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_substitute_char(EditLine *el, int c)
|
||||
{
|
||||
|
||||
c_delafter(el, el->el_state.argument);
|
||||
el->el_map.current = el->el_map.key;
|
||||
return (CC_REFRESH);
|
||||
}
|
||||
|
||||
|
||||
/* vi_substitute_line():
|
||||
* Vi substitute entire line
|
||||
* [S]
|
||||
*/
|
||||
protected el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_substitute_line(EditLine *el, int c)
|
||||
{
|
||||
|
||||
(void) em_kill_line(el, 0);
|
||||
el->el_map.current = el->el_map.key;
|
||||
return (CC_REFRESH);
|
||||
}
|
||||
|
||||
|
||||
/* vi_change_to_eol():
|
||||
* Vi change to end of line
|
||||
* [C]
|
||||
*/
|
||||
protected el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_change_to_eol(EditLine *el, int c)
|
||||
{
|
||||
|
||||
(void) ed_kill_line(el, 0);
|
||||
el->el_map.current = el->el_map.key;
|
||||
return (CC_REFRESH);
|
||||
}
|
||||
|
||||
|
||||
/* vi_insert():
|
||||
* Vi enter insert mode
|
||||
* [i]
|
||||
*/
|
||||
protected el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_insert(EditLine *el, int c)
|
||||
{
|
||||
|
||||
el->el_map.current = el->el_map.key;
|
||||
|
||||
el->el_chared.c_vcmd.ins = el->el_line.cursor;
|
||||
el->el_chared.c_undo.ptr = el->el_line.cursor;
|
||||
el->el_chared.c_undo.action = DELETE;
|
||||
|
||||
return (CC_NORM);
|
||||
}
|
||||
|
||||
|
||||
/* vi_add():
|
||||
* Vi enter insert mode after the cursor
|
||||
* [a]
|
||||
*/
|
||||
protected el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_add(EditLine *el, int c)
|
||||
{
|
||||
int ret;
|
||||
|
||||
el->el_map.current = el->el_map.key;
|
||||
if (el->el_line.cursor < el->el_line.lastchar) {
|
||||
el->el_line.cursor++;
|
||||
if (el->el_line.cursor > el->el_line.lastchar)
|
||||
el->el_line.cursor = el->el_line.lastchar;
|
||||
ret = CC_CURSOR;
|
||||
} else
|
||||
ret = CC_NORM;
|
||||
|
||||
el->el_chared.c_vcmd.ins = el->el_line.cursor;
|
||||
el->el_chared.c_undo.ptr = el->el_line.cursor;
|
||||
el->el_chared.c_undo.action = DELETE;
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
||||
/* vi_add_at_eol():
|
||||
* Vi enter insert mode at end of line
|
||||
* [A]
|
||||
*/
|
||||
protected el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_add_at_eol(EditLine *el, int c)
|
||||
{
|
||||
|
||||
el->el_map.current = el->el_map.key;
|
||||
el->el_line.cursor = el->el_line.lastchar;
|
||||
|
||||
/* Mark where insertion begins */
|
||||
el->el_chared.c_vcmd.ins = el->el_line.lastchar;
|
||||
el->el_chared.c_undo.ptr = el->el_line.lastchar;
|
||||
el->el_chared.c_undo.action = DELETE;
|
||||
return (CC_CURSOR);
|
||||
}
|
||||
|
||||
|
||||
/* vi_delete_meta():
|
||||
* Vi delete prefix command
|
||||
* [d]
|
||||
*/
|
||||
protected el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_delete_meta(EditLine *el, int c)
|
||||
{
|
||||
|
||||
return (cv_action(el, DELETE));
|
||||
}
|
||||
|
||||
|
||||
/* vi_end_word():
|
||||
* Vi move to the end of the current space delimited word
|
||||
* [E]
|
||||
*/
|
||||
protected el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_end_word(EditLine *el, int c)
|
||||
{
|
||||
|
||||
if (el->el_line.cursor == el->el_line.lastchar)
|
||||
return (CC_ERROR);
|
||||
|
||||
el->el_line.cursor = cv__endword(el->el_line.cursor,
|
||||
el->el_line.lastchar, el->el_state.argument);
|
||||
|
||||
if (el->el_chared.c_vcmd.action & DELETE) {
|
||||
el->el_line.cursor++;
|
||||
cv_delfini(el);
|
||||
return (CC_REFRESH);
|
||||
}
|
||||
return (CC_CURSOR);
|
||||
}
|
||||
|
||||
|
||||
/* vi_to_end_word():
|
||||
* Vi move to the end of the current word
|
||||
* [e]
|
||||
*/
|
||||
protected el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_to_end_word(EditLine *el, int c)
|
||||
{
|
||||
|
||||
if (el->el_line.cursor == el->el_line.lastchar)
|
||||
return (CC_ERROR);
|
||||
|
||||
el->el_line.cursor = cv__endword(el->el_line.cursor,
|
||||
el->el_line.lastchar, el->el_state.argument);
|
||||
|
||||
if (el->el_chared.c_vcmd.action & DELETE) {
|
||||
el->el_line.cursor++;
|
||||
cv_delfini(el);
|
||||
return (CC_REFRESH);
|
||||
}
|
||||
return (CC_CURSOR);
|
||||
}
|
||||
|
||||
|
||||
/* vi_undo():
|
||||
* Vi undo last change
|
||||
* [u]
|
||||
*/
|
||||
protected el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_undo(EditLine *el, int c)
|
||||
{
|
||||
char *cp, *kp;
|
||||
char temp;
|
||||
int i, size;
|
||||
c_undo_t *un = &el->el_chared.c_undo;
|
||||
|
||||
#ifdef DEBUG_UNDO
|
||||
(void) fprintf(el->el_errfile, "Undo: %x \"%s\" +%d -%d\n",
|
||||
un->action, un->buf, un->isize, un->dsize);
|
||||
#endif
|
||||
switch (un->action) {
|
||||
case DELETE:
|
||||
if (un->dsize == 0)
|
||||
return (CC_NORM);
|
||||
|
||||
(void) memcpy(un->buf, un->ptr, un->dsize);
|
||||
for (cp = un->ptr; cp <= el->el_line.lastchar; cp++)
|
||||
*cp = cp[un->dsize];
|
||||
|
||||
el->el_line.lastchar -= un->dsize;
|
||||
el->el_line.cursor = un->ptr;
|
||||
|
||||
un->action = INSERT;
|
||||
un->isize = un->dsize;
|
||||
un->dsize = 0;
|
||||
break;
|
||||
|
||||
case DELETE | INSERT:
|
||||
size = un->isize - un->dsize;
|
||||
if (size > 0)
|
||||
i = un->dsize;
|
||||
else
|
||||
i = un->isize;
|
||||
cp = un->ptr;
|
||||
kp = un->buf;
|
||||
while (i-- > 0) {
|
||||
temp = *kp;
|
||||
*kp++ = *cp;
|
||||
*cp++ = temp;
|
||||
}
|
||||
if (size > 0) {
|
||||
el->el_line.cursor = cp;
|
||||
c_insert(el, size);
|
||||
while (size-- > 0 && cp < el->el_line.lastchar) {
|
||||
temp = *kp;
|
||||
*kp++ = *cp;
|
||||
*cp++ = temp;
|
||||
}
|
||||
} else if (size < 0) {
|
||||
size = -size;
|
||||
for (; cp <= el->el_line.lastchar; cp++) {
|
||||
*kp++ = *cp;
|
||||
*cp = cp[size];
|
||||
}
|
||||
el->el_line.lastchar -= size;
|
||||
}
|
||||
el->el_line.cursor = un->ptr;
|
||||
i = un->dsize;
|
||||
un->dsize = un->isize;
|
||||
un->isize = i;
|
||||
break;
|
||||
|
||||
case INSERT:
|
||||
if (un->isize == 0)
|
||||
return (CC_NORM);
|
||||
|
||||
el->el_line.cursor = un->ptr;
|
||||
c_insert(el, (int) un->isize);
|
||||
(void) memcpy(un->ptr, un->buf, un->isize);
|
||||
un->action = DELETE;
|
||||
un->dsize = un->isize;
|
||||
un->isize = 0;
|
||||
break;
|
||||
|
||||
case CHANGE:
|
||||
if (un->isize == 0)
|
||||
return (CC_NORM);
|
||||
|
||||
el->el_line.cursor = un->ptr;
|
||||
size = (int) (el->el_line.cursor - el->el_line.lastchar);
|
||||
if (size < un->isize)
|
||||
size = un->isize;
|
||||
cp = un->ptr;
|
||||
kp = un->buf;
|
||||
for (i = 0; i < size; i++) {
|
||||
temp = *kp;
|
||||
*kp++ = *cp;
|
||||
*cp++ = temp;
|
||||
}
|
||||
un->dsize = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
return (CC_ERROR);
|
||||
}
|
||||
|
||||
return (CC_REFRESH);
|
||||
}
|
||||
|
||||
|
||||
/* vi_command_mode():
|
||||
* Vi enter command mode (use alternative key bindings)
|
||||
* [<ESC>]
|
||||
*/
|
||||
protected el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_command_mode(EditLine *el, int c)
|
||||
{
|
||||
int size;
|
||||
|
||||
/* [Esc] cancels pending action */
|
||||
el->el_chared.c_vcmd.ins = 0;
|
||||
el->el_chared.c_vcmd.action = NOP;
|
||||
el->el_chared.c_vcmd.pos = 0;
|
||||
|
||||
el->el_state.doingarg = 0;
|
||||
size = el->el_chared.c_undo.ptr - el->el_line.cursor;
|
||||
if (size < 0)
|
||||
size = -size;
|
||||
if (el->el_chared.c_undo.action == (INSERT | DELETE) ||
|
||||
el->el_chared.c_undo.action == DELETE)
|
||||
el->el_chared.c_undo.dsize = size;
|
||||
else
|
||||
el->el_chared.c_undo.isize = size;
|
||||
|
||||
el->el_state.inputmode = MODE_INSERT;
|
||||
el->el_map.current = el->el_map.alt;
|
||||
#ifdef VI_MOVE
|
||||
if (el->el_line.cursor > el->el_line.buffer)
|
||||
el->el_line.cursor--;
|
||||
#endif
|
||||
return (CC_CURSOR);
|
||||
}
|
||||
|
||||
|
||||
/* vi_zero():
|
||||
* Vi move to the beginning of line
|
||||
* [0]
|
||||
*/
|
||||
protected el_action_t
|
||||
vi_zero(EditLine *el, int c)
|
||||
{
|
||||
|
||||
if (el->el_state.doingarg) {
|
||||
if (el->el_state.argument > 1000000)
|
||||
return (CC_ERROR);
|
||||
el->el_state.argument =
|
||||
(el->el_state.argument * 10) + (c - '0');
|
||||
return (CC_ARGHACK);
|
||||
} else {
|
||||
el->el_line.cursor = el->el_line.buffer;
|
||||
if (el->el_chared.c_vcmd.action & DELETE) {
|
||||
cv_delfini(el);
|
||||
return (CC_REFRESH);
|
||||
}
|
||||
return (CC_CURSOR);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* vi_delete_prev_char():
|
||||
* Vi move to previous character (backspace)
|
||||
* [^H]
|
||||
*/
|
||||
protected el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_delete_prev_char(EditLine *el, int c)
|
||||
{
|
||||
|
||||
if (el->el_chared.c_vcmd.ins == 0)
|
||||
return (CC_ERROR);
|
||||
|
||||
if (el->el_chared.c_vcmd.ins >
|
||||
el->el_line.cursor - el->el_state.argument)
|
||||
return (CC_ERROR);
|
||||
|
||||
c_delbefore(el, el->el_state.argument);
|
||||
el->el_line.cursor -= el->el_state.argument;
|
||||
|
||||
return (CC_REFRESH);
|
||||
}
|
||||
|
||||
|
||||
/* vi_list_or_eof():
|
||||
* Vi list choices for completion or indicate end of file if empty line
|
||||
* [^D]
|
||||
*/
|
||||
protected el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_list_or_eof(EditLine *el, int c)
|
||||
{
|
||||
|
||||
#ifdef notyet
|
||||
if (el->el_line.cursor == el->el_line.lastchar &&
|
||||
el->el_line.cursor == el->el_line.buffer) {
|
||||
#endif
|
||||
term_overwrite(el, STReof, 4); /* then do a EOF */
|
||||
term__flush();
|
||||
return (CC_EOF);
|
||||
#ifdef notyet
|
||||
} else {
|
||||
re_goto_bottom(el);
|
||||
*el->el_line.lastchar = '\0'; /* just in case */
|
||||
return (CC_LIST_CHOICES);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* vi_kill_line_prev():
|
||||
* Vi cut from beginning of line to cursor
|
||||
* [^U]
|
||||
*/
|
||||
protected el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_kill_line_prev(EditLine *el, int c)
|
||||
{
|
||||
char *kp, *cp;
|
||||
|
||||
cp = el->el_line.buffer;
|
||||
kp = el->el_chared.c_kill.buf;
|
||||
while (cp < el->el_line.cursor)
|
||||
*kp++ = *cp++; /* copy it */
|
||||
el->el_chared.c_kill.last = kp;
|
||||
c_delbefore(el, el->el_line.cursor - el->el_line.buffer);
|
||||
el->el_line.cursor = el->el_line.buffer; /* zap! */
|
||||
return (CC_REFRESH);
|
||||
}
|
||||
|
||||
|
||||
/* vi_search_prev():
|
||||
* Vi search history previous
|
||||
* [?]
|
||||
*/
|
||||
protected el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_search_prev(EditLine *el, int c)
|
||||
{
|
||||
|
||||
return (cv_search(el, ED_SEARCH_PREV_HISTORY));
|
||||
}
|
||||
|
||||
|
||||
/* vi_search_next():
|
||||
* Vi search history next
|
||||
* [/]
|
||||
*/
|
||||
protected el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_search_next(EditLine *el, int c)
|
||||
{
|
||||
|
||||
return (cv_search(el, ED_SEARCH_NEXT_HISTORY));
|
||||
}
|
||||
|
||||
|
||||
/* vi_repeat_search_next():
|
||||
* Vi repeat current search in the same search direction
|
||||
* [n]
|
||||
*/
|
||||
protected el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_repeat_search_next(EditLine *el, int c)
|
||||
{
|
||||
|
||||
if (el->el_search.patlen == 0)
|
||||
return (CC_ERROR);
|
||||
else
|
||||
return (cv_repeat_srch(el, el->el_search.patdir));
|
||||
}
|
||||
|
||||
|
||||
/* vi_repeat_search_prev():
|
||||
* Vi repeat current search in the opposite search direction
|
||||
* [N]
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
protected el_action_t
|
||||
vi_repeat_search_prev(EditLine *el, int c)
|
||||
{
|
||||
|
||||
if (el->el_search.patlen == 0)
|
||||
return (CC_ERROR);
|
||||
else
|
||||
return (cv_repeat_srch(el,
|
||||
el->el_search.patdir == ED_SEARCH_PREV_HISTORY ?
|
||||
ED_SEARCH_NEXT_HISTORY : ED_SEARCH_PREV_HISTORY));
|
||||
}
|
||||
|
||||
|
||||
/* vi_next_char():
|
||||
* Vi move to the character specified next
|
||||
* [f]
|
||||
*/
|
||||
protected el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_next_char(EditLine *el, int c)
|
||||
{
|
||||
char ch;
|
||||
|
||||
if (el_getc(el, &ch) != 1)
|
||||
return (ed_end_of_file(el, 0));
|
||||
|
||||
el->el_search.chadir = CHAR_FWD;
|
||||
el->el_search.chacha = ch;
|
||||
|
||||
return (cv_csearch_fwd(el, ch, el->el_state.argument, 0));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* vi_prev_char():
|
||||
* Vi move to the character specified previous
|
||||
* [F]
|
||||
*/
|
||||
protected el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_prev_char(EditLine *el, int c)
|
||||
{
|
||||
char ch;
|
||||
|
||||
if (el_getc(el, &ch) != 1)
|
||||
return (ed_end_of_file(el, 0));
|
||||
|
||||
el->el_search.chadir = CHAR_BACK;
|
||||
el->el_search.chacha = ch;
|
||||
|
||||
return (cv_csearch_back(el, ch, el->el_state.argument, 0));
|
||||
}
|
||||
|
||||
|
||||
/* vi_to_next_char():
|
||||
* Vi move up to the character specified next
|
||||
* [t]
|
||||
*/
|
||||
protected el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_to_next_char(EditLine *el, int c)
|
||||
{
|
||||
char ch;
|
||||
|
||||
if (el_getc(el, &ch) != 1)
|
||||
return (ed_end_of_file(el, 0));
|
||||
|
||||
return (cv_csearch_fwd(el, ch, el->el_state.argument, 1));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* vi_to_prev_char():
|
||||
* Vi move up to the character specified previous
|
||||
* [T]
|
||||
*/
|
||||
protected el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_to_prev_char(EditLine *el, int c)
|
||||
{
|
||||
char ch;
|
||||
|
||||
if (el_getc(el, &ch) != 1)
|
||||
return (ed_end_of_file(el, 0));
|
||||
|
||||
return (cv_csearch_back(el, ch, el->el_state.argument, 1));
|
||||
}
|
||||
|
||||
|
||||
/* vi_repeat_next_char():
|
||||
* Vi repeat current character search in the same search direction
|
||||
* [;]
|
||||
*/
|
||||
protected el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_repeat_next_char(EditLine *el, int c)
|
||||
{
|
||||
|
||||
if (el->el_search.chacha == 0)
|
||||
return (CC_ERROR);
|
||||
|
||||
return (el->el_search.chadir == CHAR_FWD
|
||||
? cv_csearch_fwd(el, el->el_search.chacha,
|
||||
el->el_state.argument, 0)
|
||||
: cv_csearch_back(el, el->el_search.chacha,
|
||||
el->el_state.argument, 0));
|
||||
}
|
||||
|
||||
|
||||
/* vi_repeat_prev_char():
|
||||
* Vi repeat current character search in the opposite search direction
|
||||
* [,]
|
||||
*/
|
||||
protected el_action_t
|
||||
/*ARGSUSED*/
|
||||
vi_repeat_prev_char(EditLine *el, int c)
|
||||
{
|
||||
|
||||
if (el->el_search.chacha == 0)
|
||||
return (CC_ERROR);
|
||||
|
||||
return el->el_search.chadir == CHAR_BACK ?
|
||||
cv_csearch_fwd(el, el->el_search.chacha, el->el_state.argument, 0) :
|
||||
cv_csearch_back(el, el->el_search.chacha, el->el_state.argument, 0);
|
||||
}
|
Reference in New Issue
Block a user