/* * 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 (cs == 0) return 0; if (line[cs - 1] == '\n') if (!--cs) return 0; while (cs && line[cs - 1] != '\n') cs--; } 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 (cs >= ll) { cs = ll; return 0; } if (line[cs] == '\n') if (++cs == ll) return 0; while (cs != ll && line[cs] != '\n') cs++; } 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 (cs == 0) break; if (line[cs - 1] == '\n') if (!--cs) break; while (cs && line[cs - 1] != '\n') cs--; n--; } if (n) { int m = zmult, ret; zmult = n; ret = uphistory(args); zmult = m; cs = 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 (cs >= ll) { cs = ll; break; } if (line[cs] == '\n') if (++cs == ll) break; while (cs != ll && line[cs] != '\n') cs++; n--; } if (n) { int m = zmult, ret; zmult = n; ret = downhistory(args); zmult = m; return ret; } return 0; } /**/ int forwardchar(char **args) { cs += zmult; if (cs > ll) cs = ll; if (cs < 0) cs = 0; return 0; } /**/ int backwardchar(char **args) { cs -= zmult; if (cs > ll) cs = ll; if (cs < 0) cs = 0; return 0; } /**/ int setmarkcommand(char **args) { mark = cs; return 0; } /**/ int exchangepointandmark(char **args) { int x; x = mark; mark = cs; cs = x; if (cs > ll) cs = ll; return 0; } /**/ int vigotocolumn(char **args) { int x, y; findline(&x, &y); if (zmult >= 0) cs = x + zmult - (zmult > 0); else cs = y + zmult; if (cs > y) cs = y; if (cs < x) cs = x; return 0; } /**/ int vimatchbracket(char **args) { int ocs = cs, dir, ct; unsigned char oth, me; otog: if (cs == ll || line[cs] == '\n') { cs = ocs; return 1; } switch (me = line[cs]) { 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: cs++; goto otog; } ct = 1; while (cs >= 0 && cs < ll && ct) { cs += dir; if (line[cs] == oth) ct--; else if (line[cs] == me) ct++; } if (cs < 0 || cs >= ll) { cs = ocs; return 1; } else if(dir > 0 && virangeflag) cs++; 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 (cs >= lim) return 1; while (n-- && cs < lim) cs++; return 0; } /**/ int vibackwardchar(char **args) { int n = zmult; if (n < 0) { int ret; zmult = -n; ret = viforwardchar(args); zmult = n; return ret; } if (cs == findbol()) return 1; while (n--) { cs--; if (cs < 0 || line[cs] == '\n') { cs++; break; } } return 0; } /**/ int viendofline(char **args) { int oldcs = cs, n = zmult; if (n < 1) return 1; while(n--) { if (cs > ll) { cs = oldcs; return 1; } cs = findeol() + 1; } cs--; lastcol = 1<<30; return 0; } /**/ int vibeginningofline(char **args) { cs = findbol(); return 0; } static int vfindchar, vfinddir, tailadd; /**/ int vifindnextchar(char **args) { if ((vfindchar = vigetkey()) != -1) { vfinddir = 1; tailadd = 0; return virepeatfind(args); } return 1; } /**/ int vifindprevchar(char **args) { if ((vfindchar = vigetkey()) != -1) { vfinddir = -1; tailadd = 0; return virepeatfind(args); } return 1; } /**/ int vifindnextcharskip(char **args) { if ((vfindchar = vigetkey()) != -1) { vfinddir = 1; tailadd = -1; return virepeatfind(args); } return 1; } /**/ int vifindprevcharskip(char **args) { if ((vfindchar = vigetkey()) != -1) { vfinddir = -1; tailadd = 1; return virepeatfind(args); } return 1; } /**/ int virepeatfind(char **args) { int ocs = cs, n = zmult; if (!vfinddir) return 1; if (n < 0) { int ret; zmult = -n; ret = virevrepeatfind(args); zmult = n; return ret; } while (n--) { do cs += vfinddir; while (cs >= 0 && cs < ll && line[cs] != vfindchar && line[cs] != '\n'); if (cs < 0 || cs >= ll || line[cs] == '\n') { cs = ocs; return 1; } } cs += tailadd; if (vfinddir == 1 && virangeflag) cs++; 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(char **args) { cs = findbol(); while (cs != ll && iblank(line[cs])) cs++; return 0; } /**/ int visetmark(char **args) { int ch; ch = getkey(0); if (ch < 'a' || ch > 'z') return 1; ch -= 'a'; vimarkcs[ch] = cs; vimarkline[ch] = histline; return 0; } /**/ int vigotomark(char **args) { int ch; ch = getkey(0); if (ch == c) ch = 26; else { if (ch < 'a' || ch > 'z') return 1; ch -= 'a'; } if (!vimarkline[ch]) return 1; if (curhist != vimarkline[ch] && !zle_goto_hist(vimarkline[ch], 0, 0)) { vimarkline[ch] = 0; return 1; } cs = vimarkcs[ch]; if (cs > ll) cs = ll; return 0; } /**/ int vigotomarkline(char **args) { vigotomark(args); return vifirstnonblank(zlenoargs); }