1*d0ef721eSBaptiste Daroussin /* $NetBSD: chared.c,v 1.59 2019/07/23 10:18:52 christos Exp $ */ 2*d0ef721eSBaptiste Daroussin 3*d0ef721eSBaptiste Daroussin /*- 4*d0ef721eSBaptiste Daroussin * Copyright (c) 1992, 1993 5*d0ef721eSBaptiste Daroussin * The Regents of the University of California. All rights reserved. 6*d0ef721eSBaptiste Daroussin * 7*d0ef721eSBaptiste Daroussin * This code is derived from software contributed to Berkeley by 8*d0ef721eSBaptiste Daroussin * Christos Zoulas of Cornell University. 9*d0ef721eSBaptiste Daroussin * 10*d0ef721eSBaptiste Daroussin * Redistribution and use in source and binary forms, with or without 11*d0ef721eSBaptiste Daroussin * modification, are permitted provided that the following conditions 12*d0ef721eSBaptiste Daroussin * are met: 13*d0ef721eSBaptiste Daroussin * 1. Redistributions of source code must retain the above copyright 14*d0ef721eSBaptiste Daroussin * notice, this list of conditions and the following disclaimer. 15*d0ef721eSBaptiste Daroussin * 2. Redistributions in binary form must reproduce the above copyright 16*d0ef721eSBaptiste Daroussin * notice, this list of conditions and the following disclaimer in the 17*d0ef721eSBaptiste Daroussin * documentation and/or other materials provided with the distribution. 18*d0ef721eSBaptiste Daroussin * 3. Neither the name of the University nor the names of its contributors 19*d0ef721eSBaptiste Daroussin * may be used to endorse or promote products derived from this software 20*d0ef721eSBaptiste Daroussin * without specific prior written permission. 21*d0ef721eSBaptiste Daroussin * 22*d0ef721eSBaptiste Daroussin * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23*d0ef721eSBaptiste Daroussin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24*d0ef721eSBaptiste Daroussin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25*d0ef721eSBaptiste Daroussin * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26*d0ef721eSBaptiste Daroussin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27*d0ef721eSBaptiste Daroussin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28*d0ef721eSBaptiste Daroussin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29*d0ef721eSBaptiste Daroussin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30*d0ef721eSBaptiste Daroussin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31*d0ef721eSBaptiste Daroussin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32*d0ef721eSBaptiste Daroussin * SUCH DAMAGE. 33*d0ef721eSBaptiste Daroussin */ 34*d0ef721eSBaptiste Daroussin 35*d0ef721eSBaptiste Daroussin #include "config.h" 36*d0ef721eSBaptiste Daroussin #if !defined(lint) && !defined(SCCSID) 37*d0ef721eSBaptiste Daroussin #if 0 38*d0ef721eSBaptiste Daroussin static char sccsid[] = "@(#)chared.c 8.1 (Berkeley) 6/4/93"; 39*d0ef721eSBaptiste Daroussin #else 40*d0ef721eSBaptiste Daroussin __RCSID("$NetBSD: chared.c,v 1.59 2019/07/23 10:18:52 christos Exp $"); 41*d0ef721eSBaptiste Daroussin #endif 42*d0ef721eSBaptiste Daroussin #endif /* not lint && not SCCSID */ 43*d0ef721eSBaptiste Daroussin 44*d0ef721eSBaptiste Daroussin /* 45*d0ef721eSBaptiste Daroussin * chared.c: Character editor utilities 46*d0ef721eSBaptiste Daroussin */ 47*d0ef721eSBaptiste Daroussin #include <ctype.h> 48*d0ef721eSBaptiste Daroussin #include <stdlib.h> 49*d0ef721eSBaptiste Daroussin #include <string.h> 50*d0ef721eSBaptiste Daroussin 51*d0ef721eSBaptiste Daroussin #include "el.h" 52*d0ef721eSBaptiste Daroussin #include "common.h" 53*d0ef721eSBaptiste Daroussin #include "fcns.h" 54*d0ef721eSBaptiste Daroussin 55*d0ef721eSBaptiste Daroussin /* value to leave unused in line buffer */ 56*d0ef721eSBaptiste Daroussin #define EL_LEAVE 2 57*d0ef721eSBaptiste Daroussin 58*d0ef721eSBaptiste Daroussin /* cv_undo(): 59*d0ef721eSBaptiste Daroussin * Handle state for the vi undo command 60*d0ef721eSBaptiste Daroussin */ 61*d0ef721eSBaptiste Daroussin libedit_private void 62*d0ef721eSBaptiste Daroussin cv_undo(EditLine *el) 63*d0ef721eSBaptiste Daroussin { 64*d0ef721eSBaptiste Daroussin c_undo_t *vu = &el->el_chared.c_undo; 65*d0ef721eSBaptiste Daroussin c_redo_t *r = &el->el_chared.c_redo; 66*d0ef721eSBaptiste Daroussin size_t size; 67*d0ef721eSBaptiste Daroussin 68*d0ef721eSBaptiste Daroussin /* Save entire line for undo */ 69*d0ef721eSBaptiste Daroussin size = (size_t)(el->el_line.lastchar - el->el_line.buffer); 70*d0ef721eSBaptiste Daroussin vu->len = (ssize_t)size; 71*d0ef721eSBaptiste Daroussin vu->cursor = (int)(el->el_line.cursor - el->el_line.buffer); 72*d0ef721eSBaptiste Daroussin (void)memcpy(vu->buf, el->el_line.buffer, size * sizeof(*vu->buf)); 73*d0ef721eSBaptiste Daroussin 74*d0ef721eSBaptiste Daroussin /* save command info for redo */ 75*d0ef721eSBaptiste Daroussin r->count = el->el_state.doingarg ? el->el_state.argument : 0; 76*d0ef721eSBaptiste Daroussin r->action = el->el_chared.c_vcmd.action; 77*d0ef721eSBaptiste Daroussin r->pos = r->buf; 78*d0ef721eSBaptiste Daroussin r->cmd = el->el_state.thiscmd; 79*d0ef721eSBaptiste Daroussin r->ch = el->el_state.thisch; 80*d0ef721eSBaptiste Daroussin } 81*d0ef721eSBaptiste Daroussin 82*d0ef721eSBaptiste Daroussin /* cv_yank(): 83*d0ef721eSBaptiste Daroussin * Save yank/delete data for paste 84*d0ef721eSBaptiste Daroussin */ 85*d0ef721eSBaptiste Daroussin libedit_private void 86*d0ef721eSBaptiste Daroussin cv_yank(EditLine *el, const wchar_t *ptr, int size) 87*d0ef721eSBaptiste Daroussin { 88*d0ef721eSBaptiste Daroussin c_kill_t *k = &el->el_chared.c_kill; 89*d0ef721eSBaptiste Daroussin 90*d0ef721eSBaptiste Daroussin (void)memcpy(k->buf, ptr, (size_t)size * sizeof(*k->buf)); 91*d0ef721eSBaptiste Daroussin k->last = k->buf + size; 92*d0ef721eSBaptiste Daroussin } 93*d0ef721eSBaptiste Daroussin 94*d0ef721eSBaptiste Daroussin 95*d0ef721eSBaptiste Daroussin /* c_insert(): 96*d0ef721eSBaptiste Daroussin * Insert num characters 97*d0ef721eSBaptiste Daroussin */ 98*d0ef721eSBaptiste Daroussin libedit_private void 99*d0ef721eSBaptiste Daroussin c_insert(EditLine *el, int num) 100*d0ef721eSBaptiste Daroussin { 101*d0ef721eSBaptiste Daroussin wchar_t *cp; 102*d0ef721eSBaptiste Daroussin 103*d0ef721eSBaptiste Daroussin if (el->el_line.lastchar + num >= el->el_line.limit) { 104*d0ef721eSBaptiste Daroussin if (!ch_enlargebufs(el, (size_t)num)) 105*d0ef721eSBaptiste Daroussin return; /* can't go past end of buffer */ 106*d0ef721eSBaptiste Daroussin } 107*d0ef721eSBaptiste Daroussin 108*d0ef721eSBaptiste Daroussin if (el->el_line.cursor < el->el_line.lastchar) { 109*d0ef721eSBaptiste Daroussin /* if I must move chars */ 110*d0ef721eSBaptiste Daroussin for (cp = el->el_line.lastchar; cp >= el->el_line.cursor; cp--) 111*d0ef721eSBaptiste Daroussin cp[num] = *cp; 112*d0ef721eSBaptiste Daroussin } 113*d0ef721eSBaptiste Daroussin el->el_line.lastchar += num; 114*d0ef721eSBaptiste Daroussin } 115*d0ef721eSBaptiste Daroussin 116*d0ef721eSBaptiste Daroussin 117*d0ef721eSBaptiste Daroussin /* c_delafter(): 118*d0ef721eSBaptiste Daroussin * Delete num characters after the cursor 119*d0ef721eSBaptiste Daroussin */ 120*d0ef721eSBaptiste Daroussin libedit_private void 121*d0ef721eSBaptiste Daroussin c_delafter(EditLine *el, int num) 122*d0ef721eSBaptiste Daroussin { 123*d0ef721eSBaptiste Daroussin 124*d0ef721eSBaptiste Daroussin if (el->el_line.cursor + num > el->el_line.lastchar) 125*d0ef721eSBaptiste Daroussin num = (int)(el->el_line.lastchar - el->el_line.cursor); 126*d0ef721eSBaptiste Daroussin 127*d0ef721eSBaptiste Daroussin if (el->el_map.current != el->el_map.emacs) { 128*d0ef721eSBaptiste Daroussin cv_undo(el); 129*d0ef721eSBaptiste Daroussin cv_yank(el, el->el_line.cursor, num); 130*d0ef721eSBaptiste Daroussin } 131*d0ef721eSBaptiste Daroussin 132*d0ef721eSBaptiste Daroussin if (num > 0) { 133*d0ef721eSBaptiste Daroussin wchar_t *cp; 134*d0ef721eSBaptiste Daroussin 135*d0ef721eSBaptiste Daroussin for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++) 136*d0ef721eSBaptiste Daroussin *cp = cp[num]; 137*d0ef721eSBaptiste Daroussin 138*d0ef721eSBaptiste Daroussin el->el_line.lastchar -= num; 139*d0ef721eSBaptiste Daroussin } 140*d0ef721eSBaptiste Daroussin } 141*d0ef721eSBaptiste Daroussin 142*d0ef721eSBaptiste Daroussin 143*d0ef721eSBaptiste Daroussin /* c_delafter1(): 144*d0ef721eSBaptiste Daroussin * Delete the character after the cursor, do not yank 145*d0ef721eSBaptiste Daroussin */ 146*d0ef721eSBaptiste Daroussin libedit_private void 147*d0ef721eSBaptiste Daroussin c_delafter1(EditLine *el) 148*d0ef721eSBaptiste Daroussin { 149*d0ef721eSBaptiste Daroussin wchar_t *cp; 150*d0ef721eSBaptiste Daroussin 151*d0ef721eSBaptiste Daroussin for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++) 152*d0ef721eSBaptiste Daroussin *cp = cp[1]; 153*d0ef721eSBaptiste Daroussin 154*d0ef721eSBaptiste Daroussin el->el_line.lastchar--; 155*d0ef721eSBaptiste Daroussin } 156*d0ef721eSBaptiste Daroussin 157*d0ef721eSBaptiste Daroussin 158*d0ef721eSBaptiste Daroussin /* c_delbefore(): 159*d0ef721eSBaptiste Daroussin * Delete num characters before the cursor 160*d0ef721eSBaptiste Daroussin */ 161*d0ef721eSBaptiste Daroussin libedit_private void 162*d0ef721eSBaptiste Daroussin c_delbefore(EditLine *el, int num) 163*d0ef721eSBaptiste Daroussin { 164*d0ef721eSBaptiste Daroussin 165*d0ef721eSBaptiste Daroussin if (el->el_line.cursor - num < el->el_line.buffer) 166*d0ef721eSBaptiste Daroussin num = (int)(el->el_line.cursor - el->el_line.buffer); 167*d0ef721eSBaptiste Daroussin 168*d0ef721eSBaptiste Daroussin if (el->el_map.current != el->el_map.emacs) { 169*d0ef721eSBaptiste Daroussin cv_undo(el); 170*d0ef721eSBaptiste Daroussin cv_yank(el, el->el_line.cursor - num, num); 171*d0ef721eSBaptiste Daroussin } 172*d0ef721eSBaptiste Daroussin 173*d0ef721eSBaptiste Daroussin if (num > 0) { 174*d0ef721eSBaptiste Daroussin wchar_t *cp; 175*d0ef721eSBaptiste Daroussin 176*d0ef721eSBaptiste Daroussin for (cp = el->el_line.cursor - num; 177*d0ef721eSBaptiste Daroussin &cp[num] <= el->el_line.lastchar; 178*d0ef721eSBaptiste Daroussin cp++) 179*d0ef721eSBaptiste Daroussin *cp = cp[num]; 180*d0ef721eSBaptiste Daroussin 181*d0ef721eSBaptiste Daroussin el->el_line.lastchar -= num; 182*d0ef721eSBaptiste Daroussin } 183*d0ef721eSBaptiste Daroussin } 184*d0ef721eSBaptiste Daroussin 185*d0ef721eSBaptiste Daroussin 186*d0ef721eSBaptiste Daroussin /* c_delbefore1(): 187*d0ef721eSBaptiste Daroussin * Delete the character before the cursor, do not yank 188*d0ef721eSBaptiste Daroussin */ 189*d0ef721eSBaptiste Daroussin libedit_private void 190*d0ef721eSBaptiste Daroussin c_delbefore1(EditLine *el) 191*d0ef721eSBaptiste Daroussin { 192*d0ef721eSBaptiste Daroussin wchar_t *cp; 193*d0ef721eSBaptiste Daroussin 194*d0ef721eSBaptiste Daroussin for (cp = el->el_line.cursor - 1; cp <= el->el_line.lastchar; cp++) 195*d0ef721eSBaptiste Daroussin *cp = cp[1]; 196*d0ef721eSBaptiste Daroussin 197*d0ef721eSBaptiste Daroussin el->el_line.lastchar--; 198*d0ef721eSBaptiste Daroussin } 199*d0ef721eSBaptiste Daroussin 200*d0ef721eSBaptiste Daroussin 201*d0ef721eSBaptiste Daroussin /* ce__isword(): 202*d0ef721eSBaptiste Daroussin * Return if p is part of a word according to emacs 203*d0ef721eSBaptiste Daroussin */ 204*d0ef721eSBaptiste Daroussin libedit_private int 205*d0ef721eSBaptiste Daroussin ce__isword(wint_t p) 206*d0ef721eSBaptiste Daroussin { 207*d0ef721eSBaptiste Daroussin return iswalnum(p) || wcschr(L"*?_-.[]~=", p) != NULL; 208*d0ef721eSBaptiste Daroussin } 209*d0ef721eSBaptiste Daroussin 210*d0ef721eSBaptiste Daroussin 211*d0ef721eSBaptiste Daroussin /* cv__isword(): 212*d0ef721eSBaptiste Daroussin * Return if p is part of a word according to vi 213*d0ef721eSBaptiste Daroussin */ 214*d0ef721eSBaptiste Daroussin libedit_private int 215*d0ef721eSBaptiste Daroussin cv__isword(wint_t p) 216*d0ef721eSBaptiste Daroussin { 217*d0ef721eSBaptiste Daroussin if (iswalnum(p) || p == L'_') 218*d0ef721eSBaptiste Daroussin return 1; 219*d0ef721eSBaptiste Daroussin if (iswgraph(p)) 220*d0ef721eSBaptiste Daroussin return 2; 221*d0ef721eSBaptiste Daroussin return 0; 222*d0ef721eSBaptiste Daroussin } 223*d0ef721eSBaptiste Daroussin 224*d0ef721eSBaptiste Daroussin 225*d0ef721eSBaptiste Daroussin /* cv__isWord(): 226*d0ef721eSBaptiste Daroussin * Return if p is part of a big word according to vi 227*d0ef721eSBaptiste Daroussin */ 228*d0ef721eSBaptiste Daroussin libedit_private int 229*d0ef721eSBaptiste Daroussin cv__isWord(wint_t p) 230*d0ef721eSBaptiste Daroussin { 231*d0ef721eSBaptiste Daroussin return !iswspace(p); 232*d0ef721eSBaptiste Daroussin } 233*d0ef721eSBaptiste Daroussin 234*d0ef721eSBaptiste Daroussin 235*d0ef721eSBaptiste Daroussin /* c__prev_word(): 236*d0ef721eSBaptiste Daroussin * Find the previous word 237*d0ef721eSBaptiste Daroussin */ 238*d0ef721eSBaptiste Daroussin libedit_private wchar_t * 239*d0ef721eSBaptiste Daroussin c__prev_word(wchar_t *p, wchar_t *low, int n, int (*wtest)(wint_t)) 240*d0ef721eSBaptiste Daroussin { 241*d0ef721eSBaptiste Daroussin p--; 242*d0ef721eSBaptiste Daroussin 243*d0ef721eSBaptiste Daroussin while (n--) { 244*d0ef721eSBaptiste Daroussin while ((p >= low) && !(*wtest)(*p)) 245*d0ef721eSBaptiste Daroussin p--; 246*d0ef721eSBaptiste Daroussin while ((p >= low) && (*wtest)(*p)) 247*d0ef721eSBaptiste Daroussin p--; 248*d0ef721eSBaptiste Daroussin } 249*d0ef721eSBaptiste Daroussin 250*d0ef721eSBaptiste Daroussin /* cp now points to one character before the word */ 251*d0ef721eSBaptiste Daroussin p++; 252*d0ef721eSBaptiste Daroussin if (p < low) 253*d0ef721eSBaptiste Daroussin p = low; 254*d0ef721eSBaptiste Daroussin /* cp now points where we want it */ 255*d0ef721eSBaptiste Daroussin return p; 256*d0ef721eSBaptiste Daroussin } 257*d0ef721eSBaptiste Daroussin 258*d0ef721eSBaptiste Daroussin 259*d0ef721eSBaptiste Daroussin /* c__next_word(): 260*d0ef721eSBaptiste Daroussin * Find the next word 261*d0ef721eSBaptiste Daroussin */ 262*d0ef721eSBaptiste Daroussin libedit_private wchar_t * 263*d0ef721eSBaptiste Daroussin c__next_word(wchar_t *p, wchar_t *high, int n, int (*wtest)(wint_t)) 264*d0ef721eSBaptiste Daroussin { 265*d0ef721eSBaptiste Daroussin while (n--) { 266*d0ef721eSBaptiste Daroussin while ((p < high) && !(*wtest)(*p)) 267*d0ef721eSBaptiste Daroussin p++; 268*d0ef721eSBaptiste Daroussin while ((p < high) && (*wtest)(*p)) 269*d0ef721eSBaptiste Daroussin p++; 270*d0ef721eSBaptiste Daroussin } 271*d0ef721eSBaptiste Daroussin if (p > high) 272*d0ef721eSBaptiste Daroussin p = high; 273*d0ef721eSBaptiste Daroussin /* p now points where we want it */ 274*d0ef721eSBaptiste Daroussin return p; 275*d0ef721eSBaptiste Daroussin } 276*d0ef721eSBaptiste Daroussin 277*d0ef721eSBaptiste Daroussin /* cv_next_word(): 278*d0ef721eSBaptiste Daroussin * Find the next word vi style 279*d0ef721eSBaptiste Daroussin */ 280*d0ef721eSBaptiste Daroussin libedit_private wchar_t * 281*d0ef721eSBaptiste Daroussin cv_next_word(EditLine *el, wchar_t *p, wchar_t *high, int n, 282*d0ef721eSBaptiste Daroussin int (*wtest)(wint_t)) 283*d0ef721eSBaptiste Daroussin { 284*d0ef721eSBaptiste Daroussin int test; 285*d0ef721eSBaptiste Daroussin 286*d0ef721eSBaptiste Daroussin while (n--) { 287*d0ef721eSBaptiste Daroussin test = (*wtest)(*p); 288*d0ef721eSBaptiste Daroussin while ((p < high) && (*wtest)(*p) == test) 289*d0ef721eSBaptiste Daroussin p++; 290*d0ef721eSBaptiste Daroussin /* 291*d0ef721eSBaptiste Daroussin * vi historically deletes with cw only the word preserving the 292*d0ef721eSBaptiste Daroussin * trailing whitespace! This is not what 'w' does.. 293*d0ef721eSBaptiste Daroussin */ 294*d0ef721eSBaptiste Daroussin if (n || el->el_chared.c_vcmd.action != (DELETE|INSERT)) 295*d0ef721eSBaptiste Daroussin while ((p < high) && iswspace(*p)) 296*d0ef721eSBaptiste Daroussin p++; 297*d0ef721eSBaptiste Daroussin } 298*d0ef721eSBaptiste Daroussin 299*d0ef721eSBaptiste Daroussin /* p now points where we want it */ 300*d0ef721eSBaptiste Daroussin if (p > high) 301*d0ef721eSBaptiste Daroussin return high; 302*d0ef721eSBaptiste Daroussin else 303*d0ef721eSBaptiste Daroussin return p; 304*d0ef721eSBaptiste Daroussin } 305*d0ef721eSBaptiste Daroussin 306*d0ef721eSBaptiste Daroussin 307*d0ef721eSBaptiste Daroussin /* cv_prev_word(): 308*d0ef721eSBaptiste Daroussin * Find the previous word vi style 309*d0ef721eSBaptiste Daroussin */ 310*d0ef721eSBaptiste Daroussin libedit_private wchar_t * 311*d0ef721eSBaptiste Daroussin cv_prev_word(wchar_t *p, wchar_t *low, int n, int (*wtest)(wint_t)) 312*d0ef721eSBaptiste Daroussin { 313*d0ef721eSBaptiste Daroussin int test; 314*d0ef721eSBaptiste Daroussin 315*d0ef721eSBaptiste Daroussin p--; 316*d0ef721eSBaptiste Daroussin while (n--) { 317*d0ef721eSBaptiste Daroussin while ((p > low) && iswspace(*p)) 318*d0ef721eSBaptiste Daroussin p--; 319*d0ef721eSBaptiste Daroussin test = (*wtest)(*p); 320*d0ef721eSBaptiste Daroussin while ((p >= low) && (*wtest)(*p) == test) 321*d0ef721eSBaptiste Daroussin p--; 322*d0ef721eSBaptiste Daroussin } 323*d0ef721eSBaptiste Daroussin p++; 324*d0ef721eSBaptiste Daroussin 325*d0ef721eSBaptiste Daroussin /* p now points where we want it */ 326*d0ef721eSBaptiste Daroussin if (p < low) 327*d0ef721eSBaptiste Daroussin return low; 328*d0ef721eSBaptiste Daroussin else 329*d0ef721eSBaptiste Daroussin return p; 330*d0ef721eSBaptiste Daroussin } 331*d0ef721eSBaptiste Daroussin 332*d0ef721eSBaptiste Daroussin 333*d0ef721eSBaptiste Daroussin /* cv_delfini(): 334*d0ef721eSBaptiste Daroussin * Finish vi delete action 335*d0ef721eSBaptiste Daroussin */ 336*d0ef721eSBaptiste Daroussin libedit_private void 337*d0ef721eSBaptiste Daroussin cv_delfini(EditLine *el) 338*d0ef721eSBaptiste Daroussin { 339*d0ef721eSBaptiste Daroussin int size; 340*d0ef721eSBaptiste Daroussin int action = el->el_chared.c_vcmd.action; 341*d0ef721eSBaptiste Daroussin 342*d0ef721eSBaptiste Daroussin if (action & INSERT) 343*d0ef721eSBaptiste Daroussin el->el_map.current = el->el_map.key; 344*d0ef721eSBaptiste Daroussin 345*d0ef721eSBaptiste Daroussin if (el->el_chared.c_vcmd.pos == 0) 346*d0ef721eSBaptiste Daroussin /* sanity */ 347*d0ef721eSBaptiste Daroussin return; 348*d0ef721eSBaptiste Daroussin 349*d0ef721eSBaptiste Daroussin size = (int)(el->el_line.cursor - el->el_chared.c_vcmd.pos); 350*d0ef721eSBaptiste Daroussin if (size == 0) 351*d0ef721eSBaptiste Daroussin size = 1; 352*d0ef721eSBaptiste Daroussin el->el_line.cursor = el->el_chared.c_vcmd.pos; 353*d0ef721eSBaptiste Daroussin if (action & YANK) { 354*d0ef721eSBaptiste Daroussin if (size > 0) 355*d0ef721eSBaptiste Daroussin cv_yank(el, el->el_line.cursor, size); 356*d0ef721eSBaptiste Daroussin else 357*d0ef721eSBaptiste Daroussin cv_yank(el, el->el_line.cursor + size, -size); 358*d0ef721eSBaptiste Daroussin } else { 359*d0ef721eSBaptiste Daroussin if (size > 0) { 360*d0ef721eSBaptiste Daroussin c_delafter(el, size); 361*d0ef721eSBaptiste Daroussin re_refresh_cursor(el); 362*d0ef721eSBaptiste Daroussin } else { 363*d0ef721eSBaptiste Daroussin c_delbefore(el, -size); 364*d0ef721eSBaptiste Daroussin el->el_line.cursor += size; 365*d0ef721eSBaptiste Daroussin } 366*d0ef721eSBaptiste Daroussin } 367*d0ef721eSBaptiste Daroussin el->el_chared.c_vcmd.action = NOP; 368*d0ef721eSBaptiste Daroussin } 369*d0ef721eSBaptiste Daroussin 370*d0ef721eSBaptiste Daroussin 371*d0ef721eSBaptiste Daroussin /* cv__endword(): 372*d0ef721eSBaptiste Daroussin * Go to the end of this word according to vi 373*d0ef721eSBaptiste Daroussin */ 374*d0ef721eSBaptiste Daroussin libedit_private wchar_t * 375*d0ef721eSBaptiste Daroussin cv__endword(wchar_t *p, wchar_t *high, int n, int (*wtest)(wint_t)) 376*d0ef721eSBaptiste Daroussin { 377*d0ef721eSBaptiste Daroussin int test; 378*d0ef721eSBaptiste Daroussin 379*d0ef721eSBaptiste Daroussin p++; 380*d0ef721eSBaptiste Daroussin 381*d0ef721eSBaptiste Daroussin while (n--) { 382*d0ef721eSBaptiste Daroussin while ((p < high) && iswspace(*p)) 383*d0ef721eSBaptiste Daroussin p++; 384*d0ef721eSBaptiste Daroussin 385*d0ef721eSBaptiste Daroussin test = (*wtest)(*p); 386*d0ef721eSBaptiste Daroussin while ((p < high) && (*wtest)(*p) == test) 387*d0ef721eSBaptiste Daroussin p++; 388*d0ef721eSBaptiste Daroussin } 389*d0ef721eSBaptiste Daroussin p--; 390*d0ef721eSBaptiste Daroussin return p; 391*d0ef721eSBaptiste Daroussin } 392*d0ef721eSBaptiste Daroussin 393*d0ef721eSBaptiste Daroussin /* ch_init(): 394*d0ef721eSBaptiste Daroussin * Initialize the character editor 395*d0ef721eSBaptiste Daroussin */ 396*d0ef721eSBaptiste Daroussin libedit_private int 397*d0ef721eSBaptiste Daroussin ch_init(EditLine *el) 398*d0ef721eSBaptiste Daroussin { 399*d0ef721eSBaptiste Daroussin el->el_line.buffer = el_calloc(EL_BUFSIZ, 400*d0ef721eSBaptiste Daroussin sizeof(*el->el_line.buffer)); 401*d0ef721eSBaptiste Daroussin if (el->el_line.buffer == NULL) 402*d0ef721eSBaptiste Daroussin return -1; 403*d0ef721eSBaptiste Daroussin 404*d0ef721eSBaptiste Daroussin el->el_line.cursor = el->el_line.buffer; 405*d0ef721eSBaptiste Daroussin el->el_line.lastchar = el->el_line.buffer; 406*d0ef721eSBaptiste Daroussin el->el_line.limit = &el->el_line.buffer[EL_BUFSIZ - EL_LEAVE]; 407*d0ef721eSBaptiste Daroussin 408*d0ef721eSBaptiste Daroussin el->el_chared.c_undo.buf = el_calloc(EL_BUFSIZ, 409*d0ef721eSBaptiste Daroussin sizeof(*el->el_chared.c_undo.buf)); 410*d0ef721eSBaptiste Daroussin if (el->el_chared.c_undo.buf == NULL) 411*d0ef721eSBaptiste Daroussin return -1; 412*d0ef721eSBaptiste Daroussin el->el_chared.c_undo.len = -1; 413*d0ef721eSBaptiste Daroussin el->el_chared.c_undo.cursor = 0; 414*d0ef721eSBaptiste Daroussin el->el_chared.c_redo.buf = el_calloc(EL_BUFSIZ, 415*d0ef721eSBaptiste Daroussin sizeof(*el->el_chared.c_redo.buf)); 416*d0ef721eSBaptiste Daroussin if (el->el_chared.c_redo.buf == NULL) 417*d0ef721eSBaptiste Daroussin return -1; 418*d0ef721eSBaptiste Daroussin el->el_chared.c_redo.pos = el->el_chared.c_redo.buf; 419*d0ef721eSBaptiste Daroussin el->el_chared.c_redo.lim = el->el_chared.c_redo.buf + EL_BUFSIZ; 420*d0ef721eSBaptiste Daroussin el->el_chared.c_redo.cmd = ED_UNASSIGNED; 421*d0ef721eSBaptiste Daroussin 422*d0ef721eSBaptiste Daroussin el->el_chared.c_vcmd.action = NOP; 423*d0ef721eSBaptiste Daroussin el->el_chared.c_vcmd.pos = el->el_line.buffer; 424*d0ef721eSBaptiste Daroussin 425*d0ef721eSBaptiste Daroussin el->el_chared.c_kill.buf = el_calloc(EL_BUFSIZ, 426*d0ef721eSBaptiste Daroussin sizeof(*el->el_chared.c_kill.buf)); 427*d0ef721eSBaptiste Daroussin if (el->el_chared.c_kill.buf == NULL) 428*d0ef721eSBaptiste Daroussin return -1; 429*d0ef721eSBaptiste Daroussin el->el_chared.c_kill.mark = el->el_line.buffer; 430*d0ef721eSBaptiste Daroussin el->el_chared.c_kill.last = el->el_chared.c_kill.buf; 431*d0ef721eSBaptiste Daroussin el->el_chared.c_resizefun = NULL; 432*d0ef721eSBaptiste Daroussin el->el_chared.c_resizearg = NULL; 433*d0ef721eSBaptiste Daroussin el->el_chared.c_aliasfun = NULL; 434*d0ef721eSBaptiste Daroussin el->el_chared.c_aliasarg = NULL; 435*d0ef721eSBaptiste Daroussin 436*d0ef721eSBaptiste Daroussin el->el_map.current = el->el_map.key; 437*d0ef721eSBaptiste Daroussin 438*d0ef721eSBaptiste Daroussin el->el_state.inputmode = MODE_INSERT; /* XXX: save a default */ 439*d0ef721eSBaptiste Daroussin el->el_state.doingarg = 0; 440*d0ef721eSBaptiste Daroussin el->el_state.metanext = 0; 441*d0ef721eSBaptiste Daroussin el->el_state.argument = 1; 442*d0ef721eSBaptiste Daroussin el->el_state.lastcmd = ED_UNASSIGNED; 443*d0ef721eSBaptiste Daroussin 444*d0ef721eSBaptiste Daroussin return 0; 445*d0ef721eSBaptiste Daroussin } 446*d0ef721eSBaptiste Daroussin 447*d0ef721eSBaptiste Daroussin /* ch_reset(): 448*d0ef721eSBaptiste Daroussin * Reset the character editor 449*d0ef721eSBaptiste Daroussin */ 450*d0ef721eSBaptiste Daroussin libedit_private void 451*d0ef721eSBaptiste Daroussin ch_reset(EditLine *el) 452*d0ef721eSBaptiste Daroussin { 453*d0ef721eSBaptiste Daroussin el->el_line.cursor = el->el_line.buffer; 454*d0ef721eSBaptiste Daroussin el->el_line.lastchar = el->el_line.buffer; 455*d0ef721eSBaptiste Daroussin 456*d0ef721eSBaptiste Daroussin el->el_chared.c_undo.len = -1; 457*d0ef721eSBaptiste Daroussin el->el_chared.c_undo.cursor = 0; 458*d0ef721eSBaptiste Daroussin 459*d0ef721eSBaptiste Daroussin el->el_chared.c_vcmd.action = NOP; 460*d0ef721eSBaptiste Daroussin el->el_chared.c_vcmd.pos = el->el_line.buffer; 461*d0ef721eSBaptiste Daroussin 462*d0ef721eSBaptiste Daroussin el->el_chared.c_kill.mark = el->el_line.buffer; 463*d0ef721eSBaptiste Daroussin 464*d0ef721eSBaptiste Daroussin el->el_map.current = el->el_map.key; 465*d0ef721eSBaptiste Daroussin 466*d0ef721eSBaptiste Daroussin el->el_state.inputmode = MODE_INSERT; /* XXX: save a default */ 467*d0ef721eSBaptiste Daroussin el->el_state.doingarg = 0; 468*d0ef721eSBaptiste Daroussin el->el_state.metanext = 0; 469*d0ef721eSBaptiste Daroussin el->el_state.argument = 1; 470*d0ef721eSBaptiste Daroussin el->el_state.lastcmd = ED_UNASSIGNED; 471*d0ef721eSBaptiste Daroussin 472*d0ef721eSBaptiste Daroussin el->el_history.eventno = 0; 473*d0ef721eSBaptiste Daroussin } 474*d0ef721eSBaptiste Daroussin 475*d0ef721eSBaptiste Daroussin /* ch_enlargebufs(): 476*d0ef721eSBaptiste Daroussin * Enlarge line buffer to be able to hold twice as much characters. 477*d0ef721eSBaptiste Daroussin * Returns 1 if successful, 0 if not. 478*d0ef721eSBaptiste Daroussin */ 479*d0ef721eSBaptiste Daroussin libedit_private int 480*d0ef721eSBaptiste Daroussin ch_enlargebufs(EditLine *el, size_t addlen) 481*d0ef721eSBaptiste Daroussin { 482*d0ef721eSBaptiste Daroussin size_t sz, newsz; 483*d0ef721eSBaptiste Daroussin wchar_t *newbuffer, *oldbuf, *oldkbuf; 484*d0ef721eSBaptiste Daroussin 485*d0ef721eSBaptiste Daroussin sz = (size_t)(el->el_line.limit - el->el_line.buffer + EL_LEAVE); 486*d0ef721eSBaptiste Daroussin newsz = sz * 2; 487*d0ef721eSBaptiste Daroussin /* 488*d0ef721eSBaptiste Daroussin * If newly required length is longer than current buffer, we need 489*d0ef721eSBaptiste Daroussin * to make the buffer big enough to hold both old and new stuff. 490*d0ef721eSBaptiste Daroussin */ 491*d0ef721eSBaptiste Daroussin if (addlen > sz) { 492*d0ef721eSBaptiste Daroussin while(newsz - sz < addlen) 493*d0ef721eSBaptiste Daroussin newsz *= 2; 494*d0ef721eSBaptiste Daroussin } 495*d0ef721eSBaptiste Daroussin 496*d0ef721eSBaptiste Daroussin /* 497*d0ef721eSBaptiste Daroussin * Reallocate line buffer. 498*d0ef721eSBaptiste Daroussin */ 499*d0ef721eSBaptiste Daroussin newbuffer = el_realloc(el->el_line.buffer, newsz * sizeof(*newbuffer)); 500*d0ef721eSBaptiste Daroussin if (!newbuffer) 501*d0ef721eSBaptiste Daroussin return 0; 502*d0ef721eSBaptiste Daroussin 503*d0ef721eSBaptiste Daroussin /* zero the newly added memory, leave old data in */ 504*d0ef721eSBaptiste Daroussin (void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer)); 505*d0ef721eSBaptiste Daroussin 506*d0ef721eSBaptiste Daroussin oldbuf = el->el_line.buffer; 507*d0ef721eSBaptiste Daroussin 508*d0ef721eSBaptiste Daroussin el->el_line.buffer = newbuffer; 509*d0ef721eSBaptiste Daroussin el->el_line.cursor = newbuffer + (el->el_line.cursor - oldbuf); 510*d0ef721eSBaptiste Daroussin el->el_line.lastchar = newbuffer + (el->el_line.lastchar - oldbuf); 511*d0ef721eSBaptiste Daroussin /* don't set new size until all buffers are enlarged */ 512*d0ef721eSBaptiste Daroussin el->el_line.limit = &newbuffer[sz - EL_LEAVE]; 513*d0ef721eSBaptiste Daroussin 514*d0ef721eSBaptiste Daroussin /* 515*d0ef721eSBaptiste Daroussin * Reallocate kill buffer. 516*d0ef721eSBaptiste Daroussin */ 517*d0ef721eSBaptiste Daroussin newbuffer = el_realloc(el->el_chared.c_kill.buf, newsz * 518*d0ef721eSBaptiste Daroussin sizeof(*newbuffer)); 519*d0ef721eSBaptiste Daroussin if (!newbuffer) 520*d0ef721eSBaptiste Daroussin return 0; 521*d0ef721eSBaptiste Daroussin 522*d0ef721eSBaptiste Daroussin /* zero the newly added memory, leave old data in */ 523*d0ef721eSBaptiste Daroussin (void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer)); 524*d0ef721eSBaptiste Daroussin 525*d0ef721eSBaptiste Daroussin oldkbuf = el->el_chared.c_kill.buf; 526*d0ef721eSBaptiste Daroussin 527*d0ef721eSBaptiste Daroussin el->el_chared.c_kill.buf = newbuffer; 528*d0ef721eSBaptiste Daroussin el->el_chared.c_kill.last = newbuffer + 529*d0ef721eSBaptiste Daroussin (el->el_chared.c_kill.last - oldkbuf); 530*d0ef721eSBaptiste Daroussin el->el_chared.c_kill.mark = el->el_line.buffer + 531*d0ef721eSBaptiste Daroussin (el->el_chared.c_kill.mark - oldbuf); 532*d0ef721eSBaptiste Daroussin 533*d0ef721eSBaptiste Daroussin /* 534*d0ef721eSBaptiste Daroussin * Reallocate undo buffer. 535*d0ef721eSBaptiste Daroussin */ 536*d0ef721eSBaptiste Daroussin newbuffer = el_realloc(el->el_chared.c_undo.buf, 537*d0ef721eSBaptiste Daroussin newsz * sizeof(*newbuffer)); 538*d0ef721eSBaptiste Daroussin if (!newbuffer) 539*d0ef721eSBaptiste Daroussin return 0; 540*d0ef721eSBaptiste Daroussin 541*d0ef721eSBaptiste Daroussin /* zero the newly added memory, leave old data in */ 542*d0ef721eSBaptiste Daroussin (void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer)); 543*d0ef721eSBaptiste Daroussin el->el_chared.c_undo.buf = newbuffer; 544*d0ef721eSBaptiste Daroussin 545*d0ef721eSBaptiste Daroussin newbuffer = el_realloc(el->el_chared.c_redo.buf, 546*d0ef721eSBaptiste Daroussin newsz * sizeof(*newbuffer)); 547*d0ef721eSBaptiste Daroussin if (!newbuffer) 548*d0ef721eSBaptiste Daroussin return 0; 549*d0ef721eSBaptiste Daroussin el->el_chared.c_redo.pos = newbuffer + 550*d0ef721eSBaptiste Daroussin (el->el_chared.c_redo.pos - el->el_chared.c_redo.buf); 551*d0ef721eSBaptiste Daroussin el->el_chared.c_redo.lim = newbuffer + 552*d0ef721eSBaptiste Daroussin (el->el_chared.c_redo.lim - el->el_chared.c_redo.buf); 553*d0ef721eSBaptiste Daroussin el->el_chared.c_redo.buf = newbuffer; 554*d0ef721eSBaptiste Daroussin 555*d0ef721eSBaptiste Daroussin if (!hist_enlargebuf(el, sz, newsz)) 556*d0ef721eSBaptiste Daroussin return 0; 557*d0ef721eSBaptiste Daroussin 558*d0ef721eSBaptiste Daroussin /* Safe to set enlarged buffer size */ 559*d0ef721eSBaptiste Daroussin el->el_line.limit = &el->el_line.buffer[newsz - EL_LEAVE]; 560*d0ef721eSBaptiste Daroussin if (el->el_chared.c_resizefun) 561*d0ef721eSBaptiste Daroussin (*el->el_chared.c_resizefun)(el, el->el_chared.c_resizearg); 562*d0ef721eSBaptiste Daroussin return 1; 563*d0ef721eSBaptiste Daroussin } 564*d0ef721eSBaptiste Daroussin 565*d0ef721eSBaptiste Daroussin /* ch_end(): 566*d0ef721eSBaptiste Daroussin * Free the data structures used by the editor 567*d0ef721eSBaptiste Daroussin */ 568*d0ef721eSBaptiste Daroussin libedit_private void 569*d0ef721eSBaptiste Daroussin ch_end(EditLine *el) 570*d0ef721eSBaptiste Daroussin { 571*d0ef721eSBaptiste Daroussin el_free(el->el_line.buffer); 572*d0ef721eSBaptiste Daroussin el->el_line.buffer = NULL; 573*d0ef721eSBaptiste Daroussin el->el_line.limit = NULL; 574*d0ef721eSBaptiste Daroussin el_free(el->el_chared.c_undo.buf); 575*d0ef721eSBaptiste Daroussin el->el_chared.c_undo.buf = NULL; 576*d0ef721eSBaptiste Daroussin el_free(el->el_chared.c_redo.buf); 577*d0ef721eSBaptiste Daroussin el->el_chared.c_redo.buf = NULL; 578*d0ef721eSBaptiste Daroussin el->el_chared.c_redo.pos = NULL; 579*d0ef721eSBaptiste Daroussin el->el_chared.c_redo.lim = NULL; 580*d0ef721eSBaptiste Daroussin el->el_chared.c_redo.cmd = ED_UNASSIGNED; 581*d0ef721eSBaptiste Daroussin el_free(el->el_chared.c_kill.buf); 582*d0ef721eSBaptiste Daroussin el->el_chared.c_kill.buf = NULL; 583*d0ef721eSBaptiste Daroussin ch_reset(el); 584*d0ef721eSBaptiste Daroussin } 585*d0ef721eSBaptiste Daroussin 586*d0ef721eSBaptiste Daroussin 587*d0ef721eSBaptiste Daroussin /* el_insertstr(): 588*d0ef721eSBaptiste Daroussin * Insert string at cursor 589*d0ef721eSBaptiste Daroussin */ 590*d0ef721eSBaptiste Daroussin int 591*d0ef721eSBaptiste Daroussin el_winsertstr(EditLine *el, const wchar_t *s) 592*d0ef721eSBaptiste Daroussin { 593*d0ef721eSBaptiste Daroussin size_t len; 594*d0ef721eSBaptiste Daroussin 595*d0ef721eSBaptiste Daroussin if (s == NULL || (len = wcslen(s)) == 0) 596*d0ef721eSBaptiste Daroussin return -1; 597*d0ef721eSBaptiste Daroussin if (el->el_line.lastchar + len >= el->el_line.limit) { 598*d0ef721eSBaptiste Daroussin if (!ch_enlargebufs(el, len)) 599*d0ef721eSBaptiste Daroussin return -1; 600*d0ef721eSBaptiste Daroussin } 601*d0ef721eSBaptiste Daroussin 602*d0ef721eSBaptiste Daroussin c_insert(el, (int)len); 603*d0ef721eSBaptiste Daroussin while (*s) 604*d0ef721eSBaptiste Daroussin *el->el_line.cursor++ = *s++; 605*d0ef721eSBaptiste Daroussin return 0; 606*d0ef721eSBaptiste Daroussin } 607*d0ef721eSBaptiste Daroussin 608*d0ef721eSBaptiste Daroussin 609*d0ef721eSBaptiste Daroussin /* el_deletestr(): 610*d0ef721eSBaptiste Daroussin * Delete num characters before the cursor 611*d0ef721eSBaptiste Daroussin */ 612*d0ef721eSBaptiste Daroussin void 613*d0ef721eSBaptiste Daroussin el_deletestr(EditLine *el, int n) 614*d0ef721eSBaptiste Daroussin { 615*d0ef721eSBaptiste Daroussin if (n <= 0) 616*d0ef721eSBaptiste Daroussin return; 617*d0ef721eSBaptiste Daroussin 618*d0ef721eSBaptiste Daroussin if (el->el_line.cursor < &el->el_line.buffer[n]) 619*d0ef721eSBaptiste Daroussin return; 620*d0ef721eSBaptiste Daroussin 621*d0ef721eSBaptiste Daroussin c_delbefore(el, n); /* delete before dot */ 622*d0ef721eSBaptiste Daroussin el->el_line.cursor -= n; 623*d0ef721eSBaptiste Daroussin if (el->el_line.cursor < el->el_line.buffer) 624*d0ef721eSBaptiste Daroussin el->el_line.cursor = el->el_line.buffer; 625*d0ef721eSBaptiste Daroussin } 626*d0ef721eSBaptiste Daroussin 627*d0ef721eSBaptiste Daroussin /* el_cursor(): 628*d0ef721eSBaptiste Daroussin * Move the cursor to the left or the right of the current position 629*d0ef721eSBaptiste Daroussin */ 630*d0ef721eSBaptiste Daroussin int 631*d0ef721eSBaptiste Daroussin el_cursor(EditLine *el, int n) 632*d0ef721eSBaptiste Daroussin { 633*d0ef721eSBaptiste Daroussin if (n == 0) 634*d0ef721eSBaptiste Daroussin goto out; 635*d0ef721eSBaptiste Daroussin 636*d0ef721eSBaptiste Daroussin el->el_line.cursor += n; 637*d0ef721eSBaptiste Daroussin 638*d0ef721eSBaptiste Daroussin if (el->el_line.cursor < el->el_line.buffer) 639*d0ef721eSBaptiste Daroussin el->el_line.cursor = el->el_line.buffer; 640*d0ef721eSBaptiste Daroussin if (el->el_line.cursor > el->el_line.lastchar) 641*d0ef721eSBaptiste Daroussin el->el_line.cursor = el->el_line.lastchar; 642*d0ef721eSBaptiste Daroussin out: 643*d0ef721eSBaptiste Daroussin return (int)(el->el_line.cursor - el->el_line.buffer); 644*d0ef721eSBaptiste Daroussin } 645*d0ef721eSBaptiste Daroussin 646*d0ef721eSBaptiste Daroussin /* c_gets(): 647*d0ef721eSBaptiste Daroussin * Get a string 648*d0ef721eSBaptiste Daroussin */ 649*d0ef721eSBaptiste Daroussin libedit_private int 650*d0ef721eSBaptiste Daroussin c_gets(EditLine *el, wchar_t *buf, const wchar_t *prompt) 651*d0ef721eSBaptiste Daroussin { 652*d0ef721eSBaptiste Daroussin ssize_t len; 653*d0ef721eSBaptiste Daroussin wchar_t *cp = el->el_line.buffer, ch; 654*d0ef721eSBaptiste Daroussin 655*d0ef721eSBaptiste Daroussin if (prompt) { 656*d0ef721eSBaptiste Daroussin len = (ssize_t)wcslen(prompt); 657*d0ef721eSBaptiste Daroussin (void)memcpy(cp, prompt, (size_t)len * sizeof(*cp)); 658*d0ef721eSBaptiste Daroussin cp += len; 659*d0ef721eSBaptiste Daroussin } 660*d0ef721eSBaptiste Daroussin len = 0; 661*d0ef721eSBaptiste Daroussin 662*d0ef721eSBaptiste Daroussin for (;;) { 663*d0ef721eSBaptiste Daroussin el->el_line.cursor = cp; 664*d0ef721eSBaptiste Daroussin *cp = ' '; 665*d0ef721eSBaptiste Daroussin el->el_line.lastchar = cp + 1; 666*d0ef721eSBaptiste Daroussin re_refresh(el); 667*d0ef721eSBaptiste Daroussin 668*d0ef721eSBaptiste Daroussin if (el_wgetc(el, &ch) != 1) { 669*d0ef721eSBaptiste Daroussin ed_end_of_file(el, 0); 670*d0ef721eSBaptiste Daroussin len = -1; 671*d0ef721eSBaptiste Daroussin break; 672*d0ef721eSBaptiste Daroussin } 673*d0ef721eSBaptiste Daroussin 674*d0ef721eSBaptiste Daroussin switch (ch) { 675*d0ef721eSBaptiste Daroussin 676*d0ef721eSBaptiste Daroussin case L'\b': /* Delete and backspace */ 677*d0ef721eSBaptiste Daroussin case 0177: 678*d0ef721eSBaptiste Daroussin if (len == 0) { 679*d0ef721eSBaptiste Daroussin len = -1; 680*d0ef721eSBaptiste Daroussin break; 681*d0ef721eSBaptiste Daroussin } 682*d0ef721eSBaptiste Daroussin len--; 683*d0ef721eSBaptiste Daroussin cp--; 684*d0ef721eSBaptiste Daroussin continue; 685*d0ef721eSBaptiste Daroussin 686*d0ef721eSBaptiste Daroussin case 0033: /* ESC */ 687*d0ef721eSBaptiste Daroussin case L'\r': /* Newline */ 688*d0ef721eSBaptiste Daroussin case L'\n': 689*d0ef721eSBaptiste Daroussin buf[len] = ch; 690*d0ef721eSBaptiste Daroussin break; 691*d0ef721eSBaptiste Daroussin 692*d0ef721eSBaptiste Daroussin default: 693*d0ef721eSBaptiste Daroussin if (len >= (ssize_t)(EL_BUFSIZ - 16)) 694*d0ef721eSBaptiste Daroussin terminal_beep(el); 695*d0ef721eSBaptiste Daroussin else { 696*d0ef721eSBaptiste Daroussin buf[len++] = ch; 697*d0ef721eSBaptiste Daroussin *cp++ = ch; 698*d0ef721eSBaptiste Daroussin } 699*d0ef721eSBaptiste Daroussin continue; 700*d0ef721eSBaptiste Daroussin } 701*d0ef721eSBaptiste Daroussin break; 702*d0ef721eSBaptiste Daroussin } 703*d0ef721eSBaptiste Daroussin 704*d0ef721eSBaptiste Daroussin el->el_line.buffer[0] = '\0'; 705*d0ef721eSBaptiste Daroussin el->el_line.lastchar = el->el_line.buffer; 706*d0ef721eSBaptiste Daroussin el->el_line.cursor = el->el_line.buffer; 707*d0ef721eSBaptiste Daroussin return (int)len; 708*d0ef721eSBaptiste Daroussin } 709*d0ef721eSBaptiste Daroussin 710*d0ef721eSBaptiste Daroussin 711*d0ef721eSBaptiste Daroussin /* c_hpos(): 712*d0ef721eSBaptiste Daroussin * Return the current horizontal position of the cursor 713*d0ef721eSBaptiste Daroussin */ 714*d0ef721eSBaptiste Daroussin libedit_private int 715*d0ef721eSBaptiste Daroussin c_hpos(EditLine *el) 716*d0ef721eSBaptiste Daroussin { 717*d0ef721eSBaptiste Daroussin wchar_t *ptr; 718*d0ef721eSBaptiste Daroussin 719*d0ef721eSBaptiste Daroussin /* 720*d0ef721eSBaptiste Daroussin * Find how many characters till the beginning of this line. 721*d0ef721eSBaptiste Daroussin */ 722*d0ef721eSBaptiste Daroussin if (el->el_line.cursor == el->el_line.buffer) 723*d0ef721eSBaptiste Daroussin return 0; 724*d0ef721eSBaptiste Daroussin else { 725*d0ef721eSBaptiste Daroussin for (ptr = el->el_line.cursor - 1; 726*d0ef721eSBaptiste Daroussin ptr >= el->el_line.buffer && *ptr != '\n'; 727*d0ef721eSBaptiste Daroussin ptr--) 728*d0ef721eSBaptiste Daroussin continue; 729*d0ef721eSBaptiste Daroussin return (int)(el->el_line.cursor - ptr - 1); 730*d0ef721eSBaptiste Daroussin } 731*d0ef721eSBaptiste Daroussin } 732*d0ef721eSBaptiste Daroussin 733*d0ef721eSBaptiste Daroussin libedit_private int 734*d0ef721eSBaptiste Daroussin ch_resizefun(EditLine *el, el_zfunc_t f, void *a) 735*d0ef721eSBaptiste Daroussin { 736*d0ef721eSBaptiste Daroussin el->el_chared.c_resizefun = f; 737*d0ef721eSBaptiste Daroussin el->el_chared.c_resizearg = a; 738*d0ef721eSBaptiste Daroussin return 0; 739*d0ef721eSBaptiste Daroussin } 740*d0ef721eSBaptiste Daroussin 741*d0ef721eSBaptiste Daroussin libedit_private int 742*d0ef721eSBaptiste Daroussin ch_aliasfun(EditLine *el, el_afunc_t f, void *a) 743*d0ef721eSBaptiste Daroussin { 744*d0ef721eSBaptiste Daroussin el->el_chared.c_aliasfun = f; 745*d0ef721eSBaptiste Daroussin el->el_chared.c_aliasarg = a; 746*d0ef721eSBaptiste Daroussin return 0; 747*d0ef721eSBaptiste Daroussin } 748