Exemplo n.º 1
0
Arquivo: move.c Projeto: ryanlee/mc
void
mcview_moveto_eol (mcview_t * view)
{
    off_t bol;
    if (view->hex_mode)
    {
        off_t filesize;

        bol = mcview_offset_rounddown (view->hex_cursor, view->bytes_per_line);
        if (mcview_get_byte_indexed (view, bol, view->bytes_per_line - 1, NULL) == TRUE)
        {
            view->hex_cursor = bol + view->bytes_per_line - 1;
        }
        else
        {
            filesize = mcview_get_filesize (view);
            view->hex_cursor = mcview_offset_doz (filesize, 1);
        }
    }
    else
    {
        off_t eol;
        bol = mcview_bol (view, view->dpy_start, 0);
        eol = mcview_eol (view, view->dpy_start, mcview_get_filesize (view));
        if (!view->utf8)
        {
            if (eol > bol)
                view->dpy_text_column = eol - bol;
        }
        else
        {
            char *str = NULL;
            switch (view->datasource)
            {
            case DS_STDIO_PIPE:
            case DS_VFS_PIPE:
                str = mcview_get_ptr_growing_buffer (view, bol);
                break;
            case DS_FILE:
                str = mcview_get_ptr_file (view, bol);
                break;
            case DS_STRING:
                str = mcview_get_ptr_string (view, bol);
                break;
            case DS_NONE:
                break;
            }
            if (str != NULL && eol > bol)
                view->dpy_text_column = g_utf8_strlen (str, eol - bol);
            else
                view->dpy_text_column = eol - bol;
        }
        view->dpy_text_column = max (0, view->dpy_text_column - view->data_area.width);
    }
    mcview_movement_fixups (view, FALSE);
}
Exemplo n.º 2
0
Arquivo: lib.c Projeto: iNode/mc
off_t
mcview_eol (mcview_t * view, off_t current, off_t limit)
{
    int c, prev_ch = 0;
    off_t filesize;
    filesize = mcview_get_filesize (view);
    if (current < 0)
        return 0;
    if (current >= filesize)
        return filesize;
    while (current < filesize && current < limit)
    {
        if (!mcview_get_byte (view, current, &c))
            break;
        if (c == '\n')
        {
            current++;
            break;
        }
        else if (prev_ch == '\r')
        {
            break;
        }
        current++;
        prev_ch = c;
    }
    return current;
}
Exemplo n.º 3
0
Arquivo: lib.c Projeto: iNode/mc
off_t
mcview_bol (mcview_t * view, off_t current, off_t limit)
{
    int c;
    off_t filesize;
    filesize = mcview_get_filesize (view);
    if (current <= 0)
        return 0;
    if (current > filesize)
        return filesize;
    if (!mcview_get_byte (view, current, &c))
        return current;
    if (c == '\n')
    {
        if (!mcview_get_byte (view, current - 1, &c))
            return current;
        if (c == '\r')
            current--;
    }
    while (current > 0 && current >= limit)
    {
        if (!mcview_get_byte (view, current - 1, &c))
            break;
        if (c == '\r' || c == '\n')
            break;
        current--;
    }
    return current;
}
Exemplo n.º 4
0
Arquivo: lib.c Projeto: iNode/mc
int
mcview_calc_percent (mcview_t * view, off_t p)
{
    const screen_dimen right = view->status_area.left + view->status_area.width;
    const screen_dimen height = view->status_area.height;
    off_t filesize;
    int percent;

    if (height < 1 || right < 4)
        return (-1);
    if (mcview_may_still_grow (view))
        return (-1);

    filesize = mcview_get_filesize (view);
    if (view->hex_mode && filesize > 0)
    {
        /* p can't be beyond the last char, only over that. Compensate for this. */
        filesize--;
    }

    if (filesize == 0 || p >= filesize)
        percent = 100;
    else if (p > (INT_MAX / 100))
        percent = p / (filesize / 100);
    else
        percent = p * 100 / filesize;

    return percent;
}
Exemplo n.º 5
0
void
mcview_moveto_eol (WView * view)
{
    off_t bol;

    if (view->mode_flags.hex)
    {
        off_t filesize;

        bol = mcview_offset_rounddown (view->hex_cursor, view->bytes_per_line);
        if (mcview_get_byte_indexed (view, bol, view->bytes_per_line - 1, NULL) == TRUE)
        {
            view->hex_cursor = bol + view->bytes_per_line - 1;
        }
        else
        {
            filesize = mcview_get_filesize (view);
            view->hex_cursor = mcview_offset_doz (filesize, 1);
        }
    }
    else
    {
        mcview_ascii_moveto_eol (view);
    }
    mcview_movement_fixups (view, FALSE);
}
Exemplo n.º 6
0
Arquivo: move.c Projeto: ryanlee/mc
void
mcview_moveto_bottom (mcview_t * view)
{
    off_t filesize;

    mcview_update_filesize (view);

    if (view->growbuf_in_use)
        mcview_growbuf_read_until (view, OFFSETTYPE_MAX);

    filesize = mcview_get_filesize (view);

    if (view->hex_mode)
    {
        view->hex_cursor = mcview_offset_doz (filesize, 1);
        mcview_movement_fixups (view, TRUE);
    }
    else
    {
        const off_t datalines = view->data_area.height;

        view->dpy_start = filesize;
        mcview_move_up (view, datalines);
    }
}
Exemplo n.º 7
0
Arquivo: move.c Projeto: ryanlee/mc
void
mcview_move_right (mcview_t * view, off_t columns)
{
    if (view->hex_mode)
    {
        off_t last_byte;
        off_t old_cursor = view->hex_cursor;
        last_byte = mcview_offset_doz (mcview_get_filesize (view), 1);
#ifdef HAVE_ASSERT_H
        assert (columns == 1);
#endif
        if (view->hexview_in_text || view->hexedit_lownibble)
        {
            if (view->hex_cursor < last_byte)
                view->hex_cursor++;
        }
        if (!view->hexview_in_text)
            if (old_cursor < last_byte || !view->hexedit_lownibble)
                view->hexedit_lownibble = !view->hexedit_lownibble;
    }
    else
    {
        view->dpy_text_column += columns;
    }
    mcview_movement_fixups (view, FALSE);
}
Exemplo n.º 8
0
void
mcview_move_down (WView * view, off_t lines)
{
    off_t last_byte;

    last_byte = mcview_get_filesize (view);

    if (view->mode_flags.hex)
    {
        off_t i, limit;

        limit = mcview_offset_doz (last_byte, (off_t) view->bytes_per_line);

        for (i = 0; i < lines && view->hex_cursor < limit; i++)
        {
            view->hex_cursor += view->bytes_per_line;
            if (lines != 1)
            {
                view->dpy_start += view->bytes_per_line;
                view->dpy_paragraph_skip_lines = 0;
                view->dpy_wrap_dirty = TRUE;
            }
        }
    }
    else
    {
        mcview_ascii_move_down (view, lines);
    }
    mcview_movement_fixups (view, TRUE);
}
Exemplo n.º 9
0
Arquivo: display.c Projeto: artzub/mc
void
mcview_percent (mcview_t * view, off_t p)
{
    const screen_dimen top = view->status_area.top;
    const screen_dimen right = view->status_area.left + view->status_area.width;
    const screen_dimen height = view->status_area.height;
    int percent;
    off_t filesize;

    if (height < 1 || right < 4)
        return;
    if (mcview_may_still_grow (view))
        return;
    filesize = mcview_get_filesize (view);

    if (filesize == 0 || view->dpy_end == filesize)
        percent = 100;
    else if (p > (INT_MAX / 100))
        percent = p / (filesize / 100);
    else
        percent = p * 100 / filesize;

    widget_move (view, top, right - 4);
    tty_printf ("%3d%%", percent);
}
Exemplo n.º 10
0
void
mcview_move_right (WView * view, off_t columns)
{
    if (view->mode_flags.hex)
    {
        off_t last_byte;
        off_t old_cursor = view->hex_cursor;

        last_byte = mcview_offset_doz (mcview_get_filesize (view), 1);

        g_assert (columns == 1);

        if (view->hexview_in_text || view->hexedit_lownibble)
        {
            if (view->hex_cursor < last_byte)
                view->hex_cursor++;
        }
        if (!view->hexview_in_text)
            if (old_cursor < last_byte || !view->hexedit_lownibble)
                view->hexedit_lownibble = !view->hexedit_lownibble;
    }
    else if (!view->mode_flags.wrap)
    {
        view->dpy_text_column += columns;
    }
    mcview_movement_fixups (view, FALSE);
}
Exemplo n.º 11
0
void
mcview_moveto_bottom (WView * view)
{
    off_t filesize;

    mcview_update_filesize (view);

    if (view->growbuf_in_use)
        mcview_growbuf_read_all_data (view);

    filesize = mcview_get_filesize (view);

    if (view->mode_flags.hex)
    {
        view->hex_cursor = mcview_offset_doz (filesize, 1);
        mcview_movement_fixups (view, TRUE);
    }
    else
    {
        const off_t datalines = view->data_area.height;

        view->dpy_start = filesize;
        view->dpy_paragraph_skip_lines = 0;
        view->dpy_wrap_dirty = TRUE;
        mcview_move_up (view, datalines);
    }
}
Exemplo n.º 12
0
/**
 * Move down.
 *
 * It's very simple. Just invisibly format the next "lines" lines, carefully carrying the formatter
 * state in wrap mode. But before each step we need to check if we've already hit the end of the
 * file, in that case we can no longer move. This is done by walking from dpy_state_bottom.
 *
 * Note that this relies on mcview_display_text() setting dpy_state_bottom to its correct value
 * upon rendering the screen contents. So don't call this function from other functions (e.g. at
 * the bottom of mcview_ascii_move_up()) which invalidate this value.
 */
