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