/* * * zle_vi.c - vi-specific functions * * This file is part of zsh, the Z shell. * * This software is Copyright 1992 by Paul Falstad * * Permission is hereby granted to copy, reproduce, redistribute or otherwise * use this software as long as: there is no monetary profit gained * specifically from the use or reproduction of this software, it is not * sold, rented, traded or otherwise marketed, and this copyright notice is * included prominently in any copy made. * * The author make no claims as to the fitness or correctness of this software * for any use whatsoever, and it is provided as is. Any use of this software * is at the user's own risk. * */ #define ZLE #include "zsh.h" static void startvichange(im) int im; { insmode = im; if (vichgbuf) free(vichgbuf); vichgbuf = zalloc(vichgbufsz = 16); vichgbuf[0] = c; vichgbufptr = 1; vichgflag = 1; viinsbegin = cs; } static void startvitext(im) int im; { startvichange(im); bindtab = mainbindtab; undoing = 0; } int vigetkey() /**/ { int ch; if ((ch = getkey(0)) == -1) return 0; if (ch == 22) { if ((ch = getkey(0)) == -1) return 0; return ch; } else if (ch == 27) return 0; return ch; } int getvirange(wf) /**/ int wf; { int k2,t0,startline,endline; startline = findbol(); endline = findeol(); for (;;) { k2 = getkeycmd(); if (k2 == -1) { feep(); return -1; } if (zlecmds[k2].flags & ZLE_ARG) (*zlecmds[k2].func)(); else break; } if (k2 == bindk) { findline(&cs,&t0); return (t0 == ll) ? t0 : t0+1; } if (!(zlecmds[k2].flags & ZLE_MOVEMENT)) { feep(); return -1; } t0 = cs; virangeflag = 1; wordflag = wf; (*zlecmds[k2].func)(); wordflag = virangeflag = 0; if (cs == t0) { feep(); return -1; } if (startline != findbol()) { if (zlecmds[k2].flags & ZLE_LINEMOVE) { if (cs < t0) { cs = startline; t0 = findeol()+1; } else { t0 = startline; cs = findeol()+1; } } else { if (cs < startline) cs = startline; else if (cs >= endline) cs = endline-1; } } if (cs > t0) { k2 = cs; cs = t0; t0 = k2; } return t0; } void viaddnext() /**/ { if (cs != ll) cs++; startvitext(1); } void viaddeol() /**/ { cs = findeol(); startvitext(1); } void viinsert() /**/ { startvitext(1); } void viinsertbol() /**/ { cs = findbol(); startvitext(1); } void videlete() /**/ { int c2; startvichange(1); if ((c2 = getvirange(0)) == -1) { vichgflag = 0; return; } forekill(c2-cs,0); vichgflag = 0; } void videletechar() /**/ { if (mult < 0) { mult = -mult; vibackwarddeletechar(); return; } if (c == 4 && !ll) { eofsent = 1; return; } if (!(cs+mult > ll || line[cs] == '\n')) { if ( vichgbuf == NULL ) vichgbuf = zalloc ( vichgbufsz = 16 ); vichgbufptr = 1; vichgbuf[0] = c; cs += mult; backkill(mult,0); if (cs && (cs == ll || line[cs] == '\n')) cs--; } else feep(); } void vichange() /**/ { int c2; startvichange(1); if ((c2 = getvirange(1)) == -1) { vichgflag = 0; return; } forekill(c2-cs,0); bindtab = mainbindtab; undoing = 0; } void visubstitute() /**/ { if (mult < 0) return; if (findeol()-cs < mult) mult = findeol()-cs; if (mult) { foredel(mult); startvitext(1); } } void vichangeeol() /**/ { killline(); startvitext(1); } void vichangewholeline() /**/ { int cq; findline(&cs,&cq); foredel(cq-cs); startvitext(1); } void viyank() /**/ { int c2; if ((c2 = getvirange(0)) == -1) return; cut(cs,c2-cs,0); } void viyankeol() /**/ { int x = findeol(); if (x == cs) feep(); else cut(cs,x-cs,0); } void vireplace() /**/ { startvitext(0); } void vireplacechars() /**/ { int ch; if (mult < 0) return; if (mult+cs > ll) { feep(); return; } startvichange(1); if (ch = vigetkey()) while (mult--) line[cs++] = ch; vichgflag = 0; cs--; } void vicmdmode() /**/ { bindtab = altbindtab; if (cs) cs--; undoing = 1; if (vichgflag) vichgflag = 0; } void viopenlinebelow() /**/ { cs = findeol(); spaceinline(1); line[cs++] = '\n'; startvitext(1); } void viopenlineabove() /**/ { cs = findbol(); spaceinline(1); line[cs] = '\n'; startvitext(1); } void vioperswapcase() /**/ { int c2; if ((c2 = getvirange(0)) == -1) return; while (cs < c2) { int ch = line[cs]; if (islower(ch)) ch = tuupper(ch); else if (isupper(ch)) ch = tulower(ch); line[cs++] = ch; } } void virepeatchange() /**/ { if (!vichgbuf || bindtab == mainbindtab || vichgflag) feep(); else ungetkeys(vichgbuf,vichgbufptr); } void viindent() /**/ { int c2,endcs,t0,rmult; if (mult < 0) { mult = -mult; viunindent(); return; } rmult = mult; if ((c2 = getvirange(0)) == -1) return; if (cs != findbol()) { feep(); return; } endcs = cs+rmult; while (cs < c2) { spaceinline(rmult); for (t0 = 0; t0 != rmult; t0++) line[cs++] = '\t'; cs = findeol()+1; } cs = endcs; } void viunindent() /**/ { int c2,endcs,t0,rmult; rmult = mult; if (mult < 0) { mult = -mult; viindent(); return; } if ((c2 = getvirange(0)) == -1) return; if (cs != findbol()) { feep(); return; } endcs = cs; while (cs < c2) { for (t0 = 0; t0 != rmult && line[cs] == '\t'; t0++) foredel(1); cs = findeol()+1; } cs = endcs; }