home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / LESS177.ZIP / src / jump.c < prev    next >
C/C++ Source or Header  |  1992-07-18  |  5KB  |  262 lines

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