void setline(char *s, int flags) { char *scp; UNMETACHECK(); if (flags & ZSL_COPY) scp = ztrdup(s); else scp = s; /* * TBD: we could make this more efficient by passing the existing * allocated line to stringaszleline. */ free(zleline); zleline = stringaszleline(scp, 0, &zlell, &linesz, NULL); if ((flags & ZSL_TOEND) && (zlecs = zlell) && invicmdmode()) DECCS(); else if (zlecs > zlell) zlecs = zlell; CCRIGHT(); if (flags & ZSL_COPY) free(scp); }
void setlastline(void) { UNMETACHECK(); if(lastlinesz != linesz) lastline = realloc(lastline, (lastlinesz = linesz) * ZLE_CHAR_SIZE); ZS_memcpy(lastline, zleline, (lastll = zlell)); lastcs = zlecs; }
void mkundoent(void) { int pre, suf; int sh = zlell < lastll ? zlell : lastll; struct change *ch; UNMETACHECK(); if(lastll == zlell && !ZS_memcmp(lastline, zleline, zlell)) { lastcs = zlecs; return; } for(pre = 0; pre < sh && zleline[pre] == lastline[pre]; ) pre++; for(suf = 0; suf < sh - pre && zleline[zlell - 1 - suf] == lastline[lastll - 1 - suf]; ) suf++; ch = zalloc(sizeof(*ch)); ch->next = NULL; ch->hist = histline; ch->off = pre; ch->old_cs = lastcs; ch->new_cs = zlecs; if(suf + pre == lastll) { ch->del = NULL; ch->dell = 0; } else { ch->dell = lastll - pre - suf; ch->del = (ZLE_STRING_T)zalloc(ch->dell * ZLE_CHAR_SIZE); ZS_memcpy(ch->del, lastline + pre, ch->dell); } if(suf + pre == zlell) { ch->ins = NULL; ch->insl = 0; } else { ch->insl = zlell - pre - suf; ch->ins = (ZLE_STRING_T)zalloc(ch->insl * ZLE_CHAR_SIZE); ZS_memcpy(ch->ins, zleline + pre, ch->insl); } if(nextchanges) { ch->flags = CH_PREV; ch->prev = endnextchanges; endnextchanges->flags |= CH_NEXT; endnextchanges->next = ch; } else { nextchanges = ch; ch->flags = 0; ch->prev = NULL; } ch->changeno = ++undo_changeno; endnextchanges = ch; }
void regionlines(int *start, int *end) { int origcs = zlecs; UNMETACHECK(); if (zlecs < mark) { *start = findbol(); zlecs = (mark > zlell) ? zlell : mark; *end = findeol(); } else { *end = findeol(); zlecs = mark; *start = findbol(); } zlecs = origcs; }
mod_export void backkill(int ct, int flags) { UNMETACHECK(); if (flags & CUT_RAW) { zlecs -= ct; } else { int origcs = zlecs; while (ct--) DECCS(); ct = origcs - zlecs; } cut(zlecs, ct, flags); shiftchars(zlecs, ct); CCRIGHT(); }
mod_export void forekill(int ct, int flags) { int i = zlecs; UNMETACHECK(); if (!(flags & CUT_RAW)) { int n = ct; while (n--) INCCS(); ct = zlecs - i; zlecs = i; } cut(i, ct, flags); shiftchars(i, ct); CCRIGHT(); }
void doinsert(ZLE_STRING_T zstr, int len) { ZLE_STRING_T s; ZLE_CHAR_T c1 = *zstr; /* first character */ int neg = zmult < 0; /* insert *after* the cursor? */ int m = neg ? -zmult : zmult; /* number of copies to insert */ int count; UNMETACHECK(); iremovesuffix(c1, 0); invalidatelist(); /* In overwrite mode, don't replace newlines. */ if (insmode || zleline[zlecs] == ZWC('\n')) spaceinline(m * len); else { int pos = zlecs, diff, i; #ifdef MULTIBYTE_SUPPORT /* * Calculate the number of character positions we are * going to be using. The algorithm is that * anything that shows up as a logical single character * (i.e. even if control, or double width, or with combining * characters) is treated as 1 for the purpose of replacing * what's there already. * * This can cause inserting of a combining character in * places where it should overwrite, such as the start * of a line. However, combining characters aren't * useful there anyway and this doesn't cause any * particular harm. */ for (i = 0, count = 0; i < len * m; i++) { if (!IS_COMBINING(zstr[i])) count++; } #else count = len * m; #endif /* * Ensure we replace a complete combining characterfor each * character we overwrite. Switch to inserting at first newline. */ for (i = count; pos < zlell && zleline[pos] != ZWC('\n') && i--; ) { INCPOS(pos); } /* * Calculate how many raw line places we need. * pos - zlecs is the raw line distance we're replacing, * m * len the number we're inserting. */ diff = pos - zlecs - m * len; if (diff < 0) { spaceinline(-diff); } else if (diff > 0) { /* * We use shiftchars() here because we don't * want combining char alignment fixed up: we * are going to write over any that remain. */ shiftchars(zlecs, diff); } } while (m--) for (s = zstr, count = len; count; s++, count--) zleline[zlecs++] = *s; if (neg) zlecs += zmult * len; /* if we ended up on a combining character, skip over it */ CCRIGHT(); }
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 cuttext(ZLE_STRING_T line, int ct, int flags) { if (!ct) return; UNMETACHECK(); if (zmod.flags & MOD_VIBUF) { struct cutbuffer *b = &vibuf[zmod.vibuf]; if (!(zmod.flags & MOD_VIAPP) || !b->buf) { free(b->buf); b->buf = (ZLE_STRING_T)zalloc(ct * ZLE_CHAR_SIZE); ZS_memcpy(b->buf, line, ct); b->len = ct; b->flags = vilinerange ? CUTBUFFER_LINE : 0; } else { int len = b->len; if(vilinerange) b->flags |= CUTBUFFER_LINE; b->buf = (ZLE_STRING_T) realloc((char *)b->buf, (ct + len + !!(b->flags & CUTBUFFER_LINE)) * ZLE_CHAR_SIZE); if (b->flags & CUTBUFFER_LINE) b->buf[len++] = ZWC('\n'); ZS_memcpy(b->buf + len, line, ct); b->len = len + ct; } return; } else { /* Save in "1, shifting "1-"8 along to "2-"9 */ int n; free(vibuf[34].buf); for(n=34; n>26; n--) vibuf[n] = vibuf[n-1]; vibuf[26].buf = (ZLE_STRING_T)zalloc(ct * ZLE_CHAR_SIZE); ZS_memcpy(vibuf[26].buf, line, ct); vibuf[26].len = ct; vibuf[26].flags = vilinerange ? CUTBUFFER_LINE : 0; } if (!cutbuf.buf) { cutbuf.buf = (ZLE_STRING_T)zalloc(ZLE_CHAR_SIZE); cutbuf.buf[0] = ZWC('\0'); cutbuf.len = cutbuf.flags = 0; } else if (!(lastcmd & ZLE_KILL) || (flags & CUT_REPLACE)) { Cutbuffer kptr; if (!kring) { kringsize = KRINGCTDEF; kring = (Cutbuffer)zshcalloc(kringsize * sizeof(struct cutbuffer)); } else kringnum = (kringnum + 1) % kringsize; kptr = kring + kringnum; if (kptr->buf) free(kptr->buf); *kptr = cutbuf; cutbuf.buf = (ZLE_STRING_T)zalloc(ZLE_CHAR_SIZE); cutbuf.buf[0] = ZWC('\0'); cutbuf.len = cutbuf.flags = 0; } if (flags & (CUT_FRONT|CUT_REPLACE)) { ZLE_STRING_T s = (ZLE_STRING_T)zalloc((cutbuf.len + ct)*ZLE_CHAR_SIZE); ZS_memcpy(s, line, ct); ZS_memcpy(s + ct, cutbuf.buf, cutbuf.len); free(cutbuf.buf); cutbuf.buf = s; cutbuf.len += ct; } else { cutbuf.buf = realloc((char *)cutbuf.buf, (cutbuf.len + ct) * ZLE_CHAR_SIZE); ZS_memcpy(cutbuf.buf + cutbuf.len, line, ct); cutbuf.len += ct; } if(vilinerange) cutbuf.flags |= CUTBUFFER_LINE; else cutbuf.flags &= ~CUTBUFFER_LINE; }