int viyankwholeline(UNUSED(char **args)) { int bol = findbol(), oldcs = zlecs; int n = zmult; startvichange(-1); if (n < 1) return 1; while(n--) { if (zlecs > zlell) { zlecs = oldcs; return 1; } zlecs = findeol() + 1; } vilinerange = 1; cut(bol, zlecs - bol - 1, 0); zlecs = oldcs; return 0; }
int whatcursorposition(UNUSED(char **args)) { char msg[100]; char *s = msg, *mbstr; int bol = findbol(), len; ZLE_CHAR_T c = zleline[zlecs]; if (zlecs == zlell) strucpy(&s, "EOF"); else { strucpy(&s, "Char: "); switch (c) { case ZWC(' '): strucpy(&s, "SPC"); break; case ZWC('\t'): strucpy(&s, "TAB"); break; case ZWC('\n'): strucpy(&s, "LFD"); break; default: /* * convert a single character, remembering it may * turn into a multibyte string or be metafied. */ mbstr = zlelineasstring(zleline+zlecs, 1, 0, &len, NULL, 1); strcpy(s, mbstr); s += len; } sprintf(s, " (0%o, %u, 0x%x)", (unsigned int)c, (unsigned int)c, (unsigned int)c); s += strlen(s); } sprintf(s, " point %d of %d(%d%%) column %d", zlecs+1, zlell+1, zlell ? 100 * zlecs / zlell : 0, zlecs - bol); showmsg(msg); return 0; }
void zlecore(void) { Keymap km; #if !defined(HAVE_POLL) && defined(HAVE_SELECT) struct timeval tv; fd_set foofd; FD_ZERO(&foofd); #endif pushheap(); /* * A widget function may decide to exit the shell. * We never exit directly from functions, to allow * the shell to tidy up, so we have to test for * that explicitly. */ while (!done && !errflag && !exit_pending) { UNMETACHECK(); statusline = NULL; vilinerange = 0; reselectkeymap(); selectlocalmap(invicmdmode() && region_active && (km = openkeymap("visual")) ? km : NULL); bindk = getkeycmd(); selectlocalmap(NULL); if (bindk) { if (!zlell && isfirstln && !(zlereadflags & ZLRF_IGNOREEOF) && lastchar == eofchar) { /* * Slight hack: this relies on getkeycmd returning * a value for the EOF character. However, * undefined-key is fine. That's necessary because * otherwise we can't distinguish this case from * a ^C. */ eofsent = 1; break; } if (execzlefunc(bindk, zlenoargs, 0)) { handlefeep(zlenoargs); if (eofsent) break; } handleprefixes(); /* for vi mode, make sure the cursor isn't somewhere illegal */ if (invicmdmode() && zlecs > findbol() && (zlecs == zlell || zleline[zlecs] == ZWC('\n'))) DECCS(); handleundo(); } else { errflag |= ERRFLAG_ERROR; break; } #ifdef HAVE_POLL if (baud && !(lastcmd & ZLE_MENUCMP)) { struct pollfd pfd; int to = cost * costmult / 1000; /* milliseconds */ if (to > 500) to = 500; pfd.fd = SHTTY; pfd.events = POLLIN; if (!kungetct && poll(&pfd, 1, to) <= 0) zrefresh(); } else #else # ifdef HAVE_SELECT if (baud && !(lastcmd & ZLE_MENUCMP)) { FD_SET(SHTTY, &foofd); tv.tv_sec = 0; if ((tv.tv_usec = cost * costmult) > 500000) tv.tv_usec = 500000; if (!kungetct && select(SHTTY+1, (SELECT_ARG_2_T) & foofd, NULL, NULL, &tv) <= 0) zrefresh(); } else # endif #endif if (!kungetct) zrefresh(); freeheap(); } region_active = 0; popheap(); }
void findline(int *a, int *b) { *a = findbol(); *b = findeol(); }
static int getvirange(int wf) { int pos = zlecs, ret = 0; int mult1 = zmult, hist1 = histline; Thingy k2; virangeflag = 1; wordflag = wf; /* Now we need to execute the movement command, to see where it * * actually goes. virangeflag here indicates to the movement * * function that it should place the cursor at the end of the * * range, rather than where the cursor would actually go if it * * were executed normally. This makes a difference to some * * commands, but not all. For example, if searching forward * * for a character, under normal circumstances the cursor lands * * on the character. For a range, the range must include the * * character, so the cursor gets placed after the character if * * virangeflag is set. vi-match-bracket needs to change the * * value of virangeflag under some circumstances, meaning that * * we need to change the *starting* position. */ zmod.flags &= ~MOD_TMULT; do { vilinerange = 0; prefixflag = 0; if (!(k2 = getkeycmd()) || (k2->flags & DISABLED) || k2 == Th(z_sendbreak)) { wordflag = 0; virangeflag = 0; return -1; } /* * With k2 == bindk, the command key is repeated: * a number of lines is used. If the function used * returns 1, we fail. */ if ((k2 == bindk) ? dovilinerange() : execzlefunc(k2, zlenoargs, 1)) ret = -1; if(vichgrepeat) zmult = mult1; else zmult = mult1 * zmod.tmult; } while(prefixflag && !ret); wordflag = 0; virangeflag = 0; /* It is an error to use a non-movement command to delimit the * * range. We here reject the case where the command modified * * the line, or selected a different history line. */ if (histline != hist1 || zlell != lastll || memcmp(zleline, lastline, zlell)) { histline = hist1; ZS_memcpy(zleline, lastline, zlell = lastll); zlecs = pos; return -1; } /* Can't handle an empty file. Also, if the movement command * * failed, or didn't move, it is an error. */ if (!zlell || (zlecs == pos && virangeflag != 2) || ret == -1) return -1; /* vi-match-bracket changes the value of virangeflag when * * moving to the opening bracket, meaning that we need to * * change the *starting* position. */ if(virangeflag == -1) { int origcs = zlecs; zlecs = pos; INCCS(); pos = zlecs; zlecs = origcs; } /* Get the range the right way round. zlecs is placed at the * * start of the range, and pos (the return value of this * * function) is the end. */ if (zlecs > pos) { int tmp = zlecs; zlecs = pos; pos = tmp; } /* Was it a line-oriented move? If so, the command will have set * * the vilinerange flag. In this case, entire lines are taken, * * rather than just the sequence of characters delimited by pos * * and zlecs. The terminating newline is left out of the range, * * which the real command must deal with appropriately. At this * * point we just need to make the range encompass entire lines. */ if(vilinerange) { int newcs = findbol(); zlecs = pos; pos = findeol(); zlecs = newcs; } return pos; }
void vibeginningofline(void) { cs = findbol(); }
int getvirange(int wf) { int k2, t0, startline, endline, obeep; int mult1, gotmult1; vilinerange = 0; startline = findbol(); endline = findeol(); /* get arguments for the command, and then the command key */ mult1 = zmult; gotmult1 = gotmult; zmult = 1; gotmult = 0; lastcmd &= ~(ZLE_NEGARG | ZLE_DIGIT); while(1) { if ((k2 = getkeycmd()) < 0 || k2 == z_sendbreak) { feep(); return -1; } if (!(zlecmds[k2].flags & ZLE_ARG)) break; (*zlecmds[k2].func) (); lastcmd = zlecmds[k2].flags; } /* double counts, such as in 3d4j, get multiplied, unless we're repeating */ if(vichgrepeat && gotmult1) { zmult = mult1; gotmult = 1; } else if (gotmult1) { zmult *= mult1; gotmult = 1; } /* can't handle an empty file */ if (!ll) { feep(); return -1; } /* This bit handles repeated command keys, such as dd. A number * * of lines is taken as the range. The current line is included. * * If the argument is positive, the lines go downward, otherwise * * vice versa. The argument gives the number of lines. */ if (k2 == bindk) { vilinerange = 1; if (!zmult) { feep(); return -1; } t0 = cs; if (zmult > 0) { while(zmult-- && cs <= ll) cs = findeol() + 1; if (zmult != -1) { cs = t0; feep(); return -1; } t0 = cs - 1; cs = startline; return t0; } else { while(zmult++ && cs >= 0) cs = findbol() - 1; if (zmult != 1) { cs = t0; feep(); return -1; } cs++; return endline; } } /* Not a movement?! No, you can't do yd. */ if (!(zlecmds[k2].flags & ZLE_MOVEMENT)) { feep(); return -1; } /* Now we need to execute the movement command, to see where it * * actually goes. virangeflag here indicates to the movement * * function that it should place the cursor at the end of the * * range, rather than where the cursor would actually go if it * * were executed normally. This makes a difference to some * * commands, but not all. For example, if searching forward * * for a character, under normal circumstances the cursor lands * * on the character. For a range, the range must include the * * character, so the cursor gets placed after the character if * * virangeflag is set. vi-match-bracket needs to change the * * value of virangeflag under some circumstances, meaning that * * we need to change the *starting* position. */ t0 = cs; virangeflag = 1; wordflag = wf; obeep = opts[BEEP]; opts[BEEP] = 0; (*zlecmds[k2].func) (); wordflag = 0; opts[BEEP] = obeep; if (cs == t0) { /* An error occured -- couldn't move. The movement command didn't * * feep, because we set NO_BEEP for the duration of the command. */ feep(); virangeflag = 0; return -1; } if(virangeflag == -1) t0++; virangeflag = 0; /* get the range the right way round */ if (cs > t0) { int tmp = cs; cs = t0; t0 = tmp; } /* Was it a line-oriented move? In this case, entire lines are taken. * * The terminating newline is left out of the range, which the real * * command must deal with appropriately. At this point we just need * * to make the range encompass entire lines. */ if (zlecmds[k2].flags & ZLE_LINEMOVE) { int newcs = findbol(); cs = t0; t0 = findeol(); cs = newcs; vilinerange = 1; } return t0; }
static int getvirange(int wf) { int pos = zlecs, mpos = mark, ret = 0; int visual = region_active; /* movement command might set it */ int mult1 = zmult, hist1 = histline; Thingy k2; if (visual) { if (!zlell) return -1; pos = mark; vilinerange = (visual == 2); region_active = 0; } else { virangeflag = 1; wordflag = wf; mark = -1; /* use operator-pending keymap if one exists */ Keymap km = openkeymap("viopp"); if (km) selectlocalmap(km); /* Now we need to execute the movement command, to see where it * * actually goes. virangeflag here indicates to the movement * * function that it should place the cursor at the end of the * * range, rather than where the cursor would actually go if it * * were executed normally. This makes a difference to some * * commands, but not all. For example, if searching forward * * for a character, under normal circumstances the cursor lands * * on the character. For a range, the range must include the * * character, so the cursor gets placed after the character if * * virangeflag is set. */ zmod.flags &= ~MOD_TMULT; do { vilinerange = 0; prefixflag = 0; if (!(k2 = getkeycmd()) || (k2->flags & DISABLED) || k2 == Th(z_sendbreak)) { wordflag = 0; virangeflag = 0; mark = mpos; return -1; } /* * With k2 == bindk, the command key is repeated: * a number of lines is used. If the function used * returns 1, we fail. */ if ((k2 == bindk) ? dovilinerange() : execzlefunc(k2, zlenoargs, 1)) ret = -1; if(vichgrepeat) zmult = mult1; else zmult = mult1 * zmod.tmult; } while(prefixflag && !ret); wordflag = 0; selectlocalmap(NULL); /* It is an error to use a non-movement command to delimit the * * range. We here reject the case where the command modified * * the line, or selected a different history line. */ if (histline != hist1 || zlell != lastll || memcmp(zleline, lastline, zlell)) { histline = hist1; ZS_memcpy(zleline, lastline, zlell = lastll); zlecs = pos; mark = mpos; virangeflag = 0; return -1; } /* Can't handle an empty file. Also, if the movement command * * failed, or didn't move, it is an error. */ if (!zlell || (zlecs == pos && (mark == -1 || mark == zlecs) && virangeflag != 2) || ret == -1) { mark = mpos; virangeflag = 0; return -1; } virangeflag = 0; /* if the mark has moved, ignore the original cursor position * * and use the mark. */ if (mark != -1) pos = mark; } mark = mpos; /* Get the range the right way round. zlecs is placed at the * * start of the range, and pos (the return value of this * * function) is the end. */ if (zlecs > pos) { int tmp = zlecs; zlecs = pos; pos = tmp; } /* visual selection mode needs to include additional position */ if (visual == 1 && pos < zlell && invicmdmode()) INCPOS(pos); /* Was it a line-oriented move? If so, the command will have set * * the vilinerange flag. In this case, entire lines are taken, * * rather than just the sequence of characters delimited by pos * * and zlecs. The terminating newline is left out of the range, * * which the real command must deal with appropriately. At this * * point we just need to make the range encompass entire lines. */ vilinerange = (zmod.flags & MOD_LINE) || (vilinerange && !(zmod.flags & MOD_CHAR)); if (vilinerange) { int newcs = findbol(); lastcol = zlecs - newcs; zlecs = pos; pos = findeol(); zlecs = newcs; } else if (!visual) { /* for a character-wise move don't include a newline at the * * end of the range */ int prev = pos; DECPOS(prev); if (zleline[prev] == ZWC('\n')) pos = prev; } return pos; }