00001 /* $NetBSD: common.c,v 1.16 2003/08/07 16:44:30 agc Exp $ */ 00002 00003 /*- 00004 * Copyright (c) 1992, 1993 00005 * The Regents of the University of California. All rights reserved. 00006 * 00007 * This code is derived from software contributed to Berkeley by 00008 * Christos Zoulas of Cornell University. 00009 * 00010 * Redistribution and use in source and binary forms, with or without 00011 * modification, are permitted provided that the following conditions 00012 * are met: 00013 * 1. Redistributions of source code must retain the above copyright 00014 * notice, this list of conditions and the following disclaimer. 00015 * 2. Redistributions in binary form must reproduce the above copyright 00016 * notice, this list of conditions and the following disclaimer in the 00017 * documentation and/or other materials provided with the distribution. 00018 * 3. Neither the name of the University nor the names of its contributors 00019 * may be used to endorse or promote products derived from this software 00020 * without specific prior written permission. 00021 * 00022 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 00023 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00024 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00025 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 00026 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00027 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00028 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00029 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00030 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00031 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00032 * SUCH DAMAGE. 00033 */ 00034 00035 #include <config.h> 00036 00037 /* 00038 * common.c: Common Editor functions 00039 */ 00040 #include "el.h" 00041 00042 /* ed_end_of_file(): 00043 * Indicate end of file 00044 * [^D] 00045 */ 00046 protected el_action_t 00047 /*ARGSUSED*/ 00048 ed_end_of_file(EditLine *el, int c __attribute__((__unused__))) 00049 { 00050 00051 re_goto_bottom(el); 00052 *el->el_line.lastchar = '\0'; 00053 return (CC_EOF); 00054 } 00055 00056 00057 /* ed_insert(): 00058 * Add character to the line 00059 * Insert a character [bound to all insert keys] 00060 */ 00061 protected el_action_t 00062 ed_insert(EditLine *el, int c) 00063 { 00064 int count = el->el_state.argument; 00065 00066 if (c == '\0') 00067 return (CC_ERROR); 00068 00069 if (el->el_line.lastchar + el->el_state.argument >= 00070 el->el_line.limit) { 00071 /* end of buffer space, try to allocate more */ 00072 if (!ch_enlargebufs(el, (size_t) count)) 00073 return CC_ERROR; /* error allocating more */ 00074 } 00075 00076 if (count == 1) { 00077 if (el->el_state.inputmode == MODE_INSERT 00078 || el->el_line.cursor >= el->el_line.lastchar) 00079 c_insert(el, 1); 00080 00081 *el->el_line.cursor++ = c; 00082 re_fastaddc(el); /* fast refresh for one char. */ 00083 } else { 00084 if (el->el_state.inputmode != MODE_REPLACE_1) 00085 c_insert(el, el->el_state.argument); 00086 00087 while (count-- && el->el_line.cursor < el->el_line.lastchar) 00088 *el->el_line.cursor++ = c; 00089 re_refresh(el); 00090 } 00091 00092 if (el->el_state.inputmode == MODE_REPLACE_1) 00093 return vi_command_mode(el, 0); 00094 00095 return (CC_NORM); 00096 } 00097 00098 00099 /* ed_delete_prev_word(): 00100 * Delete from beginning of current word to cursor 00101 * [M-^?] [^W] 00102 */ 00103 protected el_action_t 00104 /*ARGSUSED*/ 00105 ed_delete_prev_word(EditLine *el, int c __attribute__((__unused__))) 00106 { 00107 char *cp, *p, *kp; 00108 00109 if (el->el_line.cursor == el->el_line.buffer) 00110 return (CC_ERROR); 00111 00112 cp = c__prev_word(el->el_line.cursor, el->el_line.buffer, 00113 el->el_state.argument, ce__isword); 00114 00115 for (p = cp, kp = el->el_chared.c_kill.buf; p < el->el_line.cursor; p++) 00116 *kp++ = *p; 00117 el->el_chared.c_kill.last = kp; 00118 00119 c_delbefore(el, el->el_line.cursor - cp); /* delete before dot */ 00120 el->el_line.cursor = cp; 00121 if (el->el_line.cursor < el->el_line.buffer) 00122 el->el_line.cursor = el->el_line.buffer; /* bounds check */ 00123 return (CC_REFRESH); 00124 } 00125 00126 00127 /* ed_delete_next_char(): 00128 * Delete character under cursor 00129 * [^D] [x] 00130 */ 00131 protected el_action_t 00132 /*ARGSUSED*/ 00133 ed_delete_next_char(EditLine *el, int c __attribute__((__unused__))) 00134 { 00135 #ifdef notdef /* XXX */ 00136 #define EL el->el_line 00137 (void) fprintf(el->el_errlfile, 00138 "\nD(b: %x(%s) c: %x(%s) last: %x(%s) limit: %x(%s)\n", 00139 EL.buffer, EL.buffer, EL.cursor, EL.cursor, EL.lastchar, 00140 EL.lastchar, EL.limit, EL.limit); 00141 #endif 00142 if (el->el_line.cursor == el->el_line.lastchar) { 00143 /* if I'm at the end */ 00144 if (el->el_map.type == MAP_VI) { 00145 if (el->el_line.cursor == el->el_line.buffer) { 00146 /* if I'm also at the beginning */ 00147 #ifdef KSHVI 00148 return (CC_ERROR); 00149 #else 00150 term_overwrite(el, STReof, 4); 00151 /* then do a EOF */ 00152 term__flush(); 00153 return (CC_EOF); 00154 #endif 00155 } else { 00156 #ifdef KSHVI 00157 el->el_line.cursor--; 00158 #else 00159 return (CC_ERROR); 00160 #endif 00161 } 00162 } else { 00163 if (el->el_line.cursor != el->el_line.buffer) 00164 el->el_line.cursor--; 00165 else 00166 return (CC_ERROR); 00167 } 00168 } 00169 c_delafter(el, el->el_state.argument); /* delete after dot */ 00170 if (el->el_line.cursor >= el->el_line.lastchar && 00171 el->el_line.cursor > el->el_line.buffer) 00172 /* bounds check */ 00173 el->el_line.cursor = el->el_line.lastchar - 1; 00174 return (CC_REFRESH); 00175 } 00176 00177 00178 /* ed_kill_line(): 00179 * Cut to the end of line 00180 * [^K] [^K] 00181 */ 00182 protected el_action_t 00183 /*ARGSUSED*/ 00184 ed_kill_line(EditLine *el, int c __attribute__((__unused__))) 00185 { 00186 char *kp, *cp; 00187 00188 cp = el->el_line.cursor; 00189 kp = el->el_chared.c_kill.buf; 00190 while (cp < el->el_line.lastchar) 00191 *kp++ = *cp++; /* copy it */ 00192 el->el_chared.c_kill.last = kp; 00193 /* zap! -- delete to end */ 00194 el->el_line.lastchar = el->el_line.cursor; 00195 return (CC_REFRESH); 00196 } 00197 00198 00199 /* ed_move_to_end(): 00200 * Move cursor to the end of line 00201 * [^E] [^E] 00202 */ 00203 protected el_action_t 00204 /*ARGSUSED*/ 00205 ed_move_to_end(EditLine *el, int c __attribute__((__unused__))) 00206 { 00207 00208 el->el_line.cursor = el->el_line.lastchar; 00209 if (el->el_map.type == MAP_VI) { 00210 #ifdef VI_MOVE 00211 el->el_line.cursor--; 00212 #endif 00213 if (el->el_chared.c_vcmd.action != NOP) { 00214 cv_delfini(el); 00215 return (CC_REFRESH); 00216 } 00217 } 00218 return (CC_CURSOR); 00219 } 00220 00221 00222 /* ed_move_to_beg(): 00223 * Move cursor to the beginning of line 00224 * [^A] [^A] 00225 */ 00226 protected el_action_t 00227 /*ARGSUSED*/ 00228 ed_move_to_beg(EditLine *el, int c __attribute__((__unused__))) 00229 { 00230 00231 el->el_line.cursor = el->el_line.buffer; 00232 00233 if (el->el_map.type == MAP_VI) { 00234 /* We want FIRST non space character */ 00235 while (isspace((unsigned char) *el->el_line.cursor)) 00236 el->el_line.cursor++; 00237 if (el->el_chared.c_vcmd.action != NOP) { 00238 cv_delfini(el); 00239 return (CC_REFRESH); 00240 } 00241 } 00242 return (CC_CURSOR); 00243 } 00244 00245 00246 /* ed_transpose_chars(): 00247 * Exchange the character to the left of the cursor with the one under it 00248 * [^T] [^T] 00249 */ 00250 protected el_action_t 00251 ed_transpose_chars(EditLine *el, int c) 00252 { 00253 00254 if (el->el_line.cursor < el->el_line.lastchar) { 00255 if (el->el_line.lastchar <= &el->el_line.buffer[1]) 00256 return (CC_ERROR); 00257 else 00258 el->el_line.cursor++; 00259 } 00260 if (el->el_line.cursor > &el->el_line.buffer[1]) { 00261 /* must have at least two chars entered */ 00262 c = el->el_line.cursor[-2]; 00263 el->el_line.cursor[-2] = el->el_line.cursor[-1]; 00264 el->el_line.cursor[-1] = c; 00265 return (CC_REFRESH); 00266 } else 00267 return (CC_ERROR); 00268 } 00269 00270 00271 /* ed_next_char(): 00272 * Move to the right one character 00273 * [^F] [^F] 00274 */ 00275 protected el_action_t 00276 /*ARGSUSED*/ 00277 ed_next_char(EditLine *el, int c __attribute__((__unused__))) 00278 { 00279 char *lim = el->el_line.lastchar; 00280 00281 if (el->el_line.cursor >= lim || 00282 (el->el_line.cursor == lim - 1 && 00283 el->el_map.type == MAP_VI && 00284 el->el_chared.c_vcmd.action == NOP)) 00285 return (CC_ERROR); 00286 00287 el->el_line.cursor += el->el_state.argument; 00288 if (el->el_line.cursor > lim) 00289 el->el_line.cursor = lim; 00290 00291 if (el->el_map.type == MAP_VI) 00292 if (el->el_chared.c_vcmd.action != NOP) { 00293 cv_delfini(el); 00294 return (CC_REFRESH); 00295 } 00296 return (CC_CURSOR); 00297 } 00298 00299 00300 /* ed_prev_word(): 00301 * Move to the beginning of the current word 00302 * [M-b] [b] 00303 */ 00304 protected el_action_t 00305 /*ARGSUSED*/ 00306 ed_prev_word(EditLine *el, int c __attribute__((__unused__))) 00307 { 00308 00309 if (el->el_line.cursor == el->el_line.buffer) 00310 return (CC_ERROR); 00311 00312 el->el_line.cursor = c__prev_word(el->el_line.cursor, 00313 el->el_line.buffer, 00314 el->el_state.argument, 00315 ce__isword); 00316 00317 if (el->el_map.type == MAP_VI) 00318 if (el->el_chared.c_vcmd.action != NOP) { 00319 cv_delfini(el); 00320 return (CC_REFRESH); 00321 } 00322 return (CC_CURSOR); 00323 } 00324 00325 00326 /* ed_prev_char(): 00327 * Move to the left one character 00328 * [^B] [^B] 00329 */ 00330 protected el_action_t 00331 /*ARGSUSED*/ 00332 ed_prev_char(EditLine *el, int c __attribute__((__unused__))) 00333 { 00334 00335 if (el->el_line.cursor > el->el_line.buffer) { 00336 el->el_line.cursor -= el->el_state.argument; 00337 if (el->el_line.cursor < el->el_line.buffer) 00338 el->el_line.cursor = el->el_line.buffer; 00339 00340 if (el->el_map.type == MAP_VI) 00341 if (el->el_chared.c_vcmd.action != NOP) { 00342 cv_delfini(el); 00343 return (CC_REFRESH); 00344 } 00345 return (CC_CURSOR); 00346 } else 00347 return (CC_ERROR); 00348 } 00349 00350 00351 /* ed_quoted_insert(): 00352 * Add the next character typed verbatim 00353 * [^V] [^V] 00354 */ 00355 protected el_action_t 00356 ed_quoted_insert(EditLine *el, int c) 00357 { 00358 int num; 00359 char tc; 00360 00361 tty_quotemode(el); 00362 num = el_getc(el, &tc); 00363 c = (unsigned char) tc; 00364 tty_noquotemode(el); 00365 if (num == 1) 00366 return (ed_insert(el, c)); 00367 else 00368 return (ed_end_of_file(el, 0)); 00369 } 00370 00371 00372 /* ed_digit(): 00373 * Adds to argument or enters a digit 00374 */ 00375 protected el_action_t 00376 ed_digit(EditLine *el, int c) 00377 { 00378 00379 if (!isdigit(c)) 00380 return (CC_ERROR); 00381 00382 if (el->el_state.doingarg) { 00383 /* if doing an arg, add this in... */ 00384 if (el->el_state.lastcmd == EM_UNIVERSAL_ARGUMENT) 00385 el->el_state.argument = c - '0'; 00386 else { 00387 if (el->el_state.argument > 1000000) 00388 return (CC_ERROR); 00389 el->el_state.argument = 00390 (el->el_state.argument * 10) + (c - '0'); 00391 } 00392 return (CC_ARGHACK); 00393 } 00394 00395 return ed_insert(el, c); 00396 } 00397 00398 00399 /* ed_argument_digit(): 00400 * Digit that starts argument 00401 * For ESC-n 00402 */ 00403 protected el_action_t 00404 ed_argument_digit(EditLine *el, int c) 00405 { 00406 00407 if (!isdigit(c)) 00408 return (CC_ERROR); 00409 00410 if (el->el_state.doingarg) { 00411 if (el->el_state.argument > 1000000) 00412 return (CC_ERROR); 00413 el->el_state.argument = (el->el_state.argument * 10) + 00414 (c - '0'); 00415 } else { /* else starting an argument */ 00416 el->el_state.argument = c - '0'; 00417 el->el_state.doingarg = 1; 00418 } 00419 return (CC_ARGHACK); 00420 } 00421 00422 00423 /* ed_unassigned(): 00424 * Indicates unbound character 00425 * Bound to keys that are not assigned 00426 */ 00427 protected el_action_t 00428 /*ARGSUSED*/ 00429 ed_unassigned(EditLine *el, int c __attribute__((__unused__))) 00430 { 00431 00432 return (CC_ERROR); 00433 } 00434 00435 00440 /* ed_tty_sigint(): 00441 * Tty interrupt character 00442 * [^C] 00443 */ 00444 protected el_action_t 00445 /*ARGSUSED*/ 00446 ed_tty_sigint(EditLine *el __attribute__((__unused__)), 00447 int c __attribute__((__unused__))) 00448 { 00449 00450 return (CC_NORM); 00451 } 00452 00453 00454 /* ed_tty_dsusp(): 00455 * Tty delayed suspend character 00456 * [^Y] 00457 */ 00458 protected el_action_t 00459 /*ARGSUSED*/ 00460 ed_tty_dsusp(EditLine *el __attribute__((__unused__)), 00461 int c __attribute__((__unused__))) 00462 { 00463 00464 return (CC_NORM); 00465 } 00466 00467 00468 /* ed_tty_flush_output(): 00469 * Tty flush output characters 00470 * [^O] 00471 */ 00472 protected el_action_t 00473 /*ARGSUSED*/ 00474 ed_tty_flush_output(EditLine *el __attribute__((__unused__)), 00475 int c __attribute__((__unused__))) 00476 { 00477 00478 return (CC_NORM); 00479 } 00480 00481 00482 /* ed_tty_sigquit(): 00483 * Tty quit character 00484 * [^\] 00485 */ 00486 protected el_action_t 00487 /*ARGSUSED*/ 00488 ed_tty_sigquit(EditLine *el __attribute__((__unused__)), 00489 int c __attribute__((__unused__))) 00490 { 00491 00492 return (CC_NORM); 00493 } 00494 00495 00496 /* ed_tty_sigtstp(): 00497 * Tty suspend character 00498 * [^Z] 00499 */ 00500 protected el_action_t 00501 /*ARGSUSED*/ 00502 ed_tty_sigtstp(EditLine *el __attribute__((__unused__)), 00503 int c __attribute__((__unused__))) 00504 { 00505 00506 return (CC_NORM); 00507 } 00508 00509 00510 /* ed_tty_stop_output(): 00511 * Tty disallow output characters 00512 * [^S] 00513 */ 00514 protected el_action_t 00515 /*ARGSUSED*/ 00516 ed_tty_stop_output(EditLine *el __attribute__((__unused__)), 00517 int c __attribute__((__unused__))) 00518 { 00519 00520 return (CC_NORM); 00521 } 00522 00523 00524 /* ed_tty_start_output(): 00525 * Tty allow output characters 00526 * [^Q] 00527 */ 00528 protected el_action_t 00529 /*ARGSUSED*/ 00530 ed_tty_start_output(EditLine *el __attribute__((__unused__)), 00531 int c __attribute__((__unused__))) 00532 { 00533 00534 return (CC_NORM); 00535 } 00536 00537 00538 /* ed_newline(): 00539 * Execute command 00540 * [^J] 00541 */ 00542 protected el_action_t 00543 /*ARGSUSED*/ 00544 ed_newline(EditLine *el, int c __attribute__((__unused__))) 00545 { 00546 00547 re_goto_bottom(el); 00548 *el->el_line.lastchar++ = '\n'; 00549 *el->el_line.lastchar = '\0'; 00550 return (CC_NEWLINE); 00551 } 00552 00553 00554 /* ed_delete_prev_char(): 00555 * Delete the character to the left of the cursor 00556 * [^?] 00557 */ 00558 protected el_action_t 00559 /*ARGSUSED*/ 00560 ed_delete_prev_char(EditLine *el, int c __attribute__((__unused__))) 00561 { 00562 00563 if (el->el_line.cursor <= el->el_line.buffer) 00564 return (CC_ERROR); 00565 00566 c_delbefore(el, el->el_state.argument); 00567 el->el_line.cursor -= el->el_state.argument; 00568 if (el->el_line.cursor < el->el_line.buffer) 00569 el->el_line.cursor = el->el_line.buffer; 00570 return (CC_REFRESH); 00571 } 00572 00573 00574 /* ed_clear_screen(): 00575 * Clear screen leaving current line at the top 00576 * [^L] 00577 */ 00578 protected el_action_t 00579 /*ARGSUSED*/ 00580 ed_clear_screen(EditLine *el, int c __attribute__((__unused__))) 00581 { 00582 00583 term_clear_screen(el); /* clear the whole real screen */ 00584 re_clear_display(el); /* reset everything */ 00585 return (CC_REFRESH); 00586 } 00587 00588 00589 /* ed_redisplay(): 00590 * Redisplay everything 00591 * ^R 00592 */ 00593 protected el_action_t 00594 /*ARGSUSED*/ 00595 ed_redisplay(EditLine *el __attribute__((__unused__)), 00596 int c __attribute__((__unused__))) 00597 { 00598 00599 return (CC_REDISPLAY); 00600 } 00601 00602 00603 /* ed_start_over(): 00604 * Erase current line and start from scratch 00605 * [^G] 00606 */ 00607 protected el_action_t 00608 /*ARGSUSED*/ 00609 ed_start_over(EditLine *el, int c __attribute__((__unused__))) 00610 { 00611 00612 ch_reset(el); 00613 return (CC_REFRESH); 00614 } 00615 00616 00617 /* ed_sequence_lead_in(): 00618 * First character in a bound sequence 00619 * Placeholder for external keys 00620 */ 00621 protected el_action_t 00622 /*ARGSUSED*/ 00623 ed_sequence_lead_in(EditLine *el __attribute__((__unused__)), 00624 int c __attribute__((__unused__))) 00625 { 00626 00627 return (CC_NORM); 00628 } 00629 00630 00631 /* ed_prev_history(): 00632 * Move to the previous history line 00633 * [^P] [k] 00634 */ 00635 protected el_action_t 00636 /*ARGSUSED*/ 00637 ed_prev_history(EditLine *el, int c __attribute__((__unused__))) 00638 { 00639 char beep = 0; 00640 int sv_event = el->el_history.eventno; 00641 00642 el->el_chared.c_undo.len = -1; 00643 *el->el_line.lastchar = '\0'; /* just in case */ 00644 00645 if (el->el_history.eventno == 0) { /* save the current buffer 00646 * away */ 00647 (void) strncpy(el->el_history.buf, el->el_line.buffer, 00648 EL_BUFSIZ); 00649 el->el_history.last = el->el_history.buf + 00650 (el->el_line.lastchar - el->el_line.buffer); 00651 } 00652 el->el_history.eventno += el->el_state.argument; 00653 00654 if (hist_get(el) == CC_ERROR) { 00655 if (el->el_map.type == MAP_VI) { 00656 el->el_history.eventno = sv_event; 00657 return CC_ERROR; 00658 } 00659 beep = 1; 00660 /* el->el_history.eventno was fixed by first call */ 00661 (void) hist_get(el); 00662 } 00663 if (beep) 00664 return CC_REFRESH_BEEP; 00665 return CC_REFRESH; 00666 } 00667 00668 00669 /* ed_next_history(): 00670 * Move to the next history line 00671 * [^N] [j] 00672 */ 00673 protected el_action_t 00674 /*ARGSUSED*/ 00675 ed_next_history(EditLine *el, int c __attribute__((__unused__))) 00676 { 00677 el_action_t beep = CC_REFRESH, rval; 00678 00679 el->el_chared.c_undo.len = -1; 00680 *el->el_line.lastchar = '\0'; /* just in case */ 00681 00682 el->el_history.eventno -= el->el_state.argument; 00683 00684 if (el->el_history.eventno < 0) { 00685 el->el_history.eventno = 0; 00686 beep = CC_REFRESH_BEEP; 00687 } 00688 rval = hist_get(el); 00689 if (rval == CC_REFRESH) 00690 return beep; 00691 return rval; 00692 00693 } 00694 00695 00696 /* ed_search_prev_history(): 00697 * Search previous in history for a line matching the current 00698 * next search history [M-P] [K] 00699 */ 00700 protected el_action_t 00701 /*ARGSUSED*/ 00702 ed_search_prev_history(EditLine *el, int c __attribute__((__unused__))) 00703 { 00704 const char *hp; 00705 int h; 00706 bool_t found = 0; 00707 00708 el->el_chared.c_vcmd.action = NOP; 00709 el->el_chared.c_undo.len = -1; 00710 *el->el_line.lastchar = '\0'; /* just in case */ 00711 if (el->el_history.eventno < 0) { 00712 #ifdef DEBUG_EDIT 00713 (void) fprintf(el->el_errfile, 00714 "e_prev_search_hist(): eventno < 0;\n"); 00715 #endif 00716 el->el_history.eventno = 0; 00717 return (CC_ERROR); 00718 } 00719 if (el->el_history.eventno == 0) { 00720 (void) strncpy(el->el_history.buf, el->el_line.buffer, 00721 EL_BUFSIZ); 00722 el->el_history.last = el->el_history.buf + 00723 (el->el_line.lastchar - el->el_line.buffer); 00724 } 00725 if (el->el_history.ref == NULL) 00726 return (CC_ERROR); 00727 00728 hp = HIST_FIRST(el); 00729 if (hp == NULL) 00730 return (CC_ERROR); 00731 00732 c_setpat(el); /* Set search pattern !! */ 00733 00734 for (h = 1; h <= el->el_history.eventno; h++) 00735 hp = HIST_NEXT(el); 00736 00737 while (hp != NULL) { 00738 #ifdef SDEBUG 00739 (void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp); 00740 #endif 00741 if ((strncmp(hp, el->el_line.buffer, (size_t) 00742 (el->el_line.lastchar - el->el_line.buffer)) || 00743 hp[el->el_line.lastchar - el->el_line.buffer]) && 00744 c_hmatch(el, hp)) { 00745 found++; 00746 break; 00747 } 00748 h++; 00749 hp = HIST_NEXT(el); 00750 } 00751 00752 if (!found) { 00753 #ifdef SDEBUG 00754 (void) fprintf(el->el_errfile, "not found\n"); 00755 #endif 00756 return (CC_ERROR); 00757 } 00758 el->el_history.eventno = h; 00759 00760 return (hist_get(el)); 00761 } 00762 00763 00764 /* ed_search_next_history(): 00765 * Search next in history for a line matching the current 00766 * [M-N] [J] 00767 */ 00768 protected el_action_t 00769 /*ARGSUSED*/ 00770 ed_search_next_history(EditLine *el, int c __attribute__((__unused__))) 00771 { 00772 const char *hp; 00773 int h; 00774 bool_t found = 0; 00775 00776 el->el_chared.c_vcmd.action = NOP; 00777 el->el_chared.c_undo.len = -1; 00778 *el->el_line.lastchar = '\0'; /* just in case */ 00779 00780 if (el->el_history.eventno == 0) 00781 return (CC_ERROR); 00782 00783 if (el->el_history.ref == NULL) 00784 return (CC_ERROR); 00785 00786 hp = HIST_FIRST(el); 00787 if (hp == NULL) 00788 return (CC_ERROR); 00789 00790 c_setpat(el); /* Set search pattern !! */ 00791 00792 for (h = 1; h < el->el_history.eventno && hp; h++) { 00793 #ifdef SDEBUG 00794 (void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp); 00795 #endif 00796 if ((strncmp(hp, el->el_line.buffer, (size_t) 00797 (el->el_line.lastchar - el->el_line.buffer)) || 00798 hp[el->el_line.lastchar - el->el_line.buffer]) && 00799 c_hmatch(el, hp)) 00800 found = h; 00801 hp = HIST_NEXT(el); 00802 } 00803 00804 if (!found) { /* is it the current history number? */ 00805 if (!c_hmatch(el, el->el_history.buf)) { 00806 #ifdef SDEBUG 00807 (void) fprintf(el->el_errfile, "not found\n"); 00808 #endif 00809 return (CC_ERROR); 00810 } 00811 } 00812 el->el_history.eventno = found; 00813 00814 return (hist_get(el)); 00815 } 00816 00817 00818 /* ed_prev_line(): 00819 * Move up one line 00820 * Could be [k] [^p] 00821 */ 00822 protected el_action_t 00823 /*ARGSUSED*/ 00824 ed_prev_line(EditLine *el, int c __attribute__((__unused__))) 00825 { 00826 char *ptr; 00827 int nchars = c_hpos(el); 00828 00829 /* 00830 * Move to the line requested 00831 */ 00832 if (*(ptr = el->el_line.cursor) == '\n') 00833 ptr--; 00834 00835 for (; ptr >= el->el_line.buffer; ptr--) 00836 if (*ptr == '\n' && --el->el_state.argument <= 0) 00837 break; 00838 00839 if (el->el_state.argument > 0) 00840 return (CC_ERROR); 00841 00842 /* 00843 * Move to the beginning of the line 00844 */ 00845 for (ptr--; ptr >= el->el_line.buffer && *ptr != '\n'; ptr--) 00846 continue; 00847 00848 /* 00849 * Move to the character requested 00850 */ 00851 for (ptr++; 00852 nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n'; 00853 ptr++) 00854 continue; 00855 00856 el->el_line.cursor = ptr; 00857 return (CC_CURSOR); 00858 } 00859 00860 00861 /* ed_next_line(): 00862 * Move down one line 00863 * Could be [j] [^n] 00864 */ 00865 protected el_action_t 00866 /*ARGSUSED*/ 00867 ed_next_line(EditLine *el, int c __attribute__((__unused__))) 00868 { 00869 char *ptr; 00870 int nchars = c_hpos(el); 00871 00872 /* 00873 * Move to the line requested 00874 */ 00875 for (ptr = el->el_line.cursor; ptr < el->el_line.lastchar; ptr++) 00876 if (*ptr == '\n' && --el->el_state.argument <= 0) 00877 break; 00878 00879 if (el->el_state.argument > 0) 00880 return (CC_ERROR); 00881 00882 /* 00883 * Move to the character requested 00884 */ 00885 for (ptr++; 00886 nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n'; 00887 ptr++) 00888 continue; 00889 00890 el->el_line.cursor = ptr; 00891 return (CC_CURSOR); 00892 } 00893 00894 00895 /* ed_command(): 00896 * Editline extended command 00897 * [M-X] [:] 00898 */ 00899 protected el_action_t 00900 /*ARGSUSED*/ 00901 ed_command(EditLine *el, int c __attribute__((__unused__))) 00902 { 00903 char tmpbuf[EL_BUFSIZ]; 00904 int tmplen; 00905 00906 tmplen = c_gets(el, tmpbuf, "\n: "); 00907 term__putc('\n'); 00908 00909 if (tmplen < 0 || (tmpbuf[tmplen] = 0, parse_line(el, tmpbuf)) == -1) 00910 term_beep(el); 00911 00912 el->el_map.current = el->el_map.key; 00913 re_clear_display(el); 00914 return CC_REFRESH; 00915 }
1.4.7

