mirror of
git://git.code.sf.net/p/zsh/code
synced 2024-11-20 05:53:52 +01:00
513 lines
8.0 KiB
C
513 lines
8.0 KiB
C
/*
|
|
* zle_move.c - editor movement
|
|
*
|
|
* This file is part of zsh, the Z shell.
|
|
*
|
|
* Copyright (c) 1992-1997 Paul Falstad
|
|
* All rights reserved.
|
|
*
|
|
* Permission is hereby granted, without written agreement and without
|
|
* license or royalty fees, to use, copy, modify, and distribute this
|
|
* software and to distribute modified versions of this software for any
|
|
* purpose, provided that the above copyright notice and the following
|
|
* two paragraphs appear in all copies of this software.
|
|
*
|
|
* In no event shall Paul Falstad or the Zsh Development Group be liable
|
|
* to any party for direct, indirect, special, incidental, or consequential
|
|
* damages arising out of the use of this software and its documentation,
|
|
* even if Paul Falstad and the Zsh Development Group have been advised of
|
|
* the possibility of such damage.
|
|
*
|
|
* Paul Falstad and the Zsh Development Group specifically disclaim any
|
|
* warranties, including, but not limited to, the implied warranties of
|
|
* merchantability and fitness for a particular purpose. The software
|
|
* provided hereunder is on an "as is" basis, and Paul Falstad and the
|
|
* Zsh Development Group have no obligation to provide maintenance,
|
|
* support, updates, enhancements, or modifications.
|
|
*
|
|
*/
|
|
|
|
#include "zle.mdh"
|
|
#include "zle_move.pro"
|
|
|
|
static int vimarkcs[27], vimarkline[27];
|
|
|
|
/**/
|
|
int
|
|
beginningofline(char **args)
|
|
{
|
|
int n = zmult;
|
|
|
|
if (n < 0) {
|
|
int ret;
|
|
zmult = -n;
|
|
ret = endofline(args);
|
|
zmult = n;
|
|
return ret;
|
|
}
|
|
while (n--) {
|
|
if (zlecs == 0)
|
|
return 0;
|
|
if (zleline[zlecs - 1] == '\n')
|
|
if (!--zlecs)
|
|
return 0;
|
|
while (zlecs && zleline[zlecs - 1] != '\n')
|
|
zlecs--;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/**/
|
|
int
|
|
endofline(char **args)
|
|
{
|
|
int n = zmult;
|
|
|
|
if (n < 0) {
|
|
int ret;
|
|
zmult = -n;
|
|
ret = beginningofline(args);
|
|
zmult = n;
|
|
return ret;
|
|
}
|
|
while (n--) {
|
|
if (zlecs >= zlell) {
|
|
zlecs = zlell;
|
|
return 0;
|
|
}
|
|
if (zleline[zlecs] == '\n')
|
|
if (++zlecs == zlell)
|
|
return 0;
|
|
while (zlecs != zlell && zleline[zlecs] != '\n')
|
|
zlecs++;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/**/
|
|
int
|
|
beginningoflinehist(char **args)
|
|
{
|
|
int n = zmult;
|
|
|
|
if (n < 0) {
|
|
int ret;
|
|
zmult = -n;
|
|
ret = endoflinehist(args);
|
|
zmult = n;
|
|
return ret;
|
|
}
|
|
while (n) {
|
|
if (zlecs == 0)
|
|
break;
|
|
if (zleline[zlecs - 1] == '\n')
|
|
if (!--zlecs)
|
|
break;
|
|
while (zlecs && zleline[zlecs - 1] != '\n')
|
|
zlecs--;
|
|
n--;
|
|
}
|
|
if (n) {
|
|
int m = zmult, ret;
|
|
|
|
zmult = n;
|
|
ret = uphistory(args);
|
|
zmult = m;
|
|
zlecs = 0;
|
|
return ret;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/**/
|
|
int
|
|
endoflinehist(char **args)
|
|
{
|
|
int n = zmult;
|
|
|
|
if (n < 0) {
|
|
int ret;
|
|
zmult = -n;
|
|
ret = beginningoflinehist(args);
|
|
zmult = n;
|
|
return ret;
|
|
}
|
|
while (n) {
|
|
if (zlecs >= zlell) {
|
|
zlecs = zlell;
|
|
break;
|
|
}
|
|
if (zleline[zlecs] == '\n')
|
|
if (++zlecs == zlell)
|
|
break;
|
|
while (zlecs != zlell && zleline[zlecs] != '\n')
|
|
zlecs++;
|
|
n--;
|
|
}
|
|
if (n) {
|
|
int m = zmult, ret;
|
|
|
|
zmult = n;
|
|
ret = downhistory(args);
|
|
zmult = m;
|
|
return ret;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/**/
|
|
int
|
|
forwardchar(UNUSED(char **args))
|
|
{
|
|
zlecs += zmult;
|
|
if (zlecs > zlell)
|
|
zlecs = zlell;
|
|
if (zlecs < 0)
|
|
zlecs = 0;
|
|
return 0;
|
|
}
|
|
|
|
/**/
|
|
int
|
|
backwardchar(UNUSED(char **args))
|
|
{
|
|
zlecs -= zmult;
|
|
if (zlecs > zlell)
|
|
zlecs = zlell;
|
|
if (zlecs < 0)
|
|
zlecs = 0;
|
|
return 0;
|
|
}
|
|
|
|
/**/
|
|
int
|
|
setmarkcommand(UNUSED(char **args))
|
|
{
|
|
mark = zlecs;
|
|
return 0;
|
|
}
|
|
|
|
/**/
|
|
int
|
|
exchangepointandmark(UNUSED(char **args))
|
|
{
|
|
int x;
|
|
|
|
x = mark;
|
|
mark = zlecs;
|
|
zlecs = x;
|
|
if (zlecs > zlell)
|
|
zlecs = zlell;
|
|
return 0;
|
|
}
|
|
|
|
/**/
|
|
int
|
|
vigotocolumn(UNUSED(char **args))
|
|
{
|
|
int x, y;
|
|
|
|
findline(&x, &y);
|
|
if (zmult >= 0)
|
|
zlecs = x + zmult - (zmult > 0);
|
|
else
|
|
zlecs = y + zmult;
|
|
if (zlecs > y)
|
|
zlecs = y;
|
|
if (zlecs < x)
|
|
zlecs = x;
|
|
return 0;
|
|
}
|
|
|
|
/**/
|
|
int
|
|
vimatchbracket(UNUSED(char **args))
|
|
{
|
|
int ocs = zlecs, dir, ct;
|
|
unsigned char oth, me;
|
|
|
|
otog:
|
|
if (zlecs == zlell || zleline[zlecs] == '\n') {
|
|
zlecs = ocs;
|
|
return 1;
|
|
}
|
|
switch (me = zleline[zlecs]) {
|
|
case '{':
|
|
dir = 1;
|
|
oth = '}';
|
|
break;
|
|
case /*{*/ '}':
|
|
virangeflag = -virangeflag;
|
|
dir = -1;
|
|
oth = '{'; /*}*/
|
|
break;
|
|
case '(':
|
|
dir = 1;
|
|
oth = ')';
|
|
break;
|
|
case ')':
|
|
virangeflag = -virangeflag;
|
|
dir = -1;
|
|
oth = '(';
|
|
break;
|
|
case '[':
|
|
dir = 1;
|
|
oth = ']';
|
|
break;
|
|
case ']':
|
|
virangeflag = -virangeflag;
|
|
dir = -1;
|
|
oth = '[';
|
|
break;
|
|
default:
|
|
zlecs++;
|
|
goto otog;
|
|
}
|
|
ct = 1;
|
|
while (zlecs >= 0 && zlecs < zlell && ct) {
|
|
zlecs += dir;
|
|
if (zleline[zlecs] == oth)
|
|
ct--;
|
|
else if (zleline[zlecs] == me)
|
|
ct++;
|
|
}
|
|
if (zlecs < 0 || zlecs >= zlell) {
|
|
zlecs = ocs;
|
|
return 1;
|
|
} else if(dir > 0 && virangeflag)
|
|
zlecs++;
|
|
return 0;
|
|
}
|
|
|
|
/**/
|
|
int
|
|
viforwardchar(char **args)
|
|
{
|
|
int lim = findeol() - invicmdmode();
|
|
int n = zmult;
|
|
|
|
if (n < 0) {
|
|
int ret;
|
|
zmult = -n;
|
|
ret = vibackwardchar(args);
|
|
zmult = n;
|
|
return ret;
|
|
}
|
|
if (zlecs >= lim)
|
|
return 1;
|
|
while (n-- && zlecs < lim)
|
|
zlecs++;
|
|
return 0;
|
|
}
|
|
|
|
/**/
|
|
int
|
|
vibackwardchar(char **args)
|
|
{
|
|
int n = zmult;
|
|
|
|
if (n < 0) {
|
|
int ret;
|
|
zmult = -n;
|
|
ret = viforwardchar(args);
|
|
zmult = n;
|
|
return ret;
|
|
}
|
|
if (zlecs == findbol())
|
|
return 1;
|
|
while (n--) {
|
|
zlecs--;
|
|
if (zlecs < 0 || zleline[zlecs] == '\n') {
|
|
zlecs++;
|
|
break;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/**/
|
|
int
|
|
viendofline(UNUSED(char **args))
|
|
{
|
|
int oldcs = zlecs, n = zmult;
|
|
|
|
if (n < 1)
|
|
return 1;
|
|
while(n--) {
|
|
if (zlecs > zlell) {
|
|
zlecs = oldcs;
|
|
return 1;
|
|
}
|
|
zlecs = findeol() + 1;
|
|
}
|
|
zlecs--;
|
|
lastcol = 1<<30;
|
|
return 0;
|
|
}
|
|
|
|
/**/
|
|
int
|
|
vibeginningofline(UNUSED(char **args))
|
|
{
|
|
zlecs = findbol();
|
|
return 0;
|
|
}
|
|
|
|
static ZLE_INT_T vfindchar;
|
|
static int vfinddir, tailadd;
|
|
|
|
/**/
|
|
int
|
|
vifindnextchar(char **args)
|
|
{
|
|
if ((vfindchar = vigetkey()) != ZLEEOF) {
|
|
vfinddir = 1;
|
|
tailadd = 0;
|
|
return virepeatfind(args);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/**/
|
|
int
|
|
vifindprevchar(char **args)
|
|
{
|
|
if ((vfindchar = vigetkey()) != ZLEEOF) {
|
|
vfinddir = -1;
|
|
tailadd = 0;
|
|
return virepeatfind(args);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/**/
|
|
int
|
|
vifindnextcharskip(char **args)
|
|
{
|
|
if ((vfindchar = vigetkey()) != ZLEEOF) {
|
|
vfinddir = 1;
|
|
tailadd = -1;
|
|
return virepeatfind(args);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/**/
|
|
int
|
|
vifindprevcharskip(char **args)
|
|
{
|
|
if ((vfindchar = vigetkey()) != ZLEEOF) {
|
|
vfinddir = -1;
|
|
tailadd = 1;
|
|
return virepeatfind(args);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/**/
|
|
int
|
|
virepeatfind(char **args)
|
|
{
|
|
int ocs = zlecs, n = zmult;
|
|
|
|
if (!vfinddir)
|
|
return 1;
|
|
if (n < 0) {
|
|
int ret;
|
|
zmult = -n;
|
|
ret = virevrepeatfind(args);
|
|
zmult = n;
|
|
return ret;
|
|
}
|
|
while (n--) {
|
|
do
|
|
zlecs += vfinddir;
|
|
while (zlecs >= 0 && zlecs < zlell && zleline[zlecs] != vfindchar && zleline[zlecs] != '\n');
|
|
if (zlecs < 0 || zlecs >= zlell || zleline[zlecs] == '\n') {
|
|
zlecs = ocs;
|
|
return 1;
|
|
}
|
|
}
|
|
zlecs += tailadd;
|
|
if (vfinddir == 1 && virangeflag)
|
|
zlecs++;
|
|
return 0;
|
|
}
|
|
|
|
/**/
|
|
int
|
|
virevrepeatfind(char **args)
|
|
{
|
|
int ret;
|
|
|
|
if (zmult < 0) {
|
|
zmult = -zmult;
|
|
ret = virepeatfind(args);
|
|
zmult = -zmult;
|
|
return ret;
|
|
}
|
|
vfinddir = -vfinddir;
|
|
ret = virepeatfind(args);
|
|
vfinddir = -vfinddir;
|
|
return ret;
|
|
}
|
|
|
|
/**/
|
|
int
|
|
vifirstnonblank(UNUSED(char **args))
|
|
{
|
|
zlecs = findbol();
|
|
while (zlecs != zlell && iblank(zleline[zlecs]))
|
|
zlecs++;
|
|
return 0;
|
|
}
|
|
|
|
/**/
|
|
int
|
|
visetmark(UNUSED(char **args))
|
|
{
|
|
ZLE_INT_T ch;
|
|
|
|
ch = getfullchar(0);
|
|
if (ch < ZWC('a') || ch > ZWC('z'))
|
|
return 1;
|
|
ch -= ZWC('a');
|
|
vimarkcs[ch] = zlecs;
|
|
vimarkline[ch] = histline;
|
|
return 0;
|
|
}
|
|
|
|
/**/
|
|
int
|
|
vigotomark(UNUSED(char **args))
|
|
{
|
|
ZLE_INT_T ch;
|
|
|
|
ch = getfullchar(0);
|
|
if (ch == LASTFULLCHAR)
|
|
ch = 26;
|
|
else {
|
|
if (ch < ZWC('a') || ch > ZWC('z'))
|
|
return 1;
|
|
ch -= ZWC('a');
|
|
}
|
|
if (!vimarkline[ch])
|
|
return 1;
|
|
if (curhist != vimarkline[ch] && !zle_goto_hist(vimarkline[ch], 0, 0)) {
|
|
vimarkline[ch] = 0;
|
|
return 1;
|
|
}
|
|
zlecs = vimarkcs[ch];
|
|
if (zlecs > zlell)
|
|
zlecs = zlell;
|
|
return 0;
|
|
}
|
|
|
|
/**/
|
|
int
|
|
vigotomarkline(char **args)
|
|
{
|
|
vigotomark(args);
|
|
return vifirstnonblank(zlenoargs);
|
|
}
|