Пример #1
0
static void filedlg_hscroll(struct filedlg *fd, int offset)
{
    int lwidth;
    int max_width;
    int width;

    if (fd->buf) {
        width = swin_getmaxx(fd->win);

        lwidth = log10_uint(sbcount(fd->buf->files)) + 1;
        max_width = fd->buf->max_width - width + lwidth + 6;

        fd->buf->sel_col += offset;
        if (fd->buf->sel_col > max_width)
            fd->buf->sel_col = max_width;
        if (fd->buf->sel_col < 0)
            fd->buf->sel_col = 0;
    }
}
Пример #2
0
void source_hscroll(struct sviewer *sview, int offset)
{
    int lwidth;
    int max_width;
    int width, height;

    if (sview->cur) {
        height = swin_getmaxy(sview->win);
        width = swin_getmaxx(sview->win);

        lwidth = log10_uint(sbcount(sview->cur->file_buf.lines)) + 1;
        max_width = sview->cur->file_buf.max_width - width + lwidth + 6;

        sview->cur->sel_col += offset;
        if (sview->cur->sel_col > max_width)
            sview->cur->sel_col = max_width;
        if (sview->cur->sel_col < 0)
            sview->cur->sel_col = 0;
    }
}
Пример #3
0
/** 
 * Display the source.
 *
 * A line in the source viewer looks like,
 *   # │ marker text
 * where,
 *   # is the line number to display or ~ if no line number
 *   │ is the divider between the line number or it is a mark
 *   marker is shortarrow, longarrow, highlight, block, etc
 *   text is the source code to display
 *
 * The syntax highlighting works as follows,
 *
 * The #
 * - If breakpoint is set, use Breakpoint
 * - If breakpoint is disabled, use DisabledBreakpoint
 * - If selected line, use SelectedLineNr
 * - If executing line, use ExecutingLineNr
 * - Otherwise, no highlighting group
 *
 * The │ 
 * - When source window is in focus, the character is bolded, otherwise normal
 * - If the user has a mark set, the mark will be displayed instead of any
 *   other character.
 * - Edge case: When the marker is long or short arrow, CGDB prints ├
 *   instead of │ the ├ is colored based on highlighting group for 
 *   the selected or executing arrow.
 *
 * The marker
 * - The marker is the shortarrow, longarrow, highlight or block
 * - The color is based off the corresponding highlighting group
 *
 * The text
 * - The syntax highlighting source code to display
 * - Will be colored with SelectedLineHighlight or ExecutingLineHighlight
 *   if the line is the selected or executing line and the display is set
 *   to highlight.
 */
