mirror of
https://github.com/MidnightCommander/mc
synced 2024-12-22 20:36:50 +03:00
Merge branch '3250_mcviewer'
* 3250_mcviewer: Tickets #3250, #3256: rewrite mcview's rendering and scrolling
This commit is contained in:
commit
6b5ba76c6a
1
AUTHORS
1
AUTHORS
@ -64,6 +64,7 @@ Egmont Koblinger <egmont@gmail.com>
|
|||||||
Support of extended mouse clicks beyond 223 column
|
Support of extended mouse clicks beyond 223 column
|
||||||
Support of bracketed paste mode of xterm
|
Support of bracketed paste mode of xterm
|
||||||
(http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Bracketed%20Paste%20Mode)
|
(http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Bracketed%20Paste%20Mode)
|
||||||
|
Rewritten viewer
|
||||||
|
|
||||||
Erwin van Eijk <wabbit@corner.iaf.nl>
|
Erwin van Eijk <wabbit@corner.iaf.nl>
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ noinst_LTLIBRARIES = libmcviewer.la
|
|||||||
|
|
||||||
libmcviewer_la_SOURCES = \
|
libmcviewer_la_SOURCES = \
|
||||||
actions_cmd.c \
|
actions_cmd.c \
|
||||||
|
ascii.c \
|
||||||
coord_cache.c \
|
coord_cache.c \
|
||||||
datasource.c \
|
datasource.c \
|
||||||
dialogs.c \
|
dialogs.c \
|
||||||
@ -16,7 +17,6 @@ libmcviewer_la_SOURCES = \
|
|||||||
mcviewer.h \
|
mcviewer.h \
|
||||||
move.c \
|
move.c \
|
||||||
nroff.c \
|
nroff.c \
|
||||||
plain.c \
|
|
||||||
search.c
|
search.c
|
||||||
|
|
||||||
AM_CPPFLAGS = -I$(top_srcdir) $(GLIB_CFLAGS) $(PCRE_CPPFLAGS)
|
AM_CPPFLAGS = -I$(top_srcdir) $(GLIB_CFLAGS) $(PCRE_CPPFLAGS)
|
||||||
|
@ -510,6 +510,8 @@ mcview_execute_cmd (mcview_t * view, unsigned long command)
|
|||||||
break;
|
break;
|
||||||
case CK_Bookmark:
|
case CK_Bookmark:
|
||||||
view->dpy_start = view->marks[view->marker];
|
view->dpy_start = view->marks[view->marker];
|
||||||
|
view->dpy_paragraph_skip_lines = 0; /* TODO: remember this value in the marker? */
|
||||||
|
view->dpy_wrap_dirty = TRUE;
|
||||||
view->dirty++;
|
view->dirty++;
|
||||||
break;
|
break;
|
||||||
#ifdef HAVE_CHARSET
|
#ifdef HAVE_CHARSET
|
||||||
@ -592,6 +594,7 @@ mcview_adjust_size (WDialog * h)
|
|||||||
widget_set_size (WIDGET (view), 0, 0, LINES - 1, COLS);
|
widget_set_size (WIDGET (view), 0, 0, LINES - 1, COLS);
|
||||||
widget_set_size (WIDGET (b), LINES - 1, 0, 1, COLS);
|
widget_set_size (WIDGET (b), LINES - 1, 0, 1, COLS);
|
||||||
|
|
||||||
|
view->dpy_wrap_dirty = TRUE;
|
||||||
mcview_compute_areas (view);
|
mcview_compute_areas (view);
|
||||||
mcview_update_bytes_per_line (view);
|
mcview_update_bytes_per_line (view);
|
||||||
}
|
}
|
||||||
|
1038
src/viewer/ascii.c
Normal file
1038
src/viewer/ascii.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -152,7 +152,7 @@ mcview_get_ptr_file (mcview_t * view, off_t byte_index)
|
|||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
int
|
int
|
||||||
mcview_get_utf (mcview_t * view, off_t byte_index, int *char_width, gboolean * result)
|
mcview_get_utf (mcview_t * view, off_t byte_index, int *bytes_consumed, gboolean * result)
|
||||||
{
|
{
|
||||||
gchar *str = NULL;
|
gchar *str = NULL;
|
||||||
int res = -1;
|
int res = -1;
|
||||||
@ -160,7 +160,7 @@ mcview_get_utf (mcview_t * view, off_t byte_index, int *char_width, gboolean * r
|
|||||||
gchar *next_ch = NULL;
|
gchar *next_ch = NULL;
|
||||||
gchar utf8buf[UTF8_CHAR_LEN + 1];
|
gchar utf8buf[UTF8_CHAR_LEN + 1];
|
||||||
|
|
||||||
*char_width = 0;
|
*bytes_consumed = 0;
|
||||||
*result = FALSE;
|
*result = FALSE;
|
||||||
|
|
||||||
switch (view->datasource)
|
switch (view->datasource)
|
||||||
@ -206,7 +206,7 @@ mcview_get_utf (mcview_t * view, off_t byte_index, int *char_width, gboolean * r
|
|||||||
if (res < 0)
|
if (res < 0)
|
||||||
{
|
{
|
||||||
ch = *str;
|
ch = *str;
|
||||||
*char_width = 1;
|
*bytes_consumed = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -214,7 +214,7 @@ mcview_get_utf (mcview_t * view, off_t byte_index, int *char_width, gboolean * r
|
|||||||
/* Calculate UTF-8 char width */
|
/* Calculate UTF-8 char width */
|
||||||
next_ch = g_utf8_next_char (str);
|
next_ch = g_utf8_next_char (str);
|
||||||
if (next_ch)
|
if (next_ch)
|
||||||
*char_width = next_ch - str;
|
*bytes_consumed = next_ch - str;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -251,10 +251,6 @@ mcview_display (mcview_t * view)
|
|||||||
{
|
{
|
||||||
mcview_display_hex (view);
|
mcview_display_hex (view);
|
||||||
}
|
}
|
||||||
else if (view->text_nroff_mode)
|
|
||||||
{
|
|
||||||
mcview_display_nroff (view);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mcview_display_text (view);
|
mcview_display_text (view);
|
||||||
|
@ -87,6 +87,18 @@ typedef struct
|
|||||||
coord_cache_entry_t **cache;
|
coord_cache_entry_t **cache;
|
||||||
} coord_cache_t;
|
} coord_cache_t;
|
||||||
|
|
||||||
|
/* TODO: find a better name. This is not actually a "state machine",
|
||||||
|
* but a "state machine's state", but that sounds silly.
|
||||||
|
* Could be parser_state, formatter_state... */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
off_t offset; /* The file offset at which this is the state. */
|
||||||
|
off_t unwrapped_column; /* Columns if the paragraph wasn't wrapped, */
|
||||||
|
/* used for positioning TABs in wrapped lines */
|
||||||
|
gboolean nroff_underscore_is_underlined; /* whether _\b_ is underlined rather than bold */
|
||||||
|
gboolean print_lonely_combining; /* whether lonely combining marks are printed on a dotted circle */
|
||||||
|
} mcview_state_machine_t;
|
||||||
|
|
||||||
struct mcview_nroff_struct;
|
struct mcview_nroff_struct;
|
||||||
|
|
||||||
struct mcview_struct
|
struct mcview_struct
|
||||||
@ -144,8 +156,12 @@ struct mcview_struct
|
|||||||
/* Display information */
|
/* Display information */
|
||||||
gboolean active; /* Active or not in QuickView mode */
|
gboolean active; /* Active or not in QuickView mode */
|
||||||
screen_dimen dpy_frame_size; /* Size of the frame surrounding the real viewer */
|
screen_dimen dpy_frame_size; /* Size of the frame surrounding the real viewer */
|
||||||
off_t dpy_start; /* Offset of the displayed data */
|
off_t dpy_start; /* Offset of the displayed data (start of the paragraph in non-hex mode) */
|
||||||
off_t dpy_end; /* Offset after the displayed data */
|
off_t dpy_end; /* Offset after the displayed data */
|
||||||
|
off_t dpy_paragraph_skip_lines; /* Extra lines to skip in wrap mode */
|
||||||
|
mcview_state_machine_t dpy_state_top; /* Parser-formatter state at the topmost visible line in wrap mode */
|
||||||
|
mcview_state_machine_t dpy_state_bottom; /* Parser-formatter state after the bottomvisible line in wrap mode */
|
||||||
|
gboolean dpy_wrap_dirty; /* dpy_state_top needs to be recomputed */
|
||||||
off_t dpy_text_column; /* Number of skipped columns in non-wrap
|
off_t dpy_text_column; /* Number of skipped columns in non-wrap
|
||||||
* text mode */
|
* text mode */
|
||||||
off_t hex_cursor; /* Hexview cursor position in file */
|
off_t hex_cursor; /* Hexview cursor position in file */
|
||||||
@ -156,6 +172,8 @@ struct mcview_struct
|
|||||||
struct area ruler_area; /* Where the ruler is displayed */
|
struct area ruler_area; /* Where the ruler is displayed */
|
||||||
struct area data_area; /* Where the data is displayed */
|
struct area data_area; /* Where the data is displayed */
|
||||||
|
|
||||||
|
ssize_t force_max; /* Force a max offset, or -1 */
|
||||||
|
|
||||||
int dirty; /* Number of skipped updates */
|
int dirty; /* Number of skipped updates */
|
||||||
gboolean dpy_bbar_dirty; /* Does the button bar need to be updated? */
|
gboolean dpy_bbar_dirty; /* Does the button bar need to be updated? */
|
||||||
|
|
||||||
@ -223,6 +241,14 @@ cb_ret_t mcview_callback (Widget * w, Widget * sender, widget_msg_t msg, int par
|
|||||||
cb_ret_t mcview_dialog_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm,
|
cb_ret_t mcview_dialog_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm,
|
||||||
void *data);
|
void *data);
|
||||||
|
|
||||||
|
/* ascii.c: */
|
||||||
|
void mcview_display_text (mcview_t *);
|
||||||
|
void mcview_state_machine_init (mcview_state_machine_t *, off_t);
|
||||||
|
void mcview_ascii_move_down (mcview_t *, off_t);
|
||||||
|
void mcview_ascii_move_up (mcview_t *, off_t);
|
||||||
|
void mcview_ascii_moveto_bol (mcview_t *);
|
||||||
|
void mcview_ascii_moveto_eol (mcview_t *);
|
||||||
|
|
||||||
/* coord_cache.c: */
|
/* coord_cache.c: */
|
||||||
coord_cache_t *coord_cache_new (void);
|
coord_cache_t *coord_cache_new (void);
|
||||||
void coord_cache_free (coord_cache_t * cache);
|
void coord_cache_free (coord_cache_t * cache);
|
||||||
@ -312,9 +338,7 @@ void mcview_place_cursor (mcview_t *);
|
|||||||
void mcview_moveto_match (mcview_t *);
|
void mcview_moveto_match (mcview_t *);
|
||||||
|
|
||||||
/* nroff.c: */
|
/* nroff.c: */
|
||||||
void mcview_display_nroff (mcview_t * view);
|
|
||||||
int mcview__get_nroff_real_len (mcview_t * view, off_t, off_t p);
|
int mcview__get_nroff_real_len (mcview_t * view, off_t, off_t p);
|
||||||
|
|
||||||
mcview_nroff_t *mcview_nroff_seq_new_num (mcview_t * view, off_t p);
|
mcview_nroff_t *mcview_nroff_seq_new_num (mcview_t * view, off_t p);
|
||||||
mcview_nroff_t *mcview_nroff_seq_new (mcview_t * view);
|
mcview_nroff_t *mcview_nroff_seq_new (mcview_t * view);
|
||||||
void mcview_nroff_seq_free (mcview_nroff_t **);
|
void mcview_nroff_seq_free (mcview_nroff_t **);
|
||||||
@ -322,10 +346,6 @@ nroff_type_t mcview_nroff_seq_info (mcview_nroff_t *);
|
|||||||
int mcview_nroff_seq_next (mcview_nroff_t *);
|
int mcview_nroff_seq_next (mcview_nroff_t *);
|
||||||
int mcview_nroff_seq_prev (mcview_nroff_t *);
|
int mcview_nroff_seq_prev (mcview_nroff_t *);
|
||||||
|
|
||||||
|
|
||||||
/* plain.c: */
|
|
||||||
void mcview_display_text (mcview_t *);
|
|
||||||
|
|
||||||
/* search.c: */
|
/* search.c: */
|
||||||
mc_search_cbret_t mcview_search_cmd_callback (const void *user_data, gsize char_offset,
|
mc_search_cbret_t mcview_search_cmd_callback (const void *user_data, gsize char_offset,
|
||||||
int *current_char);
|
int *current_char);
|
||||||
|
@ -106,9 +106,8 @@ mcview_toggle_magic_mode (mcview_t * view)
|
|||||||
void
|
void
|
||||||
mcview_toggle_wrap_mode (mcview_t * view)
|
mcview_toggle_wrap_mode (mcview_t * view)
|
||||||
{
|
{
|
||||||
if (view->text_wrap_mode)
|
|
||||||
view->dpy_start = mcview_bol (view, view->dpy_start, 0);
|
|
||||||
view->text_wrap_mode = !view->text_wrap_mode;
|
view->text_wrap_mode = !view->text_wrap_mode;
|
||||||
|
view->dpy_wrap_dirty = TRUE;
|
||||||
view->dpy_bbar_dirty = TRUE;
|
view->dpy_bbar_dirty = TRUE;
|
||||||
view->dirty++;
|
view->dirty++;
|
||||||
}
|
}
|
||||||
@ -120,6 +119,7 @@ mcview_toggle_nroff_mode (mcview_t * view)
|
|||||||
{
|
{
|
||||||
view->text_nroff_mode = !view->text_nroff_mode;
|
view->text_nroff_mode = !view->text_nroff_mode;
|
||||||
mcview_altered_nroff_flag = 1;
|
mcview_altered_nroff_flag = 1;
|
||||||
|
view->dpy_wrap_dirty = TRUE;
|
||||||
view->dpy_bbar_dirty = TRUE;
|
view->dpy_bbar_dirty = TRUE;
|
||||||
view->dirty++;
|
view->dirty++;
|
||||||
}
|
}
|
||||||
@ -144,6 +144,8 @@ mcview_toggle_hex_mode (mcview_t * view)
|
|||||||
widget_want_cursor (WIDGET (view), FALSE);
|
widget_want_cursor (WIDGET (view), FALSE);
|
||||||
}
|
}
|
||||||
mcview_altered_hex_mode = 1;
|
mcview_altered_hex_mode = 1;
|
||||||
|
view->dpy_paragraph_skip_lines = 0;
|
||||||
|
view->dpy_wrap_dirty = TRUE;
|
||||||
view->dpy_bbar_dirty = TRUE;
|
view->dpy_bbar_dirty = TRUE;
|
||||||
view->dirty++;
|
view->dirty++;
|
||||||
}
|
}
|
||||||
@ -170,6 +172,10 @@ mcview_init (mcview_t * view)
|
|||||||
view->coord_cache = NULL;
|
view->coord_cache = NULL;
|
||||||
|
|
||||||
view->dpy_start = 0;
|
view->dpy_start = 0;
|
||||||
|
view->dpy_paragraph_skip_lines = 0;
|
||||||
|
mcview_state_machine_init (&view->dpy_state_top, 0);
|
||||||
|
view->dpy_wrap_dirty = FALSE;
|
||||||
|
view->force_max = -1;
|
||||||
view->dpy_text_column = 0;
|
view->dpy_text_column = 0;
|
||||||
view->dpy_end = 0;
|
view->dpy_end = 0;
|
||||||
view->hex_cursor = 0;
|
view->hex_cursor = 0;
|
||||||
@ -281,6 +287,7 @@ mcview_set_codeset (mcview_t * view)
|
|||||||
view->converter = conv;
|
view->converter = conv;
|
||||||
}
|
}
|
||||||
view->utf8 = (gboolean) str_isutf8 (cp_id);
|
view->utf8 = (gboolean) str_isutf8 (cp_id);
|
||||||
|
view->dpy_wrap_dirty = TRUE;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
(void) view;
|
(void) view;
|
||||||
@ -333,7 +340,7 @@ mcview_bol (mcview_t * view, off_t current, off_t limit)
|
|||||||
if (c == '\r')
|
if (c == '\r')
|
||||||
current--;
|
current--;
|
||||||
}
|
}
|
||||||
while (current > 0 && current >= limit)
|
while (current > 0 && current > limit)
|
||||||
{
|
{
|
||||||
if (!mcview_get_byte (view, current - 1, &c))
|
if (!mcview_get_byte (view, current - 1, &c))
|
||||||
break;
|
break;
|
||||||
|
@ -406,6 +406,10 @@ mcview_load (mcview_t * view, const char *command, const char *file, int start_l
|
|||||||
finish:
|
finish:
|
||||||
view->command = g_strdup (command);
|
view->command = g_strdup (command);
|
||||||
view->dpy_start = 0;
|
view->dpy_start = 0;
|
||||||
|
view->dpy_paragraph_skip_lines = 0;
|
||||||
|
mcview_state_machine_init (&view->dpy_state_top, 0);
|
||||||
|
view->dpy_wrap_dirty = FALSE;
|
||||||
|
view->force_max = -1;
|
||||||
view->search_start = 0;
|
view->search_start = 0;
|
||||||
view->search_end = 0;
|
view->search_end = 0;
|
||||||
view->dpy_text_column = 0;
|
view->dpy_text_column = 0;
|
||||||
@ -425,7 +429,10 @@ mcview_load (mcview_t * view, const char *command, const char *file, int start_l
|
|||||||
else
|
else
|
||||||
new_offset = min (new_offset, max_offset);
|
new_offset = min (new_offset, max_offset);
|
||||||
if (!view->hex_mode)
|
if (!view->hex_mode)
|
||||||
|
{
|
||||||
view->dpy_start = mcview_bol (view, new_offset, 0);
|
view->dpy_start = mcview_bol (view, new_offset, 0);
|
||||||
|
view->dpy_wrap_dirty = TRUE;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
view->dpy_start = new_offset - new_offset % view->bytes_per_line;
|
view->dpy_start = new_offset - new_offset % view->bytes_per_line;
|
||||||
|
@ -83,6 +83,8 @@ mcview_scroll_to_cursor (mcview_t * view)
|
|||||||
if (cursor < topleft)
|
if (cursor < topleft)
|
||||||
topleft = mcview_offset_rounddown (cursor, bytes);
|
topleft = mcview_offset_rounddown (cursor, bytes);
|
||||||
view->dpy_start = topleft;
|
view->dpy_start = topleft;
|
||||||
|
view->dpy_paragraph_skip_lines = 0;
|
||||||
|
view->dpy_wrap_dirty = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,8 +109,6 @@ mcview_movement_fixups (mcview_t * view, gboolean reset_search)
|
|||||||
void
|
void
|
||||||
mcview_move_up (mcview_t * view, off_t lines)
|
mcview_move_up (mcview_t * view, off_t lines)
|
||||||
{
|
{
|
||||||
off_t new_offset;
|
|
||||||
|
|
||||||
if (view->hex_mode)
|
if (view->hex_mode)
|
||||||
{
|
{
|
||||||
off_t bytes = lines * view->bytes_per_line;
|
off_t bytes = lines * view->bytes_per_line;
|
||||||
@ -116,7 +116,11 @@ mcview_move_up (mcview_t * view, off_t lines)
|
|||||||
{
|
{
|
||||||
view->hex_cursor -= bytes;
|
view->hex_cursor -= bytes;
|
||||||
if (view->hex_cursor < view->dpy_start)
|
if (view->hex_cursor < view->dpy_start)
|
||||||
|
{
|
||||||
view->dpy_start = mcview_offset_doz (view->dpy_start, bytes);
|
view->dpy_start = mcview_offset_doz (view->dpy_start, bytes);
|
||||||
|
view->dpy_paragraph_skip_lines = 0;
|
||||||
|
view->dpy_wrap_dirty = TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -125,46 +129,7 @@ mcview_move_up (mcview_t * view, off_t lines)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
off_t i;
|
mcview_ascii_move_up (view, lines);
|
||||||
|
|
||||||
for (i = 0; i < lines; i++)
|
|
||||||
{
|
|
||||||
if (view->dpy_start == 0)
|
|
||||||
break;
|
|
||||||
if (view->text_wrap_mode)
|
|
||||||
{
|
|
||||||
new_offset = mcview_bol (view, view->dpy_start, view->dpy_start - (off_t) 1);
|
|
||||||
/* check if dpy_start == BOL or not (then new_offset = dpy_start - 1,
|
|
||||||
* no need to check more) */
|
|
||||||
if (new_offset == view->dpy_start)
|
|
||||||
{
|
|
||||||
size_t last_row_length;
|
|
||||||
|
|
||||||
new_offset = mcview_bol (view, new_offset - 1, 0);
|
|
||||||
last_row_length = (view->dpy_start - new_offset) % view->data_area.width;
|
|
||||||
if (last_row_length != 0)
|
|
||||||
{
|
|
||||||
/* if dpy_start == BOL in wrapped mode, find BOL of previous line
|
|
||||||
* and move down all but the last rows */
|
|
||||||
new_offset = view->dpy_start - (off_t) last_row_length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* if dpy_start != BOL in wrapped mode, just move one row up;
|
|
||||||
* no need to check if > 0 as there is at least exactly one wrap
|
|
||||||
* between dpy_start and BOL */
|
|
||||||
new_offset = view->dpy_start - (off_t) view->data_area.width;
|
|
||||||
}
|
|
||||||
view->dpy_start = new_offset;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* if unwrapped -> current BOL equals dpy_start, just find BOL of previous line */
|
|
||||||
new_offset = view->dpy_start - 1;
|
|
||||||
view->dpy_start = mcview_bol (view, new_offset, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
mcview_movement_fixups (view, TRUE);
|
mcview_movement_fixups (view, TRUE);
|
||||||
}
|
}
|
||||||
@ -186,51 +151,16 @@ mcview_move_down (mcview_t * view, off_t lines)
|
|||||||
{
|
{
|
||||||
view->hex_cursor += view->bytes_per_line;
|
view->hex_cursor += view->bytes_per_line;
|
||||||
if (lines != 1)
|
if (lines != 1)
|
||||||
|
{
|
||||||
view->dpy_start += view->bytes_per_line;
|
view->dpy_start += view->bytes_per_line;
|
||||||
|
view->dpy_paragraph_skip_lines = 0;
|
||||||
|
view->dpy_wrap_dirty = TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
off_t new_offset = 0;
|
mcview_ascii_move_down (view, lines);
|
||||||
|
|
||||||
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);
|
mcview_movement_fixups (view, TRUE);
|
||||||
}
|
}
|
||||||
@ -255,9 +185,8 @@ mcview_move_left (mcview_t * view, off_t columns)
|
|||||||
if (old_cursor > 0 || view->hexedit_lownibble)
|
if (old_cursor > 0 || view->hexedit_lownibble)
|
||||||
view->hexedit_lownibble = !view->hexedit_lownibble;
|
view->hexedit_lownibble = !view->hexedit_lownibble;
|
||||||
}
|
}
|
||||||
else
|
else if (!view->text_wrap_mode)
|
||||||
view->dpy_text_column = mcview_offset_doz (view->dpy_text_column, columns);
|
view->dpy_text_column = mcview_offset_doz (view->dpy_text_column, columns);
|
||||||
|
|
||||||
mcview_movement_fixups (view, FALSE);
|
mcview_movement_fixups (view, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,7 +213,7 @@ mcview_move_right (mcview_t * view, off_t columns)
|
|||||||
if (old_cursor < last_byte || !view->hexedit_lownibble)
|
if (old_cursor < last_byte || !view->hexedit_lownibble)
|
||||||
view->hexedit_lownibble = !view->hexedit_lownibble;
|
view->hexedit_lownibble = !view->hexedit_lownibble;
|
||||||
}
|
}
|
||||||
else
|
else if (!view->text_wrap_mode)
|
||||||
{
|
{
|
||||||
view->dpy_text_column += columns;
|
view->dpy_text_column += columns;
|
||||||
}
|
}
|
||||||
@ -297,6 +226,8 @@ void
|
|||||||
mcview_moveto_top (mcview_t * view)
|
mcview_moveto_top (mcview_t * view)
|
||||||
{
|
{
|
||||||
view->dpy_start = 0;
|
view->dpy_start = 0;
|
||||||
|
view->dpy_paragraph_skip_lines = 0;
|
||||||
|
mcview_state_machine_init (&view->dpy_state_top, 0);
|
||||||
view->hex_cursor = 0;
|
view->hex_cursor = 0;
|
||||||
view->dpy_text_column = 0;
|
view->dpy_text_column = 0;
|
||||||
mcview_movement_fixups (view, TRUE);
|
mcview_movement_fixups (view, TRUE);
|
||||||
@ -326,6 +257,8 @@ mcview_moveto_bottom (mcview_t * view)
|
|||||||
const off_t datalines = view->data_area.height;
|
const off_t datalines = view->data_area.height;
|
||||||
|
|
||||||
view->dpy_start = filesize;
|
view->dpy_start = filesize;
|
||||||
|
view->dpy_paragraph_skip_lines = 0;
|
||||||
|
view->dpy_wrap_dirty = TRUE;
|
||||||
mcview_move_up (view, datalines);
|
mcview_move_up (view, datalines);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -338,12 +271,12 @@ mcview_moveto_bol (mcview_t * view)
|
|||||||
if (view->hex_mode)
|
if (view->hex_mode)
|
||||||
{
|
{
|
||||||
view->hex_cursor -= view->hex_cursor % view->bytes_per_line;
|
view->hex_cursor -= view->hex_cursor % view->bytes_per_line;
|
||||||
|
view->dpy_text_column = 0;
|
||||||
}
|
}
|
||||||
else if (!view->text_wrap_mode)
|
else
|
||||||
{
|
{
|
||||||
view->dpy_start = mcview_bol (view, view->dpy_start, 0);
|
mcview_ascii_moveto_bol (view);
|
||||||
}
|
}
|
||||||
view->dpy_text_column = 0;
|
|
||||||
mcview_movement_fixups (view, TRUE);
|
mcview_movement_fixups (view, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -370,43 +303,7 @@ mcview_moveto_eol (mcview_t * view)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
off_t eol;
|
mcview_ascii_moveto_eol (view);
|
||||||
|
|
||||||
bol = mcview_bol (view, view->dpy_start, 0);
|
|
||||||
eol = mcview_eol (view, view->dpy_start, mcview_get_filesize (view));
|
|
||||||
|
|
||||||
#ifdef HAVE_CHARSET
|
|
||||||
if (view->utf8)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif /* HAVE_CHARSET */
|
|
||||||
if (eol > bol)
|
|
||||||
view->dpy_text_column = eol - bol;
|
|
||||||
|
|
||||||
view->dpy_text_column =
|
|
||||||
mcview_offset_doz (view->dpy_text_column, (off_t) view->data_area.width);
|
|
||||||
}
|
}
|
||||||
mcview_movement_fixups (view, FALSE);
|
mcview_movement_fixups (view, FALSE);
|
||||||
}
|
}
|
||||||
@ -420,10 +317,14 @@ mcview_moveto_offset (mcview_t * view, off_t offset)
|
|||||||
{
|
{
|
||||||
view->hex_cursor = offset;
|
view->hex_cursor = offset;
|
||||||
view->dpy_start = offset - offset % view->bytes_per_line;
|
view->dpy_start = offset - offset % view->bytes_per_line;
|
||||||
|
view->dpy_paragraph_skip_lines = 0;
|
||||||
|
view->dpy_wrap_dirty = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
view->dpy_start = offset;
|
view->dpy_start = offset;
|
||||||
|
view->dpy_paragraph_skip_lines = 0;
|
||||||
|
view->dpy_wrap_dirty = TRUE;
|
||||||
}
|
}
|
||||||
mcview_movement_fixups (view, TRUE);
|
mcview_movement_fixups (view, TRUE);
|
||||||
}
|
}
|
||||||
@ -494,9 +395,15 @@ mcview_moveto_match (mcview_t * view)
|
|||||||
view->hexedit_lownibble = FALSE;
|
view->hexedit_lownibble = FALSE;
|
||||||
view->dpy_start = view->search_start - view->search_start % view->bytes_per_line;
|
view->dpy_start = view->search_start - view->search_start % view->bytes_per_line;
|
||||||
view->dpy_end = view->search_end - view->search_end % view->bytes_per_line;
|
view->dpy_end = view->search_end - view->search_end % view->bytes_per_line;
|
||||||
|
view->dpy_paragraph_skip_lines = 0;
|
||||||
|
view->dpy_wrap_dirty = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
view->dpy_start = mcview_bol (view, view->search_start, 0);
|
view->dpy_start = mcview_bol (view, view->search_start, 0);
|
||||||
|
view->dpy_paragraph_skip_lines = 0;
|
||||||
|
view->dpy_wrap_dirty = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
mcview_scroll_to_cursor (view);
|
mcview_scroll_to_cursor (view);
|
||||||
view->dirty++;
|
view->dirty++;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Internal file viewer for the Midnight Commander
|
Internal file viewer for the Midnight Commander
|
||||||
Function for nroff-like view
|
Functions for searching in nroff-like view
|
||||||
|
|
||||||
Copyright (C) 1994-2014
|
Copyright (C) 1994-2014
|
||||||
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
||||||
@ -91,162 +91,6 @@ mcview_nroff_get_char (mcview_nroff_t * nroff, int *ret_val, off_t nroff_index)
|
|||||||
/*** public functions ****************************************************************************/
|
/*** public functions ****************************************************************************/
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
void
|
|
||||||
mcview_display_nroff (mcview_t * view)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
screen_dimen row, col;
|
|
||||||
off_t from;
|
|
||||||
int cw = 1;
|
|
||||||
int c;
|
|
||||||
int c_prev = 0;
|
|
||||||
int c_next = 0;
|
|
||||||
|
|
||||||
mcview_display_clean (view);
|
|
||||||
mcview_display_ruler (view);
|
|
||||||
|
|
||||||
/* Find the first displayable changed byte */
|
|
||||||
from = view->dpy_start;
|
|
||||||
|
|
||||||
tty_setcolor (VIEW_NORMAL_COLOR);
|
|
||||||
for (row = 0, col = 0; row < height;)
|
|
||||||
{
|
|
||||||
#ifdef HAVE_CHARSET
|
|
||||||
if (view->utf8)
|
|
||||||
{
|
|
||||||
gboolean read_res = TRUE;
|
|
||||||
c = mcview_get_utf (view, from, &cw, &read_res);
|
|
||||||
if (!read_res)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
if (!mcview_get_byte (view, from, &c))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
from++;
|
|
||||||
if (cw > 1)
|
|
||||||
from += cw - 1;
|
|
||||||
|
|
||||||
if (c == '\b')
|
|
||||||
{
|
|
||||||
if (from > 1)
|
|
||||||
{
|
|
||||||
#ifdef HAVE_CHARSET
|
|
||||||
if (view->utf8)
|
|
||||||
{
|
|
||||||
gboolean read_res;
|
|
||||||
c_next = mcview_get_utf (view, from, &cw, &read_res);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
mcview_get_byte (view, from, &c_next);
|
|
||||||
}
|
|
||||||
if (g_unichar_isprint (c_prev) && g_unichar_isprint (c_next)
|
|
||||||
&& (c_prev == c_next || c_prev == '_' || (c_prev == '+' && c_next == 'o')))
|
|
||||||
{
|
|
||||||
if (col == 0)
|
|
||||||
{
|
|
||||||
if (row == 0)
|
|
||||||
{
|
|
||||||
/* We're inside an nroff character sequence at the
|
|
||||||
* beginning of the screen -- just skip the
|
|
||||||
* backspace and continue with the next character. */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
row--;
|
|
||||||
col = width;
|
|
||||||
}
|
|
||||||
col--;
|
|
||||||
if (c_prev == '_'
|
|
||||||
&& (c_next != '_' || mcview_count_backspaces (view, from + 1) == 1))
|
|
||||||
tty_setcolor (VIEW_UNDERLINED_COLOR);
|
|
||||||
else
|
|
||||||
tty_setcolor (VIEW_BOLD_COLOR);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((c == '\n') || (col >= width && view->text_wrap_mode))
|
|
||||||
{
|
|
||||||
col = 0;
|
|
||||||
row++;
|
|
||||||
if (c == '\n' || row >= height)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c == '\r')
|
|
||||||
{
|
|
||||||
mcview_get_byte_indexed (view, from, 1, &c);
|
|
||||||
if (c == '\r' || c == '\n')
|
|
||||||
continue;
|
|
||||||
col = 0;
|
|
||||||
row++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c == '\t')
|
|
||||||
{
|
|
||||||
off_t line, column;
|
|
||||||
mcview_offset_to_coord (view, &line, &column, from);
|
|
||||||
col += (option_tab_spacing - col % option_tab_spacing);
|
|
||||||
if (view->text_wrap_mode && col >= width && width != 0)
|
|
||||||
{
|
|
||||||
row += col / width;
|
|
||||||
col %= width;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (view->search_start <= from && from < view->search_end)
|
|
||||||
{
|
|
||||||
tty_setcolor (SELECTED_COLOR);
|
|
||||||
}
|
|
||||||
|
|
||||||
c_prev = c;
|
|
||||||
|
|
||||||
if ((off_t) col >= view->dpy_text_column
|
|
||||||
&& (off_t) col - view->dpy_text_column < (off_t) width)
|
|
||||||
{
|
|
||||||
widget_move (view, top + row, left + ((off_t) col - view->dpy_text_column));
|
|
||||||
#ifdef HAVE_CHARSET
|
|
||||||
if (mc_global.utf8_display)
|
|
||||||
{
|
|
||||||
if (!view->utf8)
|
|
||||||
{
|
|
||||||
c = convert_from_8bit_to_utf_c ((unsigned char) c, view->converter);
|
|
||||||
}
|
|
||||||
if (!g_unichar_isprint (c))
|
|
||||||
c = '.';
|
|
||||||
}
|
|
||||||
else if (view->utf8)
|
|
||||||
c = convert_from_utf_to_current_c (c, view->converter);
|
|
||||||
else
|
|
||||||
c = convert_to_display_c (c);
|
|
||||||
#endif
|
|
||||||
tty_print_anychar (c);
|
|
||||||
}
|
|
||||||
col++;
|
|
||||||
#ifdef HAVE_CHARSET
|
|
||||||
if (view->utf8)
|
|
||||||
{
|
|
||||||
if (g_unichar_iswide (c))
|
|
||||||
col++;
|
|
||||||
else if (g_unichar_iszerowidth (c))
|
|
||||||
col--;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
tty_setcolor (VIEW_NORMAL_COLOR);
|
|
||||||
}
|
|
||||||
view->dpy_end = from;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
int
|
int
|
||||||
mcview__get_nroff_real_len (mcview_t * view, off_t start, off_t length)
|
mcview__get_nroff_real_len (mcview_t * view, off_t start, off_t length)
|
||||||
{
|
{
|
||||||
|
@ -1,204 +0,0 @@
|
|||||||
/*
|
|
||||||
Internal file viewer for the Midnight Commander
|
|
||||||
Function for plain view
|
|
||||||
|
|
||||||
Copyright (C) 1994-2014
|
|
||||||
Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
Written by:
|
|
||||||
Miguel de Icaza, 1994, 1995, 1998
|
|
||||||
Janne Kukonlehto, 1994, 1995
|
|
||||||
Jakub Jelinek, 1995
|
|
||||||
Joseph M. Hinkle, 1996
|
|
||||||
Norbert Warmuth, 1997
|
|
||||||
Pavel Machek, 1998
|
|
||||||
Roland Illig <roland.illig@gmx.de>, 2004, 2005
|
|
||||||
Slava Zanko <slavazanko@google.com>, 2009
|
|
||||||
Andrew Borodin <aborodin@vmail.ru>, 2009-2014
|
|
||||||
Ilia Maslakov <il.smind@gmail.com>, 2009
|
|
||||||
|
|
||||||
This file is part of the Midnight Commander.
|
|
||||||
|
|
||||||
The Midnight Commander is free software: you can redistribute it
|
|
||||||
and/or modify it under the terms of the GNU General Public License as
|
|
||||||
published by the Free Software Foundation, either version 3 of the License,
|
|
||||||
or (at your option) any later version.
|
|
||||||
|
|
||||||
The Midnight Commander is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#include "lib/global.h"
|
|
||||||
#include "lib/tty/tty.h"
|
|
||||||
#include "lib/skin.h"
|
|
||||||
#include "lib/util.h" /* is_printable() */
|
|
||||||
#ifdef HAVE_CHARSET
|
|
||||||
#include "lib/charsets.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "src/setup.h" /* option_tab_spacing */
|
|
||||||
|
|
||||||
#include "internal.h"
|
|
||||||
|
|
||||||
/*** global variables ****************************************************************************/
|
|
||||||
|
|
||||||
/*** file scope macro definitions ****************************************************************/
|
|
||||||
|
|
||||||
/*** file scope type declarations ****************************************************************/
|
|
||||||
|
|
||||||
/*** file scope variables ************************************************************************/
|
|
||||||
|
|
||||||
/*** file scope functions ************************************************************************/
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
|
||||||
/*** public functions ****************************************************************************/
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
void
|
|
||||||
mcview_display_text (mcview_t * view)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
screen_dimen row = 0, col = 0;
|
|
||||||
off_t from;
|
|
||||||
int cw = 1;
|
|
||||||
int c, prev_ch = 0;
|
|
||||||
gboolean last_row = TRUE;
|
|
||||||
|
|
||||||
mcview_display_clean (view);
|
|
||||||
mcview_display_ruler (view);
|
|
||||||
|
|
||||||
/* Find the first displayable changed byte */
|
|
||||||
from = view->dpy_start;
|
|
||||||
|
|
||||||
while (row < height)
|
|
||||||
{
|
|
||||||
#ifdef HAVE_CHARSET
|
|
||||||
if (view->utf8)
|
|
||||||
{
|
|
||||||
gboolean read_res = TRUE;
|
|
||||||
|
|
||||||
c = mcview_get_utf (view, from, &cw, &read_res);
|
|
||||||
if (!read_res)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
if (!mcview_get_byte (view, from, &c))
|
|
||||||
break;
|
|
||||||
|
|
||||||
last_row = FALSE;
|
|
||||||
from++;
|
|
||||||
if (cw > 1)
|
|
||||||
from += cw - 1;
|
|
||||||
|
|
||||||
if (c != '\n' && prev_ch == '\r')
|
|
||||||
{
|
|
||||||
if (++row >= height)
|
|
||||||
break;
|
|
||||||
|
|
||||||
col = 0;
|
|
||||||
/* tty_print_anychar ('\n'); */
|
|
||||||
}
|
|
||||||
|
|
||||||
prev_ch = c;
|
|
||||||
if (c == '\r')
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (c == '\n')
|
|
||||||
{
|
|
||||||
col = 0;
|
|
||||||
row++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (col >= width && view->text_wrap_mode)
|
|
||||||
{
|
|
||||||
col = 0;
|
|
||||||
if (++row >= height)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c == '\t')
|
|
||||||
{
|
|
||||||
col += (option_tab_spacing - col % option_tab_spacing);
|
|
||||||
if (view->text_wrap_mode && col >= width && width != 0)
|
|
||||||
{
|
|
||||||
row += col / width;
|
|
||||||
col %= width;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (view->search_start <= from && from < view->search_end)
|
|
||||||
tty_setcolor (SELECTED_COLOR);
|
|
||||||
else
|
|
||||||
tty_setcolor (VIEW_NORMAL_COLOR);
|
|
||||||
|
|
||||||
if (((off_t) col >= view->dpy_text_column)
|
|
||||||
&& ((off_t) col - view->dpy_text_column < (off_t) width))
|
|
||||||
{
|
|
||||||
widget_move (view, top + row, left + ((off_t) col - view->dpy_text_column));
|
|
||||||
|
|
||||||
#ifdef HAVE_CHARSET
|
|
||||||
if (mc_global.utf8_display)
|
|
||||||
{
|
|
||||||
if (!view->utf8)
|
|
||||||
c = convert_from_8bit_to_utf_c ((unsigned char) c, view->converter);
|
|
||||||
if (!g_unichar_isprint (c))
|
|
||||||
c = '.';
|
|
||||||
}
|
|
||||||
else if (view->utf8)
|
|
||||||
c = convert_from_utf_to_current_c (c, view->converter);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
c = convert_to_display_c (c);
|
|
||||||
if (!is_printable (c))
|
|
||||||
c = '.';
|
|
||||||
}
|
|
||||||
#else /* HAVE_CHARSET */
|
|
||||||
if (!is_printable (c))
|
|
||||||
c = '.';
|
|
||||||
#endif /* HAVE_CHARSET */
|
|
||||||
|
|
||||||
tty_print_anychar (c);
|
|
||||||
}
|
|
||||||
|
|
||||||
col++;
|
|
||||||
|
|
||||||
#ifdef HAVE_CHARSET
|
|
||||||
if (view->utf8)
|
|
||||||
{
|
|
||||||
if (g_unichar_iswide (c))
|
|
||||||
col++;
|
|
||||||
else if (g_unichar_iszerowidth (c))
|
|
||||||
col--;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
view->dpy_end = from;
|
|
||||||
if (mcview_show_eof != NULL && mcview_show_eof[0] != '\0')
|
|
||||||
{
|
|
||||||
if (last_row && mcview_get_byte (view, from - 1, &c) && c != '\n')
|
|
||||||
row--;
|
|
||||||
|
|
||||||
while (++row < height)
|
|
||||||
{
|
|
||||||
widget_move (view, top + row, left);
|
|
||||||
tty_print_string (mcview_show_eof);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
|
BIN
tests/src/viewer/viewertest.txt
Normal file
BIN
tests/src/viewer/viewertest.txt
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user