home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 6 File / 06-File.zip / less373.zip / jump.c < prev    next >
C/C++ Source or Header  |  2002-01-14  |  6KB  |  288 lines

  1. /*
  2.  * Copyright (C) 1984-2000  Mark Nudelman
  3.  *
  4.  * You may distribute under the terms of either the GNU General Public
  5.  * License or the Less License, as specified in the README file.
  6.  *
  7.  * For more information about less, or for information on how to 
  8.  * contact the author, see the README file.
  9.  */
  10.  
  11.  
  12. /*
  13.  * Routines which jump to a new location in the file.
  14.  */
  15.  
  16. #include "less.h"
  17. #include "position.h"
  18.  
  19. extern int hit_eof;
  20. extern int jump_sline;
  21. extern int squished;
  22. extern int screen_trashed;
  23. extern int sc_width, sc_height;
  24. extern int show_attn;
  25.  
  26. /*
  27.  * Jump to the end of the file.
  28.  */
  29.     public void
  30. jump_forw()
  31. {
  32.     POSITION pos;
  33.  
  34.     if (ch_end_seek())
  35.     {
  36.         error("Cannot seek to end of file", NULL_PARG);
  37.         return;
  38.     }
  39.     /*
  40.      * Position the last line in the file at the last screen line.
  41.      * Go back one line from the end of the file
  42.      * to get to the beginning of the last line.
  43.      */
  44.     pos = back_line(ch_tell());
  45.     if (pos == NULL_POSITION)
  46.         jump_loc((POSITION)0, sc_height-1);
  47.     else
  48.         jump_loc(pos, sc_height-1);
  49. }
  50.  
  51. /*
  52.  * Jump to line n in the file.
  53.  */
  54.     public void
  55. jump_back(n)
  56.     int n;
  57. {
  58.     POSITION pos;
  59.     PARG parg;
  60.  
  61.     /*
  62.      * Find the position of the specified line.
  63.      * If we can seek there, just jump to it.
  64.      * If we can't seek, but we're trying to go to line number 1,
  65.      * use ch_beg_seek() to get as close as we can.
  66.      */
  67.     pos = find_pos(n);
  68.     if (pos != NULL_POSITION && ch_seek(pos) == 0)
  69.     {
  70.         if (show_attn)
  71.             set_attnpos(pos);
  72.         jump_loc(pos, jump_sline);
  73.     } else if (n <= 1 && ch_beg_seek() == 0)
  74.     {
  75.         jump_loc(ch_tell(), jump_sline);
  76.         error("Cannot seek to beginning of file", NULL_PARG);
  77.     } else
  78.     {
  79.         parg.p_int = n;
  80.         error("Cannot seek to line number %d", &parg);
  81.     }
  82. }
  83.  
  84. /*
  85.  * Repaint the screen.
  86.  */
  87.     public void
  88. repaint()
  89. {
  90.     struct scrpos scrpos;
  91.     /*
  92.      * Start at the line currently at the top of the screen
  93.      * and redisplay the screen.
  94.      */
  95.     get_scrpos(&scrpos);
  96.     pos_clear();
  97.     jump_loc(scrpos.pos, scrpos.ln);
  98. }
  99.  
  100. /*
  101.  * Jump to a specified percentage into the file.
  102.  */
  103.     public void
  104. jump_percent(percent)
  105.     int percent;
  106. {
  107.     POSITION pos, len;
  108.  
  109.     /*
  110.      * Determine the position in the file
  111.      * (the specified percentage of the file's length).
  112.      */
  113.     if ((len = ch_length()) == NULL_POSITION)
  114.     {
  115.         ierror("Determining length of file", NULL_PARG);
  116.         ch_end_seek();
  117.     }
  118.     if ((len = ch_length()) == NULL_POSITION)
  119.     {
  120.         error("Don't know length of file", NULL_PARG);
  121.         return;
  122.     }
  123.     pos = percent_pos(len, percent);
  124.     if (pos >= len)
  125.         pos = len-1;
  126.  
  127.     jump_line_loc(pos, jump_sline);
  128. }
  129.  
  130. /*
  131.  * Jump to a specified position in the file.
  132.  * Like jump_loc, but the position need not be 
  133.  * the first character in a line.
  134.  */
  135.     public void
  136. jump_line_loc(pos, sline)
  137.     POSITION pos;
  138.     int sline;
  139. {
  140.     int c;
  141.  
  142.     if (ch_seek(pos) == 0)
  143.     {
  144.         /*
  145.          * Back up to the beginning of the line.
  146.          */
  147.         while ((c = ch_back_get()) != '\n' && c != EOI)
  148.             ;
  149.         if (c == '\n')
  150.             (void) ch_forw_get();
  151.         pos = ch_tell();
  152.     }
  153.     if (show_attn)
  154.         set_attnpos(pos);
  155.     jump_loc(pos, sline);
  156. }
  157.  
  158. /*
  159.  * Jump to a specified position in the file.
  160.  * The position must be the first character in a line.
  161.  * Place the target line on a specified line on the screen.
  162.  */
  163.     public void
  164. jump_loc(pos, sline)
  165.     POSITION pos;
  166.     int sline;
  167. {
  168.     register int nline;
  169.     POSITION tpos;
  170.     POSITION bpos;
  171.  
  172.     /*
  173.      * Normalize sline.
  174.      */
  175.     sline = adjsline(sline);
  176.  
  177.     if ((nline = onscreen(pos)) >= 0)
  178.     {
  179.         /*
  180.          * The line is currently displayed.  
  181.          * Just scroll there.
  182.          */
  183.         nline -= sline;
  184.         if (nline > 0)
  185.             forw(nline, position(BOTTOM_PLUS_ONE), 1, 0, 0);
  186.         else
  187.             back(-nline, position(TOP), 1, 0);
  188.         if (show_attn)
  189.             repaint_hilite(1);
  190.         return;
  191.     }
  192.  
  193.     /*
  194.      * Line is not on screen.
  195.      * Seek to the desired location.
  196.      */
  197.     if (ch_seek(pos))
  198.     {
  199.         error("Cannot seek to that file position", NULL_PARG);
  200.         return;
  201.     }
  202.  
  203.     /*
  204.      * See if the desired line is before or after 
  205.      * the currently displayed screen.
  206.      */
  207.     tpos = position(TOP);
  208.     bpos = position(BOTTOM_PLUS_ONE);
  209.     if (tpos == NULL_POSITION || pos >= tpos)
  210.     {
  211.         /*
  212.          * The desired line is after the current screen.
  213.          * Move back in the file far enough so that we can
  214.          * call forw() and put the desired line at the 
  215.          * sline-th line on the screen.
  216.          */
  217.         for (nline = 0;  nline < sline;  nline++)
  218.         {
  219.             if (bpos != NULL_POSITION && pos <= bpos)
  220.             {
  221.                 /*
  222.                  * Surprise!  The desired line is
  223.                  * close enough to the current screen
  224.                  * that we can just scroll there after all.
  225.                  */
  226.                 forw(sc_height-sline+nline-1, bpos, 1, 0, 0);
  227.                 if (show_attn)
  228.                     repaint_hilite(1);
  229.                 return;
  230.             }
  231.             pos = back_line(pos);
  232.             if (pos == NULL_POSITION)
  233.             {
  234.                 /*
  235.                  * Oops.  Ran into the beginning of the file.
  236.                  * Exit the loop here and rely on forw()
  237.                  * below to draw the required number of
  238.                  * blank lines at the top of the screen.
  239.                  */
  240.                 break;
  241.             }
  242.         }
  243.         lastmark();
  244.         hit_eof = 0;
  245.         squished = 0;
  246.         screen_trashed = 0;
  247.         forw(sc_height-1, pos, 1, 0, sline-nline);
  248.     } else
  249.     {
  250.         /*
  251.          * The desired line is before the current screen.
  252.          * Move forward in the file far enough so that we
  253.          * can call back() and put the desired line at the 
  254.          * sline-th line on the screen.
  255.          */
  256.         for (nline = sline;  nline < sc_height - 1;  nline++)
  257.         {
  258.             pos = forw_line(pos);
  259.             if (pos == NULL_POSITION)
  260.             {
  261.                 /*
  262.                  * Ran into end of file.
  263.                  * This shouldn't normally happen, 
  264.                  * but may if there is some kind of read error.
  265.                  */
  266.                 break;
  267.             }
  268.             if (pos >= tpos)
  269.             {
  270.                 /* 
  271.                  * Surprise!  The desired line is
  272.                  * close enough to the current screen
  273.                  * that we can just scroll there after all.
  274.                  */
  275.                 back(nline+1, tpos, 1, 0);
  276.                 if (show_attn)
  277.                     repaint_hilite(1);
  278.                 return;
  279.             }
  280.         }
  281.         lastmark();
  282.         clear();
  283.         screen_trashed = 0;
  284.         add_back_pos(pos);
  285.         back(sc_height-1, pos, 1, 0);
  286.     }
  287. }
  288.