[BACK]Return to command.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / less

Diff for /src/usr.bin/less/command.c between version 1.1.1.2 and 1.1.1.3

version 1.1.1.2, 2003/04/13 18:21:21 version 1.1.1.3, 2011/09/16 17:47:02
Line 1 
Line 1 
 /*  /*
  * Copyright (C) 1984-2002  Mark Nudelman   * Copyright (C) 1984-2011  Mark Nudelman
  *   *
  * You may distribute under the terms of either the GNU General Public   * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.   * License or the Less License, as specified in the README file.
Line 21 
Line 21 
 #include "option.h"  #include "option.h"
 #include "cmd.h"  #include "cmd.h"
   
 extern int erase_char, kill_char;  extern int erase_char, erase2_char, kill_char;
 extern int sigs;  extern int sigs;
 extern int quit_at_eof;  
 extern int quit_if_one_screen;  extern int quit_if_one_screen;
 extern int squished;  extern int squished;
 extern int hit_eof;  
 extern int sc_width;  extern int sc_width;
 extern int sc_height;  extern int sc_height;
 extern int swindow;  extern int swindow;
Line 54 
Line 52 
 #endif  #endif
 extern int screen_trashed;      /* The screen has been overwritten */  extern int screen_trashed;      /* The screen has been overwritten */
 extern int shift_count;  extern int shift_count;
   extern int oldbot;
   extern int forw_prompt;
   
 static char ungot[UNGOT_SIZE];  
 static char *ungotp = NULL;  
 #if SHELL_ESCAPE  #if SHELL_ESCAPE
 static char *shellcmd = NULL;   /* For holding last shell command for "!!" */  static char *shellcmd = NULL;   /* For holding last shell command for "!!" */
 #endif  #endif
 static int mca;                 /* The multicharacter command (action) */  static int mca;                 /* The multicharacter command (action) */
 static int search_type;         /* The previous type of search */  static int search_type;         /* The previous type of search */
 static LINENUM number;          /* The number typed by the user */  static LINENUM number;          /* The number typed by the user */
 static char optchar;  static long fraction;           /* The fractional part of the number */
   static struct loption *curropt;
   static int opt_lower;
 static int optflag;  static int optflag;
 static int optgetname;  static int optgetname;
 static POSITION bottompos;  static POSITION bottompos;
   static int save_hshift;
 #if PIPEC  #if PIPEC
 static char pipec;  static char pipec;
 #endif  #endif
   
   struct ungot {
           struct ungot *ug_next;
           char ug_char;
   };
   static struct ungot* ungot = NULL;
   static int unget_end = 0;
   
 static void multi_search();  static void multi_search();
   
 /*  /*
  * Move the cursor to lower left before executing a command.   * Move the cursor to start of prompt line before executing a command.
  * This looks nicer if the command takes a long time before   * This looks nicer if the command takes a long time before
  * updating the screen.   * updating the screen.
  */   */
         static void          static void
 cmd_exec()  cmd_exec()
 {  {
   #if HILITE_SEARCH
         clear_attn();          clear_attn();
         lower_left();  #endif
           clear_bot();
         flush();          flush();
 }  }
   
