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); }
void mcview_scroll_to_cursor (mcview_t * view) { if (view->hex_mode) { const off_t bytes = view->bytes_per_line; const off_t displaysize = view->data_area.height * bytes; const off_t cursor = view->hex_cursor; off_t topleft = view->dpy_start; if (topleft + displaysize <= cursor) topleft = mcview_offset_rounddown (cursor, bytes) - (displaysize - bytes); if (cursor < topleft) topleft = mcview_offset_rounddown (cursor, bytes); view->dpy_start = topleft; } }
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); }
static void mcview_scroll_to_cursor (WView * view) { if (view->mode_flags.hex) { off_t bytes = view->bytes_per_line; off_t cursor = view->hex_cursor; off_t topleft = view->dpy_start; off_t displaysize; displaysize = view->data_area.height * bytes; if (topleft + displaysize <= cursor) topleft = mcview_offset_rounddown (cursor, bytes) - (displaysize - bytes); if (cursor < topleft) topleft = mcview_offset_rounddown (cursor, bytes); view->dpy_start = topleft; view->dpy_paragraph_skip_lines = 0; view->dpy_wrap_dirty = TRUE; } }
/*static */ void mcview_file_load_data (mcview_t * view, off_t byte_index) { off_t blockoffset; ssize_t res; size_t bytes_read; #ifdef HAVE_ASSERT_H assert (view->datasource == DS_FILE); #endif if (mcview_already_loaded (view->ds_file_offset, byte_index, view->ds_file_datalen)) return; if (byte_index >= view->ds_file_filesize) return; blockoffset = mcview_offset_rounddown (byte_index, view->ds_file_datasize); if (mc_lseek (view->ds_file_fd, blockoffset, SEEK_SET) == -1) goto error; bytes_read = 0; while (bytes_read < view->ds_file_datasize) { res = mc_read (view->ds_file_fd, view->ds_file_data + bytes_read, view->ds_file_datasize - bytes_read); if (res == -1) goto error; if (res == 0) break; bytes_read += (size_t) res; } view->ds_file_offset = blockoffset; if ((off_t) bytes_read > view->ds_file_filesize - view->ds_file_offset) { /* the file has grown in the meantime -- stick to the old size */ view->ds_file_datalen = view->ds_file_filesize - view->ds_file_offset; } else { view->ds_file_datalen = bytes_read; } return; error: view->ds_file_datalen = 0; }
void mcview_toggle_hex_mode (mcview_t * view) { view->hex_mode = !view->hex_mode; if (view->hex_mode) { view->hex_cursor = view->dpy_start; view->dpy_start = mcview_offset_rounddown (view->dpy_start, view->bytes_per_line); widget_want_cursor (WIDGET (view), TRUE); } else { view->dpy_start = mcview_bol (view, view->hex_cursor, 0); view->hex_cursor = view->dpy_start; widget_want_cursor (WIDGET (view), FALSE); } mcview_altered_hex_mode = 1; view->dpy_bbar_dirty = TRUE; view->dirty++; }
void mcview_ccache_lookup (mcview_t * view, coord_cache_entry_t * coord, enum ccache_type lookup_what) { size_t i; coord_cache_t *cache; coord_cache_entry_t current, next, entry; enum ccache_type sorter; off_t limit; cmp_func_t cmp_func; enum { NROFF_START, NROFF_BACKSPACE, NROFF_CONTINUATION } nroff_state; if (view->coord_cache == NULL) view->coord_cache = coord_cache_new (); cache = view->coord_cache; if (cache->size == 0) { current.cc_offset = 0; current.cc_line = 0; current.cc_column = 0; current.cc_nroff_column = 0; mcview_ccache_add_entry (cache, 0, ¤t); } sorter = (lookup_what == CCACHE_OFFSET) ? CCACHE_LINECOL : CCACHE_OFFSET; if (sorter == CCACHE_OFFSET) cmp_func = mcview_coord_cache_entry_less_offset; else if (view->text_nroff_mode) cmp_func = mcview_coord_cache_entry_less_nroff; else cmp_func = mcview_coord_cache_entry_less_plain; tty_enable_interrupt_key (); retry: /* find the two neighbor entries in the cache */ i = mcview_ccache_find (view, coord, cmp_func); /* now i points to the lower neighbor in the cache */ current = *cache->cache[i]; if (i + 1 < view->coord_cache->size) limit = cache->cache[i + 1]->cc_offset; else limit = current.cc_offset + VIEW_COORD_CACHE_GRANUL; entry = current; nroff_state = NROFF_START; for (; current.cc_offset < limit; current = next) { int c, nextc; if (!mcview_get_byte (view, current.cc_offset, &c)) break; if (!cmp_func (¤t, coord)) { if (lookup_what == CCACHE_OFFSET && view->text_nroff_mode && nroff_state != NROFF_START) { /* don't break here */ } else { break; } } /* Provide useful default values for ''next'' */ next.cc_offset = current.cc_offset + 1; next.cc_line = current.cc_line; next.cc_column = current.cc_column + 1; next.cc_nroff_column = current.cc_nroff_column + 1; /* and override some of them as necessary. */ if (c == '\r') { mcview_get_byte_indexed (view, current.cc_offset, 1, &nextc); /* Ignore '\r' if it is followed by '\r' or '\n'. If it is * followed by anything else, it is a Mac line ending and * produces a line break. */ if (nextc == '\r' || nextc == '\n') { next.cc_column = current.cc_column; next.cc_nroff_column = current.cc_nroff_column; } else { next.cc_line = current.cc_line + 1; next.cc_column = 0; next.cc_nroff_column = 0; } } else if (nroff_state == NROFF_BACKSPACE) { next.cc_nroff_column = current.cc_nroff_column - 1; } else if (c == '\t') { next.cc_column = mcview_offset_rounddown (current.cc_column, 8) + 8; next.cc_nroff_column = mcview_offset_rounddown (current.cc_nroff_column, 8) + 8; } else if (c == '\n') { next.cc_line = current.cc_line + 1; next.cc_column = 0; next.cc_nroff_column = 0; } else { /* Use all default values from above */ } switch (nroff_state) { case NROFF_START: case NROFF_CONTINUATION: nroff_state = mcview_is_nroff_sequence (view, current.cc_offset) ? NROFF_BACKSPACE : NROFF_START; break; case NROFF_BACKSPACE: nroff_state = NROFF_CONTINUATION; break; } /* Cache entries must guarantee that for each i < j, * line[i] <= line[j] and column[i] < column[j]. In the case of * nroff sequences and '\r' characters, this is not guaranteed, * so we cannot save them. */ if (nroff_state == NROFF_START && c != '\r') entry = next; } if (i + 1 == cache->size && entry.cc_offset != cache->cache[i]->cc_offset) { mcview_ccache_add_entry (cache, cache->size, &entry); if (!tty_got_interrupt ()) goto retry; } tty_disable_interrupt_key (); if (lookup_what == CCACHE_OFFSET) { coord->cc_offset = current.cc_offset; } else { coord->cc_line = current.cc_line; coord->cc_column = current.cc_column; coord->cc_nroff_column = current.cc_nroff_column; } }