1
0
mirror of git://git.code.sf.net/p/zsh/code synced 2024-11-20 05:53:52 +01:00
zsh/Src/Zle/zle_move.c
2005-02-23 13:50:09 +00:00

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);
}