void
mcview_ascii_move_down (WView * view, off_t lines)
{
    while (lines-- != 0)
    {
        gboolean paragraph_ended;

        /* See if there's still data below the bottom line, by imaginarily displaying one
         * more line. This takes care of reading more data into growbuf, if required.
         * If the end position didn't advance, we're at EOF and hence bail out. */
        if (mcview_display_line (view, &view->dpy_state_bottom, -1, &paragraph_ended, NULL) == 0)
            break;

        /* Okay, there's enough data. Move by 1 row at the top, too. No need to check for
         * EOF, that can't happen. */
        if (!view->text_wrap_mode)
        {
            view->dpy_start = mcview_eol (view, view->dpy_start, mcview_get_filesize (view));
            view->dpy_paragraph_skip_lines = 0;
            view->dpy_wrap_dirty = TRUE;
        }
        else
        {
            mcview_display_line (view, &view->dpy_state_top, -1, &paragraph_ended, NULL);
            if (!paragraph_ended)
                view->dpy_paragraph_skip_lines++;
            else
            {
                view->dpy_start = view->dpy_state_top.offset;
                view->dpy_paragraph_skip_lines = 0;
            }
        }
    }
}
Exemplo n.º 13
0
void
mcview_set_byte (mcview_t * view, off_t offset, byte b)
{
    (void) &b;
    assert (offset < mcview_get_filesize (view));
    assert (view->datasource == DS_FILE);
    view->ds_file_datalen = 0;  /* just force reloading */
}
Exemplo n.º 14
0
static gboolean
mcview_find (mcview_t * view, gsize search_start, gsize * len)
{
    gsize search_end;

    view->search_numNeedSkipChar = 0;
    search_cb_char_curr_index = -1;

    if (mcview_search_options.backwards)
    {
        search_end = mcview_get_filesize (view);
        while ((int) search_start >= 0)
        {
            view->search_nroff_seq->index = search_start;
            mcview_nroff_seq_info (view->search_nroff_seq);

            if (search_end > search_start + view->search->original_len
                && mc_search_is_fixed_search_str (view->search))
                search_end = search_start + view->search->original_len;

            if (mc_search_run (view->search, (void *) view, search_start, search_end, len)
                && view->search->normal_offset == (off_t) search_start)
            {
                if (view->text_nroff_mode)
                    view->search->normal_offset++;
                return TRUE;
            }

            search_start--;
        }
        view->search->error_str = g_strdup (_("Search string not found"));
        return FALSE;
    }
    view->search_nroff_seq->index = search_start;
    mcview_nroff_seq_info (view->search_nroff_seq);

    return mc_search_run (view->search, (void *) view, search_start, mcview_get_filesize (view),
                          len);
}
Exemplo n.º 15
0
void
mcview_set_byte (mcview_t * view, off_t offset, byte b)
{
    (void) &b;
#ifndef HAVE_ASSERT_H
    (void) offset;
#else
    assert (offset < mcview_get_filesize (view));
    assert (view->datasource == DS_FILE);

#endif
    view->ds_file_datalen = 0;  /* just force reloading */
}
Exemplo n.º 16
0
static void
mcview_search_update_steps (mcview_t * view)
{
    off_t filesize = mcview_get_filesize (view);
    if (filesize != 0)
        view->update_steps = 40000;
    else                        /* viewing a data stream, not a file */
        view->update_steps = filesize / 100;

    /* Do not update the percent display but every 20 ks */
    if (view->update_steps < 20000)
        view->update_steps = 20000;
}
Exemplo n.º 17
0
static void
mcview_display_status (WView * view)
{
    const screen_dimen top = view->status_area.top;
    const screen_dimen left = view->status_area.left;
    const screen_dimen width = view->status_area.width;
    const screen_dimen height = view->status_area.height;
    const char *file_label;

    if (height < 1)
        return;

    tty_setcolor (STATUSBAR_COLOR);
    tty_draw_hline (WIDGET (view)->y + top, WIDGET (view)->x + left, ' ', width);

    file_label =
        view->filename_vpath != NULL ?
        vfs_path_get_last_path_str (view->filename_vpath) : view->command != NULL ?
        view->command : "";

    if (width > 40)
    {
        widget_move (view, top, width - 32);
        if (view->hex_mode)
            tty_printf ("0x%08" PRIxMAX, (uintmax_t) view->hex_cursor);
        else
        {
            char buffer[BUF_TRUNC_LEN + 1];

            size_trunc_len (buffer, BUF_TRUNC_LEN, mcview_get_filesize (view), 0,
                            panels_options.kilobyte_si);
            tty_printf ("%9" PRIuMAX "/%s%s %s", (uintmax_t) view->dpy_end,
                        buffer, mcview_may_still_grow (view) ? "+" : " ",
#ifdef HAVE_CHARSET
                        mc_global.source_codepage >= 0 ?
                        get_codepage_id (mc_global.source_codepage) :
#endif
                        "");
        }
    }
    widget_move (view, top, left);
    if (width > 40)
        tty_print_string (str_fit_to_term (file_label, width - 34, J_LEFT_FIT));
    else
        tty_print_string (str_fit_to_term (file_label, width - 5, J_LEFT_FIT));
    if (width > 26)
        mcview_display_percent (view, view->hex_mode ? view->hex_cursor : view->dpy_end);
}
Exemplo n.º 18
0
static void
mcview_display_status (mcview_t * view)
{
    const screen_dimen top = view->status_area.top;
    const screen_dimen left = view->status_area.left;
    const screen_dimen width = view->status_area.width;
    const screen_dimen height = view->status_area.height;
    const char *file_label;
    screen_dimen file_label_width;

    if (height < 1)
        return;

    tty_setcolor (STATUSBAR_COLOR);
    widget_move (view, top, left);
    tty_draw_hline (-1, -1, ' ', width);

    file_label = view->filename ? view->filename : view->command ? view->command : "";
    file_label_width = str_term_width1 (file_label) - 2;
    if (width > 40)
    {
        char buffer[BUF_TINY];
        widget_move (view, top, width - 32);
        if (view->hex_mode)
            tty_printf ("0x%08" PRIxMAX, (uintmax_t) view->hex_cursor);
        else
        {
            size_trunc_len (buffer, 5, mcview_get_filesize (view), 0, panels_options.kilobyte_si);
            tty_printf ("%9" PRIuMAX "/%s%s %s", (uintmax_t) view->dpy_end,
                        buffer, mcview_may_still_grow (view) ? "+" : " ",
#ifdef HAVE_CHARSET
                        mc_global.source_codepage >=
                        0 ? get_codepage_id (mc_global.source_codepage) : ""
#else
                        ""
#endif
                );
        }
    }
    widget_move (view, top, left);
    if (width > 40)
        tty_print_string (str_fit_to_term (file_label, width - 34, J_LEFT_FIT));
    else
        tty_print_string (str_fit_to_term (file_label, width - 5, J_LEFT_FIT));
    if (width > 26)
        mcview_percent (view, view->hex_mode ? view->hex_cursor : view->dpy_end);
}
Exemplo n.º 19
0
static gboolean
mcview_find (mcview_search_status_msg_t * ssm, off_t search_start, off_t search_end, gsize * len)
{
    WView *view = ssm->view;

    view->search_numNeedSkipChar = 0;
    search_cb_char_curr_index = -1;

    if (mcview_search_options.backwards)
    {
        search_end = mcview_get_filesize (view);
        while (search_start >= 0)
        {
            gboolean ok;

            view->search_nroff_seq->index = search_start;
            mcview_nroff_seq_info (view->search_nroff_seq);

            if (search_end > search_start + (off_t) view->search->original_len
                && mc_search_is_fixed_search_str (view->search))
                search_end = search_start + view->search->original_len;

            ok = mc_search_run (view->search, (void *) ssm, search_start, search_end, len);
            if (ok && view->search->normal_offset == search_start)
            {
                if (view->text_nroff_mode)
                    view->search->normal_offset++;
                return TRUE;
            }

            /* We abort the search in case of a pattern error, or if the user aborts
               the search. In other words: in all cases except "string not found". */
            if (!ok && view->search->error != MC_SEARCH_E_NOTFOUND)
                return FALSE;

            search_start--;
        }

        mc_search_set_error (view->search, MC_SEARCH_E_NOTFOUND, "%s", _(STR_E_NOTFOUND));
        return FALSE;
    }
    view->search_nroff_seq->index = search_start;
    mcview_nroff_seq_info (view->search_nroff_seq);

    return mc_search_run (view->search, (void *) ssm, search_start, search_end, len);
}
Exemplo n.º 20
0
static void
mcview_search_update_steps (WView * view)
{
    off_t filesize;

    filesize = mcview_get_filesize (view);

    if (filesize != 0)
        view->update_steps = filesize / 100;
    else                        /* viewing a data stream, not a file */
        view->update_steps = 40000;

    /* Do not update the percent display but every 20 kb */
    if (view->update_steps < 20000)
        view->update_steps = 20000;

    /* Make interrupt more responsive */
    if (view->update_steps > 40000)
        view->update_steps = 40000;
}
Exemplo n.º 21
0
gboolean
mcview_dialog_goto (WView * view, off_t * offset)
{
    typedef enum
    {
        MC_VIEW_GOTO_LINENUM = 0,
        MC_VIEW_GOTO_PERCENT = 1,
        MC_VIEW_GOTO_OFFSET_DEC = 2,
        MC_VIEW_GOTO_OFFSET_HEX = 3
    } mcview_goto_type_t;

    const char *mc_view_goto_str[] = {
        N_("&Line number"),
        N_("Pe&rcents"),
        N_("&Decimal offset"),
        N_("He&xadecimal offset")
    };

    static mcview_goto_type_t current_goto_type = MC_VIEW_GOTO_LINENUM;

    size_t num_of_types;
    char *exp = NULL;
    int qd_result;
    gboolean res;

    num_of_types = G_N_ELEMENTS (mc_view_goto_str);

#ifdef ENABLE_NLS
    {
        size_t i;

        for (i = 0; i < num_of_types; i++)
            mc_view_goto_str[i] = _(mc_view_goto_str[i]);
    }
#endif

    {
        quick_widget_t quick_widgets[] = {
            /* *INDENT-OFF* */
            QUICK_INPUT (INPUT_LAST_TEXT, MC_HISTORY_VIEW_GOTO, &exp, NULL,
                         FALSE, FALSE, INPUT_COMPLETE_NONE),
            QUICK_RADIO (num_of_types, (const char **) mc_view_goto_str, (int *) &current_goto_type,
                         NULL),
            QUICK_BUTTONS_OK_CANCEL,
            QUICK_END
            /* *INDENT-ON* */
        };

        quick_dialog_t qdlg = {
            -1, -1, 40,
            N_("Goto"), "[Input Line Keys]",
            quick_widgets, NULL, NULL
        };

        /* run dialog */
        qd_result = quick_dialog (&qdlg);
    }

    *offset = -1;

    /* check input line value */
    res = (qd_result != B_CANCEL && exp != NULL && exp[0] != '\0');
    if (res)
    {
        int base = (current_goto_type == MC_VIEW_GOTO_OFFSET_HEX) ? 16 : 10;
        off_t addr;
        char *error;

        addr = (off_t) g_ascii_strtoll (exp, &error, base);
        if ((*error == '\0') && (addr >= 0))
        {
            switch (current_goto_type)
            {
            case MC_VIEW_GOTO_LINENUM:
                /* Line number entered by user is 1-based. */
                if (addr > 0)
                    addr--;
                mcview_coord_to_offset (view, offset, addr, 0);
                *offset = mcview_bol (view, *offset, 0);
                break;
            case MC_VIEW_GOTO_PERCENT:
                if (addr > 100)
                    addr = 100;
                /* read all data from pipe to get real size */
                if (view->growbuf_in_use)
                    mcview_growbuf_read_all_data (view);
                *offset = addr * mcview_get_filesize (view) / 100;
                if (!view->mode_flags.hex)
                    *offset = mcview_bol (view, *offset, 0);
                break;
            case MC_VIEW_GOTO_OFFSET_DEC:
            case MC_VIEW_GOTO_OFFSET_HEX:
                if (!view->mode_flags.hex)
                {
                    if (view->growbuf_in_use)
                        mcview_growbuf_read_until (view, addr);

                    *offset = mcview_bol (view, addr, 0);
                }
                else
                {
                    /* read all data from pipe to get real size */
                    if (view->growbuf_in_use)
                        mcview_growbuf_read_all_data (view);

                    *offset = addr;
                    addr = mcview_get_filesize (view);
                    if (*offset > addr)
                        *offset = addr;
                }
                break;
            default:
                *offset = 0;
                break;
            }
        }
    }

    g_free (exp);
    return res;
}
Exemplo n.º 22
0
void
mcview_do_search (mcview_t * view)
{
    mcview_search_status_msg_t vsm;

    off_t search_start = 0;
    gboolean isFound = FALSE;
    gboolean need_search_again = TRUE;

    size_t match_len;

    /* for avoid infinite search loop we need to increase or decrease start offset of search */

    if (view->search_start != 0)
    {
        if (!view->text_nroff_mode)
            search_start = view->search_start + (mcview_search_options.backwards ? -2 : 0);
        else
        {
            if (mcview_search_options.backwards)
            {
                mcview_nroff_t *nroff;
                nroff = mcview_nroff_seq_new_num (view, view->search_start);
                if (mcview_nroff_seq_prev (nroff) != -1)
                    search_start =
                        -(mcview__get_nroff_real_len (view, nroff->index - 1, 2) +
                          nroff->char_width + 1);
                else
                    search_start = -2;

                mcview_nroff_seq_free (&nroff);
            }
            else
            {
                search_start = mcview__get_nroff_real_len (view, view->search_start + 1, 2);
            }
            search_start += view->search_start;
        }
    }

    if (mcview_search_options.backwards && (int) search_start < 0)
        search_start = 0;

    /* Compute the percent steps */
    mcview_search_update_steps (view);

    view->update_activate = search_start;

    vsm.first = TRUE;
    vsm.view = view;
    vsm.offset = search_start;

    status_msg_init (STATUS_MSG (&vsm), _("Search"), 1.0, simple_status_msg_init_cb,
                     mcview_search_status_update_cb, NULL);

    do
    {
        off_t growbufsize;

        if (view->growbuf_in_use)
            growbufsize = mcview_growbuf_filesize (view);
        else
            growbufsize = view->search->original_len;

        if (mcview_find (&vsm, search_start, mcview_get_filesize (view), &match_len))
        {
            mcview_search_show_result (view, match_len);
            need_search_again = FALSE;
            isFound = TRUE;
            break;
        }

        if (view->search->error_str == NULL)
            break;

        search_start = growbufsize - view->search->original_len;
        if (search_start <= 0)
        {
            search_start = 0;
            break;
        }
    }
    while (mcview_may_still_grow (view));

    status_msg_deinit (STATUS_MSG (&vsm));

    if (view->search_start != 0 && !isFound && need_search_again
        && !mcview_search_options.backwards)
    {
        int result;

        mcview_update (view);

        result =
            query_dialog (_("Search done"), _("Continue from beginning?"), D_NORMAL, 2, _("&Yes"),
                          _("&No"));

        if (result != 0)
            isFound = TRUE;
        else
            search_start = 0;
    }

    if (!isFound && view->search->error_str != NULL)
    {
        /* continue search form beginning */
        off_t search_end;

        search_end = view->search_start;
        /* search_start is 0 here */
        view->update_activate = search_start;

        vsm.first = TRUE;
        vsm.view = view;
        vsm.offset = search_start;

        status_msg_init (STATUS_MSG (&vsm), _("Search"), 1.0, simple_status_msg_init_cb,
                         mcview_search_status_update_cb, NULL);

        if (mcview_find (&vsm, search_start, search_end, &match_len))
        {
            mcview_search_show_result (view, match_len);
            isFound = TRUE;
        }

        status_msg_deinit (STATUS_MSG (&vsm));
    }

    if (!isFound && view->search->error_str != NULL)
        query_dialog (_("Search"), view->search->error_str, D_NORMAL, 1, _("&Dismiss"));

    view->dirty++;
}
Exemplo n.º 23
0
void
mcview_ccache_dump (mcview_t * view)
{
    FILE *f;
    off_t offset, line, column, nextline_offset, filesize;
    guint i;
    const coord_cache_t *cache = view->coord_cache;

#ifdef HAVE_ASSERT_H
    assert (cache != NULL);
#endif

    filesize = mcview_get_filesize (view);

    f = fopen ("mcview-ccache.out", "w");
    if (f == NULL)
        return;
    (void) setvbuf (f, NULL, _IONBF, 0);

    /* cache entries */
    for (i = 0; i < cache->size; i++)
    {
        (void) fprintf (f,
                        "entry %8u  offset %8" PRIuMAX
                        "  line %8" PRIuMAX "  column %8" PRIuMAX
                        "  nroff_column %8" PRIuMAX "\n",
                        (unsigned int) i,
                        (uintmax_t) cache->cache[i]->cc_offset,
                        (uintmax_t) cache->cache[i]->cc_line,
                        (uintmax_t) cache->cache[i]->cc_column,
                        (uintmax_t) cache->cache[i]->cc_nroff_column);
    }
    (void) fprintf (f, "\n");

    /* offset -> line/column translation */
    for (offset = 0; offset < filesize; offset++)
    {
        mcview_offset_to_coord (view, &line, &column, offset);
        (void) fprintf (f,
                        "offset %8" PRIuMAX "  line %8" PRIuMAX "  column %8" PRIuMAX "\n",
                        (uintmax_t) offset, (uintmax_t) line, (uintmax_t) column);
    }

    /* line/column -> offset translation */
    for (line = 0; TRUE; line++)
    {
        mcview_coord_to_offset (view, &nextline_offset, line + 1, 0);
        (void) fprintf (f, "nextline_offset %8" PRIuMAX "\n", (uintmax_t) nextline_offset);

        for (column = 0; TRUE; column++)
        {
            mcview_coord_to_offset (view, &offset, line, column);
            if (offset >= nextline_offset)
                break;

            (void) fprintf (f,
                            "line %8" PRIuMAX "  column %8" PRIuMAX "  offset %8" PRIuMAX "\n",
                            (uintmax_t) line, (uintmax_t) column, (uintmax_t) offset);
        }

        if (nextline_offset >= filesize - 1)
            break;
    }

    (void) fclose (f);
}
Exemplo n.º 24
0
void
mcview_do_search (WView * view, off_t want_search_start)
{
    mcview_search_status_msg_t vsm;

    off_t search_start = 0;
    off_t orig_search_start = view->search_start;
    gboolean found = FALSE;

    size_t match_len;

    view->search_start = want_search_start;
    /* for avoid infinite search loop we need to increase or decrease start offset of search */

    if (view->search_start != 0)
    {
        if (!view->text_nroff_mode)
            search_start = view->search_start + (mcview_search_options.backwards ? -2 : 0);
        else
        {
            if (mcview_search_options.backwards)
            {
                mcview_nroff_t *nroff;

                nroff = mcview_nroff_seq_new_num (view, view->search_start);
                if (mcview_nroff_seq_prev (nroff) != -1)
                    search_start =
                        -(mcview__get_nroff_real_len (view, nroff->index - 1, 2) +
                          nroff->char_length + 1);
                else
                    search_start = -2;

                mcview_nroff_seq_free (&nroff);
            }
            else
            {
                search_start = mcview__get_nroff_real_len (view, view->search_start + 1, 2);
            }
            search_start += view->search_start;
        }
    }

    if (mcview_search_options.backwards && search_start < 0)
        search_start = 0;

    /* Compute the percent steps */
    mcview_search_update_steps (view);

    view->update_activate = search_start;

    vsm.first = TRUE;
    vsm.view = view;
    vsm.offset = search_start;

    status_msg_init (STATUS_MSG (&vsm), _("Search"), 1.0, simple_status_msg_init_cb,
                     mcview_search_status_update_cb, NULL);

    do
    {
        off_t growbufsize;

        if (view->growbuf_in_use)
            growbufsize = mcview_growbuf_filesize (view);
        else
            growbufsize = view->search->original_len;

        if (mcview_find (&vsm, search_start, mcview_get_filesize (view), &match_len))
        {
            mcview_search_show_result (view, match_len);
            found = TRUE;
            break;
        }

        if (view->search->error == MC_SEARCH_E_ABORT || view->search->error == MC_SEARCH_E_NOTFOUND)
            break;

        search_start = growbufsize - view->search->original_len;
    }
    while (search_start > 0 && mcview_may_still_grow (view));

    status_msg_deinit (STATUS_MSG (&vsm));

    if (orig_search_start != 0 && (!found && view->search->error == MC_SEARCH_E_NOTFOUND)
        && !mcview_search_options.backwards)
    {
        view->search_start = orig_search_start;
        mcview_update (view);

        if (query_dialog
            (_("Search done"), _("Continue from beginning?"), D_NORMAL, 2, _("&Yes"),
             _("&No")) != 0)
            found = TRUE;
        else
        {
            /* continue search from beginning */
            view->update_activate = 0;

            vsm.first = TRUE;
            vsm.view = view;
            vsm.offset = 0;

            status_msg_init (STATUS_MSG (&vsm), _("Search"), 1.0, simple_status_msg_init_cb,
                             mcview_search_status_update_cb, NULL);

            /* search from file begin up to initial search start position */
            if (mcview_find (&vsm, 0, orig_search_start, &match_len))
            {
                mcview_search_show_result (view, match_len);
                found = TRUE;
            }

            status_msg_deinit (STATUS_MSG (&vsm));
        }
    }

    if (!found)
    {
        view->search_start = orig_search_start;
        mcview_update (view);

        if (view->search->error == MC_SEARCH_E_NOTFOUND)
            query_dialog (_("Search"), _(STR_E_NOTFOUND), D_NORMAL, 1, _("&Dismiss"));
        else if (view->search->error_str != NULL)
            query_dialog (_("Search"), view->search->error_str, D_NORMAL, 1, _("&Dismiss"));
    }
    view->dirty++;
}
Exemplo n.º 25
0
Arquivo: move.c Projeto: ryanlee/mc
void
mcview_move_down (mcview_t * view, off_t lines)
{
    off_t last_byte;
    last_byte = mcview_get_filesize (view);
    if (view->hex_mode)
    {
        off_t i, limit;

        if (last_byte >= (off_t) view->bytes_per_line)
            limit = last_byte - view->bytes_per_line;
        else
            limit = 0;
        for (i = 0; i < lines && view->hex_cursor < limit; i++)
        {
            view->hex_cursor += view->bytes_per_line;
            if (lines != 1)
                view->dpy_start += view->bytes_per_line;
        }
    }
    else
    {
        off_t new_offset = 0;

        if (view->dpy_end - view->dpy_start > last_byte - view->dpy_end)
        {
            while (lines-- > 0)
            {
                if (view->text_wrap_mode)
                    view->dpy_end =
                        mcview_eol (view, view->dpy_end,
                                    view->dpy_end + (off_t) view->data_area.width);
                else
                    view->dpy_end = mcview_eol (view, view->dpy_end, last_byte);

                if (view->text_wrap_mode)
                    new_offset =
                        mcview_eol (view, view->dpy_start,
                                    view->dpy_start + (off_t) view->data_area.width);
                else
                    new_offset = mcview_eol (view, view->dpy_start, last_byte);
                if (new_offset < last_byte)
                    view->dpy_start = new_offset;
                if (view->dpy_end >= last_byte)
                    break;
            }
        }
        else
        {
            off_t i;
            for (i = 0; i < lines && new_offset < last_byte; i++)
            {
                if (view->text_wrap_mode)
                    new_offset =
                        mcview_eol (view, view->dpy_start,
                                    view->dpy_start + (off_t) view->data_area.width);
                else
                    new_offset = mcview_eol (view, view->dpy_start, last_byte);
                if (new_offset < last_byte)
                    view->dpy_start = new_offset;
            }
        }
    }
    mcview_movement_fixups (view, TRUE);
}
Exemplo n.º 26
0
Arquivo: dialogs.c Projeto: BrEacK/mc
gboolean
mcview_dialog_goto (mcview_t * view, off_t * offset)
{
    typedef enum
    {
        MC_VIEW_GOTO_LINENUM = 0,
        MC_VIEW_GOTO_PERCENT = 1,
        MC_VIEW_GOTO_OFFSET_DEC = 2,
        MC_VIEW_GOTO_OFFSET_HEX = 3
    } mcview_goto_type_t;

    const char *mc_view_goto_str[] = {
        N_("&Line number (decimal)"),
        N_("Pe&rcents"),
        N_("&Decimal offset"),
        N_("He&xadecimal offset")
    };

    const int goto_dlg_height = 12;
    int goto_dlg_width = 40;

    static mcview_goto_type_t current_goto_type = MC_VIEW_GOTO_LINENUM;

    size_t i;

    size_t num_of_types = sizeof (mc_view_goto_str) / sizeof (mc_view_goto_str[0]);
    char *exp = NULL;
    int qd_result;
    gboolean res = FALSE;

    QuickWidget quick_widgets[] = {
        QUICK_BUTTON (6, 10, goto_dlg_height - 3, goto_dlg_height, N_("&Cancel"), B_CANCEL, NULL),
        QUICK_BUTTON (2, 10, goto_dlg_height - 3, goto_dlg_height, N_("&OK"), B_ENTER, NULL),
        QUICK_RADIO (3, goto_dlg_width, 4, goto_dlg_height,
                     num_of_types, (const char **) mc_view_goto_str, (int *) &current_goto_type),
        QUICK_INPUT (3, goto_dlg_width, 2, goto_dlg_height,
                     INPUT_LAST_TEXT, goto_dlg_width - 6, 0, MC_HISTORY_VIEW_GOTO, &exp),
        QUICK_END
    };

    QuickDialog Quick_input = {
        goto_dlg_width, goto_dlg_height, -1, -1,
        N_("Goto"), "[Input Line Keys]",
        quick_widgets, NULL, NULL, FALSE
    };

#ifdef ENABLE_NLS
    for (i = 0; i < num_of_types; i++)
        mc_view_goto_str[i] = _(mc_view_goto_str[i]);

    quick_widgets[0].u.button.text = _(quick_widgets[0].u.button.text);
    quick_widgets[1].u.button.text = _(quick_widgets[1].u.button.text);
#endif

    /* calculate widget coordinates */
    {
        int b0_len, b1_len, len;
        const int button_gap = 2;

        /* preliminary dialog width */
        goto_dlg_width = max (goto_dlg_width, str_term_width1 (Quick_input.title) + 4);

        /* length of radiobuttons */
        for (i = 0; i < num_of_types; i++)
            goto_dlg_width = max (goto_dlg_width, str_term_width1 (mc_view_goto_str[i]) + 10);

        /* length of buttons */
        b0_len = str_term_width1 (quick_widgets[0].u.button.text) + 3;
        b1_len = str_term_width1 (quick_widgets[1].u.button.text) + 5;  /* default button */
        len = b0_len + b1_len + button_gap * 2;

        /* dialog width */
        Quick_input.xlen = max (goto_dlg_width, len + 6);

        /* correct widget coordinates */
        for (i = sizeof (quick_widgets) / sizeof (quick_widgets[0]); i > 0; i--)
            quick_widgets[i - 1].x_divisions = Quick_input.xlen;

        /* input length */
        quick_widgets[3].u.input.len = Quick_input.xlen - 6;

        /* button positions */
        quick_widgets[1].relative_x = Quick_input.xlen / 2 - len / 2;
        quick_widgets[0].relative_x = quick_widgets[1].relative_x + b1_len + button_gap;
    }

    /* run dialog */
    qd_result = quick_dialog (&Quick_input);

    *offset = -1;

    /* check input line value */
    if ((qd_result != B_CANCEL) && (exp != NULL) && (exp[0] != '\0'))
    {
        int base = (current_goto_type == MC_VIEW_GOTO_OFFSET_HEX) ? 16 : 10;
        off_t addr;
        char *error;

        res = TRUE;

        addr = strtoll (exp, &error, base);
        if ((*error == '\0') && (addr >= 0))
        {
            switch (current_goto_type)
            {
            case MC_VIEW_GOTO_LINENUM:
                mcview_coord_to_offset (view, offset, addr, 0);
                *offset = mcview_bol (view, *offset, 0);
                break;
            case MC_VIEW_GOTO_PERCENT:
                if (addr > 100)
                    addr = 100;
                *offset = addr * mcview_get_filesize (view) / 100;
                if (!view->hex_mode)
                    *offset = mcview_bol (view, *offset, 0);
                break;
            case MC_VIEW_GOTO_OFFSET_DEC:
            case MC_VIEW_GOTO_OFFSET_HEX:
                *offset = addr;
                if (!view->hex_mode)
                    *offset = mcview_bol (view, *offset, 0);
                else
                {
                    addr = mcview_get_filesize (view);
                    if (*offset > addr)
                        *offset = addr;
                }
                break;
            default:
                *offset = 0;
                break;
            }
        }
    }

    g_free (exp);
    return res;
}
Exemplo n.º 27
0
/**
 * Parse, format and possibly display one visual line of text.
 *
 * Formatting starts at the given "state" (which encodes the file offset and parser and formatter's
 * internal state). In unwrap mode, this should point to the beginning of the paragraph with the
 * default state, the additional horizontal scrolling is added here. In wrap mode, this should
 * point to the beginning of the line, with the proper state at that point.
 *
 * In wrap mode, if a line ends in a newline, it is consumed, even if it's exactly at the right
 * edge. In unwrap mode, the whole remaining line, including the newline is consumed. Displaying
 * the next line should start at "state"'s new value, or if we displayed the bottom line then
 * state->offset tells the file offset to be shown in the top bar.
 *
 * If "row" is offscreen, don't actually display the line but still update "state" and return the
 * proper value. This is used by mcview_wrap_move_down to advance in the file.
 *
 * @param view ...
 * @param state the parser-formatter state machine's state, updated
 * @param row print to this row
 * @param paragraph_ended store TRUE if paragraph ended by newline or EOF, FALSE if wraps to next
 *   line
 * @param linewidth store the width of the line here
 * @return the number of rows, that is, 0 if we were already at EOF, otherwise 1
 */