int source_display(struct sviewer *sview, int focus, enum win_refresh dorefresh)
{
    int i;
    int lwidth;
    int line;
    int count;

    enum LineDisplayStyle exe_display_style, sel_display_style;
    int sellineno, exelineno;
    int enabled_bp, disabled_bp;
    int exe_line_display_is_arrow, sel_line_display_is_arrow;
    int exe_arrow_attr, sel_arrow_attr;
    int exe_block_attr, sel_block_attr;
    char fmt[16];
    int width, height;
    int focus_attr = focus ? SWIN_A_BOLD : 0;
    int showmarks = cgdbrc_get_int(CGDBRC_SHOWMARKS);
    int hlsearch = cgdbrc_get_int(CGDBRC_HLSEARCH);
    int mark_attr;

    struct hl_line_attr *sel_highlight_attrs = 0;
    struct hl_line_attr *exe_highlight_attrs = 0;

    /* Check that a file is loaded */
    if (!sview->cur || !sview->cur->file_buf.lines) {
        logo_display(sview->win);

        if (dorefresh == WIN_REFRESH)
            swin_wrefresh(sview->win);
        else
            swin_wnoutrefresh(sview->win);

        return 0;
    }

    sellineno = hl_groups_get_attr(
        hl_groups_instance, HLG_SELECTED_LINE_NUMBER);
    exelineno = hl_groups_get_attr(
        hl_groups_instance, HLG_EXECUTING_LINE_NUMBER);
    enabled_bp = hl_groups_get_attr(
        hl_groups_instance, HLG_ENABLED_BREAKPOINT);
    disabled_bp = hl_groups_get_attr(
        hl_groups_instance, HLG_DISABLED_BREAKPOINT);

    exe_display_style = cgdbrc_get_displaystyle(CGDBRC_EXECUTING_LINE_DISPLAY);
    exe_arrow_attr = hl_groups_get_attr(
        hl_groups_instance, HLG_EXECUTING_LINE_ARROW);
    exe_block_attr = hl_groups_get_attr(
        hl_groups_instance, HLG_EXECUTING_LINE_BLOCK);

    sel_display_style = cgdbrc_get_displaystyle(CGDBRC_SELECTED_LINE_DISPLAY);
    sel_arrow_attr = hl_groups_get_attr(
        hl_groups_instance, HLG_SELECTED_LINE_ARROW);
    sel_block_attr = hl_groups_get_attr(
        hl_groups_instance, HLG_SELECTED_LINE_BLOCK);

    exe_line_display_is_arrow =
        exe_display_style == LINE_DISPLAY_SHORT_ARROW ||
        exe_display_style == LINE_DISPLAY_LONG_ARROW;
    sel_line_display_is_arrow = 
        sel_display_style == LINE_DISPLAY_SHORT_ARROW ||
        sel_display_style == LINE_DISPLAY_LONG_ARROW;

    mark_attr = hl_groups_get_attr(hl_groups_instance, HLG_MARK);

    sbpush(sel_highlight_attrs, hl_line_attr(0, HLG_SELECTED_LINE_HIGHLIGHT));
    sbpush(exe_highlight_attrs, hl_line_attr(0, HLG_EXECUTING_LINE_HIGHLIGHT));
    
    /* Make sure cursor is visible */
    swin_curs_set(!!focus);

    /* Initialize variables */
    height = swin_getmaxy(sview->win);
    width = swin_getmaxx(sview->win);

    /* Set starting line number (center source file if it's small enough) */
    count = sbcount(sview->cur->file_buf.lines);
    if (count < height) {
        line = (count - height) / 2;
    } else {
        line = sview->cur->sel_line - height / 2;
        if (line > count - height)
            line = count - height;
        else if (line < 0)
            line = 0;
    }

    /* Print 'height' lines of the file, starting at 'line' */
    lwidth = log10_uint(count) + 1;
    snprintf(fmt, sizeof(fmt), "%%%dd", lwidth);

    for (i = 0; i < height; i++, line++) {

        int column_offset = 0;
        /* Is this the current selected line? */
        int is_sel_line = (line >= 0 && sview->cur->sel_line == line);
        /* Is this the current executing line */
        int is_exe_line = (line >= 0 && sview->cur->exe_line == line);
        struct source_line *sline = (line < 0 || line >= count)?
            NULL:&sview->cur->file_buf.lines[line];
        struct hl_line_attr *printline_attrs = (sline)?sline->attrs:0;

        swin_wmove(sview->win, i, 0);

        /* Print the line number */
        if (line < 0 || line >= count) {
            for (int j = 1; j < lwidth; j++)
                swin_waddch(sview->win, ' ');
            swin_waddch(sview->win, '~');
        } else {
            int line_attr = 0;
            int bp_val = sview->cur->lflags[line].breakpt;
            if (bp_val == 1) {
                line_attr = enabled_bp;
            } else if (bp_val == 2) {
                line_attr = disabled_bp;
            } else if (bp_val == 0 && is_exe_line) {
                line_attr = exelineno;
            } else if (bp_val == 0 && is_sel_line) {
                line_attr = sellineno;
            }

            swin_wattron(sview->win, line_attr);
            swin_wprintw(sview->win, fmt, line + 1);
            swin_wattroff(sview->win, line_attr);
        }

        if (!swin_has_colors()) {
            /* TODO:
            swin_wprintw(sview->win, "%.*s\n",
                    sview->cur->file_buf.lines[line].line,
                    sview->cur->file_buf.lines[line].len);
            */
            continue;
        }

        /* Print the vertical bar or mark */
        {
            SWIN_CHTYPE vert_bar_char;
            int vert_bar_attr;
            int mc;

            if (showmarks &&
                ((mc = source_get_mark_char(sview, sview->cur, line)) > 0)) {
                vert_bar_char = mc;
                vert_bar_attr = mark_attr;
            } else if (is_exe_line && exe_line_display_is_arrow) {
                vert_bar_attr = exe_arrow_attr;
                vert_bar_char = SWIN_SYM_LTEE;
            } else if (is_sel_line && sel_line_display_is_arrow) {
                vert_bar_attr = sel_arrow_attr;
                vert_bar_char = SWIN_SYM_LTEE;
            } else {
                vert_bar_attr = focus_attr;
                vert_bar_char = SWIN_SYM_VLINE;
            }

            swin_wattron(sview->win, vert_bar_attr);
            swin_waddch(sview->win, vert_bar_char);
            swin_wattroff(sview->win, vert_bar_attr);
        }

        /* Print the marker */
        if (is_exe_line || is_sel_line) {
            enum LineDisplayStyle display_style;
            int arrow_attr, block_attr;
            struct hl_line_attr *highlight_attr;

            if (is_exe_line) {
                display_style = exe_display_style;
                arrow_attr = exe_arrow_attr;
                block_attr = exe_block_attr;
                highlight_attr = exe_highlight_attrs;
            } else {
                display_style = sel_display_style;
                arrow_attr = sel_arrow_attr;
                block_attr = sel_block_attr;
                highlight_attr = sel_highlight_attrs;
            }

            switch (display_style) {
                case LINE_DISPLAY_SHORT_ARROW:
                    swin_wattron(sview->win, arrow_attr);
                    swin_waddch(sview->win, '>');
                    swin_wattroff(sview->win, arrow_attr);
                    break;
                case LINE_DISPLAY_LONG_ARROW:
                    swin_wattron(sview->win, arrow_attr);
                    column_offset = get_line_leading_ws_count(
                        sline->line, sline->len);
                    column_offset -= (sview->cur->sel_col + 1);
                    if (column_offset < 0)
                        column_offset = 0;

                    /* Now actually draw the arrow */
                    for (int j = 0; j < column_offset; j++)
                        swin_waddch(sview->win, SWIN_SYM_HLINE);

                    swin_waddch(sview->win, '>');
                    swin_wattroff(sview->win, arrow_attr);

                    break;
                case LINE_DISPLAY_HIGHLIGHT:
                    swin_waddch(sview->win, ' ');
                    printline_attrs = highlight_attr;
                    break;
                case LINE_DISPLAY_BLOCK:
                    column_offset = get_line_leading_ws_count(
                        sline->line, sline->len);
                    column_offset -= (sview->cur->sel_col + 1);
                    if (column_offset < 0)
                        column_offset = 0;

                    /* Now actually draw the space to the block */
                    for (int j = 0; j < column_offset; j++)
                        swin_waddch(sview->win, ' ');

                    /* Draw the block */
                    swin_wattron(sview->win, block_attr);
                    swin_waddch(sview->win, ' ');
                    swin_wattroff(sview->win, block_attr);
                    break;
            }
        } else {
            swin_waddch(sview->win, ' ');
        }


        /* Print the text */
        if (line < 0 || line >= count) {
            for (int j = 2 + lwidth; j < width; j++)
                swin_waddch(sview->win, ' ');
        } else {
            int x, y;
            y = swin_getcury(sview->win);
            x = swin_getcurx(sview->win);

            hl_printline(sview->win, sline->line, sline->len,
                printline_attrs, -1, -1, sview->cur->sel_col + column_offset,
                width - lwidth - 2);

            if (hlsearch && sview->last_hlregex) {
                struct hl_line_attr *attrs = hl_regex_highlight(
                        &sview->last_hlregex, sline->line, HLG_SEARCH);
                if (sbcount(attrs)) {
                    hl_printline_highlight(sview->win, sline->line, sline->len,
                        attrs, x, y, sview->cur->sel_col + column_offset,
                        width - lwidth - 2);
                    sbfree(attrs);
                }
            }

            if (is_sel_line && sview->hlregex) {
                struct hl_line_attr *attrs = hl_regex_highlight(
                        &sview->hlregex, sline->line, HLG_INCSEARCH);
                if (sbcount(attrs)) {
                    hl_printline_highlight(sview->win, sline->line, sline->len,
                        attrs, x, y, sview->cur->sel_col + column_offset,
                        width - lwidth - 2);
                    sbfree(attrs);
                }
            }
        }
    }

    switch(dorefresh) {
        case WIN_NO_REFRESH:
            swin_wnoutrefresh(sview->win);
            break;
        case WIN_REFRESH:
            swin_wrefresh(sview->win);
            break;
    }

    sbfree(sel_highlight_attrs);
    sbfree(exe_highlight_attrs);

    return 0;
}
Пример #4
0
int filedlg_display(struct filedlg *fd)
{
    char fmt[16];
    int width, height;
    int lwidth;
    int file;
    int i;
    int statusbar;
    int arrow_attr;
    int count = sbcount(fd->buf->files);
    int hlsearch = cgdbrc_get_int(CGDBRC_HLSEARCH);
    static const char label[] = "Select a file or press q to cancel.";
    int inc_search_attr = hl_groups_get_attr(hl_groups_instance, HLG_INCSEARCH);
    int search_attr = hl_groups_get_attr(hl_groups_instance, HLG_SEARCH);

    swin_curs_set(0);

    statusbar = hl_groups_get_attr(hl_groups_instance, HLG_STATUS_BAR);
    arrow_attr = hl_groups_get_attr(hl_groups_instance, HLG_SELECTED_LINE_ARROW);

    /* Check that a file is loaded */
    if (fd == NULL || fd->buf == NULL || fd->buf->files == NULL) {
        swin_wrefresh(fd->win);
        return 0;
    }

    /* Initialize variables */
    height = swin_getmaxy(fd->win);
    width = swin_getmaxx(fd->win);

    /* The status bar and display line 
     * Fake the display function to think the height is 2 lines less */
    height -= 2;

    /* Set starting line number (center source file if it's small enough) */
    if (count < height)
        file = (count - height) / 2;
    else {
        file = fd->buf->sel_line - height / 2;
        if (file > count - height)
            file = count - height;
        else if (file < 0)
            file = 0;
    }

    /* Print 'height' lines of the file, starting at 'file' */
    lwidth = log10_uint(count) + 1;
    snprintf(fmt, sizeof(fmt), "%%%dd", lwidth);

    print_in_middle(fd->win, 0, width, label);

    swin_wmove(fd->win, 0, 0);

    for (i = 1; i < height + 1; i++, file++) {
        swin_wmove(fd->win, i, 0);

        /* Outside of filename, just finish drawing the vertical file */
        if (file < 0 || file >= count) {
            int j;

            for (j = 1; j < lwidth; j++)
                swin_waddch(fd->win, ' ');
            swin_waddch(fd->win, '~');

            swin_wattron(fd->win, SWIN_A_BOLD);
            swin_waddch(fd->win, SWIN_SYM_VLINE);
            swin_wattroff(fd->win, SWIN_A_BOLD);

            for (j = 2 + lwidth; j < width; j++)
                swin_waddch(fd->win, ' ');
            continue;
        }

        int x, y;
        char *filename = fd->buf->files[file];

        /* Mark the current file with an arrow */
        if (file == fd->buf->sel_line) {
            swin_wattron(fd->win, SWIN_A_BOLD);
            swin_wprintw(fd->win, fmt, file + 1);
            swin_wattroff(fd->win, SWIN_A_BOLD);

            swin_wattron(fd->win, arrow_attr);
            swin_waddch(fd->win, '-');
            swin_waddch(fd->win, '>');
            swin_wattroff(fd->win, arrow_attr);

        }
        else {
            /* Ordinary file */
            swin_wprintw(fd->win, fmt, file + 1);

            swin_wattron(fd->win, SWIN_A_BOLD);
            swin_waddch(fd->win, SWIN_SYM_VLINE);
            swin_wattroff(fd->win, SWIN_A_BOLD);

            swin_waddch(fd->win, ' ');
        }

        y = swin_getcury(fd->win);
        x = swin_getcurx(fd->win);

        hl_printline(fd->win, filename, strlen(filename),
                     NULL, -1, -1, fd->buf->sel_col, width - lwidth - 2);

        if (hlsearch && fd->last_hlregex) {
            struct hl_line_attr *attrs = hl_regex_highlight(
                    &fd->last_hlregex, filename, search_attr);

            if (sbcount(attrs)) {
                hl_printline_highlight(fd->win, filename, strlen(filename),
                             attrs, x, y, fd->buf->sel_col, width - lwidth - 2);
                sbfree(attrs);
            }
        }

        if (regex_search && file == fd->buf->sel_line) {
            struct hl_line_attr *attrs = hl_regex_highlight(
                    &fd->hlregex, filename, inc_search_attr);

            if (sbcount(attrs)) {
                hl_printline_highlight(fd->win, filename, strlen(filename),
                             attrs, x, y, fd->buf->sel_col, width - lwidth - 2);
                sbfree(attrs);
            }
        }
    }

    /* Add the 2 lines back in so the status bar can be drawn */
    height += 2;

    /* Update status bar */
    swin_wmove(fd->win, height, 0);

    /* Print white background */
    swin_wattron(fd->win, statusbar);

    for (i = 0; i < width; i++)
        swin_mvwprintw(fd->win, height - 1, i, " ");

    if (regex_search && regex_direction)
        swin_mvwprintw(fd->win, height - 1, 0, "Search:%s", regex_line);
    else if (regex_search)
        swin_mvwprintw(fd->win, height - 1, 0, "RSearch:%s", regex_line);

    swin_wattroff(fd->win, statusbar);

    swin_wmove(fd->win, height - (file - fd->buf->sel_line) - 1, lwidth + 2);
    swin_wrefresh(fd->win);

    return 0;
}