[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.10

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