Line 97 
Line 107 
         int cmdflags;          int cmdflags;
 {  {
         mca = action;          mca = action;
           clear_bot();
         clear_cmd();          clear_cmd();
         cmd_putstr(prompt);          cmd_putstr(prompt);
         set_mlist(mlist, cmdflags);          set_mlist(mlist, cmdflags);
Line 114 
Line 125 
         static void          static void
 mca_search()  mca_search()
 {  {
   #if HILITE_SEARCH
           if (search_type & SRCH_FILTER)
                   mca = A_FILTER;
           else
   #endif
         if (search_type & SRCH_FORW)          if (search_type & SRCH_FORW)
                 mca = A_F_SEARCH;                  mca = A_F_SEARCH;
         else          else
                 mca = A_B_SEARCH;                  mca = A_B_SEARCH;
   
           clear_bot();
         clear_cmd();          clear_cmd();
   
         if (search_type & SRCH_NO_MATCH)          if (search_type & SRCH_NO_MATCH)
Line 132 
Line 149 
         if (search_type & SRCH_NO_REGEX)          if (search_type & SRCH_NO_REGEX)
                 cmd_putstr("Regex-off ");                  cmd_putstr("Regex-off ");
   
   #if HILITE_SEARCH
           if (search_type & SRCH_FILTER)
                   cmd_putstr("&/");
           else
   #endif
         if (search_type & SRCH_FORW)          if (search_type & SRCH_FORW)
                 cmd_putstr("/");                  cmd_putstr("/");
         else          else
Line 154 
Line 176 
         dash = (flag == OPT_NO_TOGGLE) ? "_" : "-";          dash = (flag == OPT_NO_TOGGLE) ? "_" : "-";
   
         mca = A_OPT_TOGGLE;          mca = A_OPT_TOGGLE;
           clear_bot();
         clear_cmd();          clear_cmd();
         cmd_putstr(dash);          cmd_putstr(dash);
         if (optgetname)          if (optgetname)
Line 189 
Line 212 
         case A_B_SEARCH:          case A_B_SEARCH:
                 multi_search(cbuf, (int) number);                  multi_search(cbuf, (int) number);
                 break;                  break;
   #if HILITE_SEARCH
           case A_FILTER:
                   search_type ^= SRCH_NO_MATCH;
                   set_filter_pattern(cbuf, search_type);
                   break;
   #endif
         case A_FIRSTCMD:          case A_FIRSTCMD:
                 /*                  /*
                  * Skip leading spaces or + signs in the string.                   * Skip leading spaces or + signs in the string.
Line 203 
Line 232 
                         every_first_cmd = save(cbuf);                          every_first_cmd = save(cbuf);
                 break;                  break;
         case A_OPT_TOGGLE:          case A_OPT_TOGGLE:
                 toggle_option(optchar, cbuf, optflag);                  toggle_option(curropt, opt_lower, cbuf, optflag);
                 optchar = '\0';                  curropt = NULL;
                 break;                  break;
         case A_F_BRACKET:          case A_F_BRACKET:
                 match_brac(cbuf[0], cbuf[1], 1, (int) number);                  match_brac(cbuf[0], cbuf[1], 1, (int) number);
Line 257 
Line 286 
 }  }
   
 /*  /*
  * Add a character to a multi-character command.   * Is a character an erase or kill char?
  */   */
         static int          static int
 mca_char(c)  is_erase_char(c)
         int c;          int c;
 {  {
           return (c == erase_char || c == erase2_char || c == kill_char);
   }
   
   /*
    * Handle the first char of an option (after the initial dash).
    */
           static int
   mca_opt_first_char(c)
       int c;
   {
           int flag = (optflag & ~OPT_NO_PROMPT);
           if (flag == OPT_NO_TOGGLE)
           {
                   switch (c)
                   {
                   case '_':
                           /* "__" = long option name. */
                           optgetname = TRUE;
                           mca_opt_toggle();
                           return (MCA_MORE);
                   }
           } else
           {
                   switch (c)
                   {
                   case '+':
                           /* "-+" = UNSET. */
                           optflag = (flag == OPT_UNSET) ?
                                   OPT_TOGGLE : OPT_UNSET;
                           mca_opt_toggle();
                           return (MCA_MORE);
                   case '!':
                           /* "-!" = SET */
                           optflag = (flag == OPT_SET) ?
                                   OPT_TOGGLE : OPT_SET;
                           mca_opt_toggle();
                           return (MCA_MORE);
                   case CONTROL('P'):
                           optflag ^= OPT_NO_PROMPT;
                           mca_opt_toggle();
                           return (MCA_MORE);
                   case '-':
                           /* "--" = long option name. */
                           optgetname = TRUE;
                           mca_opt_toggle();
                           return (MCA_MORE);
                   }
           }
           /* Char was not handled here. */
           return (NO_MCA);
   }
   
   /*
    * Add a char to a long option name.
    * See if we've got a match for an option name yet.
    * If so, display the complete name and stop
    * accepting chars until user hits RETURN.
    */
           static int
   mca_opt_nonfirst_char(c)
           int c;
   {
         char *p;          char *p;
         int flag;          char *oname;
         char buf[3];  
           if (curropt != NULL)
           {
                   /*
                    * Already have a match for the name.
                    * Don't accept anything but erase/kill.
                    */
                   if (is_erase_char(c))
                           return (MCA_DONE);
                   return (MCA_MORE);
           }
           /*
            * Add char to cmd buffer and try to match
            * the option name.
            */
           if (cmd_char(c) == CC_QUIT)
                   return (MCA_DONE);
           p = get_cmdbuf();
           opt_lower = ASCII_IS_LOWER(p[0]);
           curropt = findopt_name(&p, &oname, NULL);
           if (curropt != NULL)
           {
                   /*
                    * Got a match.
                    * Remember the option and
                    * display the full option name.
                    */
                   cmd_reset();
                   mca_opt_toggle();
                   for (p = oname;  *p != '\0';  p++)
                   {
                           c = *p;
                           if (!opt_lower && ASCII_IS_LOWER(c))
                                   c = ASCII_TO_UPPER(c);
                           if (cmd_char(c) != CC_OK)
                                   return (MCA_DONE);
                   }
           }
           return (MCA_MORE);
   }
   
   /*
    * Handle a char of an option toggle command.
    */
           static int
   mca_opt_char(c)
           int c;
   {
         PARG parg;          PARG parg;
   
           /*
            * This may be a short option (single char),
            * or one char of a long option name,
            * or one char of the option parameter.
            */
           if (curropt == NULL && len_cmdbuf() == 0)
           {
                   int ret = mca_opt_first_char(c);
                   if (ret != NO_MCA)
                           return (ret);
           }
           if (optgetname)
           {
                   /* We're getting a long option name.  */
                   if (c != '\n' && c != '\r')
                           return (mca_opt_nonfirst_char(c));
                   if (curropt == NULL)
                   {
                           parg.p_string = get_cmdbuf();
                           error("There is no --%s option", &parg);
                           return (MCA_DONE);
                   }
                   optgetname = FALSE;
                   cmd_reset();
           } else
           {
                   if (is_erase_char(c))
                           return (NO_MCA);
                   if (curropt != NULL)
                           /* We're getting the option parameter. */
                           return (NO_MCA);
                   curropt = findopt(c);
                   if (curropt == NULL)
                   {
                           parg.p_string = propt(c);
                           error("There is no %s option", &parg);
                           return (MCA_DONE);
                   }
           }
           /*
            * If the option which was entered does not take a
            * parameter, toggle the option immediately,
            * so user doesn't have to hit RETURN.
            */
           if ((optflag & ~OPT_NO_PROMPT) != OPT_TOGGLE ||
               !opt_has_param(curropt))
           {
                   toggle_option(curropt, ASCII_IS_LOWER(c), "", optflag);
                   return (MCA_DONE);
           }
           /*
            * Display a prompt appropriate for the option parameter.
            */
           start_mca(A_OPT_TOGGLE, opt_prompt(curropt), (void*)NULL, 0);
           return (MCA_MORE);
   }
   
   /*
    * Handle a char of a search command.
    */
           static int
   mca_search_char(c)
           int c;
   {
           int flag = 0;
   
           /*
            * Certain characters as the first char of
            * the pattern have special meaning:
            *      !  Toggle the NO_MATCH flag
            *      *  Toggle the PAST_EOF flag
            *      @  Toggle the FIRST_FILE flag
            */
           if (len_cmdbuf() > 0)
                   return (NO_MCA);
   
           switch (c)
           {
           case CONTROL('E'): /* ignore END of file */
           case '*':
                   if (mca != A_FILTER)
                           flag = SRCH_PAST_EOF;
                   break;
           case CONTROL('F'): /* FIRST file */
           case '@':
                   if (mca != A_FILTER)
                           flag = SRCH_FIRST_FILE;
                   break;
           case CONTROL('K'): /* KEEP position */
                   if (mca != A_FILTER)
                           flag = SRCH_NO_MOVE;
                   break;
           case CONTROL('R'): /* Don't use REGULAR EXPRESSIONS */
                   flag = SRCH_NO_REGEX;
                   break;
           case CONTROL('N'): /* NOT match */
           case '!':
                   flag = SRCH_NO_MATCH;
                   break;
           }
   
           if (flag != 0)
           {
                   search_type ^= flag;
                   mca_search();
                   return (MCA_MORE);
           }
           return (NO_MCA);
   }
   
   /*
    * Handle a character of a multi-character command.
    */
           static int
   mca_char(c)
           int c;
   {
           int ret;
   
         switch (mca)          switch (mca)
         {          {
         case 0:          case 0:
                 /*                  /*
                  * Not in a multicharacter command.                   * We're not in a multicharacter command.
                  */                   */
                 return (NO_MCA);                  return (NO_MCA);
   
Line 290 
Line 547 
                  * Entering digits of a number.                   * Entering digits of a number.
                  * Terminated by a non-digit.                   * Terminated by a non-digit.
                  */                   */
                 if ((c < '0' || c > '9') &&                  if (!((c >= '0' && c <= '9') || c == '.') &&
                   editchar(c, EC_PEEK|EC_NOHISTORY|EC_NOCOMPLETE|EC_NORIGHTLEFT) == A_INVALID)                    editchar(c, EC_PEEK|EC_NOHISTORY|EC_NOCOMPLETE|EC_NORIGHTLEFT) == A_INVALID)
                 {                  {
                         /*                          /*
                          * Not part of the number.                           * Not part of the number.
                          * Treat as a normal command character.                           * End the number and treat this char
                            * as a normal command character.
                          */                           */
                         number = cmd_int();                          number = cmd_int(&fraction);
                         mca = 0;                          mca = 0;
                         cmd_accept();                          cmd_accept();
                         return (NO_MCA);                          return (NO_MCA);
Line 305 
Line 563 
                 break;                  break;
   
         case A_OPT_TOGGLE:          case A_OPT_TOGGLE:
                 /*                  ret = mca_opt_char(c);
                  * Special case for the TOGGLE_OPTION command.                  if (ret != NO_MCA)
                  * If the option letter which was entered is a                          return (ret);
                  * single-char option, execute the command immediately,                  break;
                  * so user doesn't have to hit RETURN.  
                  * If the first char is + or -, this indicates  
                  * OPT_UNSET or OPT_SET respectively, instead of OPT_TOGGLE.  
                  * "--" begins inputting a long option name.  
                  */  
                 if (optchar == '\0' && len_cmdbuf() == 0)  
                 {  
                         flag = (optflag & ~OPT_NO_PROMPT);  
                         if (flag == OPT_NO_TOGGLE)  
                         {  
                                 switch (c)  
                                 {  
                                 case '_':  
                                         /* "__" = long option name. */  
                                         optgetname = TRUE;  
                                         mca_opt_toggle();  
                                         return (MCA_MORE);  
                                 }  
                         } else  
                         {  
                                 switch (c)  
                                 {  
                                 case '+':  
                                         /* "-+" = UNSET. */  
                                         optflag = (flag == OPT_UNSET) ?  
                                                 OPT_TOGGLE : OPT_UNSET;  
                                         mca_opt_toggle();  
                                         return (MCA_MORE);  
                                 case '!':  
                                         /* "-!" = SET */  
                                         optflag = (flag == OPT_SET) ?  
                                                 OPT_TOGGLE : OPT_SET;  
                                         mca_opt_toggle();  
                                         return (MCA_MORE);  
                                 case CONTROL('P'):  
                                         optflag ^= OPT_NO_PROMPT;  
                                         mca_opt_toggle();  
                                         return (MCA_MORE);  
                                 case '-':  
                                         /* "--" = long option name. */  
                                         optgetname = TRUE;  
                                         mca_opt_toggle();  
                                         return (MCA_MORE);  
                                 }  
                         }  
                 }  
                 if (optgetname)  
                 {  
                         /*  
                          * We're getting a long option name.  
                          * See if we've matched an option name yet.  
                          * If so, display the complete name and stop  
                          * accepting chars until user hits RETURN.  
                          */  
                         struct loption *o;  
                         char *oname;  
                         int lc;  
   
                         if (c == '\n' || c == '\r')  
                         {  
                                 /*  
                                  * When the user hits RETURN, make sure  
                                  * we've matched an option name, then  
                                  * pretend he just entered the equivalent  
                                  * option letter.  
                                  */  
                                 if (optchar == '\0')  
                                 {  
                                         parg.p_string = get_cmdbuf();  
                                         error("There is no --%s option", &parg);  
                                         return (MCA_DONE);  
                                 }  
                                 optgetname = FALSE;  
                                 cmd_reset();  
                                 c = optchar;  
                         } else  
                         {  
                                 if (optchar != '\0')  
                                 {  
                                         /*  
                                          * Already have a match for the name.  
                                          * Don't accept anything but erase/kill.  
                                          */  
                                         if (c == erase_char || c == kill_char)  
                                                 return (MCA_DONE);  
                                         return (MCA_MORE);  
                                 }  
                                 /*  
                                  * Add char to cmd buffer and try to match  
                                  * the option name.  
                                  */  
                                 if (cmd_char(c) == CC_QUIT)  
                                         return (MCA_DONE);  
                                 p = get_cmdbuf();  
                                 lc = islower(p[0]);  
                                 o = findopt_name(&p, &oname, NULL);  
                                 if (o != NULL)  
                                 {  
                                         /*  
                                          * Got a match.  
                                          * Remember the option letter and  
                                          * display the full option name.  
                                          */  
                                         optchar = o->oletter;  
                                         if (!lc && islower(optchar))  
                                                 optchar = toupper(optchar);  
                                         cmd_reset();  
                                         mca_opt_toggle();  
                                         for (p = oname;  *p != '\0';  p++)  
                                         {  
                                                 c = *p;  
                                                 if (!lc && islower(c))  
                                                         c = toupper(c);  
                                                 if (cmd_char(c) != CC_OK)  
                                                         return (MCA_DONE);  
                                         }  
                                 }  
                                 return (MCA_MORE);  
                         }  
                 } else  
                 {  
                         if (c == erase_char || c == kill_char)  
                                 break;  
                         if (optchar != '\0')  
                                 /* We already have the option letter. */  
                                 break;  
                 }  
   
                 optchar = c;  
                 if ((optflag & ~OPT_NO_PROMPT) != OPT_TOGGLE ||  
                     single_char_option(c))  
                 {  
                         toggle_option(c, "", optflag);  
                         return (MCA_DONE);  
                 }  
                 /*  
                  * Display a prompt appropriate for the option letter.  
                  */  
                 if ((p = opt_prompt(c)) == NULL)  
                 {  
                         buf[0] = '-';  
                         buf[1] = c;  
                         buf[2] = '\0';  
                         p = buf;  
                 }  
                 start_mca(A_OPT_TOGGLE, p, (void*)NULL, 0);  
                 return (MCA_MORE);  
   
         case A_F_SEARCH:          case A_F_SEARCH:
         case A_B_SEARCH:          case A_B_SEARCH:
                 /*          case A_FILTER:
                  * Special case for search commands.                  ret = mca_search_char(c);
                  * Certain characters as the first char of                  if (ret != NO_MCA)
                  * the pattern have special meaning:                          return (ret);
                  *      !  Toggle the NO_MATCH flag                  break;
                  *      *  Toggle the PAST_EOF flag  
                  *      @  Toggle the FIRST_FILE flag  
                  */  
                 if (len_cmdbuf() > 0)  
                         /*  
                          * Only works for the first char of the pattern.  
                          */  
                         break;  
   
                 flag = 0;          default:
                 switch (c)                  /* Other multicharacter command. */
                 {  
                 case CONTROL('E'): /* ignore END of file */  
                 case '*':  
                         flag = SRCH_PAST_EOF;  
                         break;  
                 case CONTROL('F'): /* FIRST file */  
                 case '@':  
                         flag = SRCH_FIRST_FILE;  
                         break;  
                 case CONTROL('K'): /* KEEP position */  
                         flag = SRCH_NO_MOVE;  
                         break;  
                 case CONTROL('R'): /* Don't use REGULAR EXPRESSIONS */  
                         flag = SRCH_NO_REGEX;  
                         break;  
                 case CONTROL('N'): /* NOT match */  
                 case '!':  
                         flag = SRCH_NO_MATCH;  
                         break;  
                 }  
                 if (flag != 0)  
                 {  
                         search_type ^= flag;  
                         mca_search();  
                         return (MCA_MORE);  
                 }  
                 break;                  break;
         }          }
   
         /*          /*
          * Any other multicharacter command           * The multichar command is terminated by a newline.
          * is terminated by a newline.  
          */           */
         if (c == '\n' || c == '\r')          if (c == '\n' || c == '\r')
         {          {
Line 544 
Line 620 
 }  }
   
 /*  /*
    * Discard any buffered file data.
    */
           static void
   clear_buffers()
   {
           if (!(ch_getflags() & CH_CANSEEK))
                   return;
           ch_flush();
           clr_linenum();
   #if HILITE_SEARCH
           clr_hilite();
   #endif
   }
   
   /*
  * Make sure the screen is displayed.   * Make sure the screen is displayed.
  */   */
         static void          static void
Line 566 
Line 657 
                         jump_loc(initial_scrpos.pos, initial_scrpos.ln);                          jump_loc(initial_scrpos.pos, initial_scrpos.ln);
         } else if (screen_trashed)          } else if (screen_trashed)
         {          {
                 int save_top_scroll;                  int save_top_scroll = top_scroll;
                 save_top_scroll = top_scroll;                  int save_ignore_eoi = ignore_eoi;
                 top_scroll = 1;                  top_scroll = 1;
                   ignore_eoi = 0;
                   if (screen_trashed == 2)
                   {
                           /* Special case used by ignore_eoi: re-open the input file
                            * and jump to the end of the file. */
                           reopen_curr_ifile();
                           jump_forw();
                   }
                 repaint();                  repaint();
                 top_scroll = save_top_scroll;                  top_scroll = save_top_scroll;
                   ignore_eoi = save_ignore_eoi;
         }          }
 }  }
   
Line 582 
Line 682 
 {  {
         register char *p;          register char *p;
   
         if (ungotp != NULL && ungotp > ungot)          if (ungot != NULL)
         {          {
                 /*                  /*
                  * No prompt necessary if commands are from                   * No prompt necessary if commands are from
Line 598 
Line 698 
         bottompos = position(BOTTOM_PLUS_ONE);          bottompos = position(BOTTOM_PLUS_ONE);
   
         /*          /*
          * If the -E flag is set and we've hit EOF on the last file, quit.           * If we've hit EOF on the last file and the -E flag is set, quit.
          */           */
         if ((quit_at_eof == OPT_ONPLUS || quit_if_one_screen) &&          if (get_quit_at_eof() == OPT_ONPLUS &&
             hit_eof && !(ch_getflags() & CH_HELPFILE) &&              eof_displayed() && !(ch_getflags() & CH_HELPFILE) &&
             next_ifile(curr_ifile) == NULL_IFILE)              next_ifile(curr_ifile) == NULL_IFILE)
                 quit(QUIT_OK);                  quit(QUIT_OK);
         quit_if_one_screen = FALSE;  
 #if 0 /* This doesn't work well because some "te"s clear the screen. */  
         /*          /*
          * If the -e flag is set and we've hit EOF on the last file,           * If the entire file is displayed and the -F flag is set, quit.
          * and the file is squished (shorter than the screen), quit.  
          */           */
         if (quit_at_eof && squished &&          if (quit_if_one_screen &&
               entire_file_displayed() && !(ch_getflags() & CH_HELPFILE) &&
             next_ifile(curr_ifile) == NULL_IFILE)              next_ifile(curr_ifile) == NULL_IFILE)
                 quit(QUIT_OK);                  quit(QUIT_OK);
 #endif  
   
 #if MSDOS_COMPILER==WIN32C  #if MSDOS_COMPILER==WIN32C
         /*          /*
Line 625 
Line 723 
         /*          /*
          * Select the proper prompt and display it.           * Select the proper prompt and display it.
          */           */
           /*
            * If the previous action was a forward movement,
            * don't clear the bottom line of the display;
            * just print the prompt since the forward movement guarantees
            * that we're in the right position to display the prompt.
            * Clearing the line could cause a problem: for example, if the last
            * line displayed ended at the right screen edge without a newline,
            * then clearing would clear the last displayed line rather than
            * the prompt line.
            */
           if (!forw_prompt)
                   clear_bot();
         clear_cmd();          clear_cmd();
           forw_prompt = 0;
         p = pr_string();          p = pr_string();
         if (p == NULL)          if (is_filtering())
                   putstr("& ");
           if (p == NULL || *p == '\0')
                 putchr(':');                  putchr(':');
         else          else
         {          {
                 so_enter();                  at_enter(AT_STANDOUT);
                 putstr(p);                  putstr(p);
                 so_exit();                  at_exit();
         }          }
           clear_eol();
 }  }
   
 /*  /*
Line 658 
Line 772 
         public int          public int
 getcc()  getcc()
 {  {
         if (ungotp == NULL)          if (unget_end)
           {
                 /*                  /*
                  * Normal case: no ungotten chars, so get one from the user.                   * We have just run out of ungotten chars.
                  */                   */
                 return (getchr());                  unget_end = 0;
                   if (len_cmdbuf() == 0 || !empty_screen())
         if (ungotp > ungot)                          return (getchr());
                 /*                  /*
                  * Return the next ungotten char.                   * Command is incomplete, so try to complete it.
                  */                   */
                 return (*--ungotp);                  switch (mca)
                   {
                   case A_DIGIT:
                           /*
                            * We have a number but no command.  Treat as #g.
                            */
                           return ('g');
   
         /*                  case A_F_SEARCH:
          * We have just run out of ungotten chars.                  case A_B_SEARCH:
          */                          /*
         ungotp = NULL;                           * We have "/string" but no newline.  Add the \n.
         if (len_cmdbuf() == 0 || !empty_screen())                           */
                 return (getchr());                          return ('\n');
         /*  
          * Command is incomplete, so try to complete it.  
          */  
         switch (mca)  
         {  
         case A_DIGIT:  
                 /*  
                  * We have a number but no command.  Treat as #g.  
                  */  
                 return ('g');  
   
         case A_F_SEARCH:                  default:
         case A_B_SEARCH:                          /*
                 /*                           * Some other incomplete command.  Let user complete it.
                  * We have "/string" but no newline.  Add the \n.                           */
                  */                          return (getchr());
                 return ('\n');                  }
           }
   
         default:          if (ungot == NULL)
           {
                 /*                  /*
                  * Some other incomplete command.  Let user complete it.                   * Normal case: no ungotten chars, so get one from the user.
                  */                   */
                 return (getchr());                  return (getchr());
         }          }
   
           /*
            * Return the next ungotten char.
            */
           {
                   struct ungot *ug = ungot;
                   char c = ug->ug_char;
                   ungot = ug->ug_next;
                   free(ug);
                   unget_end = (ungot == NULL);
                   return (c);
           }
 }  }
   
 /*  /*
Line 710 
Line 835 
 ungetcc(c)  ungetcc(c)
         int c;          int c;
 {  {
         if (ungotp == NULL)          struct ungot *ug = (struct ungot *) ecalloc(1, sizeof(struct ungot));
                 ungotp = ungot;  
         if (ungotp >= ungot + sizeof(ungot))          ug->ug_char = c;
         {          ug->ug_next = ungot;
                 error("ungetcc overflow", NULL_PARG);          ungot = ug;
                 quit(QUIT_ERROR);          unget_end = 0;
         }  
         *ungotp++ = c;  
 }  }
   
 /*  /*
Line 826 
Line 949 
                  * Restore the file we were originally viewing.                   * Restore the file we were originally viewing.
                  */                   */
                 reedit_ifile(save_ifile);                  reedit_ifile(save_ifile);
           } else
           {
                   unsave_ifile(save_ifile);
         }          }
 }  }
   
