[BACK]Return to grid-reader.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / tmux

Annotation of src/usr.bin/tmux/grid-reader.c, Revision 1.1

1.1     ! nicm        1: /* $OpenBSD$ */
        !             2:
        !             3: /*
        !             4:  * Copyright (c) 2020 Anindya Mukherjee <anindya49@hotmail.com>
        !             5:  *
        !             6:  * Permission to use, copy, modify, and distribute this software for any
        !             7:  * purpose with or without fee is hereby granted, provided that the above
        !             8:  * copyright notice and this permission notice appear in all copies.
        !             9:  *
        !            10:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
        !            11:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
        !            12:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
        !            13:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
        !            14:  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
        !            15:  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
        !            16:  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
        !            17:  */
        !            18:
        !            19: #include "tmux.h"
        !            20:
        !            21: /* Initialise virtual cursor. */
        !            22: void
        !            23: grid_reader_start(struct grid_reader *gr, struct grid *gd, u_int cx, u_int cy)
        !            24: {
        !            25:        gr->gd = gd;
        !            26:        gr->cx = cx;
        !            27:        gr->cy = cy;
        !            28: }
        !            29:
        !            30: /* Get cursor position from reader. */
        !            31: void
        !            32: grid_reader_get_cursor(struct grid_reader *gr, u_int *cx, u_int *cy)
        !            33: {
        !            34:        *cx = gr->cx;
        !            35:        *cy = gr->cy;
        !            36: }
        !            37:
        !            38: /* Get length of line containing the cursor. */
        !            39: u_int
        !            40: grid_reader_line_length(struct grid_reader *gr)
        !            41: {
        !            42:        return (grid_line_length(gr->gd, gr->cy));
        !            43: }
        !            44:
        !            45: /* Move cursor forward one position. */
        !            46: void
        !            47: grid_reader_cursor_right(struct grid_reader *gr, int wrap, int all)
        !            48: {
        !            49:        u_int                   px;
        !            50:        struct grid_cell        gc;
        !            51:
        !            52:        if (all)
        !            53:                px = gr->gd->sx;
        !            54:        else
        !            55:                px = grid_reader_line_length(gr);
        !            56:
        !            57:        if (wrap && gr->cx >= px && gr->cy < gr->gd->hsize + gr->gd->sy - 1) {
        !            58:                grid_reader_cursor_start_of_line(gr, 0);
        !            59:                grid_reader_cursor_down(gr);
        !            60:        } else if (gr->cx < px) {
        !            61:                gr->cx++;
        !            62:                while (gr->cx < px) {
        !            63:                        grid_get_cell(gr->gd, gr->cx, gr->cy, &gc);
        !            64:                        if (~gc.flags & GRID_FLAG_PADDING)
        !            65:                                break;
        !            66:                        gr->cx++;
        !            67:                }
        !            68:        }
        !            69: }
        !            70:
        !            71: /* Move cursor back one position. */
        !            72: void
        !            73: grid_reader_cursor_left(struct grid_reader *gr)
        !            74: {
        !            75:        struct grid_cell        gc;
        !            76:
        !            77:        while (gr->cx > 0) {
        !            78:                grid_get_cell(gr->gd, gr->cx, gr->cy, &gc);
        !            79:                if (~gc.flags & GRID_FLAG_PADDING)
        !            80:                        break;
        !            81:                gr->cx--;
        !            82:        }
        !            83:        if (gr->cx == 0 && gr->cy > 0) {
        !            84:                grid_reader_cursor_up(gr);
        !            85:                grid_reader_cursor_end_of_line(gr, 0, 0);
        !            86:        } else if (gr->cx > 0)
        !            87:                gr->cx--;
        !            88: }
        !            89:
        !            90: /* Move cursor down one line. */
        !            91: void
        !            92: grid_reader_cursor_down(struct grid_reader *gr)
        !            93: {
        !            94:        struct grid_cell        gc;
        !            95:
        !            96:        if (gr->cy < gr->gd->hsize + gr->gd->sy - 1)
        !            97:                gr->cy++;
        !            98:        while (gr->cx > 0) {
        !            99:                grid_get_cell(gr->gd, gr->cx, gr->cy, &gc);
        !           100:                if (~gc.flags & GRID_FLAG_PADDING)
        !           101:                        break;
        !           102:                gr->cx--;
        !           103:        }
        !           104: }
        !           105:
        !           106: /* Move cursor up one line. */
        !           107: void
        !           108: grid_reader_cursor_up(struct grid_reader *gr)
        !           109: {
        !           110:        struct grid_cell        gc;
        !           111:
        !           112:        if (gr->cy > 0)
        !           113:                gr->cy--;
        !           114:        while (gr->cx > 0) {
        !           115:                grid_get_cell(gr->gd, gr->cx, gr->cy, &gc);
        !           116:                if (~gc.flags & GRID_FLAG_PADDING)
        !           117:                        break;
        !           118:                gr->cx--;
        !           119:        }
        !           120: }
        !           121:
        !           122: /* Move cursor to the start of the line. */
        !           123: void
        !           124: grid_reader_cursor_start_of_line(struct grid_reader *gr, int wrap)
        !           125: {
        !           126:        if (wrap) {
        !           127:                while (gr->cy > 0 &&
        !           128:                    grid_get_line(gr->gd, gr->cy - 1)->flags &
        !           129:                        GRID_LINE_WRAPPED)
        !           130:                        gr->cy--;
        !           131:        }
        !           132:        gr->cx = 0;
        !           133: }
        !           134:
        !           135: /* Move cursor to the end of the line. */
        !           136: void
        !           137: grid_reader_cursor_end_of_line(struct grid_reader *gr, int wrap, int all)
        !           138: {
        !           139:        u_int   yy;
        !           140:
        !           141:        if (wrap) {
        !           142:                yy = gr->gd->hsize + gr->gd->sy - 1;
        !           143:                while (gr->cy < yy && grid_get_line(gr->gd, gr->cy)->flags &
        !           144:                    GRID_LINE_WRAPPED)
        !           145:                        gr->cy++;
        !           146:        }
        !           147:        if (all)
        !           148:                gr->cx = gr->gd->sx;
        !           149:        else
        !           150:                gr->cx = grid_reader_line_length(gr);
        !           151: }
        !           152:
        !           153: /* Check if character under cursor is in set. */
        !           154: int
        !           155: grid_reader_in_set(struct grid_reader *gr, const char *set)
        !           156: {
        !           157:        struct grid_cell        gc;
        !           158:
        !           159:        grid_get_cell(gr->gd, gr->cx, gr->cy, &gc);
        !           160:        if (gc.flags & GRID_FLAG_PADDING)
        !           161:                return (0);
        !           162:        return (utf8_cstrhas(set, &gc.data));
        !           163: }
        !           164:
        !           165: /* Move cursor to the start of the next word. */
        !           166: void
        !           167: grid_reader_cursor_next_word(struct grid_reader *gr, const char *separators)
        !           168: {
        !           169:        u_int   xx, yy;
        !           170:        int expected = 0;
        !           171:
        !           172:        /* Do not break up wrapped words. */
        !           173:        if (grid_get_line(gr->gd, gr->cy)->flags & GRID_LINE_WRAPPED)
        !           174:                xx = grid_reader_line_length(gr) - 1;
        !           175:        else
        !           176:                xx = grid_reader_line_length(gr);
        !           177:        yy = gr->gd->hsize + gr->gd->sy - 1;
        !           178:
        !           179:        /*
        !           180:         * If we started inside a word, skip over word characters. Then skip
        !           181:         * over separators till the next word.
        !           182:         *
        !           183:         * expected is initially set to 0 for the former and then 1 for the
        !           184:         * latter. It is finally set to 0 when the beginning of the next word is
        !           185:         * found.
        !           186:         */
        !           187:        do {
        !           188:                while (gr->cx > xx ||
        !           189:                    grid_reader_in_set(gr, separators) == expected) {
        !           190:                        /* Move down if we are past the end of the line. */
        !           191:                        if (gr->cx > xx) {
        !           192:                                if (gr->cy == yy)
        !           193:                                        return;
        !           194:                                grid_reader_cursor_start_of_line(gr, 0);
        !           195:                                grid_reader_cursor_down(gr);
        !           196:
        !           197:                                if (grid_get_line(gr->gd, gr->cy)->flags &
        !           198:                                    GRID_LINE_WRAPPED)
        !           199:                                        xx = grid_reader_line_length(gr) - 1;
        !           200:                                else
        !           201:                                        xx = grid_reader_line_length(gr);
        !           202:                        } else
        !           203:                                gr->cx++;
        !           204:                }
        !           205:                expected = !expected;
        !           206:        } while (expected == 1);
        !           207: }
        !           208:
        !           209: /* Move cursor to the end of the next word. */
        !           210: void
        !           211: grid_reader_cursor_next_word_end(struct grid_reader *gr, const char *separators)
        !           212: {
        !           213:        u_int   xx, yy;
        !           214:        int     expected = 1;
        !           215:
        !           216:        /* Do not break up wrapped words. */
        !           217:        if (grid_get_line(gr->gd, gr->cy)->flags & GRID_LINE_WRAPPED)
        !           218:                xx = grid_reader_line_length(gr) - 1;
        !           219:        else
        !           220:                xx = grid_reader_line_length(gr);
        !           221:        yy = gr->gd->hsize + gr->gd->sy - 1;
        !           222:
        !           223:        /*
        !           224:         * If we started on a separator, skip over separators. Then skip over
        !           225:         * word characters till the next separator.
        !           226:         *
        !           227:         * expected is initially set to 1 for the former and then 1 for the
        !           228:         * latter. It is finally set to 1 when the end of the next word is
        !           229:         * found.
        !           230:         */
        !           231:        do {
        !           232:                while (gr->cx > xx ||
        !           233:                    grid_reader_in_set(gr, separators) == expected) {
        !           234:                        /* Move down if we are past the end of the line. */
        !           235:                        if (gr->cx > xx) {
        !           236:                                if (gr->cy == yy)
        !           237:                                        return;
        !           238:                                grid_reader_cursor_start_of_line(gr, 0);
        !           239:                                grid_reader_cursor_down(gr);
        !           240:
        !           241:                                if (grid_get_line(gr->gd, gr->cy)->flags &
        !           242:                                    GRID_LINE_WRAPPED)
        !           243:                                        xx = grid_reader_line_length(gr) - 1;
        !           244:                                else
        !           245:                                        xx = grid_reader_line_length(gr);
        !           246:                        } else
        !           247:                                gr->cx++;
        !           248:                }
        !           249:                expected = !expected;
        !           250:        } while (expected == 0);
        !           251: }
        !           252:
        !           253: /* Move to the previous place where a word begins. */
        !           254: void
        !           255: grid_reader_cursor_previous_word(struct grid_reader *gr, const char *separators,
        !           256:     int already)
        !           257: {
        !           258:        int     oldx, oldy, r;
        !           259:
        !           260:        /* Move back to the previous word character. */
        !           261:        if (already || grid_reader_in_set(gr, separators)) {
        !           262:                for (;;) {
        !           263:                        if (gr->cx > 0) {
        !           264:                                gr->cx--;
        !           265:                                if (!grid_reader_in_set(gr, separators))
        !           266:                                        break;
        !           267:                        } else {
        !           268:                                if (gr->cy == 0)
        !           269:                                        return;
        !           270:                                grid_reader_cursor_up(gr);
        !           271:                                grid_reader_cursor_end_of_line(gr, 0, 0);
        !           272:
        !           273:                                /* Stop if separator at EOL. */
        !           274:                                if (gr->cx > 0) {
        !           275:                                        oldx = gr->cx;
        !           276:                                        gr->cx--;
        !           277:                                        r = grid_reader_in_set(gr, separators);
        !           278:                                        gr->cx = oldx;
        !           279:                                        if (r)
        !           280:                                                break;
        !           281:                                }
        !           282:                        }
        !           283:                }
        !           284:        }
        !           285:
        !           286:        /* Move back to the beginning of this word. */
        !           287:        do {
        !           288:                oldx = gr->cx;
        !           289:                oldy = gr->cy;
        !           290:                if (gr->cx == 0) {
        !           291:                        if (gr->cy == 0 ||
        !           292:                          ~grid_get_line(gr->gd, gr->cy - 1)->flags &
        !           293:                          GRID_LINE_WRAPPED)
        !           294:                                break;
        !           295:                        grid_reader_cursor_up(gr);
        !           296:                        grid_reader_cursor_end_of_line(gr, 0, 0);
        !           297:                }
        !           298:                if (gr->cx > 0)
        !           299:                        gr->cx--;
        !           300:        } while (!grid_reader_in_set(gr, separators));
        !           301:        gr->cx = oldx;
        !           302:        gr->cy = oldy;
        !           303: }