static int
mcview_display_line (WView * view, mcview_state_machine_t * state, int row,
                     gboolean * paragraph_ended, off_t * linewidth)
{
    const screen_dimen left = view->data_area.left;
    const screen_dimen top = view->data_area.top;
    const screen_dimen width = view->data_area.width;
    const screen_dimen height = view->data_area.height;
    off_t dpy_text_column = view->text_wrap_mode ? 0 : view->dpy_text_column;
    screen_dimen col = 0;
    int cs[1 + MAX_COMBINING_CHARS];
    char str[(1 + MAX_COMBINING_CHARS) * UTF8_CHAR_LEN + 1];
    int i, j;

    if (paragraph_ended != NULL)
        *paragraph_ended = TRUE;

    if (!view->text_wrap_mode && (row < 0 || row >= (int) height) && linewidth == NULL)
    {
        /* Optimization: Fast forward to the end of the line, rather than carefully
         * parsing and then not actually displaying it. */
        off_t eol;
        int retval;

        eol = mcview_eol (view, state->offset, mcview_get_filesize (view));
        retval = (eol > state->offset) ? 1 : 0;

        mcview_state_machine_init (state, eol);
        return retval;
    }

    while (TRUE)
    {
        int charwidth = 0;
        mcview_state_machine_t state_saved;
        int n;
        int color;

        state_saved = *state;
        n = mcview_next_combining_char_sequence (view, state, cs, 1 + MAX_COMBINING_CHARS, &color);
        if (n == 0)
        {
            if (linewidth != NULL)
                *linewidth = col;
            return (col > 0) ? 1 : 0;
        }

        if (view->search_start <= state->offset && state->offset < view->search_end)
            color = VIEW_SELECTED_COLOR;

        if (cs[0] == '\n')
        {
            /* New line: reset all formatting state for the next paragraph. */
            mcview_state_machine_init (state, state->offset);
            if (linewidth != NULL)
                *linewidth = col;
            return 1;
        }

        if (mcview_is_non_spacing_mark (view, cs[0]))
        {
            /* Lonely combining character. Probably leftover after too many combining chars. Just ignore. */
            continue;
        }

        /* Nonprintable, or lonely spacing mark */
        if ((!mcview_isprint (view, cs[0]) || mcview_ismark (view, cs[0])) && cs[0] != '\t')
            cs[0] = '.';

        for (i = 0; i < n; i++)
            charwidth += mcview_wcwidth (view, cs[i]);

        /* Adjust the width for TAB. It's handled below along with the normal characters,
         * so that it's wrapped consistently with them, and is painted with the proper
         * attributes (although currently it can't have a special color). */
        if (cs[0] == '\t')
        {
            charwidth = option_tab_spacing - state->unwrapped_column % option_tab_spacing;
            state->print_lonely_combining = TRUE;
        }
        else
            state->print_lonely_combining = FALSE;

        /* In wrap mode only: We're done with this row if the character sequence wouldn't fit.
         * Except if at the first column, because then it wouldn't fit in the next row either.
         * In this extreme case let the unwrapped code below do its best to display it. */
        if (view->text_wrap_mode && (off_t) col + charwidth > dpy_text_column + (off_t) width
            && col > 0)
        {
            *state = state_saved;
            if (paragraph_ended != NULL)
                *paragraph_ended = FALSE;
            if (linewidth != NULL)
                *linewidth = col;
            return 1;
        }

        /* Display, unless outside of the viewport. */
        if (row >= 0 && row < (int) height)
        {
            if ((off_t) col >= dpy_text_column &&
                (off_t) col + charwidth <= dpy_text_column + (off_t) width)
            {
                /* The combining character sequence fits entirely in the viewport. Print it. */
                tty_setcolor (color);
                widget_move (view, top + row, left + ((off_t) col - dpy_text_column));
                if (cs[0] == '\t')
                {
                    for (i = 0; i < charwidth; i++)
                        tty_print_char (' ');
                }
                else
                {
                    j = 0;
                    for (i = 0; i < n; i++)
                        j += mcview_char_display (view, cs[i], str + j);
                    str[j] = '\0';
                    /* This is probably a bug in our tty layer, but tty_print_string
                     * normalizes the string, whereas tty_printf doesn't. Don't normalize,
                     * since we handle combining characters ourselves correctly, it's
                     * better if they are copy-pasted correctly. Ticket 3255. */
                    tty_printf ("%s", str);
                }
            }
            else if ((off_t) col < dpy_text_column && (off_t) col + charwidth > dpy_text_column)
            {
                /* The combining character sequence would cross the left edge of the viewport.
                 * This cannot happen with wrap mode. Print replacement character(s),
                 * or spaces with the correct attributes for partial Tabs. */
                tty_setcolor (color);
                for (i = dpy_text_column;
                     i < (off_t) col + charwidth && i < dpy_text_column + (off_t) width; i++)
                {
                    widget_move (view, top + row, left + (i - dpy_text_column));
                    tty_print_anychar ((cs[0] == '\t') ? ' ' : PARTIAL_CJK_AT_LEFT_MARGIN);
                }
            }
            else if ((off_t) col < dpy_text_column + (off_t) width &&
                     (off_t) col + charwidth > dpy_text_column + (off_t) width)
            {
                /* The combining character sequence would cross the right edge of the viewport
                 * and we're not wrapping. Print replacement character(s),
                 * or spaces with the correct attributes for partial Tabs. */
                tty_setcolor (color);
                for (i = col; i < dpy_text_column + (off_t) width; i++)
                {
                    widget_move (view, top + row, left + (i - dpy_text_column));
                    tty_print_anychar ((cs[0] == '\t') ? ' ' : PARTIAL_CJK_AT_RIGHT_MARGIN);
                }
            }
        }

        col += charwidth;
        state->unwrapped_column += charwidth;

        if (!view->text_wrap_mode && (off_t) col >= dpy_text_column + (off_t) width
            && linewidth == NULL)
        {
            /* Optimization: Fast forward to the end of the line, rather than carefully
             * parsing and then not actually displaying it. */
            off_t eol;

            eol = mcview_eol (view, state->offset, mcview_get_filesize (view));
            mcview_state_machine_init (state, eol);
            return 1;
        }
    }
}
Exemplo n.º 28
0
gboolean
mcview_load (mcview_t * view, const char *command, const char *file, int start_line)
{
    gboolean retval = FALSE;
    vfs_path_t *vpath = NULL;

#ifdef HAVE_ASSERT_H
    assert (view->bytes_per_line != 0);
#endif

    view->filename_vpath = vfs_path_from_str (file);

    /* get working dir */
    if (file != NULL && file[0] != '\0')
    {
        vfs_path_free (view->workdir_vpath);

        if (!g_path_is_absolute (file))
        {
            vfs_path_t *p;

            p = vfs_path_clone (vfs_get_raw_current_dir ());
            view->workdir_vpath = vfs_path_append_new (p, file, (char *) NULL);
            vfs_path_free (p);
        }
        else
        {
            /* try extract path form filename */
            const char *fname;
            char *dir;

            fname = x_basename (file);
            dir = g_strndup (file, (size_t) (fname - file));
            view->workdir_vpath = vfs_path_from_str (dir);
            g_free (dir);
        }
    }

    if (!mcview_is_in_panel (view))
        view->dpy_text_column = 0;

    mcview_set_codeset (view);

    if (command != NULL && (view->magic_mode || file == NULL || file[0] == '\0'))
        retval = mcview_load_command_output (view, command);
    else if (file != NULL && file[0] != '\0')
    {
        int fd;
        char tmp[BUF_MEDIUM];
        struct stat st;

        /* Open the file */
        vpath = vfs_path_from_str (file);
        fd = mc_open (vpath, O_RDONLY | O_NONBLOCK);
        if (fd == -1)
        {
            g_snprintf (tmp, sizeof (tmp), _("Cannot open \"%s\"\n%s"),
                        file, unix_error_string (errno));
            mcview_show_error (view, tmp);
            vfs_path_free (view->filename_vpath);
            view->filename_vpath = NULL;
            vfs_path_free (view->workdir_vpath);
            view->workdir_vpath = NULL;
            goto finish;
        }

        /* Make sure we are working with a regular file */
        if (mc_fstat (fd, &st) == -1)
        {
            mc_close (fd);
            g_snprintf (tmp, sizeof (tmp), _("Cannot stat \"%s\"\n%s"),
                        file, unix_error_string (errno));
            mcview_show_error (view, tmp);
            vfs_path_free (view->filename_vpath);
            view->filename_vpath = NULL;
            vfs_path_free (view->workdir_vpath);
            view->workdir_vpath = NULL;
            goto finish;
        }

        if (!S_ISREG (st.st_mode))
        {
            mc_close (fd);
            mcview_show_error (view, _("Cannot view: not a regular file"));
            vfs_path_free (view->filename_vpath);
            view->filename_vpath = NULL;
            vfs_path_free (view->workdir_vpath);
            view->workdir_vpath = NULL;
            goto finish;
        }

        if (st.st_size == 0 || mc_lseek (fd, 0, SEEK_SET) == -1)
        {
            /* Must be one of those nice files that grow (/proc) */
            mcview_set_datasource_vfs_pipe (view, fd);
        }
        else
        {
            int type;

            type = get_compression_type (fd, file);

            if (view->magic_mode && (type != COMPRESSION_NONE))
            {
                char *tmp_filename;
                vfs_path_t *vpath1;
                int fd1;

                tmp_filename = g_strconcat (file, decompress_extension (type), (char *) NULL);
                vpath1 = vfs_path_from_str (tmp_filename);
                fd1 = mc_open (vpath1, O_RDONLY | O_NONBLOCK);
                if (fd1 == -1)
                {
                    g_snprintf (tmp, sizeof (tmp), _("Cannot open \"%s\" in parse mode\n%s"),
                                file, unix_error_string (errno));
                    mcview_show_error (view, tmp);
                }
                else
                {
                    mc_close (fd);
                    fd = fd1;
                    mc_fstat (fd, &st);
                }
                vfs_path_free (vpath1);

                g_free (tmp_filename);
            }
            mcview_set_datasource_file (view, fd, &st);
        }
        retval = TRUE;
    }

  finish:
    view->command = g_strdup (command);
    view->dpy_start = 0;
    view->search_start = 0;
    view->search_end = 0;
    view->dpy_text_column = 0;

    mcview_compute_areas (view);
    mcview_update_bytes_per_line (view);

    if (mcview_remember_file_position && view->filename_vpath != NULL && start_line == 0)
    {
        long line, col;
        off_t new_offset, max_offset;

        load_file_position (view->filename_vpath, &line, &col, &new_offset, &view->saved_bookmarks);
        max_offset = mcview_get_filesize (view) - 1;
        if (max_offset < 0)
            new_offset = 0;
        else
            new_offset = min (new_offset, max_offset);
        if (!view->hex_mode)
            view->dpy_start = mcview_bol (view, new_offset, 0);
        else
        {
            view->dpy_start = new_offset - new_offset % view->bytes_per_line;
            view->hex_cursor = new_offset;
        }
    }
    else if (start_line > 0)
        mcview_moveto (view, start_line - 1, 0);

    view->hexedit_lownibble = FALSE;
    view->hexview_in_text = FALSE;
    view->change_list = NULL;
    vfs_path_free (vpath);
    return retval;
}