Line 857 
Line 983 
                 mca = 0;                  mca = 0;
                 cmd_accept();                  cmd_accept();
                 number = 0;                  number = 0;
                 optchar = '\0';                  curropt = NULL;
   
                 /*                  /*
                  * See if any signals need processing.                   * See if any signals need processing.
Line 1079 
Line 1205 
                         cmd_exec();                          cmd_exec();
                         jump_forw();                          jump_forw();
                         ignore_eoi = 1;                          ignore_eoi = 1;
                         hit_eof = 0;  
                         while (!sigs)                          while (!sigs)
                           {
                                   make_display();
                                 forward(1, 0, 0);                                  forward(1, 0, 0);
                           }
                         ignore_eoi = 0;                          ignore_eoi = 0;
                         /*                          /*
                          * This gets us back in "F mode" after processing                           * This gets us back in "F mode" after processing
Line 1120 
Line 1248 
                          * Flush buffers, then repaint screen.                           * Flush buffers, then repaint screen.
                          * Don't flush the buffers on a pipe!                           * Don't flush the buffers on a pipe!
                          */                           */
                         if (ch_getflags() & CH_CANSEEK)                          clear_buffers();
                         {  
                                 ch_flush();  
                                 clr_linenum();  
 #if HILITE_SEARCH  
                                 clr_hilite();  
 #endif  
                         }  
                         /* FALLTHRU */                          /* FALLTHRU */
                 case A_REPAINT:                  case A_REPAINT:
                         /*                          /*
Line 1152 
Line 1273 
                          * Go to a specified percentage into the file.                           * Go to a specified percentage into the file.
                          */                           */
                         if (number < 0)                          if (number < 0)
                           {
                                 number = 0;                                  number = 0;
                                   fraction = 0;
                           }
                         if (number > 100)                          if (number > 100)
                           {
                                 number = 100;                                  number = 100;
                                   fraction = 0;
                           }
                         cmd_exec();                          cmd_exec();
                         jump_percent((int) number);                          jump_percent((int) number, fraction);
                         break;                          break;
   
                 case A_GOEND:                  case A_GOEND:
