common.cxx

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

Generated on Tue Jul 5 14:11:38 2011 for ROOT_528-00b_version by  doxygen 1.5.1