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

Annotation of src/usr.bin/less/jump.c, Revision 1.1.1.4

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