Line 1211 
Line 1338 
                                  * just means return to viewing the                                   * just means return to viewing the
                                  * previous file.                                   * previous file.
                                  */                                   */
                                   hshift = save_hshift;
                                 if (edit_prev(1) == 0)                                  if (edit_prev(1) == 0)
                                         break;                                          break;
                         }                          }
Line 1222 
Line 1350 
 /*  /*
  * Define abbreviation for a commonly used sequence below.   * Define abbreviation for a commonly used sequence below.
  */   */
 #define DO_SEARCH()     if (number <= 0) number = 1;    \  #define DO_SEARCH() \
                           if (number <= 0) number = 1;    \
                         mca_search();                   \                          mca_search();                   \
                         cmd_exec();                     \                          cmd_exec();                     \
                         multi_search((char *)NULL, (int) number);                          multi_search((char *)NULL, (int) number);
Line 1252 
Line 1381 
                         c = getcc();                          c = getcc();
                         goto again;                          goto again;
   
                   case A_FILTER:
   #if HILITE_SEARCH
                           search_type = SRCH_FORW | SRCH_FILTER;
                           mca_search();
                           c = getcc();
                           goto again;
   #else
                           error("Command not available", NULL_PARG);
                           break;
   #endif
   
                 case A_AGAIN_SEARCH:                  case A_AGAIN_SEARCH:
                         /*                          /*
                          * Repeat previous search.                           * Repeat previous search.
Line 1300 
Line 1440 
                         if (ch_getflags() & CH_HELPFILE)                          if (ch_getflags() & CH_HELPFILE)
                                 break;                                  break;
                         cmd_exec();                          cmd_exec();
                           save_hshift = hshift;
                           hshift = 0;
                         (void) edit(FAKE_HELPFILE);                          (void) edit(FAKE_HELPFILE);
                         break;                          break;
   
Line 1340 
Line 1482 
                         }                          }
                         if (curr_altfilename != NULL)                          if (curr_altfilename != NULL)
                         {                          {
                                 error("Cannot edit file processed with LESSOPEN",                                  error("WARNING: This file was viewed via LESSOPEN",
                                         NULL_PARG);                                          NULL_PARG);
                                 break;  
                         }                          }
                         start_mca(A_SHELL, "!", ml_shell, 0);                          start_mca(A_SHELL, "!", ml_shell, 0);
                         /*                          /*
Line 1375 
Line 1516 
                                 number = 1;                                  number = 1;
                         if (edit_next((int) number))                          if (edit_next((int) number))
                         {                          {
                                 if (quit_at_eof && hit_eof &&                                  if (get_quit_at_eof() && eof_displayed() &&
                                     !(ch_getflags() & CH_HELPFILE))                                      !(ch_getflags() & CH_HELPFILE))
                                         quit(QUIT_OK);                                          quit(QUIT_OK);
                                 parg.p_string = (number > 1) ? "(N-th) " : "";                                  parg.p_string = (number > 1) ? "(N-th) " : "";
Line 1524 
Line 1665 
                                 break;                                  break;
                         start_mca(A_SETMARK, "mark: ", (void*)NULL, 0);                          start_mca(A_SETMARK, "mark: ", (void*)NULL, 0);
                         c = getcc();                          c = getcc();
                         if (c == erase_char || c == kill_char ||                          if (c == erase_char || c == erase2_char ||
                             c == '\n' || c == '\r')                              c == kill_char || c == '\n' || c == '\r')
                                 break;                                  break;
                         setmark(c);                          setmark(c);
                         break;                          break;
Line 1536 
Line 1677 
                          */                           */
                         start_mca(A_GOMARK, "goto mark: ", (void*)NULL, 0);                          start_mca(A_GOMARK, "goto mark: ", (void*)NULL, 0);
                         c = getcc();                          c = getcc();
                         if (c == erase_char || c == kill_char ||                          if (c == erase_char || c == erase2_char ||
                             c == '\n' || c == '\r')                              c == kill_char || c == '\n' || c == '\r')
                                 break;                                  break;
                           cmd_exec();
                         gomark(c);                          gomark(c);
                         break;                          break;
   
Line 1551 
Line 1693 
                         }                          }
                         start_mca(A_PIPE, "|mark: ", (void*)NULL, 0);                          start_mca(A_PIPE, "|mark: ", (void*)NULL, 0);
                         c = getcc();                          c = getcc();
                         if (c == erase_char || c == kill_char)                          if (c == erase_char || c == erase2_char || c == kill_char)
                                 break;                                  break;
                         if (c == '\n' || c == '\r')                          if (c == '\n' || c == '\r')
                                 c = '.';                                  c = '.';

Legend:
Removed from v.1.1.1.2  
changed lines
  Added in v.1.1.1.3