2005-04-14 02:19:52 +04:00
|
|
|
/*
|
|
|
|
Internal file viewer for the Midnight Commander
|
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
Copyright (C) 1994, 1995, 1996 The Free Software Foundation
|
2005-04-14 02:19:52 +04:00
|
|
|
|
1998-04-09 08:58:24 +04:00
|
|
|
Written by: 1994, 1995, 1998 Miguel de Icaza
|
2005-07-03 19:31:55 +04:00
|
|
|
1994, 1995 Janne Kukonlehto
|
|
|
|
1995 Jakub Jelinek
|
|
|
|
1996 Joseph M. Hinkle
|
1998-02-27 07:54:42 +03:00
|
|
|
1997 Norbert Warmuth
|
1998-11-03 00:47:06 +03:00
|
|
|
1998 Pavel Machek
|
2004-12-02 20:13:39 +03:00
|
|
|
2004 Roland Illig <roland.illig@gmx.de>
|
2005-02-08 01:31:30 +03:00
|
|
|
2005 Roland Illig <roland.illig@gmx.de>
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
This program 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 2 of the License, or
|
|
|
|
(at your option) any later version.
|
2002-10-31 01:48:59 +03:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
This program 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, write to the Free Software
|
2005-05-27 07:35:10 +04:00
|
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2005-04-14 02:19:52 +04:00
|
|
|
*/
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2005-02-08 01:31:30 +03:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include <config.h>
|
1998-02-27 07:54:42 +03:00
|
|
|
#endif
|
2005-02-08 01:31:30 +03:00
|
|
|
|
2005-04-07 15:23:53 +04:00
|
|
|
#include <assert.h>
|
2005-02-08 01:31:30 +03:00
|
|
|
#include <ctype.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <limits.h>
|
|
|
|
#include <stdio.h>
|
2005-02-08 12:04:03 +03:00
|
|
|
#include <stdlib.h>
|
1998-02-27 07:54:42 +03:00
|
|
|
#include <string.h>
|
2005-02-08 01:31:30 +03:00
|
|
|
#include <sys/types.h>
|
1998-02-27 07:54:42 +03:00
|
|
|
#include <sys/stat.h>
|
2005-02-08 12:04:03 +03:00
|
|
|
#include <unistd.h>
|
2001-08-07 20:53:55 +04:00
|
|
|
|
Glibing..... (2)
Wed Jan 27 03:17:44 1999 Timur Bakeyev <mc@bat.ru>
* Converted memory managment to Glib. Now we use g_new()/g_malloc()/
g_strdup()/g_free() routings. Also, copy_strings() replaced by
g_strconcat(), strcasecmp() -> g_strcasecmp(),and sprintf() by
g_snprintf().
* Some sequences of malloc()/sprintf() changed to g_strdup_printf().
* mad.[ch]: Modified, to work with new GLib's memory managment. Fixed
a missing #undef for tempnam, which caused dead loop. Add several new
functions to emulate GLib memory managment.
*main.c, mad.[ch]: Add a new switch "-M", which allows to redirect MAD
messages to the file.
* util.[ch], utilunix.c: Modified, deleted our variants of strcasecmp()
and strdup() - we have g_ equivalences. Remove get_full_name() - it is
similar to concat_dir_and_file(). Some other tricks with g_* functions.
* global.h: Modified, extended. Now it is main memory mangment include -
i.e. all inclusions of <stdlib.h>, <malloc.h>, <glib.h>, "fs.h", "mem.h",
"util.h" and "mad.h" done there. This elimanates problem with proper or-
der of #include's.
* All around the source - changed order of #include's, most of them gone
to global.h (see above), minor changes, like "0" -> NULL in string func-
tions.
1999-01-27 04:08:30 +03:00
|
|
|
#include "global.h"
|
2001-08-07 20:53:55 +04:00
|
|
|
#include "tty.h"
|
|
|
|
#include "cmd.h" /* For view_other_cmd */
|
2003-10-25 03:20:30 +04:00
|
|
|
#include "dialog.h" /* Needed by widget.h */
|
1998-02-27 07:54:42 +03:00
|
|
|
#include "widget.h" /* Needed for buttonbar_new */
|
|
|
|
#include "color.h"
|
|
|
|
#include "mouse.h"
|
|
|
|
#include "help.h"
|
|
|
|
#include "key.h" /* For mi_getch() */
|
|
|
|
#include "layout.h"
|
1998-11-18 05:31:23 +03:00
|
|
|
#include "setup.h"
|
1998-02-27 07:54:42 +03:00
|
|
|
#include "wtools.h" /* For query_set_sel() */
|
|
|
|
#include "dir.h"
|
2002-10-31 01:48:59 +03:00
|
|
|
#include "panel.h" /* Needed for current_panel and other_panel */
|
1998-02-27 07:54:42 +03:00
|
|
|
#include "win.h"
|
2003-06-22 13:17:46 +04:00
|
|
|
#include "execute.h"
|
2005-05-11 01:38:40 +04:00
|
|
|
#include "main.h" /* slow_terminal */
|
1998-02-27 07:54:42 +03:00
|
|
|
#include "view.h"
|
2009-01-24 23:59:58 +03:00
|
|
|
#include "history.h"
|
2001-06-06 02:49:15 +04:00
|
|
|
#include "charsets.h"
|
2001-06-25 15:24:49 +04:00
|
|
|
#include "selcodepage.h"
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
#include "strutil.h"
|
2001-06-06 02:49:15 +04:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
/* Block size for reading files in parts */
|
2005-04-14 02:18:04 +04:00
|
|
|
#define VIEW_PAGE_SIZE ((size_t) 8192)
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2005-04-16 19:13:20 +04:00
|
|
|
typedef unsigned char byte;
|
|
|
|
|
2004-08-16 08:16:55 +04:00
|
|
|
/* Offset in bytes into a file */
|
|
|
|
typedef unsigned long offset_type;
|
2004-10-16 19:52:48 +04:00
|
|
|
#define INVALID_OFFSET ((offset_type) -1)
|
2004-12-02 20:13:39 +03:00
|
|
|
#define OFFSETTYPE_MAX (~((offset_type) 0))
|
2005-04-25 04:26:46 +04:00
|
|
|
#define OFFSETTYPE_PRIX "lX"
|
|
|
|
#define OFFSETTYPE_PRId "lu"
|
2004-08-16 08:16:55 +04:00
|
|
|
|
|
|
|
/* A width or height on the screen */
|
|
|
|
typedef unsigned int screen_dimen;
|
|
|
|
|
2002-11-15 00:18:28 +03:00
|
|
|
/* A node for building a change list on change_list */
|
|
|
|
struct hexedit_change_node {
|
|
|
|
struct hexedit_change_node *next;
|
2004-08-16 08:16:55 +04:00
|
|
|
offset_type offset;
|
2005-04-16 19:13:20 +04:00
|
|
|
byte value;
|
2002-11-15 00:18:28 +03:00
|
|
|
};
|
|
|
|
|
2005-04-07 15:23:53 +04:00
|
|
|
/* data sources of the view */
|
|
|
|
enum view_ds {
|
|
|
|
DS_NONE, /* No data available */
|
|
|
|
DS_STDIO_PIPE, /* Data comes from a pipe using popen/pclose */
|
|
|
|
DS_VFS_PIPE, /* Data comes from a piped-in VFS file */
|
|
|
|
DS_FILE, /* Data comes from a VFS file */
|
|
|
|
DS_STRING /* Data comes from a string in memory */
|
|
|
|
};
|
|
|
|
|
2005-07-06 23:12:25 +04:00
|
|
|
struct area {
|
|
|
|
screen_dimen top, left;
|
|
|
|
screen_dimen height, width;
|
|
|
|
};
|
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
#define VLF_DISCARD 1
|
|
|
|
#define VLF_INIT 2
|
|
|
|
#define VLF_COMPLETE 3
|
|
|
|
|
|
|
|
/* basic structure for caching text, it correspond to one line in wrapped text.
|
|
|
|
* That makes easier to move in wrap mode.
|
|
|
|
* cache_lines are stored in two linked lists, one for normal mode
|
|
|
|
* and one for nroff mode
|
|
|
|
* cache_line is valid of end is not INVALID_OFFSET
|
|
|
|
* last line has set width to (screen_dimen) (-1)*/
|
|
|
|
/* never access next and previous in cache_line directly, use appropriately function
|
|
|
|
* instead */
|
|
|
|
struct cache_line {
|
|
|
|
/* number of line in text, so two cache_line have same number
|
|
|
|
* if they are on same text line (text line is wider than screen) */
|
|
|
|
long number;
|
|
|
|
/* previous cache_line in list*/
|
|
|
|
struct cache_line *prev;
|
|
|
|
/* next cache_line in list*/
|
|
|
|
struct cache_line *next;
|
|
|
|
/* offset when cache_line start in text,
|
|
|
|
* cache_line.start = cache_line->prev.end */
|
|
|
|
offset_type start;
|
|
|
|
/* offset when cache_line ends
|
|
|
|
* cache_line.end = cache_line->next.start */
|
|
|
|
offset_type end;
|
|
|
|
/* how many column take on screen */
|
|
|
|
screen_dimen width;
|
|
|
|
/* correct ident, if prevoius line ends by tabulator */
|
|
|
|
screen_dimen left;
|
|
|
|
};
|
|
|
|
|
2002-11-15 00:18:28 +03:00
|
|
|
struct WView {
|
|
|
|
Widget widget;
|
|
|
|
|
|
|
|
char *filename; /* Name of the file */
|
|
|
|
char *command; /* Command used to pipe data in */
|
2005-01-31 00:17:29 +03:00
|
|
|
|
2005-04-07 15:23:53 +04:00
|
|
|
enum view_ds datasource; /* Where the displayed data comes from */
|
|
|
|
|
|
|
|
/* stdio pipe data source */
|
2005-04-16 16:56:50 +04:00
|
|
|
FILE *ds_stdio_pipe; /* Output of a shell command */
|
2002-11-15 00:18:28 +03:00
|
|
|
|
2005-04-07 15:23:53 +04:00
|
|
|
/* vfs pipe data source */
|
2005-04-16 16:56:50 +04:00
|
|
|
int ds_vfs_pipe; /* Non-seekable vfs file descriptor */
|
2005-04-07 15:23:53 +04:00
|
|
|
|
|
|
|
/* vfs file data source */
|
2005-04-16 16:56:50 +04:00
|
|
|
int ds_file_fd; /* File with random access */
|
|
|
|
off_t ds_file_filesize; /* Size of the file */
|
|
|
|
off_t ds_file_offset; /* Offset of the currently loaded data */
|
2005-04-16 19:13:20 +04:00
|
|
|
byte *ds_file_data; /* Currently loaded data */
|
2005-04-07 15:23:53 +04:00
|
|
|
size_t ds_file_datalen; /* Number of valid bytes in file_data */
|
|
|
|
size_t ds_file_datasize; /* Number of allocated bytes in file_data */
|
|
|
|
|
|
|
|
/* string data source */
|
2005-04-16 19:13:20 +04:00
|
|
|
byte *ds_string_data; /* The characters of the string */
|
2005-04-07 15:23:53 +04:00
|
|
|
size_t ds_string_len; /* The length of the string */
|
2002-11-15 00:18:28 +03:00
|
|
|
|
2005-04-19 00:06:16 +04:00
|
|
|
/* Growing buffers information */
|
2009-02-06 01:46:07 +03:00
|
|
|
gboolean growbuf_in_use; /* Use the growing buffers? */
|
2005-04-19 00:06:16 +04:00
|
|
|
byte **growbuf_blockptr; /* Pointer to the block pointers */
|
|
|
|
size_t growbuf_blocks; /* The number of blocks in *block_ptr */
|
|
|
|
size_t growbuf_lastindex; /* Number of bytes in the last page of the
|
2005-07-03 19:31:55 +04:00
|
|
|
growing buffer */
|
2009-02-06 01:46:07 +03:00
|
|
|
gboolean growbuf_finished; /* TRUE when all data has been read. */
|
2005-04-19 00:06:16 +04:00
|
|
|
|
2005-04-14 14:59:02 +04:00
|
|
|
/* Editor modes */
|
2009-02-06 01:46:07 +03:00
|
|
|
gboolean hex_mode; /* Hexview or Hexedit */
|
|
|
|
gboolean hexedit_mode; /* Hexedit */
|
|
|
|
gboolean hexview_in_text; /* Is the hexview cursor in the text area? */
|
|
|
|
gboolean text_nroff_mode; /* Nroff-style highlighting */
|
|
|
|
gboolean text_wrap_mode; /* Wrap text lines to fit them on the screen */
|
|
|
|
gboolean magic_mode; /* Preprocess the file using external programs */
|
2005-04-14 14:59:02 +04:00
|
|
|
|
2005-04-20 00:33:51 +04:00
|
|
|
/* Additional editor state */
|
2009-02-06 01:46:07 +03:00
|
|
|
gboolean hexedit_lownibble; /* Are we editing the last significant nibble? */
|
2005-04-20 00:33:51 +04:00
|
|
|
|
2002-11-15 00:18:28 +03:00
|
|
|
/* Display information */
|
2005-07-06 23:12:25 +04:00
|
|
|
screen_dimen dpy_frame_size;/* Size of the frame surrounding the real viewer */
|
2005-08-22 22:31:51 +04:00
|
|
|
offset_type dpy_start; /* Offset of the displayed data */
|
|
|
|
offset_type dpy_end; /* Offset after the displayed data */
|
2005-05-21 14:17:35 +04:00
|
|
|
offset_type dpy_text_column;/* Number of skipped columns in non-wrap
|
|
|
|
* text mode */
|
2005-05-21 14:23:57 +04:00
|
|
|
offset_type hex_cursor; /* Hexview cursor position in file */
|
2004-08-16 08:16:55 +04:00
|
|
|
screen_dimen cursor_col; /* Cursor column */
|
|
|
|
screen_dimen cursor_row; /* Cursor row */
|
2002-11-15 00:18:28 +03:00
|
|
|
struct hexedit_change_node *change_list; /* Linked list of changes */
|
2005-07-06 23:12:25 +04:00
|
|
|
struct area status_area; /* Where the status line is displayed */
|
|
|
|
struct area ruler_area; /* Where the ruler is displayed */
|
|
|
|
struct area data_area; /* Where the data is displayed */
|
2002-11-15 00:18:28 +03:00
|
|
|
|
|
|
|
int dirty; /* Number of skipped updates */
|
2009-02-06 01:46:07 +03:00
|
|
|
gboolean dpy_bbar_dirty; /* Does the button bar need to be updated? */
|
2005-01-31 00:17:29 +03:00
|
|
|
|
2002-11-15 00:18:28 +03:00
|
|
|
/* Mode variables */
|
|
|
|
int bytes_per_line; /* Number of bytes per line in hex mode */
|
2005-01-31 00:17:29 +03:00
|
|
|
|
2002-11-15 00:18:28 +03:00
|
|
|
/* Search variables */
|
2004-08-16 08:16:55 +04:00
|
|
|
offset_type search_start; /* First character to start searching from */
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
offset_type search_end; /* Length of found string or 0 if none was found */
|
2002-11-15 00:18:28 +03:00
|
|
|
char *search_exp; /* The search expression */
|
|
|
|
int direction; /* 1= forward; -1 backward */
|
2005-08-21 16:33:21 +04:00
|
|
|
void (*last_search)(WView *);
|
2005-07-03 19:31:55 +04:00
|
|
|
/* Pointer to the last search command */
|
2009-02-06 01:46:07 +03:00
|
|
|
gboolean want_to_quit; /* Prepare for cleanup ... */
|
2002-11-15 00:18:28 +03:00
|
|
|
|
|
|
|
/* Markers */
|
|
|
|
int marker; /* mark to use */
|
2004-08-16 08:16:55 +04:00
|
|
|
offset_type marks [10]; /* 10 marks: 0..9 */
|
2005-01-31 00:17:29 +03:00
|
|
|
|
|
|
|
int move_dir; /* return value from widget:
|
2002-11-15 00:18:28 +03:00
|
|
|
* 0 do nothing
|
|
|
|
* -1 view previous file
|
|
|
|
* 1 view next file
|
|
|
|
*/
|
2005-02-01 01:01:53 +03:00
|
|
|
|
|
|
|
offset_type update_steps; /* The number of bytes between percent
|
2005-07-03 19:31:55 +04:00
|
|
|
* increments */
|
2005-02-01 01:01:53 +03:00
|
|
|
offset_type update_activate;/* Last point where we updated the status */
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
|
|
|
|
/* never access cache_line in view directly, use appropriately function
|
|
|
|
* instead */
|
|
|
|
/* first cache_line for normal mode */
|
|
|
|
struct cache_line *lines;
|
|
|
|
/* last cache_line for normal mode, is set when text is read to the end */
|
|
|
|
struct cache_line *lines_end;
|
|
|
|
/* first cache_line for nroff mode */
|
|
|
|
struct cache_line *nroff_lines;
|
|
|
|
/* last cache_line for nroff mode, is set when text is read to the end */
|
|
|
|
struct cache_line *nroff_lines_end;
|
|
|
|
/* cache_line, that is first showed on display (something like cursor)
|
|
|
|
* used for both normal adn nroff mode */
|
|
|
|
struct cache_line *first_showed_line;
|
|
|
|
/* converter for translation of text */
|
2009-04-14 14:29:01 +04:00
|
|
|
GIConv converter;
|
2002-11-15 00:18:28 +03:00
|
|
|
};
|
|
|
|
|
2005-05-26 13:08:54 +04:00
|
|
|
|
|
|
|
/* {{{ Global Variables }}} */
|
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
/* Maxlimit for skipping updates */
|
2003-07-23 07:22:32 +04:00
|
|
|
int max_dirt_limit = 10;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
/* If set, show a ruler */
|
2005-08-16 01:59:08 +04:00
|
|
|
static enum ruler_type {
|
2005-07-06 23:12:25 +04:00
|
|
|
RULER_NONE,
|
|
|
|
RULER_TOP,
|
|
|
|
RULER_BOTTOM
|
|
|
|
} ruler = RULER_NONE;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
/* Scrolling is done in pages or line increments */
|
|
|
|
int mouse_move_pages_viewer = 1;
|
|
|
|
|
1998-03-14 03:42:23 +03:00
|
|
|
/* wrap mode default */
|
|
|
|
int global_wrap_mode = 1;
|
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
int default_hex_mode = 0;
|
|
|
|
int default_magic_flag = 1;
|
|
|
|
int default_nroff_flag = 1;
|
|
|
|
int altered_hex_mode = 0;
|
|
|
|
int altered_magic_flag = 0;
|
|
|
|
int altered_nroff_flag = 0;
|
|
|
|
|
1999-12-10 19:04:35 +03:00
|
|
|
static const char hex_char[] = "0123456789ABCDEF";
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2005-07-18 12:47:45 +04:00
|
|
|
int mcview_remember_file_position = FALSE;
|
|
|
|
|
2005-05-26 13:08:54 +04:00
|
|
|
/* {{{ Function Prototypes }}} */
|
|
|
|
|
2003-09-11 02:48:54 +04:00
|
|
|
/* Our widget callback */
|
2005-06-28 03:19:32 +04:00
|
|
|
static cb_ret_t view_callback (Widget *, widget_msg_t, int);
|
2002-08-27 23:10:54 +04:00
|
|
|
|
2002-10-31 01:48:59 +03:00
|
|
|
static int regexp_view_search (WView * view, char *pattern, char *string,
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
int match_type, size_t *match_start, size_t *match_end);
|
2002-10-31 01:48:59 +03:00
|
|
|
static void view_labels (WView * view);
|
2002-08-27 23:10:54 +04:00
|
|
|
|
2005-04-14 12:00:14 +04:00
|
|
|
static void view_init_growbuf (WView *);
|
2005-04-17 13:05:42 +04:00
|
|
|
static void view_place_cursor (WView *view);
|
2005-07-14 01:30:28 +04:00
|
|
|
static void display (WView *);
|
2005-08-29 00:38:53 +04:00
|
|
|
static void view_done (WView *);
|
2005-04-14 12:00:14 +04:00
|
|
|
|
2005-05-26 13:08:54 +04:00
|
|
|
/* {{{ Helper Functions }}} */
|
|
|
|
|
2005-07-06 23:12:25 +04:00
|
|
|
/* difference or zero */
|
|
|
|
static inline screen_dimen
|
|
|
|
dimen_doz (screen_dimen a, screen_dimen b)
|
|
|
|
{
|
|
|
|
return (a >= b) ? a - b : 0;
|
|
|
|
}
|
|
|
|
|
2005-07-07 21:49:01 +04:00
|
|
|
static inline screen_dimen
|
|
|
|
dimen_min (screen_dimen a, screen_dimen b)
|
|
|
|
{
|
|
|
|
return (a < b) ? a : b;
|
|
|
|
}
|
|
|
|
|
2005-07-06 23:12:25 +04:00
|
|
|
static inline offset_type
|
|
|
|
offset_doz (offset_type a, offset_type b)
|
|
|
|
{
|
|
|
|
return (a >= b) ? a - b : 0;
|
|
|
|
}
|
|
|
|
|
2005-06-28 02:36:00 +04:00
|
|
|
static inline offset_type
|
2005-05-26 13:08:54 +04:00
|
|
|
offset_rounddown (offset_type a, offset_type b)
|
|
|
|
{
|
2005-07-07 02:35:17 +04:00
|
|
|
assert (b != 0);
|
2005-05-26 13:08:54 +04:00
|
|
|
return a - a % b;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* {{{ Simple Primitive Functions for WView }}} */
|
|
|
|
|
2009-02-06 01:46:07 +03:00
|
|
|
static inline gboolean
|
2005-04-16 17:45:16 +04:00
|
|
|
view_is_in_panel (WView *view)
|
|
|
|
{
|
|
|
|
return (view->dpy_frame_size != 0);
|
|
|
|
}
|
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
static inline int get_byte (WView *view, offset_type offset);
|
|
|
|
|
|
|
|
/* read on character from text, character is translated into terminal encoding
|
|
|
|
* writes result in ch, return how many bytes was read or -1 if end of text */
|
|
|
|
static int
|
|
|
|
view_get_char (WView *view, offset_type from, char *ch, int size)
|
|
|
|
{
|
|
|
|
static char buffer [MB_LEN_MAX + 1];
|
|
|
|
static int c;
|
|
|
|
static size_t result;
|
|
|
|
|
|
|
|
result = 0;
|
|
|
|
|
|
|
|
while (result < sizeof (buffer) - 1) {
|
|
|
|
c = get_byte (view, from + result);
|
|
|
|
if (c == -1) break;
|
|
|
|
buffer[result] = (unsigned char) c;
|
|
|
|
result++;
|
|
|
|
buffer[result] = '\0';
|
|
|
|
switch (str_translate_char (view->converter, buffer, result, ch, size)) {
|
|
|
|
case 0:
|
|
|
|
return (int) result;
|
|
|
|
case 1:
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
ch[0] = '?';
|
|
|
|
ch[1] = '\0';
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* this structure and view_read_* functions make reading text simpler
|
|
|
|
* view need remeber 4 following charsets: actual, next and two previous */
|
|
|
|
struct read_info {
|
|
|
|
char ch[4][MB_LEN_MAX + 1];
|
|
|
|
char *cnxt;
|
|
|
|
char *cact;
|
|
|
|
char *chi1;
|
|
|
|
char *chi2;
|
|
|
|
offset_type next;
|
|
|
|
offset_type actual;
|
|
|
|
int result;
|
|
|
|
};
|
|
|
|
|
|
|
|
/* set read_info into initial state and read first character to cnxt
|
|
|
|
* return how many bytes was read or -1 if end of text */
|
|
|
|
static void
|
|
|
|
view_read_start (WView *view, struct read_info *info, offset_type from)
|
|
|
|
{
|
|
|
|
info->ch[0][0] = '\0';
|
|
|
|
info->ch[1][0] = '\0';
|
|
|
|
info->ch[2][0] = '\0';
|
|
|
|
info->ch[3][0] = '\0';
|
|
|
|
|
|
|
|
info->cnxt = info->ch[0];
|
|
|
|
info->cact = info->ch[1];
|
|
|
|
info->chi1 = info->ch[2];
|
|
|
|
info->chi2 = info->ch[3];
|
|
|
|
|
|
|
|
info->next = from;
|
|
|
|
|
|
|
|
info->result = view_get_char (view, info->next, info->cnxt, MB_LEN_MAX + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* move characters in read_info one forward (chi2 = last previous is forgotten)
|
|
|
|
* read additional charsets into cnxt
|
|
|
|
* return how many bytes was read or -1 if end of text */
|
|
|
|
static void
|
|
|
|
view_read_continue (WView *view, struct read_info *info)
|
|
|
|
{
|
|
|
|
char *tmp;
|
|
|
|
|
|
|
|
tmp = info->chi2;
|
|
|
|
info->chi2 = info->chi1;
|
|
|
|
info->chi1 = info->cact;
|
|
|
|
info->cact = info->cnxt;
|
|
|
|
info->cnxt = tmp;
|
|
|
|
|
|
|
|
info->actual = info->next;
|
|
|
|
info->next+= info->result;
|
|
|
|
|
|
|
|
info->result = view_get_char (view, info->next, info->cnxt, MB_LEN_MAX + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
#define VRT_NW_NO 0
|
|
|
|
#define VRT_NW_YES 1
|
|
|
|
#define VRT_NW_CONTINUE 2
|
|
|
|
|
|
|
|
/* test if cact of read_info is newline
|
|
|
|
* return VRT_NW_NO, VRT_NW_YES
|
|
|
|
* or VRT_NW_CONTINUE follow after cact ("\r\n", ...) */
|
|
|
|
static int
|
|
|
|
view_read_test_new_line (WView *view, struct read_info *info)
|
|
|
|
{
|
|
|
|
#define cmp(t1,t2) (strcmp((t1),(t2)) == 0)
|
|
|
|
|
|
|
|
if (cmp (info->cact, "\n")) return VRT_NW_YES;
|
|
|
|
|
|
|
|
if (cmp (info->cact, "\r")) {
|
|
|
|
if (info->result != -1 && (cmp (info->cnxt, "\r") || cmp (info->cnxt, "\n")))
|
|
|
|
return VRT_NW_CONTINUE;
|
|
|
|
|
|
|
|
return VRT_NW_YES;
|
|
|
|
}
|
|
|
|
return VRT_NW_NO;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* test if cact of read_info is tabulator
|
|
|
|
* return VRT_NW_NO or VRT_NW_YES */
|
|
|
|
static int
|
|
|
|
view_read_test_tabulator (WView *view, struct read_info *info)
|
|
|
|
{
|
|
|
|
#define cmp(t1,t2) (strcmp((t1),(t2)) == 0)
|
|
|
|
return cmp (info->cact, "\t");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* test if read_info.cact is '\b' and charsets in read_info are correct
|
|
|
|
* nroff sequence, return VRT_NW_NO or VRT_NW_YES */
|
|
|
|
static int
|
|
|
|
view_read_test_nroff_back (WView *view, struct read_info *info)
|
|
|
|
{
|
|
|
|
#define cmp(t1,t2) (strcmp((t1),(t2)) == 0)
|
|
|
|
return view->text_nroff_mode && cmp (info->cact, "\b") &&
|
|
|
|
(info->result != -1) && str_isprint (info->cnxt) &&
|
|
|
|
!cmp (info->chi1, "") && str_isprint (info->chi1) &&
|
|
|
|
(cmp (info->chi1, info->cnxt) || cmp (info->chi1, "_")
|
|
|
|
|| (cmp (info->chi1, "+") && cmp (info->cnxt, "o")));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/* rutine for view_load_cache_line, line is ended and following cache_line is
|
|
|
|
* set up for loading
|
|
|
|
* used when end of line has been read in text */
|
|
|
|
static struct cache_line *
|
|
|
|
view_lc_create_next_line (struct cache_line *line, offset_type start)
|
|
|
|
{
|
|
|
|
struct cache_line *result = NULL;
|
|
|
|
|
|
|
|
line->end = start;
|
|
|
|
|
|
|
|
if (line->next == NULL) {
|
|
|
|
result = g_new0 (struct cache_line, 1);
|
|
|
|
line->next = result;
|
|
|
|
result->prev = line;
|
|
|
|
} else result = line->next;
|
|
|
|
|
|
|
|
result->start = start;
|
|
|
|
result->width = 0;
|
|
|
|
result->left = 0;
|
|
|
|
result->number = line->number + 1;
|
|
|
|
result->end = INVALID_OFFSET;
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* rutine for view_load_cache_line, line is ended and following cache_line is
|
|
|
|
* set up for loading
|
|
|
|
* used when line has maximum width */
|
|
|
|
static struct cache_line *
|
|
|
|
view_lc_create_wrap_line (struct cache_line *line, offset_type start,
|
|
|
|
screen_dimen left)
|
|
|
|
{
|
|
|
|
struct cache_line *result = NULL;
|
|
|
|
|
|
|
|
line->end = start;
|
|
|
|
|
|
|
|
if (line->next == NULL) {
|
|
|
|
result = g_new0 (struct cache_line, 1);
|
|
|
|
line->next = result;
|
|
|
|
result->prev = line;
|
|
|
|
} else result = line->next;
|
|
|
|
|
|
|
|
result->start = start;
|
|
|
|
result->width = 0;
|
|
|
|
result->left = left;
|
|
|
|
result->number = line->number;
|
|
|
|
result->end = INVALID_OFFSET;
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* read charsets fro text and set up correct width, end and start of next line
|
|
|
|
* view->data_area.width must be greater than 0 */
|
|
|
|
static struct cache_line *
|
|
|
|
view_load_cache_line (WView *view, struct cache_line *line)
|
|
|
|
{
|
|
|
|
const screen_dimen width = view->data_area.width;
|
|
|
|
struct read_info info;
|
|
|
|
offset_type nroff_start = 0;
|
|
|
|
int nroff_seq = 0;
|
|
|
|
int w;
|
|
|
|
|
|
|
|
line->width = 0;
|
|
|
|
|
|
|
|
view_read_start (view, &info, line->start);
|
|
|
|
while (info.result != -1) {
|
|
|
|
view_read_continue (view, &info);
|
|
|
|
|
|
|
|
switch (view_read_test_new_line (view, &info)) {
|
|
|
|
case VRT_NW_YES:
|
|
|
|
line = view_lc_create_next_line (line, info.next);
|
|
|
|
return line;
|
|
|
|
case VRT_NW_CONTINUE:
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (view_read_test_tabulator (view, &info)) {
|
|
|
|
line->width+= 8 - (line->left + line->width) % 8;
|
|
|
|
if ((width != 0) && (line->left + line->width >= width)) {
|
|
|
|
w = line->left + line->width - width;
|
|
|
|
/* if width of screen is very small, tabulator is cut to line
|
|
|
|
* left of next line is 0 */
|
|
|
|
w = (w < width) ? w : 0;
|
|
|
|
line->width = width - line->left;
|
|
|
|
line = view_lc_create_wrap_line (line, info.next, w);
|
|
|
|
return line;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (view_read_test_nroff_back (view, &info)) {
|
|
|
|
w = str_term_width1 (info.chi1);
|
|
|
|
line->width-= w;
|
|
|
|
nroff_seq = 1;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
/* assure, that nroff sequence never start in previous cache_line */
|
|
|
|
if (nroff_seq > 0)
|
|
|
|
nroff_seq--;
|
|
|
|
else
|
|
|
|
nroff_start = info.actual;
|
|
|
|
|
|
|
|
w = str_isprint (info.cact) ? str_term_width1 (info.cact) : 1;
|
|
|
|
|
|
|
|
if (line->left + line->width + w > width) {
|
|
|
|
line = view_lc_create_wrap_line (line, nroff_start, 0);
|
|
|
|
return line;
|
|
|
|
} else {
|
|
|
|
while (info.result != -1 && str_iscombiningmark (info.cnxt)) {
|
|
|
|
view_read_continue (view, &info);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
line->width+= w;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/* text read to the end, seting lines_end*/
|
|
|
|
if (view->text_nroff_mode)
|
|
|
|
view->nroff_lines_end = line;
|
|
|
|
else
|
|
|
|
view->lines_end = line;
|
|
|
|
|
|
|
|
line = view_lc_create_next_line (line, info.next);
|
|
|
|
line->width = (screen_dimen) (-1);
|
|
|
|
line->end = info.next;
|
|
|
|
|
|
|
|
return line;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
view_lc_set_param (offset_type *param, offset_type value)
|
|
|
|
{
|
|
|
|
if ((*param) > value) (*param) = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* offset to column or column to offset, value that will be maped must be
|
|
|
|
* set to INVALID_OFFSET, it is very analogous to view_load_cache_line
|
|
|
|
* and it is possible to integrate them in one function */
|
|
|
|
static void
|
|
|
|
view_map_offset_and_column (WView *view, struct cache_line *line,
|
|
|
|
offset_type *column, offset_type *offset)
|
|
|
|
{
|
|
|
|
const screen_dimen width = view->data_area.width;
|
|
|
|
struct read_info info;
|
|
|
|
offset_type nroff_start = 0;
|
|
|
|
int nroff_seq = 0;
|
|
|
|
int w;
|
|
|
|
screen_dimen col;
|
|
|
|
|
|
|
|
col = 0;
|
|
|
|
view_read_start (view, &info, line->start);
|
|
|
|
while (info.result != -1) {
|
|
|
|
view_read_continue (view, &info);
|
|
|
|
|
|
|
|
if (*column == INVALID_OFFSET) {
|
|
|
|
if (*offset < info.next) {
|
|
|
|
(*column) = col + line->left;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (view_read_test_new_line (view, &info)) {
|
|
|
|
case VRT_NW_YES:
|
|
|
|
view_lc_set_param (offset, info.actual);
|
|
|
|
view_lc_set_param (column, line->left + col);
|
|
|
|
return;
|
|
|
|
case VRT_NW_CONTINUE:
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (view_read_test_tabulator (view, &info)) {
|
|
|
|
col+= 8 - (line->left + col) % 8;
|
|
|
|
if ((width != 0) && (line->left + col >= width)) {
|
|
|
|
w = line->left + col - width;
|
|
|
|
w = (w < width) ? w : 0;
|
|
|
|
col = width - line->left;
|
|
|
|
view_lc_set_param (offset, info.actual);
|
|
|
|
view_lc_set_param (column, line->left + col);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (view_read_test_nroff_back (view, &info)) {
|
|
|
|
w = str_term_width1 (info.chi1);
|
|
|
|
col-= w;
|
|
|
|
nroff_seq = 1;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (nroff_seq > 0)
|
|
|
|
nroff_seq--;
|
|
|
|
else
|
|
|
|
nroff_start = info.actual;
|
|
|
|
|
|
|
|
w = str_isprint (info.cact) ? str_term_width1 (info.cact) : 1;
|
|
|
|
|
|
|
|
if (line->left + col + w > width) {
|
|
|
|
view_lc_set_param (offset, nroff_start);
|
|
|
|
view_lc_set_param (column, line->left + col);
|
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
while (info.result != -1 && str_iscombiningmark (info.cnxt)) {
|
|
|
|
view_read_continue (view, &info);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
col+= w;
|
|
|
|
|
|
|
|
if (*offset == INVALID_OFFSET) {
|
|
|
|
if (*column < col + line->left) {
|
|
|
|
(*offset) = nroff_start;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
view_lc_set_param (offset, info.actual);
|
|
|
|
view_lc_set_param (column, line->left + col);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* macro, that iterate cache_line until stop holds,
|
|
|
|
* nf is function to iterate cache_line
|
|
|
|
* l is line to iterate and t is temporary line only */
|
|
|
|
#define view_move_to_stop(l,t,stop,nf) \
|
|
|
|
while (((t = nf (view, l)) != NULL) && (stop)) l = t;
|
|
|
|
|
|
|
|
/* make all cache_lines invalidet */
|
|
|
|
static void
|
|
|
|
view_reset_cache_lines (WView *view)
|
|
|
|
{
|
|
|
|
if (view->lines != NULL) {
|
|
|
|
view->lines->end = INVALID_OFFSET;
|
|
|
|
}
|
|
|
|
view->lines_end = NULL;
|
|
|
|
|
|
|
|
if (view->nroff_lines != NULL) {
|
|
|
|
view->nroff_lines->end = INVALID_OFFSET;
|
|
|
|
}
|
|
|
|
view->nroff_lines_end = NULL;
|
|
|
|
|
|
|
|
view->first_showed_line = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define MAX_UNLOADED_CACHE_LINE 100
|
|
|
|
|
|
|
|
/* free some cache_lines, if count of cache_lines is bigger
|
|
|
|
* than MAX_UNLOADED_CACHE_LINE */
|
|
|
|
static void
|
|
|
|
view_reduce_cache_lines (WView *view)
|
|
|
|
{
|
|
|
|
struct cache_line *line;
|
|
|
|
struct cache_line *next;
|
|
|
|
int li;
|
|
|
|
|
|
|
|
li = 0;
|
|
|
|
line = view->lines;
|
|
|
|
while (line != NULL && li < MAX_UNLOADED_CACHE_LINE) {
|
|
|
|
line = line->next;
|
|
|
|
li++;
|
|
|
|
}
|
|
|
|
if (line != NULL) line->prev->next = NULL;
|
|
|
|
while (line != NULL) {
|
|
|
|
next = line->next;
|
|
|
|
g_free (line);
|
|
|
|
line = next;
|
|
|
|
}
|
|
|
|
view->lines_end = NULL;
|
|
|
|
|
|
|
|
line = view->nroff_lines;
|
|
|
|
while (line != NULL && li < MAX_UNLOADED_CACHE_LINE) {
|
|
|
|
line = line->next;
|
|
|
|
li++;
|
|
|
|
}
|
|
|
|
if (line != NULL) line->prev->next = NULL;
|
|
|
|
while (line != NULL) {
|
|
|
|
next = line->next;
|
|
|
|
g_free (line);
|
|
|
|
line = next;
|
|
|
|
}
|
|
|
|
view->nroff_lines_end = NULL;
|
|
|
|
|
|
|
|
view->first_showed_line = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* return first cache_line for actual mode (normal / nroff) */
|
|
|
|
static struct cache_line *
|
|
|
|
view_get_first_line (WView *view)
|
|
|
|
{
|
|
|
|
struct cache_line **first_line;
|
|
|
|
|
|
|
|
first_line = (view->text_nroff_mode) ?
|
|
|
|
&(view->nroff_lines) : &(view->lines);
|
|
|
|
|
|
|
|
if (*first_line == NULL) {
|
|
|
|
(*first_line) = g_new0 (struct cache_line, 1);
|
|
|
|
(*first_line)->end = INVALID_OFFSET;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((*first_line)->end == INVALID_OFFSET)
|
|
|
|
view_load_cache_line (view, *first_line);
|
|
|
|
|
|
|
|
return (*first_line);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* return following chahe_line or NULL */
|
|
|
|
static struct cache_line*
|
|
|
|
view_get_next_line (WView *view, struct cache_line *line)
|
|
|
|
{
|
|
|
|
struct cache_line *result;
|
|
|
|
|
|
|
|
if (line->next != NULL) {
|
|
|
|
result = line->next;
|
|
|
|
|
|
|
|
if (result->end == INVALID_OFFSET)
|
|
|
|
view_load_cache_line (view, result);
|
|
|
|
|
|
|
|
return (result->width != (screen_dimen) (-1)) ? result : NULL;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* return last cache_line, it could take same time, because whole read text must
|
|
|
|
* be read (only once) */
|
|
|
|
static struct cache_line *
|
|
|
|
view_get_last_line (WView *view)
|
|
|
|
{
|
|
|
|
struct cache_line *result;
|
|
|
|
struct cache_line *next;
|
|
|
|
|
|
|
|
result = (view->text_nroff_mode) ?
|
|
|
|
view->nroff_lines_end : view->nroff_lines_end;
|
|
|
|
|
|
|
|
if (result != NULL) return result;
|
|
|
|
|
|
|
|
if (view->first_showed_line == NULL)
|
|
|
|
view->first_showed_line = view_get_first_line (view);
|
|
|
|
|
|
|
|
result = view->first_showed_line;
|
|
|
|
next = view_get_next_line (view, result);
|
|
|
|
while (next != NULL) {
|
|
|
|
result = next;
|
|
|
|
next = view_get_next_line (view, result);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* return previous cache_line or NULL */
|
|
|
|
static struct cache_line *
|
|
|
|
view_get_previous_line (WView *view, struct cache_line *line)
|
|
|
|
{
|
|
|
|
return line->prev;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* return first displayed cache_line */
|
|
|
|
static struct cache_line *
|
|
|
|
view_get_first_showed_line (WView *view)
|
|
|
|
{
|
|
|
|
struct cache_line *result;
|
|
|
|
|
|
|
|
if (view->first_showed_line == NULL)
|
|
|
|
view->first_showed_line = view_get_first_line (view);
|
|
|
|
|
|
|
|
result = view->first_showed_line;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* return first cache_line with same number as line */
|
|
|
|
static struct cache_line *
|
|
|
|
view_get_start_of_whole_line (WView *view, struct cache_line *line)
|
|
|
|
{
|
|
|
|
struct cache_line *t;
|
|
|
|
|
|
|
|
if (line != NULL) {
|
|
|
|
view_move_to_stop (line, t, t->number == line->number, view_get_previous_line)
|
|
|
|
return line;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* return last cache_line with same number as line */
|
|
|
|
static struct cache_line *
|
|
|
|
view_get_end_of_whole_line (WView *view, struct cache_line *line)
|
|
|
|
{
|
|
|
|
struct cache_line *t;
|
|
|
|
|
|
|
|
if (line != NULL) {
|
|
|
|
view_move_to_stop (line, t, t->number == line->number, view_get_next_line)
|
|
|
|
return line;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* return last cache_line, that has number lesser than line
|
|
|
|
* or NULL */
|
|
|
|
static struct cache_line *
|
|
|
|
view_get_previous_whole_line (WView *view, struct cache_line *line)
|
|
|
|
{
|
|
|
|
line = view_get_start_of_whole_line (view, line);
|
|
|
|
return view_get_previous_line (view, line);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* return first cache_line, that has number greater than line
|
|
|
|
* or NULL */
|
|
|
|
static struct cache_line *
|
|
|
|
view_get_next_whole_line (WView *view, struct cache_line *line)
|
|
|
|
{
|
|
|
|
line = view_get_end_of_whole_line (view, line);
|
|
|
|
return view_get_next_line (view, line);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* return sum of widths of all cache_lines that has same number as line */
|
|
|
|
static screen_dimen
|
|
|
|
view_width_of_whole_line (WView *view, struct cache_line *line)
|
|
|
|
{
|
|
|
|
struct cache_line *next;
|
|
|
|
screen_dimen result = 0;
|
|
|
|
|
|
|
|
line = view_get_start_of_whole_line (view, line);
|
|
|
|
next = view_get_next_line (view, line);
|
|
|
|
while ((next != NULL) && (next->number == line->number)) {
|
|
|
|
result+= line->left + line->width;
|
|
|
|
line = next;
|
|
|
|
next = view_get_next_line (view, line);
|
|
|
|
}
|
|
|
|
result+= line->left + line->width;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* return sum of widths of cache_lines before line, that has same number as line */
|
|
|
|
static screen_dimen
|
|
|
|
view_width_of_whole_line_before (WView *view, struct cache_line *line)
|
|
|
|
{
|
|
|
|
struct cache_line *next;
|
|
|
|
screen_dimen result = 0;
|
|
|
|
|
|
|
|
next = view_get_start_of_whole_line (view, line);
|
|
|
|
while (next != line) {
|
|
|
|
result+= next->left + next->width;
|
|
|
|
next = view_get_next_line (view, next);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* map column to offset and cache_line */
|
|
|
|
static offset_type
|
|
|
|
view_column_to_offset (WView *view, struct cache_line **line, offset_type column)
|
|
|
|
{
|
|
|
|
struct cache_line *next;
|
|
|
|
offset_type result;
|
|
|
|
|
|
|
|
*line = view_get_start_of_whole_line (view, *line);
|
|
|
|
|
|
|
|
while (column >= (*line)->left + (*line)->width) {
|
|
|
|
column-= (*line)->left + (*line)->width;
|
|
|
|
result = (*line)->end;
|
|
|
|
next = view_get_next_line (view, *line);
|
|
|
|
if ((next == NULL) || (next->number != (*line)->number)) break;
|
|
|
|
(*line) = next;
|
|
|
|
}
|
|
|
|
// if (column < (*line)->left + (*line)->width) {
|
|
|
|
result = INVALID_OFFSET,
|
|
|
|
view_map_offset_and_column (view, *line, &column, &result);
|
|
|
|
// }
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* map offset to cache_line */
|
|
|
|
static struct cache_line *
|
|
|
|
view_offset_to_line (WView *view, offset_type from)
|
|
|
|
{
|
|
|
|
struct cache_line *result;
|
|
|
|
struct cache_line *t;
|
|
|
|
|
|
|
|
result = view_get_first_line (view);
|
|
|
|
|
|
|
|
view_move_to_stop (result, t, result->end <= from, view_get_next_line)
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* map offset to cache_line, searching starts from line */
|
|
|
|
static struct cache_line *
|
|
|
|
view_offset_to_line_from (WView *view, offset_type from, struct cache_line *line)
|
|
|
|
{
|
|
|
|
struct cache_line *result;
|
|
|
|
struct cache_line *t;
|
|
|
|
|
|
|
|
result = line;
|
|
|
|
|
|
|
|
view_move_to_stop (result, t, result->start > from, view_get_previous_line)
|
|
|
|
view_move_to_stop (result, t, result->end <= from, view_get_next_line)
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* mam offset to column */
|
|
|
|
static screen_dimen
|
|
|
|
view_offset_to_column (WView *view, struct cache_line *line, offset_type from)
|
|
|
|
{
|
|
|
|
offset_type result = INVALID_OFFSET;
|
|
|
|
|
|
|
|
view_map_offset_and_column (view, line, &result, &from);
|
|
|
|
|
|
|
|
result+= view_width_of_whole_line_before (view, line);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2005-07-06 23:12:25 +04:00
|
|
|
static void
|
|
|
|
view_compute_areas (WView *view)
|
2005-04-17 14:14:18 +04:00
|
|
|
{
|
2005-07-06 23:12:25 +04:00
|
|
|
struct area view_area;
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
struct cache_line *next;
|
2005-07-07 21:49:01 +04:00
|
|
|
screen_dimen height, rest, y;
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
screen_dimen old_width;
|
|
|
|
|
|
|
|
old_width = view->data_area.width;
|
2005-04-17 14:14:18 +04:00
|
|
|
|
2005-07-06 23:12:25 +04:00
|
|
|
/* The viewer is surrounded by a frame of size view->dpy_frame_size.
|
|
|
|
* Inside that frame, there are: The status line (at the top),
|
|
|
|
* the data area and an optional ruler, which is shown above or
|
|
|
|
* below the data area. */
|
2005-04-17 14:14:18 +04:00
|
|
|
|
2005-07-07 20:48:55 +04:00
|
|
|
view_area.top = view->dpy_frame_size;
|
|
|
|
view_area.left = view->dpy_frame_size;
|
2005-07-06 23:12:25 +04:00
|
|
|
view_area.height = dimen_doz(view->widget.lines, 2 * view->dpy_frame_size);
|
|
|
|
view_area.width = dimen_doz(view->widget.cols, 2 * view->dpy_frame_size);
|
2005-04-17 14:14:18 +04:00
|
|
|
|
2005-07-12 10:04:38 +04:00
|
|
|
/* Most coordinates of the areas equal those of the whole viewer */
|
2005-07-06 23:12:25 +04:00
|
|
|
view->status_area = view_area;
|
|
|
|
view->ruler_area = view_area;
|
|
|
|
view->data_area = view_area;
|
2005-04-14 04:43:34 +04:00
|
|
|
|
2005-07-12 10:04:38 +04:00
|
|
|
/* Compute the heights of the areas */
|
2005-07-07 21:49:01 +04:00
|
|
|
rest = view_area.height;
|
2005-08-16 12:47:15 +04:00
|
|
|
|
2005-07-07 21:49:01 +04:00
|
|
|
height = dimen_min(rest, 1);
|
|
|
|
view->status_area.height = height;
|
|
|
|
rest -= height;
|
2005-08-16 12:47:15 +04:00
|
|
|
|
2005-07-07 21:49:01 +04:00
|
|
|
height = dimen_min(rest, (ruler == RULER_NONE || view->hex_mode) ? 0 : 2);
|
|
|
|
view->ruler_area.height = height;
|
|
|
|
rest -= height;
|
2005-08-16 12:47:15 +04:00
|
|
|
|
2005-07-07 21:49:01 +04:00
|
|
|
view->data_area.height = rest;
|
2005-04-16 22:53:51 +04:00
|
|
|
|
2005-07-12 10:04:38 +04:00
|
|
|
/* Compute the position of the areas */
|
2005-08-16 12:47:15 +04:00
|
|
|
y = view_area.top;
|
|
|
|
|
|
|
|
view->status_area.top = y;
|
|
|
|
y += view->status_area.height;
|
|
|
|
|
2005-07-06 23:12:25 +04:00
|
|
|
if (ruler == RULER_TOP) {
|
|
|
|
view->ruler_area.top = y;
|
|
|
|
y += view->ruler_area.height;
|
|
|
|
}
|
2005-08-16 12:47:15 +04:00
|
|
|
|
2005-07-06 23:12:25 +04:00
|
|
|
view->data_area.top = y;
|
|
|
|
y += view->data_area.height;
|
2005-08-16 12:47:15 +04:00
|
|
|
|
2005-07-06 23:12:25 +04:00
|
|
|
if (ruler == RULER_BOTTOM) {
|
|
|
|
view->ruler_area.top = y;
|
|
|
|
y += view->ruler_area.height;
|
|
|
|
}
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
|
|
|
|
if (old_width != view->data_area.width) {
|
|
|
|
view_reset_cache_lines (view);
|
|
|
|
view->first_showed_line = view_get_first_line (view);
|
|
|
|
next = view_get_next_line (view, view->first_showed_line);
|
|
|
|
while ((next != NULL) && (view->first_showed_line->end <= view->dpy_start)) {
|
|
|
|
view->first_showed_line = next;
|
|
|
|
next = view_get_next_line (view, view->first_showed_line);
|
|
|
|
}
|
|
|
|
view->dpy_start = view->first_showed_line->start;
|
|
|
|
}
|
2005-04-16 22:53:51 +04:00
|
|
|
}
|
|
|
|
|
2005-08-21 16:04:20 +04:00
|
|
|
static void
|
|
|
|
view_hexedit_free_change_list (WView *view)
|
|
|
|
{
|
|
|
|
struct hexedit_change_node *curr, *next;
|
|
|
|
|
|
|
|
for (curr = view->change_list; curr != NULL; curr = next) {
|
|
|
|
next = curr->next;
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (curr);
|
2005-08-21 16:04:20 +04:00
|
|
|
}
|
|
|
|
view->change_list = NULL;
|
|
|
|
view->dirty++;
|
|
|
|
}
|
|
|
|
|
2005-05-26 14:17:38 +04:00
|
|
|
/* {{{ Growing buffer }}} */
|
2005-05-26 13:08:54 +04:00
|
|
|
|
2005-05-26 14:17:38 +04:00
|
|
|
static void
|
|
|
|
view_init_growbuf (WView *view)
|
|
|
|
{
|
|
|
|
view->growbuf_in_use = TRUE;
|
|
|
|
view->growbuf_blockptr = NULL;
|
|
|
|
view->growbuf_blocks = 0;
|
2005-08-16 12:59:14 +04:00
|
|
|
view->growbuf_lastindex = VIEW_PAGE_SIZE;
|
2005-05-26 14:17:38 +04:00
|
|
|
view->growbuf_finished = FALSE;
|
|
|
|
}
|
2005-05-26 14:04:26 +04:00
|
|
|
|
2005-05-26 14:17:38 +04:00
|
|
|
static void
|
|
|
|
view_growbuf_free (WView *view)
|
|
|
|
{
|
|
|
|
size_t i;
|
2005-05-26 14:04:26 +04:00
|
|
|
|
2005-05-26 14:17:38 +04:00
|
|
|
assert (view->growbuf_in_use);
|
2005-05-26 14:04:26 +04:00
|
|
|
|
2005-05-26 14:17:38 +04:00
|
|
|
for (i = 0; i < view->growbuf_blocks; i++)
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (view->growbuf_blockptr[i]);
|
|
|
|
g_free (view->growbuf_blockptr);
|
2005-05-26 14:17:38 +04:00
|
|
|
view->growbuf_blockptr = NULL;
|
|
|
|
view->growbuf_in_use = FALSE;
|
|
|
|
}
|
2005-05-26 13:08:54 +04:00
|
|
|
|
2005-05-26 13:51:03 +04:00
|
|
|
static offset_type
|
2005-06-14 18:13:11 +04:00
|
|
|
view_growbuf_filesize (WView *view)
|
2005-05-26 13:51:03 +04:00
|
|
|
{
|
|
|
|
assert(view->growbuf_in_use);
|
|
|
|
|
|
|
|
if (view->growbuf_blocks == 0)
|
2005-07-03 19:31:55 +04:00
|
|
|
return 0;
|
2005-05-26 13:51:03 +04:00
|
|
|
else
|
2005-08-16 12:51:55 +04:00
|
|
|
return ((offset_type) view->growbuf_blocks - 1) * VIEW_PAGE_SIZE
|
|
|
|
+ view->growbuf_lastindex;
|
2005-05-26 13:51:03 +04:00
|
|
|
}
|
|
|
|
|
2005-05-26 13:34:44 +04:00
|
|
|
/* Copies the output from the pipe to the growing buffer, until either
|
2005-08-16 12:00:15 +04:00
|
|
|
* the end-of-pipe is reached or the interval [0..ofs) of the growing
|
2005-05-26 13:34:44 +04:00
|
|
|
* buffer is completely filled. */
|
|
|
|
static void
|
|
|
|
view_growbuf_read_until (WView *view, offset_type ofs)
|
|
|
|
{
|
|
|
|
ssize_t nread;
|
|
|
|
byte *p;
|
|
|
|
size_t bytesfree;
|
2009-02-06 01:46:07 +03:00
|
|
|
gboolean short_read;
|
2005-05-26 13:34:44 +04:00
|
|
|
|
|
|
|
assert (view->growbuf_in_use);
|
|
|
|
|
|
|
|
if (view->growbuf_finished)
|
|
|
|
return;
|
|
|
|
|
2005-08-06 22:19:14 +04:00
|
|
|
short_read = FALSE;
|
|
|
|
while (view_growbuf_filesize (view) < ofs || short_read) {
|
2005-08-16 12:59:14 +04:00
|
|
|
if (view->growbuf_lastindex == VIEW_PAGE_SIZE) {
|
2005-07-12 10:04:38 +04:00
|
|
|
/* Append a new block to the growing buffer */
|
2005-07-03 19:31:55 +04:00
|
|
|
byte *newblock = g_try_malloc (VIEW_PAGE_SIZE);
|
|
|
|
byte **newblocks = g_try_malloc (sizeof (*newblocks) * (view->growbuf_blocks + 1));
|
|
|
|
if (!newblock || !newblocks) {
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (newblock);
|
|
|
|
g_free (newblocks);
|
2005-07-03 19:31:55 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
memcpy (newblocks, view->growbuf_blockptr, sizeof (*newblocks) * view->growbuf_blocks);
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (view->growbuf_blockptr);
|
2005-07-03 19:31:55 +04:00
|
|
|
view->growbuf_blockptr = newblocks;
|
|
|
|
view->growbuf_blockptr[view->growbuf_blocks++] = newblock;
|
|
|
|
view->growbuf_lastindex = 0;
|
|
|
|
}
|
|
|
|
p = view->growbuf_blockptr[view->growbuf_blocks - 1] + view->growbuf_lastindex;
|
|
|
|
bytesfree = VIEW_PAGE_SIZE - view->growbuf_lastindex;
|
2005-05-26 13:34:44 +04:00
|
|
|
|
|
|
|
if (view->datasource == DS_STDIO_PIPE) {
|
|
|
|
nread = fread (p, 1, bytesfree, view->ds_stdio_pipe);
|
|
|
|
if (nread == 0) {
|
|
|
|
view->growbuf_finished = TRUE;
|
|
|
|
(void) pclose (view->ds_stdio_pipe);
|
2005-07-14 01:30:28 +04:00
|
|
|
display (view);
|
2009-01-10 16:13:56 +03:00
|
|
|
close_error_pipe (D_NORMAL, NULL);
|
2005-05-26 13:34:44 +04:00
|
|
|
view->ds_stdio_pipe = NULL;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
} else {
|
2005-07-01 02:50:30 +04:00
|
|
|
assert (view->datasource == DS_VFS_PIPE);
|
2005-08-15 14:04:49 +04:00
|
|
|
do {
|
|
|
|
nread = mc_read (view->ds_vfs_pipe, p, bytesfree);
|
|
|
|
} while (nread == -1 && errno == EINTR);
|
2005-05-26 13:34:44 +04:00
|
|
|
if (nread == -1 || nread == 0) {
|
|
|
|
view->growbuf_finished = TRUE;
|
|
|
|
(void) mc_close (view->ds_vfs_pipe);
|
|
|
|
view->ds_vfs_pipe = -1;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2005-08-29 13:34:43 +04:00
|
|
|
short_read = ((size_t)nread < bytesfree);
|
2005-07-03 19:31:55 +04:00
|
|
|
view->growbuf_lastindex += nread;
|
2005-05-26 13:34:44 +04:00
|
|
|
}
|
2005-05-26 14:17:38 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
get_byte_growing_buffer (WView *view, offset_type byte_index)
|
|
|
|
{
|
|
|
|
offset_type pageno = byte_index / VIEW_PAGE_SIZE;
|
|
|
|
offset_type pageindex = byte_index % VIEW_PAGE_SIZE;
|
|
|
|
|
|
|
|
assert (view->growbuf_in_use);
|
|
|
|
|
|
|
|
if ((size_t) pageno != pageno)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
view_growbuf_read_until (view, byte_index + 1);
|
|
|
|
if (view->growbuf_blocks == 0)
|
|
|
|
return -1;
|
|
|
|
if (pageno < view->growbuf_blocks - 1)
|
|
|
|
return view->growbuf_blockptr[pageno][pageindex];
|
|
|
|
if (pageno == view->growbuf_blocks - 1 && pageindex < view->growbuf_lastindex)
|
|
|
|
return view->growbuf_blockptr[pageno][pageindex];
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* {{{ Data sources }}} */
|
|
|
|
|
|
|
|
/*
|
|
|
|
The data source provides the viewer with data from either a file, a
|
|
|
|
string or the output of a command. The get_byte() function can be
|
|
|
|
used to get the value of a byte at a specific offset. If the offset
|
|
|
|
is out of range, -1 is returned. The function get_byte_indexed(a,b)
|
|
|
|
returns the byte at the offset a+b, or -1 if a+b is out of range.
|
|
|
|
|
|
|
|
The view_set_byte() function has the effect that later calls to
|
|
|
|
get_byte() will return the specified byte for this offset. This
|
|
|
|
function is designed only for use by the hexedit component after
|
|
|
|
saving its changes. Inspect the source before you want to use it for
|
|
|
|
other purposes.
|
|
|
|
|
|
|
|
The view_get_filesize() function returns the current size of the
|
|
|
|
data source. If the growing buffer is used, this size may increase
|
2005-07-12 10:04:38 +04:00
|
|
|
later on. Use the view_may_still_grow() function when you want to
|
2005-05-26 14:17:38 +04:00
|
|
|
know if the size can change later.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static offset_type
|
2005-06-14 18:13:11 +04:00
|
|
|
view_get_filesize (WView *view)
|
2005-05-26 14:17:38 +04:00
|
|
|
{
|
|
|
|
switch (view->datasource) {
|
|
|
|
case DS_NONE:
|
|
|
|
return 0;
|
|
|
|
case DS_STDIO_PIPE:
|
|
|
|
case DS_VFS_PIPE:
|
2005-06-14 18:13:11 +04:00
|
|
|
return view_growbuf_filesize (view);
|
2005-05-26 14:17:38 +04:00
|
|
|
case DS_FILE:
|
|
|
|
return view->ds_file_filesize;
|
|
|
|
case DS_STRING:
|
|
|
|
return view->ds_string_len;
|
|
|
|
default:
|
|
|
|
assert(!"Unknown datasource type");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-02-06 01:46:07 +03:00
|
|
|
static inline gboolean
|
2005-06-14 18:13:11 +04:00
|
|
|
view_may_still_grow (WView *view)
|
2005-05-26 14:17:38 +04:00
|
|
|
{
|
2005-06-14 18:13:11 +04:00
|
|
|
return (view->growbuf_in_use && !view->growbuf_finished);
|
2005-05-26 14:17:38 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* returns TRUE if the idx lies in the half-open interval
|
|
|
|
* [offset; offset + size), FALSE otherwise.
|
|
|
|
*/
|
2009-02-06 01:46:07 +03:00
|
|
|
static inline gboolean
|
2005-05-26 14:17:38 +04:00
|
|
|
already_loaded (offset_type offset, offset_type idx, size_t size)
|
|
|
|
{
|
|
|
|
return (offset <= idx && idx - offset < size);
|
|
|
|
}
|
|
|
|
|
2005-06-28 02:11:55 +04:00
|
|
|
static inline void
|
2005-05-26 14:17:38 +04:00
|
|
|
view_file_load_data (WView *view, offset_type byte_index)
|
|
|
|
{
|
|
|
|
offset_type blockoffset;
|
|
|
|
ssize_t res;
|
|
|
|
size_t bytes_read;
|
|
|
|
|
2005-07-01 03:16:14 +04:00
|
|
|
assert (view->datasource == DS_FILE);
|
2005-07-01 02:50:30 +04:00
|
|
|
|
2005-05-26 14:17:38 +04:00
|
|
|
if (already_loaded (view->ds_file_offset, byte_index, view->ds_file_datalen))
|
|
|
|
return;
|
|
|
|
|
2006-12-30 16:16:54 +03:00
|
|
|
if (byte_index >= view->ds_file_filesize)
|
|
|
|
return;
|
|
|
|
|
2005-07-12 10:04:38 +04:00
|
|
|
blockoffset = offset_rounddown (byte_index, view->ds_file_datasize);
|
2005-05-26 14:17:38 +04:00
|
|
|
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 (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:
|
2005-07-12 10:04:38 +04:00
|
|
|
view->ds_file_datalen = 0;
|
2005-05-26 14:17:38 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
get_byte_none (WView *view, offset_type byte_index)
|
|
|
|
{
|
|
|
|
assert (view->datasource == DS_NONE);
|
|
|
|
(void) &view;
|
|
|
|
(void) byte_index;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2005-06-28 02:11:55 +04:00
|
|
|
static inline int
|
2005-05-26 14:17:38 +04:00
|
|
|
get_byte_file (WView *view, offset_type byte_index)
|
|
|
|
{
|
|
|
|
assert (view->datasource == DS_FILE);
|
|
|
|
|
|
|
|
view_file_load_data (view, byte_index);
|
|
|
|
if (already_loaded(view->ds_file_offset, byte_index, view->ds_file_datalen))
|
|
|
|
return view->ds_file_data[byte_index - view->ds_file_offset];
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
get_byte_string (WView *view, offset_type byte_index)
|
|
|
|
{
|
|
|
|
assert (view->datasource == DS_STRING);
|
|
|
|
if (byte_index < view->ds_string_len)
|
|
|
|
return view->ds_string_data[byte_index];
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2005-06-28 02:11:55 +04:00
|
|
|
static inline int
|
2005-05-26 14:17:38 +04:00
|
|
|
get_byte (WView *view, offset_type offset)
|
|
|
|
{
|
|
|
|
switch (view->datasource) {
|
|
|
|
case DS_STDIO_PIPE:
|
|
|
|
case DS_VFS_PIPE:
|
|
|
|
return get_byte_growing_buffer (view, offset);
|
|
|
|
case DS_FILE:
|
|
|
|
return get_byte_file (view, offset);
|
|
|
|
case DS_STRING:
|
|
|
|
return get_byte_string (view, offset);
|
|
|
|
case DS_NONE:
|
|
|
|
return get_byte_none (view, offset);
|
|
|
|
}
|
|
|
|
assert(!"Unknown datasource type");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int
|
|
|
|
get_byte_indexed (WView *view, offset_type base, offset_type ofs)
|
|
|
|
{
|
|
|
|
if (base <= OFFSETTYPE_MAX - ofs)
|
|
|
|
return get_byte (view, base + ofs);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
view_set_byte (WView *view, offset_type offset, byte b)
|
|
|
|
{
|
2005-07-03 18:01:25 +04:00
|
|
|
(void) &b;
|
2005-05-26 14:17:38 +04:00
|
|
|
assert (offset < view_get_filesize (view));
|
2005-07-01 02:50:30 +04:00
|
|
|
assert (view->datasource == DS_FILE);
|
|
|
|
view->ds_file_datalen = 0; /* just force reloading */
|
2005-05-26 14:17:38 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
view_set_datasource_none (WView *view)
|
|
|
|
{
|
|
|
|
view->datasource = DS_NONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
view_set_datasource_vfs_pipe (WView *view, int fd)
|
|
|
|
{
|
2005-07-01 02:50:30 +04:00
|
|
|
assert (fd != -1);
|
2005-05-26 14:17:38 +04:00
|
|
|
view->datasource = DS_VFS_PIPE;
|
|
|
|
view->ds_vfs_pipe = fd;
|
|
|
|
|
|
|
|
view_init_growbuf (view);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
view_set_datasource_stdio_pipe (WView *view, FILE *fp)
|
|
|
|
{
|
2005-07-01 02:50:30 +04:00
|
|
|
assert (fp != NULL);
|
2005-05-26 14:17:38 +04:00
|
|
|
view->datasource = DS_STDIO_PIPE;
|
|
|
|
view->ds_stdio_pipe = fp;
|
|
|
|
|
|
|
|
view_init_growbuf (view);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
view_set_datasource_string (WView *view, const char *s)
|
|
|
|
{
|
|
|
|
view->datasource = DS_STRING;
|
2009-02-06 01:40:32 +03:00
|
|
|
view->ds_string_data = (byte *) g_strdup (s);
|
2005-05-26 14:17:38 +04:00
|
|
|
view->ds_string_len = strlen (s);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
view_set_datasource_file (WView *view, int fd, const struct stat *st)
|
|
|
|
{
|
|
|
|
view->datasource = DS_FILE;
|
|
|
|
view->ds_file_fd = fd;
|
|
|
|
view->ds_file_filesize = st->st_size;
|
|
|
|
view->ds_file_offset = 0;
|
|
|
|
view->ds_file_data = g_malloc (4096);
|
|
|
|
view->ds_file_datalen = 0;
|
|
|
|
view->ds_file_datasize = 4096;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
view_close_datasource (WView *view)
|
|
|
|
{
|
|
|
|
switch (view->datasource) {
|
|
|
|
case DS_NONE:
|
|
|
|
break;
|
|
|
|
case DS_STDIO_PIPE:
|
|
|
|
if (view->ds_stdio_pipe != NULL) {
|
|
|
|
(void) pclose (view->ds_stdio_pipe);
|
2005-07-14 01:30:28 +04:00
|
|
|
display (view);
|
2009-01-10 16:13:56 +03:00
|
|
|
close_error_pipe (D_NORMAL, NULL);
|
2005-05-26 14:17:38 +04:00
|
|
|
view->ds_stdio_pipe = NULL;
|
|
|
|
}
|
|
|
|
view_growbuf_free (view);
|
|
|
|
break;
|
|
|
|
case DS_VFS_PIPE:
|
|
|
|
if (view->ds_vfs_pipe != -1) {
|
|
|
|
(void) mc_close (view->ds_vfs_pipe);
|
|
|
|
view->ds_vfs_pipe = -1;
|
|
|
|
}
|
|
|
|
view_growbuf_free (view);
|
|
|
|
break;
|
|
|
|
case DS_FILE:
|
|
|
|
(void) mc_close (view->ds_file_fd);
|
|
|
|
view->ds_file_fd = -1;
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (view->ds_file_data);
|
2005-05-26 14:17:38 +04:00
|
|
|
view->ds_file_data = NULL;
|
|
|
|
break;
|
|
|
|
case DS_STRING:
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (view->ds_string_data);
|
2005-05-26 14:17:38 +04:00
|
|
|
view->ds_string_data = NULL;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
assert (!"Unknown datasource type");
|
|
|
|
}
|
|
|
|
view->datasource = DS_NONE;
|
2005-05-26 13:46:48 +04:00
|
|
|
}
|
|
|
|
|
2005-05-26 13:08:54 +04:00
|
|
|
/* {{{ Cursor Movement }}} */
|
|
|
|
|
|
|
|
/*
|
|
|
|
The following variables have to do with the current position and are
|
|
|
|
updated by the cursor movement functions.
|
|
|
|
|
2005-08-22 22:31:51 +04:00
|
|
|
In hex view and wrapped text view mode, dpy_start marks the offset of
|
|
|
|
the top-left corner on the screen, in non-wrapping text mode it is
|
|
|
|
the beginning of the current line. In hex mode, hex_cursor is the
|
|
|
|
offset of the cursor. In non-wrapping text mode, dpy_text_column is
|
|
|
|
the number of columns that are hidden on the left side on the screen.
|
2005-05-26 13:08:54 +04:00
|
|
|
|
2005-08-22 22:31:51 +04:00
|
|
|
In hex mode, dpy_start is updated by the view_fix_cursor_position()
|
|
|
|
function in order to keep the other functions simple. In
|
|
|
|
non-wrapping text mode dpy_start and dpy_text_column are normalized
|
|
|
|
such that dpy_text_column < view_get_datacolumns().
|
|
|
|
*/
|
2005-05-26 13:08:54 +04:00
|
|
|
|
2005-05-26 13:22:51 +04:00
|
|
|
/* prototypes for functions used by view_moveto_bottom() */
|
|
|
|
static void view_move_up (WView *, offset_type);
|
|
|
|
static void view_moveto_bol (WView *);
|
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
/* set view->first_showed_line and view->dpy_start
|
|
|
|
* use view->dpy_text_column in nowrap mode */
|
|
|
|
static void
|
|
|
|
view_set_first_showed (WView *view, struct cache_line *line)
|
|
|
|
{
|
|
|
|
if (view->text_wrap_mode) {
|
|
|
|
view->dpy_start = line->start;
|
|
|
|
view->first_showed_line = line;
|
|
|
|
} else {
|
|
|
|
view->dpy_start = view_column_to_offset (view, &line, view->dpy_text_column);
|
|
|
|
view->first_showed_line = line;
|
|
|
|
}
|
|
|
|
if (view->search_start == view->search_end) {
|
|
|
|
view->search_start = view->dpy_start;
|
|
|
|
view->search_end = view->dpy_start;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-05-26 13:08:54 +04:00
|
|
|
static void
|
2005-09-02 00:49:17 +04:00
|
|
|
view_scroll_to_cursor (WView *view)
|
2005-05-26 13:08:54 +04:00
|
|
|
{
|
|
|
|
if (view->hex_mode) {
|
|
|
|
const offset_type bytes = view->bytes_per_line;
|
2005-07-06 23:12:25 +04:00
|
|
|
const offset_type displaysize = view->data_area.height * bytes;
|
2005-05-26 13:08:54 +04:00
|
|
|
const offset_type cursor = view->hex_cursor;
|
2005-08-22 22:31:51 +04:00
|
|
|
offset_type topleft = view->dpy_start;
|
2005-05-26 13:08:54 +04:00
|
|
|
|
|
|
|
if (topleft + displaysize <= cursor)
|
|
|
|
topleft = offset_rounddown (cursor, bytes)
|
2005-07-03 19:31:55 +04:00
|
|
|
- (displaysize - bytes);
|
2005-05-26 13:08:54 +04:00
|
|
|
if (cursor < topleft)
|
|
|
|
topleft = offset_rounddown (cursor, bytes);
|
2005-08-22 22:31:51 +04:00
|
|
|
view->dpy_start = topleft;
|
2005-05-26 13:08:54 +04:00
|
|
|
} else if (view->text_wrap_mode) {
|
|
|
|
view->dpy_text_column = 0;
|
|
|
|
} else {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2009-02-06 01:46:07 +03:00
|
|
|
view_movement_fixups (WView *view, gboolean reset_search)
|
2005-05-26 13:08:54 +04:00
|
|
|
{
|
2005-09-02 00:49:17 +04:00
|
|
|
view_scroll_to_cursor (view);
|
2005-05-26 13:08:54 +04:00
|
|
|
if (reset_search) {
|
2005-08-22 22:31:51 +04:00
|
|
|
view->search_start = view->dpy_start;
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
view->search_end = view->dpy_start;
|
2005-05-26 13:08:54 +04:00
|
|
|
}
|
|
|
|
view->dirty++;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
view_moveto_top (WView *view)
|
|
|
|
{
|
2005-08-22 22:31:51 +04:00
|
|
|
view->dpy_start = 0;
|
2005-08-22 23:19:51 +04:00
|
|
|
view->hex_cursor = 0;
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
view->first_showed_line = view_get_first_line (view);
|
2005-08-22 23:19:51 +04:00
|
|
|
view->dpy_text_column = 0;
|
2005-05-26 13:08:54 +04:00
|
|
|
view_movement_fixups (view, TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
view_moveto_bottom (WView *view)
|
|
|
|
{
|
|
|
|
offset_type datalines, lines_up, filesize, last_offset;
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
struct cache_line *line;
|
2005-05-26 13:08:54 +04:00
|
|
|
|
|
|
|
if (view->growbuf_in_use)
|
|
|
|
view_growbuf_read_until (view, OFFSETTYPE_MAX);
|
|
|
|
|
|
|
|
filesize = view_get_filesize (view);
|
2005-07-06 23:12:25 +04:00
|
|
|
last_offset = offset_doz(filesize, 1);
|
|
|
|
datalines = view->data_area.height;
|
|
|
|
lines_up = offset_doz(datalines, 1);
|
2005-05-26 13:08:54 +04:00
|
|
|
|
|
|
|
if (view->hex_mode) {
|
|
|
|
view->hex_cursor = filesize;
|
|
|
|
view_move_up (view, lines_up);
|
|
|
|
view->hex_cursor = last_offset;
|
|
|
|
} else {
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
line = view_get_last_line (view);
|
|
|
|
if (!view->text_wrap_mode)
|
|
|
|
line = view_get_start_of_whole_line (view, line);
|
|
|
|
view_set_first_showed (view, line);
|
|
|
|
view->dpy_text_column = 0;
|
2005-05-26 13:08:54 +04:00
|
|
|
view_move_up (view, lines_up);
|
|
|
|
}
|
|
|
|
view_movement_fixups (view, TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
view_moveto_bol (WView *view)
|
|
|
|
{
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
struct cache_line *line;
|
|
|
|
|
2005-05-26 13:08:54 +04:00
|
|
|
if (view->hex_mode) {
|
|
|
|
view->hex_cursor -= view->hex_cursor % view->bytes_per_line;
|
|
|
|
} else if (view->text_wrap_mode) {
|
|
|
|
/* do nothing */
|
|
|
|
} else {
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
line = view_get_first_showed_line (view);
|
|
|
|
line = view_get_start_of_whole_line (view, line);
|
2005-05-26 13:08:54 +04:00
|
|
|
view->dpy_text_column = 0;
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
view_set_first_showed (view, line);
|
2005-05-26 13:08:54 +04:00
|
|
|
}
|
|
|
|
view_movement_fixups (view, TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
view_moveto_eol (WView *view)
|
|
|
|
{
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
const screen_dimen width = view->data_area.width;
|
|
|
|
struct cache_line *line;
|
|
|
|
screen_dimen w;
|
|
|
|
|
2005-05-26 13:08:54 +04:00
|
|
|
if (view->hex_mode) {
|
|
|
|
offset_type filesize, bol;
|
|
|
|
|
|
|
|
bol = offset_rounddown (view->hex_cursor, view->bytes_per_line);
|
|
|
|
if (get_byte_indexed (view, bol, view->bytes_per_line - 1) != -1) {
|
|
|
|
view->hex_cursor = bol + view->bytes_per_line - 1;
|
|
|
|
} else {
|
|
|
|
filesize = view_get_filesize (view);
|
2005-07-06 23:12:25 +04:00
|
|
|
view->hex_cursor = offset_doz(filesize, 1);
|
2005-05-26 13:08:54 +04:00
|
|
|
}
|
|
|
|
} else if (view->text_wrap_mode) {
|
|
|
|
/* nothing to do */
|
|
|
|
} else {
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
line = view_get_first_showed_line (view);
|
|
|
|
line = view_get_start_of_whole_line (view, line);
|
|
|
|
w = view_width_of_whole_line (view, line);
|
|
|
|
if (w > width) {
|
|
|
|
view->dpy_text_column = w - width;
|
|
|
|
} else {
|
|
|
|
// if (w + width <= view->dpy_text_column) {
|
|
|
|
view->dpy_text_column = 0;
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
view_set_first_showed (view, line);
|
2005-05-26 13:08:54 +04:00
|
|
|
}
|
|
|
|
view_movement_fixups (view, FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
view_moveto_offset (WView *view, offset_type offset)
|
|
|
|
{
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
struct cache_line *line;
|
|
|
|
|
2005-05-26 13:08:54 +04:00
|
|
|
if (view->hex_mode) {
|
|
|
|
view->hex_cursor = offset;
|
2005-08-22 22:31:51 +04:00
|
|
|
view->dpy_start = offset - offset % view->bytes_per_line;
|
2005-05-26 13:08:54 +04:00
|
|
|
} else {
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
line = view_offset_to_line (view, offset);
|
|
|
|
view->dpy_start = (view->text_wrap_mode) ? line->start : offset;
|
|
|
|
view->first_showed_line = line;
|
|
|
|
view->dpy_text_column = (view->text_wrap_mode) ?
|
|
|
|
0 : view_offset_to_column (view, line, offset);
|
2005-05-26 13:08:54 +04:00
|
|
|
}
|
|
|
|
view_movement_fixups (view, TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
view_moveto (WView *view, offset_type row, offset_type col)
|
2005-05-26 13:08:54 +04:00
|
|
|
{
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
struct cache_line *act;
|
|
|
|
struct cache_line *t;
|
|
|
|
|
|
|
|
act = view_get_first_line (view);
|
|
|
|
view_move_to_stop (act, t, act->number != row, view_get_next_line)
|
|
|
|
|
|
|
|
view->dpy_text_column = (view->text_wrap_mode) ? 0 : col;
|
|
|
|
view->dpy_start = view_column_to_offset (view, &act, col);
|
|
|
|
view->dpy_start = (view->text_wrap_mode) ? act->start : view->dpy_start;
|
|
|
|
view->first_showed_line = act;
|
2005-05-26 13:08:54 +04:00
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
if (view->hex_mode)
|
|
|
|
view_moveto_offset (view, view->dpy_start);
|
2005-05-26 13:08:54 +04:00
|
|
|
}
|
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
/* extendet view_move_to_stop, now has counter, too */
|
|
|
|
#define view_count_to_stop(l,t,i,stop,nf)\
|
|
|
|
while (((t = nf(view, l)) != NULL) && (stop)) {\
|
|
|
|
l = t;i++;}
|
|
|
|
|
2005-05-26 13:08:54 +04:00
|
|
|
static void
|
|
|
|
view_move_up (WView *view, offset_type lines)
|
|
|
|
{
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
struct cache_line *line, *t;
|
|
|
|
int li;
|
|
|
|
|
2005-05-26 13:08:54 +04:00
|
|
|
if (view->hex_mode) {
|
2005-06-14 17:34:41 +04:00
|
|
|
offset_type bytes = lines * view->bytes_per_line;
|
|
|
|
if (view->hex_cursor >= bytes) {
|
|
|
|
view->hex_cursor -= bytes;
|
2005-08-22 22:31:51 +04:00
|
|
|
if (view->hex_cursor < view->dpy_start)
|
|
|
|
view->dpy_start = offset_doz (view->dpy_start, bytes);
|
2005-05-26 13:08:54 +04:00
|
|
|
} else {
|
|
|
|
view->hex_cursor %= view->bytes_per_line;
|
|
|
|
}
|
|
|
|
} else if (view->text_wrap_mode) {
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
line = view_get_first_showed_line (view);
|
|
|
|
li = 0;
|
|
|
|
view_count_to_stop (line, t, li, (li < lines), view_get_previous_line)
|
|
|
|
view_set_first_showed (view, line);
|
2005-05-26 13:08:54 +04:00
|
|
|
} else {
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
line = view_get_first_showed_line (view);
|
|
|
|
li = 0;
|
|
|
|
view_count_to_stop (line, t, li, (li < lines), view_get_previous_whole_line)
|
|
|
|
view_set_first_showed (view, line);
|
2005-05-26 13:08:54 +04:00
|
|
|
}
|
|
|
|
view_movement_fixups (view, (lines != 1));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
view_move_down (WView *view, offset_type lines)
|
|
|
|
{
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
struct cache_line *line;
|
|
|
|
struct cache_line *t;
|
|
|
|
int li;
|
|
|
|
|
|
|
|
void
|
|
|
|
return_up (struct cache_line * (*ne) (WView *, struct cache_line *),
|
|
|
|
struct cache_line * (*pr) (WView *, struct cache_line *))
|
|
|
|
{
|
|
|
|
li = 0;
|
|
|
|
t = line;
|
|
|
|
while ((t != NULL) && (li < view->data_area.height)) {
|
|
|
|
li++;
|
|
|
|
t = ne (view, t);
|
|
|
|
}
|
|
|
|
li = view->data_area.height - li;
|
|
|
|
t = pr (view, line);
|
|
|
|
while ((t != NULL) && (li > 0)) {
|
|
|
|
line = t;
|
|
|
|
t = pr (view, line);
|
|
|
|
li--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-05-26 13:08:54 +04:00
|
|
|
if (view->hex_mode) {
|
|
|
|
offset_type i, limit, last_byte;
|
|
|
|
|
|
|
|
last_byte = view_get_filesize (view);
|
|
|
|
if (last_byte >= (offset_type) 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)
|
2005-08-22 22:31:51 +04:00
|
|
|
view->dpy_start += view->bytes_per_line;
|
2005-05-26 13:08:54 +04:00
|
|
|
}
|
2005-08-18 06:26:39 +04:00
|
|
|
|
2005-07-11 11:26:31 +04:00
|
|
|
} else if (view->text_wrap_mode) {
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
line = view_get_first_showed_line (view);
|
|
|
|
li = 0;
|
|
|
|
view_count_to_stop (line, t, li, li < lines, view_get_next_line)
|
|
|
|
|
|
|
|
// return_up (view_get_next_line, view_get_previous_line);
|
|
|
|
view_set_first_showed (view, line);
|
2005-07-11 11:26:31 +04:00
|
|
|
} else {
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
line = view_get_first_showed_line (view);
|
|
|
|
li = 0;
|
|
|
|
view_count_to_stop (line, t, li, li < lines, view_get_next_whole_line)
|
2005-07-11 11:26:31 +04:00
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
// return_up (view_get_next_whole_line, view_get_previous_whole_line);
|
|
|
|
view_set_first_showed (view, line);
|
2005-05-26 13:08:54 +04:00
|
|
|
}
|
|
|
|
view_movement_fixups (view, (lines != 1));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
view_move_left (WView *view, offset_type columns)
|
|
|
|
{
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
struct cache_line *line;
|
|
|
|
|
2005-05-26 13:08:54 +04:00
|
|
|
if (view->hex_mode) {
|
|
|
|
assert (columns == 1);
|
|
|
|
if (view->hexview_in_text || !view->hexedit_lownibble) {
|
|
|
|
if (view->hex_cursor > 0)
|
|
|
|
view->hex_cursor--;
|
|
|
|
}
|
|
|
|
if (!view->hexview_in_text)
|
|
|
|
view->hexedit_lownibble = !view->hexedit_lownibble;
|
|
|
|
} else if (view->text_wrap_mode) {
|
|
|
|
/* nothing to do */
|
|
|
|
} else {
|
|
|
|
if (view->dpy_text_column >= columns)
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
view->dpy_text_column-= columns;
|
2005-05-26 13:08:54 +04:00
|
|
|
else
|
|
|
|
view->dpy_text_column = 0;
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
|
|
|
|
line = view_get_first_showed_line (view);
|
|
|
|
view_set_first_showed (view, line);
|
2005-05-26 13:08:54 +04:00
|
|
|
}
|
|
|
|
view_movement_fixups (view, FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
view_move_right (WView *view, offset_type columns)
|
|
|
|
{
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
struct cache_line *line;
|
|
|
|
|
2005-05-26 13:08:54 +04:00
|
|
|
if (view->hex_mode) {
|
|
|
|
assert (columns == 1);
|
|
|
|
if (view->hexview_in_text || view->hexedit_lownibble) {
|
|
|
|
if (get_byte_indexed (view, view->hex_cursor, 1) != -1)
|
|
|
|
view->hex_cursor++;
|
|
|
|
}
|
|
|
|
if (!view->hexview_in_text)
|
|
|
|
view->hexedit_lownibble = !view->hexedit_lownibble;
|
|
|
|
} else if (view->text_wrap_mode) {
|
|
|
|
/* nothing to do */
|
|
|
|
} else {
|
|
|
|
view->dpy_text_column += columns;
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
line = view_get_first_showed_line (view);
|
|
|
|
view_set_first_showed (view, line);
|
2005-05-26 13:08:54 +04:00
|
|
|
}
|
|
|
|
view_movement_fixups (view, FALSE);
|
|
|
|
}
|
|
|
|
|
2005-08-29 00:38:53 +04:00
|
|
|
/* {{{ Toggling of viewer modes }}} */
|
|
|
|
|
|
|
|
static void
|
|
|
|
view_toggle_hex_mode (WView *view)
|
|
|
|
{
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
struct cache_line *line;
|
|
|
|
|
2005-08-29 00:38:53 +04:00
|
|
|
view->hex_mode = !view->hex_mode;
|
|
|
|
|
|
|
|
if (view->hex_mode) {
|
|
|
|
view->hex_cursor = view->dpy_start;
|
|
|
|
view->dpy_start =
|
|
|
|
offset_rounddown (view->dpy_start, view->bytes_per_line);
|
|
|
|
view->widget.options |= W_WANT_CURSOR;
|
|
|
|
} else {
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
line = view_offset_to_line (view, view->hex_cursor);
|
|
|
|
view->dpy_text_column = (view->text_wrap_mode) ? 0 :
|
|
|
|
view_offset_to_column (view, line, view->hex_cursor);
|
|
|
|
view_set_first_showed (view, line);
|
2005-08-29 00:38:53 +04:00
|
|
|
view->widget.options &= ~W_WANT_CURSOR;
|
|
|
|
}
|
|
|
|
altered_hex_mode = 1;
|
|
|
|
view->dpy_bbar_dirty = TRUE;
|
|
|
|
view->dirty++;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
view_toggle_hexedit_mode (WView *view)
|
|
|
|
{
|
|
|
|
view->hexedit_mode = !view->hexedit_mode;
|
|
|
|
view->dpy_bbar_dirty = TRUE;
|
|
|
|
view->dirty++;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
view_toggle_wrap_mode (WView *view)
|
|
|
|
{
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
struct cache_line *line;
|
|
|
|
|
2005-08-29 00:38:53 +04:00
|
|
|
view->text_wrap_mode = !view->text_wrap_mode;
|
|
|
|
if (view->text_wrap_mode) {
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
view->dpy_text_column = 0;
|
|
|
|
view->dpy_start = view_get_first_showed_line (view)->start;
|
2005-08-29 00:38:53 +04:00
|
|
|
} else {
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
line = view_get_first_showed_line (view);
|
|
|
|
view->dpy_text_column = view_width_of_whole_line_before (view, line);
|
2005-08-29 00:38:53 +04:00
|
|
|
}
|
|
|
|
view->dpy_bbar_dirty = TRUE;
|
|
|
|
view->dirty++;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
view_toggle_nroff_mode (WView *view)
|
|
|
|
{
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
struct cache_line *line;
|
|
|
|
struct cache_line *next;
|
|
|
|
|
2005-08-29 00:38:53 +04:00
|
|
|
view->text_nroff_mode = !view->text_nroff_mode;
|
|
|
|
altered_nroff_flag = 1;
|
|
|
|
view->dpy_bbar_dirty = TRUE;
|
|
|
|
view->dirty++;
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
|
|
|
|
line = view_get_first_line (view);
|
|
|
|
view_move_to_stop (line, next, line->end <= view->dpy_start, view_get_next_line)
|
|
|
|
|
|
|
|
view_set_first_showed (view, line);
|
2005-08-29 00:38:53 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
view_toggle_magic_mode (WView *view)
|
|
|
|
{
|
|
|
|
char *filename, *command;
|
|
|
|
|
|
|
|
altered_magic_flag = 1;
|
|
|
|
view->magic_mode = !view->magic_mode;
|
2009-02-06 01:40:32 +03:00
|
|
|
filename = g_strdup (view->filename);
|
|
|
|
command = g_strdup (view->command);
|
2005-08-29 00:38:53 +04:00
|
|
|
|
|
|
|
view_done (view);
|
|
|
|
view_load (view, command, filename, 0);
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (filename);
|
|
|
|
g_free (command);
|
2005-08-29 00:38:53 +04:00
|
|
|
view->dpy_bbar_dirty = TRUE;
|
|
|
|
view->dirty++;
|
|
|
|
}
|
|
|
|
|
2005-05-26 14:17:38 +04:00
|
|
|
/* {{{ Miscellaneous functions }}} */
|
2005-05-26 13:08:54 +04:00
|
|
|
|
1998-12-03 00:27:27 +03:00
|
|
|
static void
|
1998-02-27 07:54:42 +03:00
|
|
|
view_done (WView *view)
|
|
|
|
{
|
2005-08-21 15:57:45 +04:00
|
|
|
/* Save current file position */
|
2005-07-18 12:47:45 +04:00
|
|
|
if (mcview_remember_file_position && view->filename != NULL) {
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
struct cache_line *line;
|
2005-07-23 12:20:58 +04:00
|
|
|
char *canon_fname;
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
offset_type row, col;
|
2005-07-23 12:20:58 +04:00
|
|
|
|
|
|
|
canon_fname = vfs_canon (view->filename);
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
line = view_get_first_showed_line (view);
|
|
|
|
row = line->number + 1;
|
|
|
|
col = view_offset_to_column (view, line, view->dpy_start);
|
|
|
|
|
|
|
|
save_file_position (canon_fname, row, col);
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (canon_fname);
|
2005-07-18 12:47:45 +04:00
|
|
|
}
|
2005-08-21 15:57:45 +04:00
|
|
|
|
|
|
|
/* Write back the global viewer mode */
|
1998-02-27 07:54:42 +03:00
|
|
|
default_hex_mode = view->hex_mode;
|
2005-04-14 15:06:12 +04:00
|
|
|
default_nroff_flag = view->text_nroff_mode;
|
2005-04-14 15:12:01 +04:00
|
|
|
default_magic_flag = view->magic_mode;
|
2005-04-14 15:14:42 +04:00
|
|
|
global_wrap_mode = view->text_wrap_mode;
|
2005-08-21 15:57:45 +04:00
|
|
|
|
|
|
|
|
|
|
|
/* view->widget needs no destructor */
|
|
|
|
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (view->filename), view->filename = NULL;
|
|
|
|
g_free (view->command), view->command = NULL;
|
2005-08-21 15:57:45 +04:00
|
|
|
|
|
|
|
view_close_datasource (view);
|
|
|
|
/* the growing buffer is freed with the datasource */
|
|
|
|
|
2005-08-21 16:04:20 +04:00
|
|
|
view_hexedit_free_change_list (view);
|
2005-08-21 15:57:45 +04:00
|
|
|
/* FIXME: what about view->search_exp? */
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
|
|
|
|
/* Free memory used by the viewer */
|
|
|
|
view_reduce_cache_lines (view);
|
|
|
|
if (view->converter != str_cnv_from_term) str_close_conv (view->converter);
|
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2005-06-28 16:13:37 +04:00
|
|
|
static void
|
|
|
|
view_show_error (WView *view, const char *msg)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2005-06-28 16:13:37 +04:00
|
|
|
view_close_datasource (view);
|
|
|
|
if (view_is_in_panel (view)) {
|
2005-04-25 12:50:59 +04:00
|
|
|
view_set_datasource_string (view, msg);
|
2005-06-28 16:13:37 +04:00
|
|
|
} else {
|
2009-01-10 16:13:56 +03:00
|
|
|
message (D_ERROR, MSG_ERROR, "%s", msg);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-02-06 01:46:07 +03:00
|
|
|
static gboolean
|
2005-04-25 03:47:27 +04:00
|
|
|
view_load_command_output (WView *view, const char *command)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2005-04-25 03:47:27 +04:00
|
|
|
FILE *fp;
|
2002-09-08 19:22:28 +04:00
|
|
|
|
2005-04-07 15:23:53 +04:00
|
|
|
view_close_datasource (view);
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2005-07-12 10:04:38 +04:00
|
|
|
open_error_pipe ();
|
|
|
|
if ((fp = popen (command, "r")) == NULL) {
|
|
|
|
/* Avoid two messages. Message from stderr has priority. */
|
2005-07-14 01:30:28 +04:00
|
|
|
display (view);
|
2009-01-10 16:13:56 +03:00
|
|
|
if (!close_error_pipe (view_is_in_panel (view) ? -1 : D_ERROR, NULL))
|
2005-07-12 10:04:38 +04:00
|
|
|
view_show_error (view, _(" Cannot spawn child process "));
|
|
|
|
return FALSE;
|
|
|
|
}
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2005-07-12 10:04:38 +04:00
|
|
|
/* First, check if filter produced any output */
|
|
|
|
view_set_datasource_stdio_pipe (view, fp);
|
|
|
|
if (get_byte (view, 0) == -1) {
|
|
|
|
view_close_datasource (view);
|
2005-04-07 15:23:53 +04:00
|
|
|
|
2005-07-12 10:04:38 +04:00
|
|
|
/* Avoid two messages. Message from stderr has priority. */
|
2005-07-14 01:30:28 +04:00
|
|
|
display (view);
|
2009-01-10 16:13:56 +03:00
|
|
|
if (!close_error_pipe (view_is_in_panel (view) ? -1 : D_ERROR, NULL))
|
2005-07-12 10:04:38 +04:00
|
|
|
view_show_error (view, _("Empty output from child filter"));
|
|
|
|
return FALSE;
|
|
|
|
}
|
2005-06-28 16:13:37 +04:00
|
|
|
return TRUE;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2009-02-06 01:46:07 +03:00
|
|
|
gboolean
|
2005-07-12 11:01:47 +04:00
|
|
|
view_load (WView *view, const char *command, const char *file,
|
2005-04-14 12:00:14 +04:00
|
|
|
int start_line)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
1998-11-03 00:47:06 +03:00
|
|
|
int i, type;
|
2001-11-14 23:15:36 +03:00
|
|
|
int fd = -1;
|
2001-10-18 10:23:02 +04:00
|
|
|
char tmp[BUF_MEDIUM];
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
const char *enc;
|
|
|
|
char *canon_fname;
|
2004-12-02 20:13:39 +03:00
|
|
|
struct stat st;
|
2009-02-06 01:46:07 +03:00
|
|
|
gboolean retval = FALSE;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2005-07-01 02:58:52 +04:00
|
|
|
assert (view->bytes_per_line != 0);
|
2005-04-14 12:00:14 +04:00
|
|
|
view_done (view);
|
1998-02-27 07:54:42 +03:00
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
/* Set up the state */
|
2005-04-07 15:23:53 +04:00
|
|
|
view_set_datasource_none (view);
|
2009-02-06 01:40:32 +03:00
|
|
|
view->filename = g_strdup (file);
|
1998-02-27 07:54:42 +03:00
|
|
|
view->command = 0;
|
|
|
|
|
|
|
|
/* Clear the markers */
|
|
|
|
view->marker = 0;
|
|
|
|
for (i = 0; i < 10; i++)
|
2002-10-31 01:48:59 +03:00
|
|
|
view->marks[i] = 0;
|
|
|
|
|
2005-04-16 17:45:16 +04:00
|
|
|
if (!view_is_in_panel (view)) {
|
2005-05-21 14:17:35 +04:00
|
|
|
view->dpy_text_column = 0;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
1998-11-03 00:47:06 +03:00
|
|
|
|
2005-08-29 00:38:53 +04:00
|
|
|
if (command && (view->magic_mode || file == NULL || file[0] == '\0')) {
|
2005-07-12 11:01:47 +04:00
|
|
|
retval = view_load_command_output (view, command);
|
2005-08-29 00:38:53 +04:00
|
|
|
} else if (file != NULL && file[0] != '\0') {
|
2002-12-16 06:43:49 +03:00
|
|
|
/* Open the file */
|
2005-07-12 11:01:47 +04:00
|
|
|
if ((fd = mc_open (file, O_RDONLY | O_NONBLOCK)) == -1) {
|
2009-02-06 01:49:00 +03:00
|
|
|
g_snprintf (tmp, sizeof (tmp), _(" Cannot open \"%s\"\n %s "),
|
2005-07-12 11:01:47 +04:00
|
|
|
file, unix_error_string (errno));
|
2005-06-28 16:13:37 +04:00
|
|
|
view_show_error (view, tmp);
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
g_free (view->filename);
|
|
|
|
view->filename = NULL;
|
2002-12-16 06:43:49 +03:00
|
|
|
goto finish;
|
|
|
|
}
|
|
|
|
|
2001-11-14 23:15:36 +03:00
|
|
|
/* Make sure we are working with a regular file */
|
2004-12-02 20:13:39 +03:00
|
|
|
if (mc_fstat (fd, &st) == -1) {
|
2002-12-16 06:43:49 +03:00
|
|
|
mc_close (fd);
|
2009-02-06 01:49:00 +03:00
|
|
|
g_snprintf (tmp, sizeof (tmp), _(" Cannot stat \"%s\"\n %s "),
|
2005-07-12 11:01:47 +04:00
|
|
|
file, unix_error_string (errno));
|
2005-06-28 16:13:37 +04:00
|
|
|
view_show_error (view, tmp);
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
g_free (view->filename);
|
|
|
|
view->filename = NULL;
|
2001-11-14 23:15:36 +03:00
|
|
|
goto finish;
|
|
|
|
}
|
2001-10-18 10:23:02 +04:00
|
|
|
|
2004-12-02 20:13:39 +03:00
|
|
|
if (!S_ISREG (st.st_mode)) {
|
2002-12-16 06:43:49 +03:00
|
|
|
mc_close (fd);
|
2005-06-28 16:13:37 +04:00
|
|
|
view_show_error (view, _(" Cannot view: not a regular file "));
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
g_free (view->filename);
|
|
|
|
view->filename = NULL;
|
2001-11-14 23:15:36 +03:00
|
|
|
goto finish;
|
|
|
|
}
|
1999-04-16 09:53:46 +04:00
|
|
|
|
2005-04-07 15:23:53 +04:00
|
|
|
if (st.st_size == 0 || mc_lseek (fd, 0, SEEK_SET) == -1) {
|
|
|
|
/* Must be one of those nice files that grow (/proc) */
|
|
|
|
view_set_datasource_vfs_pipe (view, fd);
|
|
|
|
} else {
|
|
|
|
type = get_compression_type (fd);
|
2002-07-03 01:09:25 +04:00
|
|
|
|
2005-04-14 15:12:01 +04:00
|
|
|
if (view->magic_mode && (type != COMPRESSION_NONE)) {
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (view->filename);
|
2005-07-12 11:01:47 +04:00
|
|
|
view->filename = g_strconcat (file, decompress_extension (type), (char *) NULL);
|
2005-04-07 15:23:53 +04:00
|
|
|
}
|
|
|
|
view_set_datasource_file (view, fd, &st);
|
2001-11-14 23:15:36 +03:00
|
|
|
}
|
2005-06-28 16:13:37 +04:00
|
|
|
retval = TRUE;
|
2002-05-27 20:20:35 +04:00
|
|
|
}
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2002-10-31 01:48:59 +03:00
|
|
|
finish:
|
2009-02-06 01:40:32 +03:00
|
|
|
view->command = g_strdup (command);
|
2005-08-22 22:31:51 +04:00
|
|
|
view->dpy_start = 0;
|
2005-05-26 13:08:54 +04:00
|
|
|
view->search_start = 0;
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
view->search_end = 0;
|
2005-05-21 14:17:35 +04:00
|
|
|
view->dpy_text_column = 0;
|
2002-10-31 01:48:59 +03:00
|
|
|
view->last_search = 0; /* Start a new search */
|
1998-02-27 07:54:42 +03:00
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
view->converter = str_cnv_from_term;
|
|
|
|
/* try detect encoding from path */
|
|
|
|
if (view->filename != NULL) {
|
|
|
|
canon_fname = vfs_canon (view->filename);
|
|
|
|
enc = vfs_get_encoding (canon_fname);
|
|
|
|
if (enc != NULL) {
|
|
|
|
view->converter = str_crt_conv_from (enc);
|
2009-04-19 17:45:10 +04:00
|
|
|
if (view->converter == INVALID_CONV)
|
|
|
|
view->converter = str_cnv_from_term;
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
}
|
|
|
|
g_free (canon_fname);
|
|
|
|
}
|
|
|
|
|
|
|
|
view_compute_areas (view);
|
|
|
|
view_reset_cache_lines (view);
|
|
|
|
view->first_showed_line = view_get_first_line (view);
|
|
|
|
|
2005-07-01 02:58:52 +04:00
|
|
|
assert (view->bytes_per_line != 0);
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
if (mcview_remember_file_position && view->filename != NULL && start_line == 0) {
|
2005-07-18 12:47:45 +04:00
|
|
|
long line, col;
|
2005-07-23 12:20:58 +04:00
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
canon_fname = vfs_canon (view->filename);
|
2005-07-18 12:47:45 +04:00
|
|
|
load_file_position (file, &line, &col);
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (canon_fname);
|
2005-07-18 12:47:45 +04:00
|
|
|
view_moveto (view, offset_doz(line, 1), col);
|
|
|
|
} else if (start_line > 0) {
|
|
|
|
view_moveto (view, start_line - 1, 0);
|
|
|
|
}
|
I improved the movement keys of the internal viewer a little bit.
Now in wrap mode the End key and cursor up key behave much better
(e.g. when viewing binary files with lots of wrapped lines).
It's not perfekt but it's better than it used to be.
Tue Apr 28 06:52:24 1998 Norbert Warmuth <k3190@fh-sw.de>
* gnome/gcmd.c (gnome_open_terminal): Changed my_system(1,...) to
my_system(EXECUTE_AS_SHELL,...)
Tue Apr 28 06:06:03 1998 Norbert Warmuth <k3190@fh-sw.de>
* vfs/extfs.c (extfs_open, extfs_close): Changed my_system(1,...)
to my_system(EXECUTE_AS_SHELL,...), this fixes the broken copyin and
copyout in 4.1.32.
Tue Apr 28 06:11:08 1998 Norbert Warmuth <k3190@fh-sw.de>
* view.c (toggle_wrap_mode, toggle_hex_mode): Force recalculation
of bottom_first (we mustn't use an already calculated and cached
value because it is invalid for the new mode and the End key would
not move to the end of the file).
* configure.in: Renamed the option `--with-our-slang' to
`--with-included-slang' (this one looks better because we also
have an `--with-included-gettext').
Make the option `--with-ext2undel' recognice a given path.
* cmd.c (view_file_at_line): In plain view (F13) set the default
magic flag to zero in order to view the file content unprocessed
(esp. don't uncompress files if they are compressed). The
view_simple_cmd got broken when the default magic flag in view.c
was changed from 0 to 1.
* view.c (do_view_init, goto_line): Set wrap mode temporary off
to make goto line number work, i.e. `line number' now always means
line number in file and not line number on screen (in wrap mode
one long line wrapped once is displayed in two lines on the screen).
That's important when the viewer is invoked from the find file
dialog to display even in wrap mode approxiamtly the part of the
file where we found the content we searched for.
(move_forward2): In wrap mode lines were sometimes counted wrong
causing cursor up to move more than one line.
(move_backward2): Fixed the movement in wrap mode.
(change_viewer): Always re-init viewer when we have a filename,
i. e. if the viewer is invoked with simple_view_cmd then we can switch
with the F8 key between unprocessed file content und uncompressed
file content.
(view_init): re-init view also when magic flag was altered
1998-04-28 18:19:48 +04:00
|
|
|
|
2005-04-20 00:33:51 +04:00
|
|
|
view->hexedit_lownibble = FALSE;
|
2005-04-14 14:59:02 +04:00
|
|
|
view->hexview_in_text = FALSE;
|
1998-02-27 07:54:42 +03:00
|
|
|
view->change_list = NULL;
|
|
|
|
|
2005-06-28 16:13:37 +04:00
|
|
|
return retval;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2005-05-26 14:40:10 +04:00
|
|
|
/* {{{ Display management }}} */
|
|
|
|
|
2005-01-26 01:40:50 +03:00
|
|
|
static void
|
2002-10-07 22:09:50 +04:00
|
|
|
view_update_bytes_per_line (WView *view)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2005-07-06 23:12:25 +04:00
|
|
|
const screen_dimen cols = view->data_area.width;
|
2005-07-11 11:39:04 +04:00
|
|
|
int bytes;
|
2000-11-20 20:25:43 +03:00
|
|
|
|
2006-01-31 17:39:30 +03:00
|
|
|
if (cols < 8 + 17)
|
|
|
|
bytes = 4;
|
2002-10-07 22:09:50 +04:00
|
|
|
else
|
2006-01-31 17:39:30 +03:00
|
|
|
bytes = 4 * ((cols - 8) / ((cols < 80) ? 17 : 18));
|
|
|
|
assert(bytes != 0);
|
2002-10-07 22:09:50 +04:00
|
|
|
|
2005-07-11 11:39:04 +04:00
|
|
|
view->bytes_per_line = bytes;
|
1998-02-27 07:54:42 +03:00
|
|
|
view->dirty = max_dirt_limit + 1; /* To force refresh */
|
1999-04-06 23:00:16 +04:00
|
|
|
}
|
|
|
|
|
2002-08-27 23:10:54 +04:00
|
|
|
static void
|
2005-04-16 17:45:16 +04:00
|
|
|
view_percent (WView *view, offset_type p)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2005-08-16 12:16:12 +04:00
|
|
|
const screen_dimen top = view->status_area.top;
|
2005-07-06 23:36:59 +04:00
|
|
|
const screen_dimen right = view->status_area.left + view->status_area.width;
|
2005-07-07 21:49:01 +04:00
|
|
|
const screen_dimen height = view->status_area.height;
|
1998-02-27 07:54:42 +03:00
|
|
|
int percent;
|
2005-04-14 01:09:00 +04:00
|
|
|
offset_type filesize;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2005-07-07 21:49:01 +04:00
|
|
|
if (height < 1 || right < 4)
|
2005-07-06 23:36:59 +04:00
|
|
|
return;
|
2005-06-14 18:13:11 +04:00
|
|
|
if (view_may_still_grow (view))
|
2005-04-14 01:09:00 +04:00
|
|
|
return;
|
2005-06-14 18:13:11 +04:00
|
|
|
filesize = view_get_filesize (view);
|
2005-04-14 01:09:00 +04:00
|
|
|
|
2005-08-22 22:31:51 +04:00
|
|
|
if (filesize == 0 || view->dpy_end == filesize)
|
2005-07-03 19:31:55 +04:00
|
|
|
percent = 100;
|
2004-12-02 20:13:39 +03:00
|
|
|
else if (p > (INT_MAX / 100))
|
2005-07-03 19:31:55 +04:00
|
|
|
percent = p / (filesize / 100);
|
2004-12-02 20:13:39 +03:00
|
|
|
else
|
2005-07-03 19:31:55 +04:00
|
|
|
percent = p * 100 / filesize;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2005-08-16 12:16:12 +04:00
|
|
|
widget_move (view, top, right - 4);
|
2006-01-07 21:17:27 +03:00
|
|
|
tty_printf ("%3d%%", percent);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2002-08-27 23:10:54 +04:00
|
|
|
static void
|
2005-07-07 20:59:31 +04:00
|
|
|
view_display_status (WView *view)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2005-07-06 23:12:25 +04:00
|
|
|
const screen_dimen top = view->status_area.top;
|
|
|
|
const screen_dimen left = view->status_area.left;
|
|
|
|
const screen_dimen width = view->status_area.width;
|
2005-07-07 21:49:01 +04:00
|
|
|
const screen_dimen height = view->status_area.height;
|
|
|
|
const char *file_label, *file_name;
|
2005-07-06 23:12:25 +04:00
|
|
|
screen_dimen file_label_width;
|
1998-02-27 07:54:42 +03:00
|
|
|
int i;
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
char *tmp;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2005-07-07 21:49:01 +04:00
|
|
|
if (height < 1)
|
|
|
|
return;
|
|
|
|
|
2006-02-03 17:33:19 +03:00
|
|
|
tty_setcolor (SELECTED_COLOR);
|
2005-07-06 23:12:25 +04:00
|
|
|
widget_move (view, top, left);
|
|
|
|
hline (' ', width);
|
1999-04-06 23:00:16 +04:00
|
|
|
|
2005-07-06 23:12:25 +04:00
|
|
|
file_label = _("File: %s");
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
file_label_width = str_term_width1 (file_label) - 2;
|
2005-07-07 21:49:01 +04:00
|
|
|
file_name = view->filename ? view->filename
|
|
|
|
: view->command ? view->command
|
|
|
|
: "";
|
1999-04-06 23:00:16 +04:00
|
|
|
|
2005-07-06 23:12:25 +04:00
|
|
|
if (width < file_label_width + 6)
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
addstr (str_fit_to_term (file_name, width, J_LEFT_FIT));
|
2002-10-31 01:48:59 +03:00
|
|
|
else {
|
2005-07-06 23:12:25 +04:00
|
|
|
i = (width > 22 ? 22 : width) - file_label_width;
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
|
|
|
|
tmp = g_strdup_printf (file_label, str_fit_to_term (file_name, i, J_LEFT_FIT));
|
|
|
|
addstr (tmp);
|
|
|
|
g_free (tmp);
|
2005-07-06 23:12:25 +04:00
|
|
|
if (width > 46) {
|
|
|
|
widget_move (view, top, left + 24);
|
2005-04-16 18:25:52 +04:00
|
|
|
/* FIXME: the format strings need to be changed when offset_type changes */
|
2002-10-31 01:48:59 +03:00
|
|
|
if (view->hex_mode)
|
2006-01-07 21:17:27 +03:00
|
|
|
tty_printf (_("Offset 0x%08lx"), (unsigned long) view->hex_cursor);
|
2005-05-26 13:08:54 +04:00
|
|
|
else {
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
screen_dimen row, col;
|
|
|
|
struct cache_line *line;
|
|
|
|
|
|
|
|
line = view_get_first_showed_line (view);
|
|
|
|
row = line->number + 1;
|
|
|
|
|
|
|
|
col = (view->text_wrap_mode) ?
|
|
|
|
view_width_of_whole_line_before (view, line) :
|
|
|
|
view->dpy_text_column;
|
|
|
|
col++;
|
|
|
|
|
2006-01-07 21:17:27 +03:00
|
|
|
tty_printf (_("Line %lu Col %lu"),
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
(unsigned long) row, (unsigned long) col);
|
2005-05-26 13:08:54 +04:00
|
|
|
}
|
2002-10-31 01:48:59 +03:00
|
|
|
}
|
2005-07-06 23:12:25 +04:00
|
|
|
if (width > 62) {
|
2005-04-14 01:09:00 +04:00
|
|
|
offset_type filesize;
|
2005-06-14 18:13:11 +04:00
|
|
|
filesize = view_get_filesize (view);
|
2005-07-06 23:12:25 +04:00
|
|
|
widget_move (view, top, left + 43);
|
2005-06-14 18:13:11 +04:00
|
|
|
if (!view_may_still_grow (view)) {
|
2006-01-07 21:17:27 +03:00
|
|
|
tty_printf (_("%s bytes"), size_trunc (filesize));
|
2005-04-14 01:09:00 +04:00
|
|
|
} else {
|
2006-01-07 21:17:27 +03:00
|
|
|
tty_printf (_(">= %s bytes"), size_trunc (filesize));
|
2005-04-14 01:09:00 +04:00
|
|
|
}
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
2005-07-06 23:12:25 +04:00
|
|
|
if (width > 26) {
|
2005-04-16 17:45:16 +04:00
|
|
|
view_percent (view, view->hex_mode
|
2005-05-21 14:23:57 +04:00
|
|
|
? view->hex_cursor
|
2005-08-22 22:36:51 +04:00
|
|
|
: view->dpy_end);
|
1999-05-03 22:57:48 +04:00
|
|
|
}
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
2006-02-03 17:33:19 +03:00
|
|
|
tty_setcolor (SELECTED_COLOR);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
2005-07-06 23:12:25 +04:00
|
|
|
view_display_clean (WView *view)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2006-02-03 17:33:19 +03:00
|
|
|
tty_setcolor (NORMAL_COLOR);
|
2005-07-06 23:12:25 +04:00
|
|
|
widget_erase ((Widget *) view);
|
2005-04-19 01:02:55 +04:00
|
|
|
if (view->dpy_frame_size != 0) {
|
2002-10-31 01:48:59 +03:00
|
|
|
draw_double_box (view->widget.parent, view->widget.y,
|
|
|
|
view->widget.x, view->widget.lines,
|
|
|
|
view->widget.cols);
|
2005-07-06 23:12:25 +04:00
|
|
|
}
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2002-08-19 00:18:04 +04:00
|
|
|
typedef enum {
|
2005-08-18 07:33:33 +04:00
|
|
|
MARK_NORMAL,
|
|
|
|
MARK_SELECTED,
|
|
|
|
MARK_CURSOR,
|
|
|
|
MARK_CHANGED
|
2002-08-19 00:18:04 +04:00
|
|
|
} mark_t;
|
|
|
|
|
2005-04-19 01:02:55 +04:00
|
|
|
static inline int
|
|
|
|
view_count_backspaces (WView *view, off_t offset)
|
2004-09-25 06:00:25 +04:00
|
|
|
{
|
|
|
|
int backspaces = 0;
|
2005-04-14 01:09:00 +04:00
|
|
|
while (offset >= 2 * backspaces
|
|
|
|
&& get_byte (view, offset - 2 * backspaces) == '\b')
|
2005-07-03 19:31:55 +04:00
|
|
|
backspaces++;
|
2004-09-25 06:00:25 +04:00
|
|
|
return backspaces;
|
|
|
|
}
|
|
|
|
|
2005-04-20 02:33:21 +04:00
|
|
|
static void
|
|
|
|
view_display_ruler (WView *view)
|
|
|
|
{
|
2005-07-11 12:14:44 +04:00
|
|
|
static const char ruler_chars[] = "|----*----";
|
2005-07-06 23:12:25 +04:00
|
|
|
const screen_dimen top = view->ruler_area.top;
|
|
|
|
const screen_dimen left = view->ruler_area.left;
|
|
|
|
const screen_dimen width = view->ruler_area.width;
|
2005-07-07 21:49:01 +04:00
|
|
|
const screen_dimen height = view->ruler_area.height;
|
2005-07-06 23:12:25 +04:00
|
|
|
const screen_dimen line_row = (ruler == RULER_TOP) ? 0 : 1;
|
|
|
|
const screen_dimen nums_row = (ruler == RULER_TOP) ? 1 : 0;
|
2005-04-20 02:33:21 +04:00
|
|
|
|
|
|
|
char r_buff[10];
|
|
|
|
offset_type cl;
|
2005-07-06 23:12:25 +04:00
|
|
|
screen_dimen c;
|
|
|
|
|
2005-07-07 21:49:01 +04:00
|
|
|
if (ruler == RULER_NONE || height < 1)
|
2005-07-06 23:12:25 +04:00
|
|
|
return;
|
2005-04-20 02:33:21 +04:00
|
|
|
|
2006-02-03 17:33:19 +03:00
|
|
|
tty_setcolor (MARKED_COLOR);
|
2005-07-06 23:12:25 +04:00
|
|
|
for (c = 0; c < width; c++) {
|
|
|
|
cl = view->dpy_text_column + c;
|
2005-07-07 21:49:01 +04:00
|
|
|
if (line_row < height) {
|
2005-08-29 12:53:28 +04:00
|
|
|
widget_move (view, top + line_row, left + c);
|
|
|
|
tty_print_char (ruler_chars[cl % 10]);
|
2005-07-07 21:49:01 +04:00
|
|
|
}
|
2005-04-20 02:33:21 +04:00
|
|
|
|
|
|
|
if ((cl != 0) && (cl % 10) == 0) {
|
2009-02-06 01:49:00 +03:00
|
|
|
g_snprintf (r_buff, sizeof (r_buff), "%"OFFSETTYPE_PRId, cl);
|
2005-07-07 21:49:01 +04:00
|
|
|
if (nums_row < height) {
|
|
|
|
widget_move (view, top + nums_row, left + c - 1);
|
2005-08-29 12:53:28 +04:00
|
|
|
tty_print_string (r_buff);
|
2005-07-07 21:49:01 +04:00
|
|
|
}
|
2005-04-20 02:33:21 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
attrset (NORMAL_COLOR);
|
|
|
|
}
|
|
|
|
|
2005-06-28 17:02:09 +04:00
|
|
|
static void
|
2005-06-28 17:21:42 +04:00
|
|
|
view_display_hex (WView *view)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2005-07-06 23:12:25 +04:00
|
|
|
const screen_dimen top = view->data_area.top;
|
|
|
|
const screen_dimen left = view->data_area.left;
|
|
|
|
const screen_dimen height = view->data_area.height;
|
|
|
|
const screen_dimen width = view->data_area.width;
|
2006-01-31 17:39:30 +03:00
|
|
|
const int ngroups = view->bytes_per_line / 4;
|
|
|
|
const screen_dimen text_start =
|
2006-02-01 18:59:21 +03:00
|
|
|
8 + 13 * ngroups + ((width < 80) ? 0 : (ngroups - 1 + 1));
|
2006-01-31 17:39:30 +03:00
|
|
|
/* 8 characters are used for the file offset, and every hex group
|
|
|
|
* takes 13 characters. On ``big'' screens, the groups are separated
|
|
|
|
* by an extra vertical line, and there is an extra space before the
|
|
|
|
* text column.
|
|
|
|
*/
|
2005-07-06 23:12:25 +04:00
|
|
|
|
|
|
|
screen_dimen row, col;
|
2004-08-16 08:16:55 +04:00
|
|
|
offset_type from;
|
1998-02-27 07:54:42 +03:00
|
|
|
int c;
|
2002-08-19 00:18:04 +04:00
|
|
|
mark_t boldflag = MARK_NORMAL;
|
1998-02-27 07:54:42 +03:00
|
|
|
struct hexedit_change_node *curr = view->change_list;
|
2006-01-31 17:39:30 +03:00
|
|
|
size_t i;
|
2002-07-26 21:17:41 +04:00
|
|
|
|
2005-06-28 17:21:42 +04:00
|
|
|
char hex_buff[10]; /* A temporary buffer for sprintf and mvwaddstr */
|
|
|
|
int bytes; /* Number of bytes already printed on the line */
|
|
|
|
|
2005-07-06 23:12:25 +04:00
|
|
|
view_display_clean (view);
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
/* Find the first displayable changed byte */
|
2005-08-22 22:31:51 +04:00
|
|
|
from = view->dpy_start;
|
2000-11-20 20:25:43 +03:00
|
|
|
while (curr && (curr->offset < from)) {
|
2002-07-26 21:17:41 +04:00
|
|
|
curr = curr->next;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
2002-07-26 21:17:41 +04:00
|
|
|
|
2005-07-06 23:12:25 +04:00
|
|
|
for (row = 0; get_byte (view, from) != -1 && row < height; row++) {
|
2006-01-31 17:39:30 +03:00
|
|
|
col = 0;
|
|
|
|
|
2005-06-28 17:21:42 +04:00
|
|
|
/* Print the hex offset */
|
2009-02-06 01:49:00 +03:00
|
|
|
g_snprintf (hex_buff, sizeof (hex_buff), "%08"OFFSETTYPE_PRIX" ", from);
|
2005-08-29 12:53:28 +04:00
|
|
|
widget_move (view, top + row, left);
|
2006-02-03 17:33:19 +03:00
|
|
|
tty_setcolor (MARKED_COLOR);
|
2006-01-31 17:39:30 +03:00
|
|
|
for (i = 0; col < width && hex_buff[i] != '\0'; i++) {
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
addch (hex_buff[i]);
|
|
|
|
/* tty_print_char(hex_buff[i]);*/
|
2006-01-31 17:39:30 +03:00
|
|
|
col += 1;
|
|
|
|
}
|
2006-02-03 17:33:19 +03:00
|
|
|
tty_setcolor (NORMAL_COLOR);
|
2005-06-28 17:21:42 +04:00
|
|
|
|
2005-08-18 07:33:33 +04:00
|
|
|
for (bytes = 0; bytes < view->bytes_per_line; bytes++, from++) {
|
|
|
|
|
|
|
|
if ((c = get_byte (view, from)) == -1)
|
|
|
|
break;
|
|
|
|
|
|
|
|
/* Save the cursor position for view_place_cursor() */
|
|
|
|
if (from == view->hex_cursor && !view->hexview_in_text) {
|
|
|
|
view->cursor_row = row;
|
|
|
|
view->cursor_col = col;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Determine the state of the current byte */
|
2006-01-31 16:45:27 +03:00
|
|
|
boldflag =
|
|
|
|
(from == view->hex_cursor) ? MARK_CURSOR
|
|
|
|
: (curr != NULL && from == curr->offset) ? MARK_CHANGED
|
|
|
|
: (view->search_start <= from &&
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
from < view->search_end) ? MARK_SELECTED
|
2006-01-31 16:45:27 +03:00
|
|
|
: MARK_NORMAL;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2006-01-30 06:50:51 +03:00
|
|
|
/* Determine the value of the current byte */
|
|
|
|
if (curr != NULL && from == curr->offset) {
|
|
|
|
c = curr->value;
|
|
|
|
curr = curr->next;
|
|
|
|
}
|
|
|
|
|
2005-08-18 07:33:33 +04:00
|
|
|
/* Select the color for the hex number */
|
2006-02-03 17:33:19 +03:00
|
|
|
tty_setcolor (
|
2005-08-18 07:33:33 +04:00
|
|
|
boldflag == MARK_NORMAL ? NORMAL_COLOR :
|
|
|
|
boldflag == MARK_SELECTED ? MARKED_COLOR :
|
|
|
|
boldflag == MARK_CHANGED ? VIEW_UNDERLINED_COLOR :
|
|
|
|
/* boldflag == MARK_CURSOR */
|
|
|
|
view->hexview_in_text ? MARKED_SELECTED_COLOR :
|
|
|
|
VIEW_UNDERLINED_COLOR);
|
|
|
|
|
|
|
|
/* Print the hex number */
|
2005-08-29 12:53:28 +04:00
|
|
|
widget_move (view, top + row, left + col);
|
2006-01-31 17:39:30 +03:00
|
|
|
if (col < width) {
|
|
|
|
tty_print_char (hex_char[c / 16]);
|
|
|
|
col += 1;
|
|
|
|
}
|
|
|
|
if (col < width) {
|
|
|
|
tty_print_char (hex_char[c % 16]);
|
|
|
|
col += 1;
|
|
|
|
}
|
2005-08-18 07:33:33 +04:00
|
|
|
|
|
|
|
/* Print the separator */
|
2006-02-03 17:33:19 +03:00
|
|
|
tty_setcolor (NORMAL_COLOR);
|
2005-08-18 07:33:33 +04:00
|
|
|
if (bytes != view->bytes_per_line - 1) {
|
2006-01-31 17:39:30 +03:00
|
|
|
if (col < width) {
|
|
|
|
tty_print_char (' ');
|
|
|
|
col += 1;
|
|
|
|
}
|
2005-08-18 07:33:33 +04:00
|
|
|
|
|
|
|
/* After every four bytes, print a group separator */
|
|
|
|
if (bytes % 4 == 3) {
|
2006-01-31 17:39:30 +03:00
|
|
|
if (view->data_area.width >= 80 && col < width) {
|
2005-08-29 12:53:28 +04:00
|
|
|
tty_print_one_vline ();
|
2005-08-18 07:33:33 +04:00
|
|
|
col += 1;
|
|
|
|
}
|
2006-01-31 17:39:30 +03:00
|
|
|
if (col < width) {
|
|
|
|
tty_print_char (' ');
|
|
|
|
col += 1;
|
|
|
|
}
|
2002-07-26 21:17:41 +04:00
|
|
|
}
|
2005-06-28 17:21:42 +04:00
|
|
|
}
|
2002-07-26 21:17:41 +04:00
|
|
|
|
2005-08-18 07:33:33 +04:00
|
|
|
/* Select the color for the character; this differs from the
|
|
|
|
* hex color when boldflag == MARK_CURSOR */
|
2006-02-03 17:33:19 +03:00
|
|
|
tty_setcolor (
|
2005-08-18 07:33:33 +04:00
|
|
|
boldflag == MARK_NORMAL ? NORMAL_COLOR :
|
|
|
|
boldflag == MARK_SELECTED ? MARKED_COLOR :
|
|
|
|
boldflag == MARK_CHANGED ? VIEW_UNDERLINED_COLOR :
|
|
|
|
/* boldflag == MARK_CURSOR */
|
|
|
|
view->hexview_in_text ? VIEW_UNDERLINED_COLOR :
|
|
|
|
MARKED_SELECTED_COLOR);
|
2002-07-26 21:17:41 +04:00
|
|
|
|
2005-06-28 17:21:42 +04:00
|
|
|
c = convert_to_display_c (c);
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
if (!g_ascii_isprint (c))
|
2005-06-28 17:21:42 +04:00
|
|
|
c = '.';
|
2005-08-18 07:33:33 +04:00
|
|
|
|
|
|
|
/* Print corresponding character on the text side */
|
2006-01-31 17:39:30 +03:00
|
|
|
if (text_start + bytes < width) {
|
|
|
|
widget_move (view, top + row, left + text_start + bytes);
|
|
|
|
tty_print_char (c);
|
|
|
|
}
|
2002-07-26 21:17:41 +04:00
|
|
|
|
2005-08-18 07:33:33 +04:00
|
|
|
/* Save the cursor position for view_place_cursor() */
|
|
|
|
if (from == view->hex_cursor && view->hexview_in_text) {
|
|
|
|
view->cursor_row = row;
|
|
|
|
view->cursor_col = text_start + bytes;
|
2002-07-26 21:17:41 +04:00
|
|
|
}
|
|
|
|
}
|
2005-06-28 17:21:42 +04:00
|
|
|
}
|
2005-08-18 07:33:33 +04:00
|
|
|
|
|
|
|
/* Be polite to the other functions */
|
2006-02-03 17:33:19 +03:00
|
|
|
tty_setcolor (NORMAL_COLOR);
|
2005-08-18 07:33:33 +04:00
|
|
|
|
2005-06-28 17:21:42 +04:00
|
|
|
view_place_cursor (view);
|
2005-08-22 22:31:51 +04:00
|
|
|
view->dpy_end = from;
|
2005-06-28 17:21:42 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
view_display_text (WView * view)
|
|
|
|
{
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
#define cmp(t1,t2) (strcmp((t1),(t2)) == 0)
|
|
|
|
|
2005-07-06 23:12:25 +04:00
|
|
|
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;
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
struct read_info info;
|
|
|
|
offset_type row, col;
|
|
|
|
int w;
|
|
|
|
struct cache_line *line_act;
|
|
|
|
struct cache_line *line_nxt;
|
2005-06-28 17:21:42 +04:00
|
|
|
|
2005-07-06 23:12:25 +04:00
|
|
|
view_display_clean (view);
|
|
|
|
view_display_ruler (view);
|
2005-06-28 17:21:42 +04:00
|
|
|
|
2006-02-03 17:33:19 +03:00
|
|
|
tty_setcolor (NORMAL_COLOR);
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
|
|
|
|
widget_move (view, top, left);
|
|
|
|
|
|
|
|
line_act = view_get_first_showed_line (view);
|
|
|
|
|
|
|
|
row = 0;
|
|
|
|
/* set col correct value */
|
|
|
|
col = (view->text_wrap_mode) ? 0 : view_width_of_whole_line_before (view, line_act);
|
|
|
|
col+= line_act->left;
|
|
|
|
|
|
|
|
view_read_start (view, &info, line_act->start);
|
|
|
|
while ((info.result != -1) && (row < height)) {
|
|
|
|
/* real detection of new line */
|
|
|
|
if (info.next >= line_act->end) {
|
|
|
|
line_nxt = view_get_next_line (view, line_act);
|
|
|
|
if (line_nxt == NULL) break;
|
|
|
|
|
|
|
|
if (view->text_wrap_mode || (line_act->number != line_nxt->number)){
|
|
|
|
row++;
|
|
|
|
col = line_nxt->left;
|
|
|
|
}
|
|
|
|
line_act = line_nxt;
|
|
|
|
|
2005-07-07 22:06:57 +04:00
|
|
|
continue;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
|
|
|
|
view_read_continue (view, &info);
|
|
|
|
if (view_read_test_nroff_back (view, &info)) {
|
|
|
|
w = str_term_width1 (info.chi1);
|
|
|
|
col-= w;
|
|
|
|
if (col >= view->dpy_text_column
|
|
|
|
&& col + w - view->dpy_text_column <= width) {
|
|
|
|
|
|
|
|
widget_move (view, top + row, left + (col - view->dpy_text_column));
|
|
|
|
int c;
|
|
|
|
for (c = 0; c < w; c++) addch (' ');
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
if (cmp (info.chi1, "_") && (!cmp (info.cnxt, "_") || !cmp (info.chi2, "\b")))
|
2006-02-03 17:33:19 +03:00
|
|
|
tty_setcolor (VIEW_UNDERLINED_COLOR);
|
2005-06-28 17:21:42 +04:00
|
|
|
else
|
2006-02-03 17:33:19 +03:00
|
|
|
tty_setcolor (MARKED_COLOR);
|
2005-06-28 17:21:42 +04:00
|
|
|
continue;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
2005-08-16 12:37:05 +04:00
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
if (view_read_test_new_line (view, &info))
|
2005-06-28 17:21:42 +04:00
|
|
|
continue;
|
2005-08-16 12:37:05 +04:00
|
|
|
|
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
if (view_read_test_tabulator (view, &info)) {
|
|
|
|
col+= (8 - (col % 8));
|
2005-06-28 17:21:42 +04:00
|
|
|
continue;
|
|
|
|
}
|
2005-08-16 12:37:05 +04:00
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
if (view->search_start <= info.actual
|
|
|
|
&& info.actual < view->search_end) {
|
2006-02-03 17:33:19 +03:00
|
|
|
tty_setcolor (SELECTED_COLOR);
|
2005-06-28 17:21:42 +04:00
|
|
|
}
|
2005-08-18 07:50:29 +04:00
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
w = str_isprint (info.cact) ? str_term_width1 (info.cact) : 1;
|
|
|
|
|
2005-07-06 23:12:25 +04:00
|
|
|
if (col >= view->dpy_text_column
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
&& col + w - view->dpy_text_column <= width) {
|
2005-08-29 12:53:28 +04:00
|
|
|
widget_move (view, top + row, left + (col - view->dpy_text_column));
|
2009-04-14 14:29:01 +04:00
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
if (!str_iscombiningmark (info.cnxt)) {
|
|
|
|
if (str_isprint (info.cact)) {
|
|
|
|
addstr (str_term_form (info.cact));
|
|
|
|
} else {
|
|
|
|
addch ('.');
|
2005-06-28 17:21:42 +04:00
|
|
|
}
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
} else {
|
2009-04-14 14:29:01 +04:00
|
|
|
GString *comb = g_string_new ("");
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
if (str_isprint (info.cact)) {
|
2009-04-14 14:29:01 +04:00
|
|
|
g_string_append(comb,info.cact);
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
} else {
|
2009-04-14 14:29:01 +04:00
|
|
|
g_string_append(comb,".");
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
}
|
|
|
|
while (str_iscombiningmark (info.cnxt)) {
|
|
|
|
view_read_continue (view, &info);
|
2009-04-14 14:29:01 +04:00
|
|
|
g_string_append(comb,info.cact);
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
}
|
2009-04-14 14:29:01 +04:00
|
|
|
addstr (str_term_form (comb->str));
|
|
|
|
g_string_free (comb, TRUE);
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
while (str_iscombiningmark (info.cnxt)) {
|
|
|
|
view_read_continue (view, &info);
|
|
|
|
}
|
2009-04-14 14:29:01 +04:00
|
|
|
}
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
col+= w;
|
2009-04-14 14:29:01 +04:00
|
|
|
|
2006-02-03 17:33:19 +03:00
|
|
|
tty_setcolor (NORMAL_COLOR);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
view->dpy_end = info.next;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2005-08-22 22:31:51 +04:00
|
|
|
/* Displays as much data from view->dpy_start as fits on the screen */
|
2005-06-28 17:21:42 +04:00
|
|
|
static void
|
|
|
|
display (WView *view)
|
|
|
|
{
|
2005-07-06 23:12:25 +04:00
|
|
|
view_compute_areas (view);
|
2005-06-28 17:21:42 +04:00
|
|
|
if (view->hex_mode) {
|
|
|
|
view_display_hex (view);
|
|
|
|
} else {
|
|
|
|
view_display_text (view);
|
|
|
|
}
|
2005-07-07 21:03:25 +04:00
|
|
|
view_display_status (view);
|
2005-06-28 17:21:42 +04:00
|
|
|
}
|
|
|
|
|
1998-12-03 00:27:27 +03:00
|
|
|
static void
|
1998-02-27 07:54:42 +03:00
|
|
|
view_place_cursor (WView *view)
|
|
|
|
{
|
2005-08-16 12:22:07 +04:00
|
|
|
const screen_dimen top = view->data_area.top;
|
|
|
|
const screen_dimen left = view->data_area.left;
|
|
|
|
screen_dimen col;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2005-08-16 12:22:07 +04:00
|
|
|
col = view->cursor_col;
|
2005-04-20 00:33:51 +04:00
|
|
|
if (!view->hexview_in_text && view->hexedit_lownibble)
|
2005-07-06 23:12:25 +04:00
|
|
|
col++;
|
2005-08-16 12:22:07 +04:00
|
|
|
widget_move (&view->widget, top + view->cursor_row, left + col);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2002-08-27 23:10:54 +04:00
|
|
|
static void
|
2005-02-08 01:09:44 +03:00
|
|
|
view_update (WView *view)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
|
|
|
static int dirt_limit = 1;
|
|
|
|
|
2005-08-29 00:38:53 +04:00
|
|
|
if (view->dpy_bbar_dirty) {
|
|
|
|
view->dpy_bbar_dirty = FALSE;
|
|
|
|
view_labels (view);
|
|
|
|
buttonbar_redraw (view->widget.parent);
|
|
|
|
}
|
|
|
|
|
2002-10-31 01:48:59 +03:00
|
|
|
if (view->dirty > dirt_limit) {
|
1998-02-27 07:54:42 +03:00
|
|
|
/* Too many updates skipped -> force a update */
|
|
|
|
display (view);
|
|
|
|
view->dirty = 0;
|
|
|
|
/* Raise the update skipping limit */
|
|
|
|
dirt_limit++;
|
|
|
|
if (dirt_limit > max_dirt_limit)
|
|
|
|
dirt_limit = max_dirt_limit;
|
|
|
|
}
|
2002-10-31 01:48:59 +03:00
|
|
|
if (view->dirty) {
|
|
|
|
if (is_idle ()) {
|
1998-02-27 07:54:42 +03:00
|
|
|
/* We have time to update the screen properly */
|
|
|
|
display (view);
|
|
|
|
view->dirty = 0;
|
|
|
|
if (dirt_limit > 1)
|
|
|
|
dirt_limit--;
|
|
|
|
} else {
|
|
|
|
/* We are busy -> skipping full update,
|
|
|
|
only the status line is updated */
|
2005-07-07 20:59:31 +04:00
|
|
|
view_display_status (view);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
/* Here we had a refresh, if fast scrolling does not work
|
|
|
|
restore the refresh, although this should not happen */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-05-26 14:40:10 +04:00
|
|
|
/* {{{ Hex editor }}} */
|
|
|
|
|
|
|
|
static void
|
|
|
|
enqueue_change (struct hexedit_change_node **head,
|
|
|
|
struct hexedit_change_node *node)
|
|
|
|
{
|
2005-07-11 12:17:38 +04:00
|
|
|
/* chnode always either points to the head of the list or
|
|
|
|
* to one of the ->next fields in the list. The value at
|
|
|
|
* this location will be overwritten with the new node. */
|
2005-05-26 14:40:10 +04:00
|
|
|
struct hexedit_change_node **chnode = head;
|
|
|
|
|
|
|
|
while (*chnode != NULL && (*chnode)->offset < node->offset)
|
|
|
|
chnode = &((*chnode)->next);
|
|
|
|
|
|
|
|
node->next = *chnode;
|
|
|
|
*chnode = node;
|
|
|
|
}
|
|
|
|
|
|
|
|
static cb_ret_t
|
|
|
|
view_handle_editkey (WView *view, int key)
|
|
|
|
{
|
|
|
|
struct hexedit_change_node *node;
|
|
|
|
byte byte_val;
|
|
|
|
|
|
|
|
/* Has there been a change at this position? */
|
|
|
|
node = view->change_list;
|
|
|
|
while (node && (node->offset != view->hex_cursor))
|
|
|
|
node = node->next;
|
|
|
|
|
|
|
|
if (!view->hexview_in_text) {
|
|
|
|
/* Hex editing */
|
|
|
|
unsigned int hexvalue = 0;
|
|
|
|
|
|
|
|
if (key >= '0' && key <= '9')
|
|
|
|
hexvalue = 0 + (key - '0');
|
|
|
|
else if (key >= 'A' && key <= 'F')
|
|
|
|
hexvalue = 10 + (key - 'A');
|
|
|
|
else if (key >= 'a' && key <= 'f')
|
|
|
|
hexvalue = 10 + (key - 'a');
|
|
|
|
else
|
|
|
|
return MSG_NOT_HANDLED;
|
|
|
|
|
|
|
|
if (node)
|
|
|
|
byte_val = node->value;
|
|
|
|
else
|
|
|
|
byte_val = get_byte (view, view->hex_cursor);
|
|
|
|
|
|
|
|
if (view->hexedit_lownibble) {
|
|
|
|
byte_val = (byte_val & 0xf0) | (hexvalue);
|
|
|
|
} else {
|
|
|
|
byte_val = (byte_val & 0x0f) | (hexvalue << 4);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* Text editing */
|
|
|
|
if (key < 256 && (is_printable (key) || (key == '\n')))
|
|
|
|
byte_val = key;
|
|
|
|
else
|
|
|
|
return MSG_NOT_HANDLED;
|
|
|
|
}
|
|
|
|
if (!node) {
|
|
|
|
node = g_new (struct hexedit_change_node, 1);
|
|
|
|
node->offset = view->hex_cursor;
|
|
|
|
node->value = byte_val;
|
|
|
|
enqueue_change (&view->change_list, node);
|
|
|
|
} else {
|
|
|
|
node->value = byte_val;
|
|
|
|
}
|
|
|
|
view->dirty++;
|
|
|
|
view_update (view);
|
|
|
|
view_move_right (view, 1);
|
|
|
|
return MSG_HANDLED;
|
|
|
|
}
|
|
|
|
|
2009-02-06 01:46:07 +03:00
|
|
|
static gboolean
|
2005-05-26 14:40:10 +04:00
|
|
|
view_hexedit_save_changes (WView *view)
|
|
|
|
{
|
|
|
|
struct hexedit_change_node *curr, *next;
|
|
|
|
int fp, answer;
|
|
|
|
char *text, *error;
|
|
|
|
|
2005-08-18 06:26:39 +04:00
|
|
|
if (view->change_list == NULL)
|
|
|
|
return TRUE;
|
|
|
|
|
2005-05-26 14:40:10 +04:00
|
|
|
retry_save:
|
2005-08-28 23:10:00 +04:00
|
|
|
assert (view->filename != NULL);
|
2005-07-12 11:22:49 +04:00
|
|
|
fp = mc_open (view->filename, O_WRONLY);
|
2005-05-26 14:40:10 +04:00
|
|
|
if (fp == -1)
|
|
|
|
goto save_error;
|
|
|
|
|
|
|
|
for (curr = view->change_list; curr != NULL; curr = next) {
|
|
|
|
next = curr->next;
|
|
|
|
|
2005-07-12 11:22:49 +04:00
|
|
|
if (mc_lseek (fp, curr->offset, SEEK_SET) == -1
|
|
|
|
|| mc_write (fp, &(curr->value), 1) != 1)
|
2005-05-26 14:40:10 +04:00
|
|
|
goto save_error;
|
|
|
|
|
|
|
|
/* delete the saved item from the change list */
|
|
|
|
view->change_list = next;
|
|
|
|
view->dirty++;
|
|
|
|
view_set_byte (view, curr->offset, curr->value);
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (curr);
|
2005-05-26 14:40:10 +04:00
|
|
|
}
|
|
|
|
|
2005-07-12 11:22:49 +04:00
|
|
|
if (mc_close (fp) == -1) {
|
2009-02-06 01:40:32 +03:00
|
|
|
error = g_strdup (strerror (errno));
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
message (D_ERROR, _(" Save file "), _(
|
|
|
|
" Error while closing the file: \n %s \n"
|
2005-05-26 14:40:10 +04:00
|
|
|
" Data may have been written or not. "), error);
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (error);
|
2005-05-26 14:40:10 +04:00
|
|
|
}
|
|
|
|
view_update (view);
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
save_error:
|
2009-02-06 01:40:32 +03:00
|
|
|
error = g_strdup (strerror (errno));
|
2005-05-26 14:40:10 +04:00
|
|
|
text = g_strdup_printf (_(" Cannot save file: \n %s "), error);
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (error);
|
2005-07-12 11:22:49 +04:00
|
|
|
(void) mc_close (fp);
|
2005-05-26 14:40:10 +04:00
|
|
|
|
|
|
|
answer = query_dialog (_(" Save file "), text, D_ERROR,
|
|
|
|
2, _("&Retry"), _("&Cancel"));
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (text);
|
2005-05-26 14:40:10 +04:00
|
|
|
|
|
|
|
if (answer == 0)
|
|
|
|
goto retry_save;
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* {{{ Miscellaneous functions }}} */
|
|
|
|
|
2009-02-06 01:46:07 +03:00
|
|
|
static gboolean
|
2005-05-26 14:40:10 +04:00
|
|
|
view_ok_to_quit (WView *view)
|
|
|
|
{
|
|
|
|
int r;
|
|
|
|
|
2005-08-21 16:04:20 +04:00
|
|
|
if (view->change_list == NULL)
|
|
|
|
return TRUE;
|
2005-05-26 14:40:10 +04:00
|
|
|
|
|
|
|
r = query_dialog (_("Quit"),
|
|
|
|
_(" File was modified, Save with exit? "), D_NORMAL, 3,
|
|
|
|
_("&Cancel quit"), _("&Yes"), _("&No"));
|
|
|
|
|
|
|
|
switch (r) {
|
|
|
|
case 1:
|
|
|
|
return view_hexedit_save_changes (view);
|
|
|
|
case 2:
|
2005-08-21 16:04:20 +04:00
|
|
|
view_hexedit_free_change_list (view);
|
2005-05-26 14:40:10 +04:00
|
|
|
return TRUE;
|
|
|
|
default:
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
static inline void
|
2004-08-16 08:16:55 +04:00
|
|
|
my_define (Dlg_head *h, int idx, const char *text, void (*fn) (WView *),
|
2002-11-13 02:33:15 +03:00
|
|
|
WView *view)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2005-02-08 12:53:51 +03:00
|
|
|
buttonbar_set_label_data (h, idx, text, (buttonbarfn) fn, view);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2005-08-19 23:32:02 +04:00
|
|
|
/* {{{ Searching }}} */
|
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
/* Case insensitive search of text in data */
|
|
|
|
static int
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
icase_search_p (WView *view, char *text, char *data, int nothing,
|
|
|
|
size_t *match_start, size_t *match_end)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2004-08-16 08:16:55 +04:00
|
|
|
const char *q;
|
2005-02-08 01:09:44 +03:00
|
|
|
(void) nothing;
|
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
q = (view->direction == 1)
|
|
|
|
? str_search_first (data, text, 0)
|
|
|
|
: str_search_last (data, text, 0);
|
2003-03-19 16:39:48 +03:00
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
if (q != NULL) {
|
|
|
|
(*match_start) = str_length_noncomb (data) - str_length_noncomb (q);
|
|
|
|
(*match_end) = (*match_start) + str_length_noncomb (text);
|
2000-11-20 20:25:43 +03:00
|
|
|
return 1;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
2000-11-20 20:25:43 +03:00
|
|
|
return 0;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
/* read one whole line into buffer, return where line start and end */
|
|
|
|
static int
|
2009-04-14 14:29:01 +04:00
|
|
|
view_get_line_at (WView *view, offset_type from, GString * buffer,
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
offset_type *buff_start, offset_type *buff_end)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
#define cmp(t1,t2) (strcmp((t1),(t2)) == 0)
|
|
|
|
struct read_info info;
|
|
|
|
struct cache_line *line;
|
|
|
|
offset_type start;
|
|
|
|
offset_type end;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
line = view_get_first_showed_line (view);
|
2001-04-24 18:39:38 +04:00
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
line = view_offset_to_line_from (view, from, line);
|
2005-05-23 06:03:29 +04:00
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
if (view->direction == 1) {
|
|
|
|
start = from;
|
|
|
|
end = view_get_end_of_whole_line (view, line)->end;
|
|
|
|
if (start >= end) return 0;
|
|
|
|
} else {
|
|
|
|
start = view_get_start_of_whole_line (view, line)->start;
|
|
|
|
end = from;
|
|
|
|
}
|
2003-03-19 16:39:48 +03:00
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
(*buff_start) = start;
|
|
|
|
(*buff_end) = end;
|
|
|
|
|
2009-04-14 14:29:01 +04:00
|
|
|
g_string_set_size(buffer,0);
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
|
|
|
|
view_read_start (view, &info, start);
|
|
|
|
while ((info.result != -1) && (info.next < end)) {
|
|
|
|
view_read_continue (view, &info);
|
|
|
|
|
|
|
|
/* if text contains '\0' */
|
|
|
|
if (cmp (info.cact, "")) {
|
|
|
|
if (info.actual < from) {
|
|
|
|
/* '\0' before start offset, continue */
|
2009-04-14 14:29:01 +04:00
|
|
|
g_string_set_size(buffer,0);
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
(*buff_start) = info.next;
|
|
|
|
continue;
|
|
|
|
} else {
|
|
|
|
/* '\0' after start offset, end */
|
|
|
|
(*buff_end) = info.next;
|
|
|
|
return 1;
|
2009-04-14 14:29:01 +04:00
|
|
|
}
|
|
|
|
}
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
|
|
|
|
if (view_read_test_new_line (view, &info))
|
|
|
|
continue;
|
2001-04-24 18:39:38 +04:00
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
if (view_read_test_nroff_back (view, &info)) {
|
2009-04-14 14:29:01 +04:00
|
|
|
g_string_truncate (buffer, buffer->len-1);
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
continue;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
2000-11-20 20:25:43 +03:00
|
|
|
|
2009-04-14 14:29:01 +04:00
|
|
|
g_string_append(buffer,info.cact);
|
|
|
|
}
|
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
return 1;
|
2009-04-14 14:29:01 +04:00
|
|
|
}
|
2000-11-20 20:25:43 +03:00
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
/* map search result positions to offsets in text */
|
|
|
|
void
|
|
|
|
view_matchs_to_offsets (WView *view, offset_type start, offset_type end,
|
|
|
|
size_t match_start, size_t match_end,
|
|
|
|
offset_type *search_start, offset_type *search_end)
|
|
|
|
{
|
|
|
|
struct read_info info;
|
|
|
|
size_t c = 0;
|
2003-03-19 16:39:48 +03:00
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
(*search_start) = INVALID_OFFSET;
|
|
|
|
(*search_end) = INVALID_OFFSET;
|
2003-03-19 16:39:48 +03:00
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
view_read_start (view, &info, start);
|
2009-04-14 14:29:01 +04:00
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
while ((info.result != -1) && (info.next < end)) {
|
|
|
|
view_read_continue (view, &info);
|
|
|
|
|
|
|
|
if (view_read_test_nroff_back (view, &info)) {
|
|
|
|
c-= 1;
|
|
|
|
continue;
|
2003-03-24 21:52:02 +03:00
|
|
|
}
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
if ((c == match_start) && (*search_start == INVALID_OFFSET))
|
|
|
|
*search_start = info.actual;
|
|
|
|
if (c == match_end) (*search_end) = info.actual;
|
|
|
|
c+= !str_iscombiningmark (info.cact) || (c == 0);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
2003-03-19 16:39:48 +03:00
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
if ((c == match_start) && (*search_start == INVALID_OFFSET)) *search_start = info.next;
|
|
|
|
if (c == match_end) (*search_end) = info.next;
|
|
|
|
}
|
2003-03-21 19:01:50 +03:00
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
/* we have set view->search_start and view->search_end and must set
|
|
|
|
* view->dpy_text_column, view->first_showed_line and view->dpy_start
|
|
|
|
* try to displaye maximum of match */
|
|
|
|
void
|
|
|
|
view_moveto_match (WView *view)
|
|
|
|
{
|
|
|
|
const screen_dimen height = view->data_area.height;
|
|
|
|
const screen_dimen height3 = height / 3;
|
|
|
|
const screen_dimen width = view->data_area.width;
|
|
|
|
struct cache_line *line;
|
|
|
|
struct cache_line *line_end, *line_start;
|
|
|
|
struct cache_line *t;
|
|
|
|
int start_off = -1;
|
|
|
|
int end_off = -1;
|
|
|
|
int off = 0;
|
|
|
|
|
|
|
|
line = view_get_first_showed_line (view);
|
|
|
|
if (view->text_wrap_mode) {
|
|
|
|
if (line->start > view->search_start) {
|
|
|
|
if (line->start <= view->search_start && line->end > view->search_start)
|
|
|
|
start_off = 0;
|
|
|
|
if (line->start <= view->search_end && line->end >= view->search_end)
|
|
|
|
end_off = 0;
|
|
|
|
t = view_get_previous_line (view, line);
|
|
|
|
while ((t != NULL) && ((start_off == -1) || (end_off == -1))) {
|
|
|
|
line = t;
|
|
|
|
t = view_get_previous_line (view, line);
|
|
|
|
off++;
|
|
|
|
if (line->start <= view->search_start && line->end > view->search_start)
|
|
|
|
start_off = off;
|
|
|
|
if (line->start <= view->search_end && line->end >= view->search_end)
|
|
|
|
end_off = off;
|
|
|
|
}
|
|
|
|
|
|
|
|
line = view_get_first_showed_line (view);
|
|
|
|
|
|
|
|
off = (start_off - end_off < height - height3) ? start_off + height3: end_off;
|
|
|
|
for (;off >= 0 && line->start > 0; off--)
|
|
|
|
line = view_get_previous_line (view, line);
|
|
|
|
} else {
|
|
|
|
/* start_off, end_off - how many cache_lines far are
|
|
|
|
* view->search_start, end from line */
|
|
|
|
if (line->start <= view->search_start && line->end > view->search_start)
|
|
|
|
start_off = 0;
|
|
|
|
if (line->start <= view->search_end && line->end >= view->search_end)
|
|
|
|
end_off = 0;
|
|
|
|
t = view_get_next_line (view, line);
|
|
|
|
while ((t != NULL) && ((start_off == -1) || (end_off == -1))) {
|
|
|
|
line = t;
|
|
|
|
t = view_get_next_line (view, line);
|
|
|
|
off++;
|
|
|
|
if (line->start <= view->search_start && line->end > view->search_start)
|
|
|
|
start_off = off;
|
|
|
|
if (line->start <= view->search_end && line->end >= view->search_end)
|
|
|
|
end_off = off;
|
|
|
|
}
|
|
|
|
|
|
|
|
line = view_get_first_showed_line (view);
|
|
|
|
// if view->search_end is farther then screen heigth */
|
|
|
|
if (end_off >= height) {
|
|
|
|
off = (end_off - start_off < height - height3) ? end_off - height + height3: start_off;
|
|
|
|
|
|
|
|
for (;off >= 0; off--)
|
|
|
|
line = view_get_next_line (view, line);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* first part similar like in wrap mode,only wokrs with whole lines */
|
|
|
|
line = view_get_first_showed_line (view);
|
|
|
|
line = view_get_start_of_whole_line (view, line);
|
|
|
|
if (line->start > view->search_start) {
|
|
|
|
line_start = view_get_start_of_whole_line (view, line);
|
|
|
|
if (line_start->start <= view->search_start && line->end > view->search_start)
|
|
|
|
start_off = 0;
|
|
|
|
if (line_start->start <= view->search_end && line->end >= view->search_end)
|
|
|
|
end_off = 0;
|
|
|
|
t = view_get_previous_whole_line (view, line_start);
|
|
|
|
while ((t != NULL) && ((start_off == -1) || (end_off == -1))) {
|
|
|
|
line = t;
|
|
|
|
line_start = view_get_start_of_whole_line (view, line);
|
|
|
|
t = view_get_previous_whole_line (view, line_start);
|
|
|
|
off++;
|
|
|
|
if (line_start->start <= view->search_start && line->end > view->search_start)
|
|
|
|
start_off = off;
|
|
|
|
if (line_start->start <= view->search_end && line->end >= view->search_end)
|
|
|
|
end_off = off;
|
|
|
|
}
|
|
|
|
|
|
|
|
line = view_get_first_showed_line (view);
|
|
|
|
line = view_get_start_of_whole_line (view, line);
|
|
|
|
off = (start_off - end_off < height - height3) ? start_off + height3: end_off;
|
|
|
|
for (;off >= 0 && line->start > 0; off--) {
|
|
|
|
line = view_get_previous_whole_line (view, line);
|
|
|
|
line = view_get_start_of_whole_line (view, line);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
line_end = view_get_end_of_whole_line (view, line);
|
|
|
|
if (line->start <= view->search_start && line_end->end > view->search_start)
|
|
|
|
start_off = 0;
|
|
|
|
if (line->start <= view->search_end && line_end->end >= view->search_end)
|
|
|
|
end_off = 0;
|
|
|
|
t = view_get_next_whole_line (view, line_end);
|
|
|
|
while ((t != NULL) && ((start_off == -1) || (end_off == -1))) {
|
|
|
|
line = t;
|
|
|
|
line_end = view_get_end_of_whole_line (view, line);
|
|
|
|
t = view_get_next_whole_line (view, line_end);
|
|
|
|
off++;
|
|
|
|
if (line->start <= view->search_start && line_end->end > view->search_start)
|
|
|
|
start_off = off;
|
|
|
|
if (line->start <= view->search_end && line_end->end >= view->search_end)
|
|
|
|
end_off = off;
|
|
|
|
}
|
|
|
|
|
|
|
|
line = view_get_first_showed_line (view);
|
|
|
|
line = view_get_start_of_whole_line (view, line);
|
|
|
|
if (end_off >= height) {
|
|
|
|
off = (end_off - start_off < height - height3) ? end_off - height + height3: start_off;
|
|
|
|
|
|
|
|
for (;off >= 0; off--)
|
|
|
|
line = view_get_next_whole_line (view, line);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*now line point to begin of line, that we want show*/
|
|
|
|
|
|
|
|
t = view_offset_to_line_from (view, view->search_start, line);
|
|
|
|
start_off = view_offset_to_column (view, t, view->search_start);
|
|
|
|
t = view_offset_to_line_from (view, view->search_end, line);
|
|
|
|
end_off = view_offset_to_column (view, t, view->search_end);
|
|
|
|
|
|
|
|
if (end_off - start_off > width) end_off = start_off + width;
|
|
|
|
if (view->dpy_text_column > start_off) {
|
|
|
|
view->dpy_text_column = start_off;
|
|
|
|
} else {
|
|
|
|
if (view->dpy_text_column + width < end_off) {
|
|
|
|
view->dpy_text_column = end_off - width;
|
|
|
|
}
|
2003-03-21 19:01:50 +03:00
|
|
|
}
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
view_set_first_showed (view, line);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
search_update_steps (WView *view)
|
|
|
|
{
|
2005-04-14 01:09:00 +04:00
|
|
|
offset_type filesize = view_get_filesize (view);
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
if (filesize == 0)
|
2005-02-01 01:01:53 +03:00
|
|
|
view->update_steps = 40000;
|
2004-08-16 08:16:55 +04:00
|
|
|
else /* viewing a data stream, not a file */
|
2005-04-14 01:09:00 +04:00
|
|
|
view->update_steps = filesize / 100;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
/* Do not update the percent display but every 20 ks */
|
2005-02-01 01:01:53 +03:00
|
|
|
if (view->update_steps < 20000)
|
|
|
|
view->update_steps = 20000;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
view_search (WView *view, char *text,
|
|
|
|
int (*search) (WView *, char *, char *, int, size_t *, size_t *))
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2009-04-14 14:29:01 +04:00
|
|
|
GString *buffer;
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
offset_type search_start;
|
1998-02-27 07:54:42 +03:00
|
|
|
int search_status;
|
2001-06-02 05:01:30 +04:00
|
|
|
Dlg_head *d = 0;
|
2002-10-31 01:48:59 +03:00
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
offset_type line_start;
|
|
|
|
offset_type line_end;
|
|
|
|
size_t match_start;
|
|
|
|
size_t match_end;
|
1999-02-10 04:16:42 +03:00
|
|
|
|
2002-10-31 01:48:59 +03:00
|
|
|
if (verbose) {
|
2003-10-26 01:12:05 +04:00
|
|
|
d = create_message (D_NORMAL, _("Search"), _("Searching %s"), text);
|
1998-02-27 07:54:42 +03:00
|
|
|
mc_refresh ();
|
|
|
|
}
|
2000-11-20 20:25:43 +03:00
|
|
|
|
2009-04-14 14:29:01 +04:00
|
|
|
buffer = g_string_new ("");
|
2000-11-20 20:25:43 +03:00
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
search_start = (view->direction != 1) ? view->search_start :
|
|
|
|
view->search_end;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
/* Compute the percent steps */
|
|
|
|
search_update_steps (view);
|
2005-02-01 01:01:53 +03:00
|
|
|
view->update_activate = 0;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2005-08-15 13:55:19 +04:00
|
|
|
enable_interrupt_key ();
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
search_status = -1;
|
2009-04-14 14:29:01 +04:00
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
while (1) {
|
2009-04-14 14:29:01 +04:00
|
|
|
if (search_start >= view->update_activate) {
|
2005-02-01 01:01:53 +03:00
|
|
|
view->update_activate += view->update_steps;
|
2002-10-31 01:48:59 +03:00
|
|
|
if (verbose) {
|
2009-04-14 14:29:01 +04:00
|
|
|
view_percent (view, search_start);
|
1998-02-27 07:54:42 +03:00
|
|
|
mc_refresh ();
|
|
|
|
}
|
|
|
|
if (got_interrupt ())
|
|
|
|
break;
|
|
|
|
}
|
2000-11-20 20:25:43 +03:00
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
if (!view_get_line_at (view, search_start, buffer, &line_start, &line_end))
|
1998-02-27 07:54:42 +03:00
|
|
|
break;
|
2000-11-20 20:25:43 +03:00
|
|
|
|
2009-04-14 14:29:01 +04:00
|
|
|
search_status = (*search) (view, text, buffer->str, match_normal,
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
&match_start, &match_end);
|
2009-04-14 14:29:01 +04:00
|
|
|
|
2002-10-31 01:48:59 +03:00
|
|
|
if (search_status < 0) {
|
1998-02-27 07:54:42 +03:00
|
|
|
break;
|
2000-11-20 20:25:43 +03:00
|
|
|
}
|
1998-02-27 07:54:42 +03:00
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
if (search_status == 0) {
|
|
|
|
if (view->direction == 1)
|
|
|
|
search_start = line_end;
|
|
|
|
else {
|
|
|
|
if (line_start > 0) search_start = line_start - 1;
|
|
|
|
else break;
|
|
|
|
}
|
1998-02-27 07:54:42 +03:00
|
|
|
continue;
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
}
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
/* We found the string */
|
2002-10-31 01:48:59 +03:00
|
|
|
|
2009-04-14 14:29:01 +04:00
|
|
|
view_matchs_to_offsets (view, line_start, line_end,
|
|
|
|
match_start, match_end,
|
|
|
|
&(view->search_start), &(view->search_end));
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2009-04-14 14:29:01 +04:00
|
|
|
view_moveto_match (view);
|
2000-11-20 20:25:43 +03:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
disable_interrupt_key ();
|
2001-09-16 05:22:12 +04:00
|
|
|
if (verbose) {
|
1998-02-27 07:54:42 +03:00
|
|
|
dlg_run_done (d);
|
|
|
|
destroy_dlg (d);
|
|
|
|
}
|
2009-04-03 16:19:09 +04:00
|
|
|
if (search_status <= 0) {
|
2009-01-10 16:13:56 +03:00
|
|
|
message (D_NORMAL, _("Search"), _(" Search string not found "));
|
2009-04-03 16:19:09 +04:00
|
|
|
view->search_end = view->search_start;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
2009-04-14 14:29:01 +04:00
|
|
|
g_string_free (buffer, TRUE);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2004-10-16 19:52:48 +04:00
|
|
|
/* Search buffer (its size is len) in the complete buffer
|
|
|
|
* returns the position where the block was found or INVALID_OFFSET
|
|
|
|
* if not found */
|
2004-08-16 08:16:55 +04:00
|
|
|
static offset_type
|
|
|
|
block_search (WView *view, const char *buffer, int len)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2003-03-19 16:39:48 +03:00
|
|
|
int direction = view->direction;
|
2004-08-16 08:16:55 +04:00
|
|
|
const char *d = buffer;
|
|
|
|
char b;
|
|
|
|
offset_type e;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
enable_interrupt_key ();
|
2003-03-19 16:39:48 +03:00
|
|
|
if (direction == 1)
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
e = view->search_start + ((view->search_start != view->search_end) ? 1 : 0);
|
2003-03-19 16:39:48 +03:00
|
|
|
else
|
2005-04-17 13:50:38 +04:00
|
|
|
e = view->search_start
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
- ((view->search_end != view->search_start && view->search_start >= 1) ? 1 : 0);
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
search_update_steps (view);
|
2005-02-01 01:01:53 +03:00
|
|
|
view->update_activate = 0;
|
2002-10-31 01:48:59 +03:00
|
|
|
|
2003-03-19 16:39:48 +03:00
|
|
|
if (direction == -1) {
|
|
|
|
for (d += len - 1;; e--) {
|
2005-02-01 01:01:53 +03:00
|
|
|
if (e <= view->update_activate) {
|
|
|
|
view->update_activate -= view->update_steps;
|
2003-03-19 16:39:48 +03:00
|
|
|
if (verbose) {
|
2005-04-16 17:45:16 +04:00
|
|
|
view_percent (view, e);
|
2003-03-19 16:39:48 +03:00
|
|
|
mc_refresh ();
|
|
|
|
}
|
|
|
|
if (got_interrupt ())
|
|
|
|
break;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
2003-03-19 16:39:48 +03:00
|
|
|
b = get_byte (view, e);
|
|
|
|
|
|
|
|
if (*d == b) {
|
|
|
|
if (d == buffer) {
|
|
|
|
disable_interrupt_key ();
|
|
|
|
return e;
|
|
|
|
}
|
|
|
|
d--;
|
|
|
|
} else {
|
|
|
|
e += buffer + len - 1 - d;
|
|
|
|
d = buffer + len - 1;
|
|
|
|
}
|
|
|
|
if (e == 0)
|
1998-02-27 07:54:42 +03:00
|
|
|
break;
|
|
|
|
}
|
2003-03-21 19:01:50 +03:00
|
|
|
} else {
|
2005-04-14 01:09:00 +04:00
|
|
|
while (get_byte (view, e) != -1) {
|
2005-02-01 01:01:53 +03:00
|
|
|
if (e >= view->update_activate) {
|
|
|
|
view->update_activate += view->update_steps;
|
2003-03-19 16:39:48 +03:00
|
|
|
if (verbose) {
|
2005-04-16 17:45:16 +04:00
|
|
|
view_percent (view, e);
|
2003-03-19 16:39:48 +03:00
|
|
|
mc_refresh ();
|
|
|
|
}
|
|
|
|
if (got_interrupt ())
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
b = get_byte (view, e++);
|
2002-10-31 01:48:59 +03:00
|
|
|
|
2003-03-19 16:39:48 +03:00
|
|
|
if (*d == b) {
|
|
|
|
d++;
|
|
|
|
if (d - buffer == len) {
|
|
|
|
disable_interrupt_key ();
|
|
|
|
return e - len;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
e -= d - buffer;
|
|
|
|
d = buffer;
|
2001-08-06 19:33:38 +04:00
|
|
|
}
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
2003-03-21 19:01:50 +03:00
|
|
|
}
|
1998-02-27 07:54:42 +03:00
|
|
|
disable_interrupt_key ();
|
2004-10-16 19:52:48 +04:00
|
|
|
return INVALID_OFFSET;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2001-07-10 03:19:23 +04:00
|
|
|
/*
|
|
|
|
* Search in the hex mode. Supported input:
|
|
|
|
* - numbers (oct, dec, hex). Each of them matches one byte.
|
|
|
|
* - strings in double quotes. Matches exactly without quotes.
|
|
|
|
*/
|
1998-02-27 07:54:42 +03:00
|
|
|
static void
|
2004-08-16 08:16:55 +04:00
|
|
|
hex_search (WView *view, const char *text)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2001-09-03 00:34:44 +04:00
|
|
|
char *buffer; /* Parsed search string */
|
|
|
|
char *cur; /* Current position in it */
|
2002-10-31 01:48:59 +03:00
|
|
|
int block_len; /* Length of the search string */
|
2004-08-16 08:16:55 +04:00
|
|
|
offset_type pos; /* Position of the string in the file */
|
2002-10-31 01:48:59 +03:00
|
|
|
int parse_error = 0;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2001-07-10 21:42:25 +04:00
|
|
|
if (!*text) {
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
view->search_end = view->search_start;
|
2001-07-10 21:42:25 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2001-07-10 03:19:23 +04:00
|
|
|
/* buffer will never be longer that text */
|
|
|
|
buffer = g_new (char, strlen (text));
|
2001-09-03 00:34:44 +04:00
|
|
|
cur = buffer;
|
2001-07-10 03:19:23 +04:00
|
|
|
|
|
|
|
/* First convert the string to a stream of bytes */
|
2001-07-10 21:42:25 +04:00
|
|
|
while (*text) {
|
2001-07-10 03:19:23 +04:00
|
|
|
int val;
|
|
|
|
int ptr;
|
|
|
|
|
2001-09-03 00:34:44 +04:00
|
|
|
/* Skip leading spaces */
|
|
|
|
if (*text == ' ' || *text == '\t') {
|
|
|
|
text++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2001-07-10 03:19:23 +04:00
|
|
|
/* %i matches octal, decimal, and hexadecimal numbers */
|
2001-07-10 21:42:25 +04:00
|
|
|
if (sscanf (text, "%i%n", &val, &ptr) > 0) {
|
2001-07-10 03:19:23 +04:00
|
|
|
/* Allow signed and unsigned char in the user input */
|
|
|
|
if (val < -128 || val > 255) {
|
|
|
|
parse_error = 1;
|
1998-02-27 07:54:42 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2001-09-03 00:34:44 +04:00
|
|
|
*cur++ = (char) val;
|
2001-07-10 21:42:25 +04:00
|
|
|
text += ptr;
|
2001-07-10 03:19:23 +04:00
|
|
|
continue;
|
|
|
|
}
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2001-07-10 03:19:23 +04:00
|
|
|
/* Try quoted string, strip quotes */
|
2001-09-03 00:34:44 +04:00
|
|
|
if (*text == '"') {
|
2004-09-25 05:12:09 +04:00
|
|
|
const char *next_quote;
|
2001-09-03 00:34:44 +04:00
|
|
|
|
|
|
|
text++;
|
|
|
|
next_quote = strchr (text, '"');
|
|
|
|
if (next_quote) {
|
|
|
|
memcpy (cur, text, next_quote - text);
|
|
|
|
cur += next_quote - text;
|
|
|
|
text = next_quote + 1;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
/* fall through */
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
2001-07-10 03:19:23 +04:00
|
|
|
|
|
|
|
parse_error = 1;
|
|
|
|
break;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
2001-07-10 03:19:23 +04:00
|
|
|
|
2001-09-03 00:34:44 +04:00
|
|
|
block_len = cur - buffer;
|
|
|
|
|
2001-07-10 03:19:23 +04:00
|
|
|
/* No valid bytes in the user input */
|
|
|
|
if (block_len <= 0 || parse_error) {
|
2009-01-10 16:13:56 +03:00
|
|
|
message (D_NORMAL, _("Search"), _("Invalid hex search expression"));
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (buffer);
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
view->search_end = view->search_start;
|
2001-07-10 03:19:23 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
/* Then start the search */
|
|
|
|
pos = block_search (view, buffer, block_len);
|
2001-07-10 03:19:23 +04:00
|
|
|
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (buffer);
|
2001-07-10 21:42:25 +04:00
|
|
|
|
2004-10-16 19:52:48 +04:00
|
|
|
if (pos == INVALID_OFFSET) {
|
2009-01-10 16:13:56 +03:00
|
|
|
message (D_NORMAL, _("Search"), _(" Search string not found "));
|
1998-02-27 07:54:42 +03:00
|
|
|
return;
|
|
|
|
}
|
2002-10-31 01:48:59 +03:00
|
|
|
|
2001-08-06 19:33:38 +04:00
|
|
|
view->search_start = pos;
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
view->search_end = pos + block_len;
|
1998-02-27 07:54:42 +03:00
|
|
|
/* Set the edit cursor to the search position, left nibble */
|
2005-05-21 14:23:57 +04:00
|
|
|
view->hex_cursor = view->search_start;
|
2005-04-20 00:33:51 +04:00
|
|
|
view->hexedit_lownibble = FALSE;
|
2002-10-31 01:48:59 +03:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
/* Adjust the file offset */
|
2005-08-22 22:31:51 +04:00
|
|
|
view->dpy_start = pos - pos % view->bytes_per_line;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2002-10-31 01:48:59 +03:00
|
|
|
static int
|
|
|
|
regexp_view_search (WView *view, char *pattern, char *string,
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
int match_type, size_t *match_start, size_t *match_end)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
|
|
|
static regex_t r;
|
|
|
|
static char *old_pattern = NULL;
|
|
|
|
static int old_type;
|
|
|
|
regmatch_t pmatch[1];
|
|
|
|
int i, flags = REG_ICASE;
|
|
|
|
|
2005-08-29 13:34:43 +04:00
|
|
|
if (old_pattern == NULL || strcmp (old_pattern, pattern) != 0
|
2002-10-31 01:48:59 +03:00
|
|
|
|| old_type != match_type) {
|
2005-08-29 13:34:43 +04:00
|
|
|
if (old_pattern != NULL) {
|
1998-02-27 07:54:42 +03:00
|
|
|
regfree (&r);
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (old_pattern);
|
1998-02-27 07:54:42 +03:00
|
|
|
old_pattern = 0;
|
|
|
|
}
|
2005-08-29 13:34:43 +04:00
|
|
|
for (i = 0; pattern[i] != '\0'; i++) {
|
2005-05-11 05:16:58 +04:00
|
|
|
if (isupper ((unsigned char) pattern[i])) {
|
1998-02-27 07:54:42 +03:00
|
|
|
flags = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
flags |= REG_EXTENDED;
|
2002-10-31 01:48:59 +03:00
|
|
|
if (regcomp (&r, pattern, flags)) {
|
2009-01-10 16:13:56 +03:00
|
|
|
message (D_ERROR, MSG_ERROR, _(" Invalid regular expression "));
|
1998-02-27 07:54:42 +03:00
|
|
|
return -1;
|
|
|
|
}
|
2009-02-06 01:40:32 +03:00
|
|
|
old_pattern = g_strdup (pattern);
|
1998-02-27 07:54:42 +03:00
|
|
|
old_type = match_type;
|
|
|
|
}
|
|
|
|
if (regexec (&r, string, 1, pmatch, 0) != 0)
|
|
|
|
return 0;
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
|
|
|
|
i = str_length (string);
|
|
|
|
(*match_start) = i - str_length (string + pmatch[0].rm_so);
|
|
|
|
(*match_end) = i - str_length (string + pmatch[0].rm_eo);
|
1998-02-27 07:54:42 +03:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2002-10-31 01:48:59 +03:00
|
|
|
static void
|
2005-08-21 16:33:21 +04:00
|
|
|
do_regexp_search (WView *view)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
view_search (view, view->search_exp, regexp_view_search);
|
1998-02-27 07:54:42 +03:00
|
|
|
/* Had a refresh here */
|
|
|
|
view->dirty++;
|
2005-02-08 01:09:44 +03:00
|
|
|
view_update (view);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2002-10-31 01:48:59 +03:00
|
|
|
static void
|
2005-08-21 16:33:21 +04:00
|
|
|
do_normal_search (WView *view)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
|
|
|
if (view->hex_mode)
|
2005-08-21 16:33:21 +04:00
|
|
|
hex_search (view, view->search_exp);
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
else {
|
|
|
|
char *needle = str_create_search_needle (view->search_exp, 0);
|
|
|
|
view_search (view, needle, icase_search_p);
|
|
|
|
str_release_search_needle (needle, 0);
|
|
|
|
}
|
1998-02-27 07:54:42 +03:00
|
|
|
/* Had a refresh here */
|
|
|
|
view->dirty++;
|
2005-02-08 01:09:44 +03:00
|
|
|
view_update (view);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2005-08-19 23:32:02 +04:00
|
|
|
/* {{{ User-definable commands }}} */
|
|
|
|
|
|
|
|
/*
|
|
|
|
The functions in this section can be bound to hotkeys. They are all
|
|
|
|
of the same type (taking a pointer to WView as parameter and
|
|
|
|
returning void). TODO: In the not-too-distant future, these commands
|
|
|
|
will become fully configurable, like they already are in the
|
|
|
|
internal editor. By convention, all the function names end in
|
|
|
|
"_cmd".
|
|
|
|
*/
|
|
|
|
|
2002-10-31 01:48:59 +03:00
|
|
|
static void
|
|
|
|
view_help_cmd (void)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2001-06-09 11:13:46 +04:00
|
|
|
interactive_display (NULL, "[Internal File Viewer]");
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2005-05-21 14:04:03 +04:00
|
|
|
/* Toggle between hexview and hexedit mode */
|
2002-10-31 01:48:59 +03:00
|
|
|
static void
|
2005-08-19 23:32:02 +04:00
|
|
|
view_toggle_hexedit_mode_cmd (WView *view)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2005-08-29 00:38:53 +04:00
|
|
|
view_toggle_hexedit_mode (view);
|
2005-02-08 01:09:44 +03:00
|
|
|
view_update (view);
|
2003-10-23 23:53:22 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Toggle between wrapped and unwrapped view */
|
|
|
|
static void
|
2005-08-19 23:32:02 +04:00
|
|
|
view_toggle_wrap_mode_cmd (WView *view)
|
2003-10-23 23:53:22 +04:00
|
|
|
{
|
2005-08-29 00:38:53 +04:00
|
|
|
view_toggle_wrap_mode (view);
|
2005-02-08 01:09:44 +03:00
|
|
|
view_update (view);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2003-10-23 23:53:22 +04:00
|
|
|
/* Toggle between hex view and text view */
|
2002-08-27 23:10:54 +04:00
|
|
|
static void
|
2005-08-19 23:32:02 +04:00
|
|
|
view_toggle_hex_mode_cmd (WView *view)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2005-08-29 00:38:53 +04:00
|
|
|
view_toggle_hex_mode (view);
|
2005-02-08 01:09:44 +03:00
|
|
|
view_update (view);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2002-08-27 23:10:54 +04:00
|
|
|
static void
|
2005-08-19 23:32:02 +04:00
|
|
|
view_moveto_line_cmd (WView *view)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2005-05-26 13:08:54 +04:00
|
|
|
char *answer, *answer_end, prompt[BUF_SMALL];
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
struct cache_line *line;
|
|
|
|
offset_type row;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
line = view_get_first_showed_line (view);
|
|
|
|
row = line->number + 1;
|
2005-04-14 01:09:00 +04:00
|
|
|
|
2009-02-06 01:49:00 +03:00
|
|
|
g_snprintf (prompt, sizeof (prompt),
|
2002-10-31 01:48:59 +03:00
|
|
|
_(" The current line number is %d.\n"
|
2005-05-26 13:08:54 +04:00
|
|
|
" Enter the new line number:"), (int) (line + 1));
|
2009-01-24 23:51:29 +03:00
|
|
|
answer = input_dialog (_(" Goto line "), prompt, MC_HISTORY_VIEW_GOTO_LINE, "");
|
2005-08-29 13:34:43 +04:00
|
|
|
if (answer != NULL && answer[0] != '\0') {
|
2005-05-26 13:08:54 +04:00
|
|
|
errno = 0;
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
row = strtoul (answer, &answer_end, 10);
|
|
|
|
if (*answer_end == '\0' && errno == 0 && row >= 1)
|
|
|
|
view_moveto (view, row - 1, 0);
|
2005-05-26 13:08:54 +04:00
|
|
|
}
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (answer);
|
1998-02-27 07:54:42 +03:00
|
|
|
view->dirty++;
|
2005-02-08 01:09:44 +03:00
|
|
|
view_update (view);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2001-06-15 02:33:00 +04:00
|
|
|
static void
|
2005-08-19 23:32:02 +04:00
|
|
|
view_moveto_addr_cmd (WView *view)
|
1999-06-25 01:53:40 +04:00
|
|
|
{
|
2002-10-31 01:48:59 +03:00
|
|
|
char *line, *error, prompt[BUF_SMALL];
|
2004-08-16 08:16:55 +04:00
|
|
|
offset_type addr;
|
1999-06-25 01:53:40 +04:00
|
|
|
|
2009-02-06 01:49:00 +03:00
|
|
|
g_snprintf (prompt, sizeof (prompt),
|
2002-10-31 01:48:59 +03:00
|
|
|
_(" The current address is 0x%lx.\n"
|
2005-05-21 14:23:57 +04:00
|
|
|
" Enter the new address:"), view->hex_cursor);
|
2009-01-24 23:51:29 +03:00
|
|
|
line = input_dialog (_(" Goto Address "), prompt, MC_HISTORY_VIEW_GOTO_ADDR, "");
|
2005-08-29 13:34:43 +04:00
|
|
|
if (line != NULL) {
|
|
|
|
if (*line != '\0') {
|
2004-08-16 08:16:55 +04:00
|
|
|
addr = strtoul (line, &error, 0);
|
2005-04-14 01:09:00 +04:00
|
|
|
if ((*error == '\0') && get_byte (view, addr) != -1) {
|
2005-05-26 13:08:54 +04:00
|
|
|
view_moveto_offset (view, addr);
|
2006-12-30 16:16:54 +03:00
|
|
|
} else {
|
|
|
|
message (D_ERROR, _("Warning"), _(" Invalid address "));
|
2002-10-31 01:48:59 +03:00
|
|
|
}
|
|
|
|
}
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (line);
|
1999-06-25 01:53:40 +04:00
|
|
|
}
|
|
|
|
view->dirty++;
|
2005-02-08 01:09:44 +03:00
|
|
|
view_update (view);
|
1999-06-25 01:53:40 +04:00
|
|
|
}
|
|
|
|
|
2005-08-18 06:26:39 +04:00
|
|
|
static void
|
|
|
|
view_hexedit_save_changes_cmd (WView *view)
|
|
|
|
{
|
|
|
|
(void) view_hexedit_save_changes (view);
|
|
|
|
}
|
|
|
|
|
2005-08-19 23:32:02 +04:00
|
|
|
/* {{{ Searching }}} */
|
|
|
|
|
1998-12-03 00:27:27 +03:00
|
|
|
static void
|
1998-02-27 07:54:42 +03:00
|
|
|
regexp_search (WView *view, int direction)
|
|
|
|
{
|
2005-08-21 16:33:21 +04:00
|
|
|
const char *defval;
|
|
|
|
char *regexp;
|
2006-12-11 00:36:46 +03:00
|
|
|
static char *last_regexp;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2006-12-11 00:36:46 +03:00
|
|
|
defval = (last_regexp != NULL ? last_regexp : "");
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2009-01-24 23:51:29 +03:00
|
|
|
regexp = input_dialog (_("Search"), _(" Enter regexp:"), MC_HISTORY_VIEW_SEARCH_REGEX, defval);
|
2006-12-11 00:36:46 +03:00
|
|
|
if (regexp == NULL || regexp[0] == '\0') {
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (regexp);
|
2006-12-11 00:36:46 +03:00
|
|
|
return;
|
|
|
|
}
|
2005-08-21 16:33:21 +04:00
|
|
|
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (last_regexp);
|
2006-12-11 00:36:46 +03:00
|
|
|
view->search_exp = last_regexp = regexp;
|
2005-08-21 16:33:21 +04:00
|
|
|
|
|
|
|
view->direction = direction;
|
|
|
|
do_regexp_search (view);
|
1998-02-27 07:54:42 +03:00
|
|
|
view->last_search = do_regexp_search;
|
|
|
|
}
|
|
|
|
|
2005-08-19 23:32:02 +04:00
|
|
|
/* {{{ User-definable commands }}} */
|
|
|
|
|
2002-08-27 23:10:54 +04:00
|
|
|
static void
|
2005-08-19 23:32:02 +04:00
|
|
|
view_regexp_search_cmd (WView *view)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
|
|
|
regexp_search (view, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Both views */
|
1998-12-03 00:27:27 +03:00
|
|
|
static void
|
2005-08-19 23:32:02 +04:00
|
|
|
view_normal_search_cmd (WView *view)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2005-08-27 15:35:03 +04:00
|
|
|
char *defval, *exp = NULL;
|
2006-12-11 00:36:46 +03:00
|
|
|
static char *last_search_string;
|
2003-03-19 16:39:48 +03:00
|
|
|
|
|
|
|
enum {
|
|
|
|
SEARCH_DLG_HEIGHT = 8,
|
|
|
|
SEARCH_DLG_WIDTH = 58
|
|
|
|
};
|
|
|
|
|
|
|
|
static int replace_backwards;
|
|
|
|
int treplace_backwards = replace_backwards;
|
|
|
|
|
|
|
|
static QuickWidget quick_widgets[] = {
|
|
|
|
{quick_button, 6, 10, 5, SEARCH_DLG_HEIGHT, N_("&Cancel"), 0,
|
|
|
|
B_CANCEL,
|
|
|
|
0, 0, NULL},
|
|
|
|
{quick_button, 2, 10, 5, SEARCH_DLG_HEIGHT, N_("&OK"), 0, B_ENTER,
|
|
|
|
0, 0, NULL},
|
|
|
|
{quick_checkbox, 3, SEARCH_DLG_WIDTH, 4, SEARCH_DLG_HEIGHT,
|
|
|
|
N_("&Backwards"), 0, 0,
|
|
|
|
0, 0, NULL},
|
|
|
|
{quick_input, 3, SEARCH_DLG_WIDTH, 3, SEARCH_DLG_HEIGHT, "", 52, 0,
|
|
|
|
0, 0, N_("Search")},
|
|
|
|
{quick_label, 2, SEARCH_DLG_WIDTH, 2, SEARCH_DLG_HEIGHT,
|
|
|
|
N_(" Enter search string:"), 0, 0,
|
|
|
|
0, 0, 0},
|
2004-08-15 22:24:06 +04:00
|
|
|
NULL_QuickWidget
|
2003-03-19 16:39:48 +03:00
|
|
|
};
|
|
|
|
static QuickDialog Quick_input = {
|
|
|
|
SEARCH_DLG_WIDTH, SEARCH_DLG_HEIGHT, -1, 0, N_("Search"),
|
|
|
|
"[Input Line Keys]", quick_widgets, 0
|
|
|
|
};
|
2005-08-21 16:33:21 +04:00
|
|
|
|
2009-02-06 01:40:32 +03:00
|
|
|
defval = g_strdup (last_search_string != NULL ? last_search_string : "");
|
2005-08-21 16:33:21 +04:00
|
|
|
convert_to_display (defval);
|
2001-06-06 02:49:15 +04:00
|
|
|
|
2003-03-19 16:39:48 +03:00
|
|
|
quick_widgets[2].result = &treplace_backwards;
|
|
|
|
quick_widgets[3].str_result = &exp;
|
2005-08-21 16:33:21 +04:00
|
|
|
quick_widgets[3].text = defval;
|
2002-10-31 02:42:21 +03:00
|
|
|
|
2005-08-21 16:33:21 +04:00
|
|
|
if (quick_dialog (&Quick_input) == B_CANCEL)
|
|
|
|
goto cleanup;
|
2003-03-19 16:39:48 +03:00
|
|
|
|
2005-08-21 16:33:21 +04:00
|
|
|
replace_backwards = treplace_backwards;
|
2002-10-29 16:01:09 +03:00
|
|
|
|
2005-08-21 16:33:21 +04:00
|
|
|
if (exp == NULL || exp[0] == '\0')
|
|
|
|
goto cleanup;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2002-10-31 01:48:59 +03:00
|
|
|
convert_from_input (exp);
|
2001-06-06 02:49:15 +04:00
|
|
|
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (last_search_string);
|
2006-12-11 00:36:46 +03:00
|
|
|
view->search_exp = last_search_string = exp;
|
2005-08-21 16:33:21 +04:00
|
|
|
exp = NULL;
|
|
|
|
|
2003-03-19 16:39:48 +03:00
|
|
|
view->direction = replace_backwards ? -1 : 1;
|
2005-08-21 16:33:21 +04:00
|
|
|
do_normal_search (view);
|
1998-02-27 07:54:42 +03:00
|
|
|
view->last_search = do_normal_search;
|
2005-08-21 16:33:21 +04:00
|
|
|
|
|
|
|
cleanup:
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (exp);
|
|
|
|
g_free (defval);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
1998-12-03 00:27:27 +03:00
|
|
|
static void
|
2005-08-19 23:32:02 +04:00
|
|
|
view_toggle_magic_mode_cmd (WView *view)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2005-08-29 00:38:53 +04:00
|
|
|
view_toggle_magic_mode (view);
|
|
|
|
view_update (view);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2002-08-27 23:10:54 +04:00
|
|
|
static void
|
2005-08-28 23:10:00 +04:00
|
|
|
view_toggle_nroff_mode_cmd (WView *view)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2005-08-29 00:38:53 +04:00
|
|
|
view_toggle_nroff_mode (view);
|
2005-02-08 01:09:44 +03:00
|
|
|
view_update (view);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
1998-03-13 06:44:54 +03:00
|
|
|
view_quit_cmd (WView *view)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
|
|
|
if (view_ok_to_quit (view))
|
1998-05-05 10:18:55 +04:00
|
|
|
dlg_stop (view->widget.parent);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2005-08-19 23:32:02 +04:00
|
|
|
/* {{{ Miscellaneous functions }}} */
|
|
|
|
|
2003-10-23 23:53:22 +04:00
|
|
|
/* Define labels and handlers for functional keys */
|
2002-08-27 23:10:54 +04:00
|
|
|
static void
|
1998-02-27 07:54:42 +03:00
|
|
|
view_labels (WView *view)
|
|
|
|
{
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
const char *text;
|
1998-02-27 07:54:42 +03:00
|
|
|
Dlg_head *h = view->widget.parent;
|
2002-10-31 01:48:59 +03:00
|
|
|
|
2005-10-04 19:20:10 +04:00
|
|
|
buttonbar_set_label (h, 1, Q_("ButtonBar|Help"), view_help_cmd);
|
2005-07-20 19:39:47 +04:00
|
|
|
|
2005-10-04 19:20:10 +04:00
|
|
|
my_define (h, 10, Q_("ButtonBar|Quit"), view_quit_cmd, view);
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
text = view->hex_mode ? "ButtonBar|Ascii" : "ButtonBar|Hex";
|
|
|
|
my_define (h, 4, Q_(text), view_toggle_hex_mode_cmd, view);
|
|
|
|
text = view->hex_mode ?"ButtonBar|Goto": "ButtonBar|Line";
|
|
|
|
my_define (h, 5, Q_(text),
|
2005-08-19 23:32:02 +04:00
|
|
|
view->hex_mode ? view_moveto_addr_cmd : view_moveto_line_cmd, view);
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2005-05-21 14:34:16 +04:00
|
|
|
if (view->hex_mode) {
|
|
|
|
if (view->hexedit_mode) {
|
2005-10-04 19:20:10 +04:00
|
|
|
my_define (h, 2, Q_("ButtonBar|View"),
|
2005-08-19 23:32:02 +04:00
|
|
|
view_toggle_hexedit_mode_cmd, view);
|
2005-05-21 14:34:16 +04:00
|
|
|
} else if (view->datasource == DS_FILE) {
|
2005-10-04 19:20:10 +04:00
|
|
|
my_define (h, 2, Q_("ButtonBar|Edit"),
|
2005-08-19 23:32:02 +04:00
|
|
|
view_toggle_hexedit_mode_cmd, view);
|
2005-05-21 14:34:16 +04:00
|
|
|
} else {
|
2006-02-03 15:16:38 +03:00
|
|
|
buttonbar_clear_label (h, 2);
|
2005-05-21 14:34:16 +04:00
|
|
|
}
|
2005-10-04 19:20:10 +04:00
|
|
|
my_define (h, 6, Q_("ButtonBar|Save"),
|
2005-08-18 06:26:39 +04:00
|
|
|
view_hexedit_save_changes_cmd, view);
|
2005-07-20 19:39:47 +04:00
|
|
|
} else {
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
text = view->text_wrap_mode ? "ButtonBar|UnWrap" : "ButtonBar|Wrap";
|
|
|
|
my_define (h, 2, Q_(text), view_toggle_wrap_mode_cmd, view);
|
2005-10-04 19:20:10 +04:00
|
|
|
my_define (h, 6, Q_("ButtonBar|RxSrch"),
|
2005-08-19 23:32:02 +04:00
|
|
|
view_regexp_search_cmd, view);
|
2005-07-20 19:39:47 +04:00
|
|
|
}
|
2002-10-31 01:48:59 +03:00
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
text = view->hex_mode ? "ButtonBar|HxSrch" : "ButtonBar|Search";
|
|
|
|
my_define (h, 7, Q_(text), view_normal_search_cmd, view);
|
|
|
|
text = view->magic_mode ? "ButtonBar|Raw" : "ButtonBar|Parse";
|
|
|
|
my_define (h, 8, Q_(text), view_toggle_magic_mode_cmd, view);
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2005-04-16 17:45:16 +04:00
|
|
|
/* don't override the key to access the main menu */
|
|
|
|
if (!view_is_in_panel (view)) {
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
text = view->text_nroff_mode ? "ButtonBar|Unform" : "ButtonBar|Format";
|
|
|
|
my_define (h, 9, Q_(text), view_toggle_nroff_mode_cmd, view);
|
2005-10-04 19:20:10 +04:00
|
|
|
my_define (h, 3, Q_("ButtonBar|Quit"), view_quit_cmd, view);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-08-19 23:32:02 +04:00
|
|
|
/* {{{ Event handling }}} */
|
|
|
|
|
2003-11-21 09:27:14 +03:00
|
|
|
/* Check for left and right arrows, possibly with modifiers */
|
|
|
|
static cb_ret_t
|
1998-02-27 07:54:42 +03:00
|
|
|
check_left_right_keys (WView *view, int c)
|
|
|
|
{
|
2003-11-21 09:27:14 +03:00
|
|
|
if (c == KEY_LEFT) {
|
2005-05-26 13:08:54 +04:00
|
|
|
view_move_left (view, 1);
|
2003-11-21 09:27:14 +03:00
|
|
|
return MSG_HANDLED;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (c == KEY_RIGHT) {
|
2005-05-26 13:08:54 +04:00
|
|
|
view_move_right (view, 1);
|
2003-11-21 09:27:14 +03:00
|
|
|
return MSG_HANDLED;
|
|
|
|
}
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2003-11-21 09:27:14 +03:00
|
|
|
/* Ctrl with arrows moves by 10 postions in the unwrap mode */
|
2005-04-14 15:14:42 +04:00
|
|
|
if (view->hex_mode || view->text_wrap_mode)
|
2003-11-21 09:27:14 +03:00
|
|
|
return MSG_NOT_HANDLED;
|
|
|
|
|
|
|
|
if (c == (KEY_M_CTRL | KEY_LEFT)) {
|
2005-05-21 14:17:35 +04:00
|
|
|
if (view->dpy_text_column >= 10)
|
|
|
|
view->dpy_text_column -= 10;
|
2005-04-16 18:25:52 +04:00
|
|
|
else
|
2005-05-21 14:17:35 +04:00
|
|
|
view->dpy_text_column = 0;
|
2003-11-21 09:27:14 +03:00
|
|
|
view->dirty++;
|
|
|
|
return MSG_HANDLED;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (c == (KEY_M_CTRL | KEY_RIGHT)) {
|
2005-07-03 19:31:55 +04:00
|
|
|
if (view->dpy_text_column <= OFFSETTYPE_MAX - 10)
|
2005-05-21 14:17:35 +04:00
|
|
|
view->dpy_text_column += 10;
|
2005-04-16 18:25:52 +04:00
|
|
|
else
|
2005-05-21 14:17:35 +04:00
|
|
|
view->dpy_text_column = OFFSETTYPE_MAX;
|
2003-11-21 09:27:14 +03:00
|
|
|
view->dirty++;
|
|
|
|
return MSG_HANDLED;
|
|
|
|
}
|
|
|
|
|
|
|
|
return MSG_NOT_HANDLED;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2005-08-19 23:32:02 +04:00
|
|
|
/* {{{ User-definable commands }}} */
|
|
|
|
|
2002-08-27 23:10:54 +04:00
|
|
|
static void
|
2005-08-19 23:32:02 +04:00
|
|
|
view_continue_search_cmd (WView *view)
|
1998-03-14 03:42:23 +03:00
|
|
|
{
|
2002-10-31 01:48:59 +03:00
|
|
|
if (view->last_search) {
|
2005-08-21 16:33:21 +04:00
|
|
|
view->last_search (view);
|
1998-03-14 03:42:23 +03:00
|
|
|
} else {
|
|
|
|
/* if not... then ask for an expression */
|
2005-08-19 23:32:02 +04:00
|
|
|
view_normal_search_cmd (view);
|
1998-03-14 03:42:23 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-08-16 13:04:29 +04:00
|
|
|
static void
|
2005-08-19 23:32:02 +04:00
|
|
|
view_toggle_ruler_cmd (WView *view)
|
2005-08-16 01:59:08 +04:00
|
|
|
{
|
|
|
|
static const enum ruler_type next[3] = {
|
|
|
|
RULER_TOP,
|
|
|
|
RULER_BOTTOM,
|
|
|
|
RULER_NONE
|
|
|
|
};
|
|
|
|
|
|
|
|
assert ((size_t) ruler < 3);
|
|
|
|
ruler = next[(size_t) ruler];
|
|
|
|
view->dirty++;
|
2005-08-19 23:32:02 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* {{{ Event handling }}} */
|
2005-08-16 01:59:08 +04:00
|
|
|
|
2005-05-26 13:08:54 +04:00
|
|
|
static void view_cmk_move_up (void *w, int n) {
|
|
|
|
view_move_up ((WView *) w, n);
|
|
|
|
}
|
|
|
|
static void view_cmk_move_down (void *w, int n) {
|
|
|
|
view_move_down ((WView *) w, n);
|
|
|
|
}
|
|
|
|
static void view_cmk_moveto_top (void *w, int n) {
|
|
|
|
(void) &n;
|
|
|
|
view_moveto_top ((WView *) w);
|
|
|
|
}
|
|
|
|
static void view_cmk_moveto_bottom (void *w, int n) {
|
|
|
|
(void) &n;
|
|
|
|
view_moveto_bottom ((WView *) w);
|
2005-05-26 13:07:40 +04:00
|
|
|
}
|
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
static void
|
|
|
|
view_select_encoding (WView *view)
|
|
|
|
{
|
2009-04-16 13:34:38 +04:00
|
|
|
char *enc = NULL;
|
2009-04-15 13:22:34 +04:00
|
|
|
GIConv conv;
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
struct cache_line *line;
|
2009-04-03 16:19:09 +04:00
|
|
|
|
2009-04-20 09:51:32 +04:00
|
|
|
#ifdef HAVE_CHARSET
|
2009-04-16 13:34:38 +04:00
|
|
|
do_select_codepage ();
|
|
|
|
enc = g_strdup( get_codepage_id ( source_codepage ) );
|
2009-04-20 09:51:32 +04:00
|
|
|
#endif
|
|
|
|
if ( enc ) {
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
conv = str_crt_conv_from (enc);
|
2009-04-19 17:45:10 +04:00
|
|
|
if (conv != INVALID_CONV) {
|
|
|
|
if (view->converter != str_cnv_from_term)
|
|
|
|
str_close_conv (view->converter);
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
view->converter = conv;
|
|
|
|
view_reset_cache_lines (view);
|
|
|
|
line = view_offset_to_line (view, view->dpy_start);
|
|
|
|
view_set_first_showed (view, line);
|
|
|
|
}
|
2009-04-19 17:45:10 +04:00
|
|
|
g_free(enc);
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
}
|
2009-04-16 13:34:38 +04:00
|
|
|
|
2009-04-03 16:19:09 +04:00
|
|
|
}
|
|
|
|
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
/* Both views */
|
2003-09-11 02:48:54 +04:00
|
|
|
static cb_ret_t
|
1998-02-27 07:54:42 +03:00
|
|
|
view_handle_key (WView *view, int c)
|
|
|
|
{
|
2002-10-31 02:42:21 +03:00
|
|
|
c = convert_from_input_c (c);
|
2001-06-06 02:49:15 +04:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
if (view->hex_mode) {
|
2002-10-31 01:48:59 +03:00
|
|
|
switch (c) {
|
2005-05-26 13:08:54 +04:00
|
|
|
case '\t':
|
2005-04-14 14:59:02 +04:00
|
|
|
view->hexview_in_text = !view->hexview_in_text;
|
2002-10-31 01:48:59 +03:00
|
|
|
view->dirty++;
|
2003-09-11 02:48:54 +04:00
|
|
|
return MSG_HANDLED;
|
2002-10-31 01:48:59 +03:00
|
|
|
|
2005-05-26 13:08:54 +04:00
|
|
|
case XCTRL ('a'):
|
|
|
|
view_moveto_bol (view);
|
2002-10-31 01:48:59 +03:00
|
|
|
view->dirty++;
|
2003-09-11 02:48:54 +04:00
|
|
|
return MSG_HANDLED;
|
2002-10-31 01:48:59 +03:00
|
|
|
|
2005-05-26 13:08:54 +04:00
|
|
|
case XCTRL ('b'):
|
|
|
|
view_move_left (view, 1);
|
2003-09-11 02:48:54 +04:00
|
|
|
return MSG_HANDLED;
|
2002-10-31 01:48:59 +03:00
|
|
|
|
2005-05-26 13:08:54 +04:00
|
|
|
case XCTRL ('e'):
|
|
|
|
view_moveto_eol (view);
|
2003-09-11 02:48:54 +04:00
|
|
|
return MSG_HANDLED;
|
2002-10-31 01:48:59 +03:00
|
|
|
|
2005-05-26 13:08:54 +04:00
|
|
|
case XCTRL ('f'):
|
|
|
|
view_move_right (view, 1);
|
2003-09-11 02:48:54 +04:00
|
|
|
return MSG_HANDLED;
|
2002-10-31 01:48:59 +03:00
|
|
|
}
|
|
|
|
|
2003-10-24 02:20:15 +04:00
|
|
|
if (view->hexedit_mode
|
|
|
|
&& view_handle_editkey (view, c) == MSG_HANDLED)
|
|
|
|
return MSG_HANDLED;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
2002-10-31 01:48:59 +03:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
if (check_left_right_keys (view, c))
|
2003-09-11 02:48:54 +04:00
|
|
|
return MSG_HANDLED;
|
2002-10-31 01:48:59 +03:00
|
|
|
|
2005-07-06 23:12:25 +04:00
|
|
|
if (check_movement_keys (c, view->data_area.height + 1, view,
|
2005-05-26 13:08:54 +04:00
|
|
|
view_cmk_move_up, view_cmk_move_down,
|
|
|
|
view_cmk_moveto_top, view_cmk_moveto_bottom))
|
2003-09-11 02:48:54 +04:00
|
|
|
return MSG_HANDLED;
|
2005-05-26 13:08:54 +04:00
|
|
|
|
2002-10-31 01:48:59 +03:00
|
|
|
switch (c) {
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
case '?':
|
|
|
|
regexp_search (view, -1);
|
2003-09-11 02:48:54 +04:00
|
|
|
return MSG_HANDLED;
|
2002-10-31 01:48:59 +03:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
case '/':
|
|
|
|
regexp_search (view, 1);
|
2003-09-11 02:48:54 +04:00
|
|
|
return MSG_HANDLED;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
/* Continue search */
|
2005-08-19 23:32:02 +04:00
|
|
|
case XCTRL ('r'):
|
2002-10-31 01:48:59 +03:00
|
|
|
case XCTRL ('s'):
|
1998-02-27 07:54:42 +03:00
|
|
|
case 'n':
|
2002-10-31 01:48:59 +03:00
|
|
|
case KEY_F (17):
|
2005-08-19 23:32:02 +04:00
|
|
|
view_continue_search_cmd (view);
|
2003-09-11 02:48:54 +04:00
|
|
|
return MSG_HANDLED;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
/* toggle ruler */
|
2002-10-31 01:48:59 +03:00
|
|
|
case ALT ('r'):
|
2005-08-19 23:32:02 +04:00
|
|
|
view_toggle_ruler_cmd (view);
|
2005-08-16 13:04:29 +04:00
|
|
|
return MSG_HANDLED;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
case 'h':
|
2005-05-26 13:08:54 +04:00
|
|
|
view_move_left (view, 1);
|
2003-09-11 02:48:54 +04:00
|
|
|
return MSG_HANDLED;
|
2002-10-31 01:48:59 +03:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
case 'j':
|
|
|
|
case '\n':
|
|
|
|
case 'e':
|
2005-05-26 13:08:54 +04:00
|
|
|
view_move_down (view, 1);
|
2003-09-11 02:48:54 +04:00
|
|
|
return MSG_HANDLED;
|
2002-10-31 01:48:59 +03:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
case 'd':
|
2005-07-06 23:12:25 +04:00
|
|
|
view_move_down (view, (view->data_area.height + 1) / 2);
|
2003-09-11 02:48:54 +04:00
|
|
|
return MSG_HANDLED;
|
2002-10-31 01:48:59 +03:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
case 'u':
|
2005-07-06 23:12:25 +04:00
|
|
|
view_move_up (view, (view->data_area.height + 1) / 2);
|
2003-09-11 02:48:54 +04:00
|
|
|
return MSG_HANDLED;
|
2002-10-31 01:48:59 +03:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
case 'k':
|
|
|
|
case 'y':
|
2005-05-26 13:08:54 +04:00
|
|
|
view_move_up (view, 1);
|
2003-09-11 02:48:54 +04:00
|
|
|
return MSG_HANDLED;
|
2002-10-31 01:48:59 +03:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
case 'l':
|
2005-05-26 13:08:54 +04:00
|
|
|
view_move_right (view, 1);
|
2003-09-11 02:48:54 +04:00
|
|
|
return MSG_HANDLED;
|
2002-10-31 01:48:59 +03:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
case ' ':
|
|
|
|
case 'f':
|
2005-07-06 23:12:25 +04:00
|
|
|
view_move_down (view, view->data_area.height);
|
2003-09-11 02:48:54 +04:00
|
|
|
return MSG_HANDLED;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2002-10-31 01:48:59 +03:00
|
|
|
case XCTRL ('o'):
|
2001-08-07 20:32:22 +04:00
|
|
|
view_other_cmd ();
|
2003-09-11 02:48:54 +04:00
|
|
|
return MSG_HANDLED;
|
2001-08-07 20:32:22 +04:00
|
|
|
|
2002-10-31 01:48:59 +03:00
|
|
|
/* Unlike Ctrl-O, run a new shell if the subshell is not running. */
|
1998-02-27 07:54:42 +03:00
|
|
|
case '!':
|
|
|
|
exec_shell ();
|
2003-09-11 02:48:54 +04:00
|
|
|
return MSG_HANDLED;
|
2002-10-31 01:48:59 +03:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
case 'b':
|
2005-07-06 23:12:25 +04:00
|
|
|
view_move_up (view, view->data_area.height);
|
2003-09-11 02:48:54 +04:00
|
|
|
return MSG_HANDLED;
|
2002-10-31 01:48:59 +03:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
case KEY_IC:
|
2005-05-26 13:08:54 +04:00
|
|
|
view_move_up (view, 2);
|
2003-09-11 02:48:54 +04:00
|
|
|
return MSG_HANDLED;
|
2002-10-31 01:48:59 +03:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
case KEY_DC:
|
2005-05-26 13:08:54 +04:00
|
|
|
view_move_down (view, 2);
|
2003-09-11 02:48:54 +04:00
|
|
|
return MSG_HANDLED;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
case 'm':
|
2005-08-22 22:31:51 +04:00
|
|
|
view->marks[view->marker] = view->dpy_start;
|
2003-09-11 02:48:54 +04:00
|
|
|
return MSG_HANDLED;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
case 'r':
|
2005-08-22 22:31:51 +04:00
|
|
|
view->dpy_start = view->marks[view->marker];
|
1998-02-27 07:54:42 +03:00
|
|
|
view->dirty++;
|
2003-09-11 02:48:54 +04:00
|
|
|
return MSG_HANDLED;
|
2002-10-31 01:48:59 +03:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
/* Use to indicate parent that we want to see the next/previous file */
|
2005-04-16 17:45:16 +04:00
|
|
|
/* Does not work in panel mode */
|
2002-10-31 01:48:59 +03:00
|
|
|
case XCTRL ('f'):
|
|
|
|
case XCTRL ('b'):
|
2005-04-16 17:45:16 +04:00
|
|
|
if (!view_is_in_panel (view))
|
2002-10-31 01:48:59 +03:00
|
|
|
view->move_dir = c == XCTRL ('f') ? 1 : -1;
|
2005-04-16 17:45:16 +04:00
|
|
|
/* FALLTHROUGH */
|
1998-02-27 07:54:42 +03:00
|
|
|
case 'q':
|
2002-10-31 01:48:59 +03:00
|
|
|
case XCTRL ('g'):
|
1998-02-27 07:54:42 +03:00
|
|
|
case ESC_CHAR:
|
|
|
|
if (view_ok_to_quit (view))
|
2005-06-28 02:38:03 +04:00
|
|
|
view->want_to_quit = TRUE;
|
2003-09-11 02:48:54 +04:00
|
|
|
return MSG_HANDLED;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2002-10-31 01:48:59 +03:00
|
|
|
case XCTRL ('t'):
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
view_select_encoding (view);
|
2001-06-06 02:49:15 +04:00
|
|
|
view->dirty++;
|
2005-02-08 01:09:44 +03:00
|
|
|
view_update (view);
|
2003-09-11 02:48:54 +04:00
|
|
|
return MSG_HANDLED;
|
2001-06-06 02:49:15 +04:00
|
|
|
|
2005-05-26 13:08:54 +04:00
|
|
|
#ifdef MC_ENABLE_DEBUGGING_CODE
|
|
|
|
case 't': /* mnemonic: "test" */
|
|
|
|
view_ccache_dump (view);
|
|
|
|
return MSG_HANDLED;
|
|
|
|
#endif
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
if (c >= '0' && c <= '9')
|
|
|
|
view->marker = c - '0';
|
|
|
|
|
|
|
|
/* Key not used */
|
2003-09-11 02:48:54 +04:00
|
|
|
return MSG_NOT_HANDLED;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Both views */
|
2002-08-27 23:10:54 +04:00
|
|
|
static int
|
2002-10-31 01:48:59 +03:00
|
|
|
view_event (WView *view, Gpm_Event *event, int *result)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2005-07-06 23:12:25 +04:00
|
|
|
screen_dimen y, x;
|
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
*result = MOU_NORMAL;
|
2002-09-21 09:46:19 +04:00
|
|
|
|
|
|
|
/* We are not interested in the release events */
|
|
|
|
if (!(event->type & (GPM_DOWN | GPM_DRAG)))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* Wheel events */
|
|
|
|
if ((event->buttons & GPM_B_UP) && (event->type & GPM_DOWN)) {
|
2005-05-26 13:08:54 +04:00
|
|
|
view_move_up (view, 2);
|
2002-09-21 09:46:19 +04:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
if ((event->buttons & GPM_B_DOWN) && (event->type & GPM_DOWN)) {
|
2005-05-26 13:08:54 +04:00
|
|
|
view_move_down (view, 2);
|
2002-09-21 09:46:19 +04:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2005-07-06 23:12:25 +04:00
|
|
|
x = event->x;
|
|
|
|
y = event->y;
|
|
|
|
|
2002-09-21 09:46:19 +04:00
|
|
|
/* Scrolling left and right */
|
2005-04-14 15:14:42 +04:00
|
|
|
if (!view->text_wrap_mode) {
|
2005-07-06 23:12:25 +04:00
|
|
|
if (x < view->data_area.width * 1/4) {
|
2005-05-26 13:08:54 +04:00
|
|
|
view_move_left (view, 1);
|
2002-09-21 09:46:19 +04:00
|
|
|
goto processed;
|
2005-07-06 23:12:25 +04:00
|
|
|
} else if (x < view->data_area.width * 3/4) {
|
|
|
|
/* ignore the click */
|
|
|
|
} else {
|
2005-05-26 13:08:54 +04:00
|
|
|
view_move_right (view, 1);
|
2002-09-21 09:46:19 +04:00
|
|
|
goto processed;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
}
|
2002-09-21 09:46:19 +04:00
|
|
|
|
|
|
|
/* Scrolling up and down */
|
2005-07-06 23:12:25 +04:00
|
|
|
if (y < view->data_area.top + view->data_area.height * 1/3) {
|
2002-09-21 09:46:19 +04:00
|
|
|
if (mouse_move_pages_viewer)
|
2005-07-06 23:12:25 +04:00
|
|
|
view_move_up (view, view->data_area.height / 2);
|
2002-09-21 09:46:19 +04:00
|
|
|
else
|
2005-05-26 13:08:54 +04:00
|
|
|
view_move_up (view, 1);
|
2002-09-21 09:46:19 +04:00
|
|
|
goto processed;
|
2005-07-06 23:12:25 +04:00
|
|
|
} else if (y < view->data_area.top + view->data_area.height * 2/3) {
|
|
|
|
/* ignore the click */
|
|
|
|
} else {
|
2005-08-29 13:05:24 +04:00
|
|
|
if (mouse_move_pages_viewer)
|
2005-07-06 23:12:25 +04:00
|
|
|
view_move_down (view, view->data_area.height / 2);
|
2002-09-21 09:46:19 +04:00
|
|
|
else
|
2005-05-26 13:08:54 +04:00
|
|
|
view_move_down (view, 1);
|
2002-09-21 09:46:19 +04:00
|
|
|
goto processed;
|
|
|
|
}
|
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
return 0;
|
2002-09-21 09:46:19 +04:00
|
|
|
|
|
|
|
processed:
|
|
|
|
*result = MOU_REPEAT;
|
|
|
|
return 1;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Real view only */
|
1998-12-03 00:27:27 +03:00
|
|
|
static int
|
1998-02-27 07:54:42 +03:00
|
|
|
real_view_event (Gpm_Event *event, void *x)
|
|
|
|
{
|
2005-02-08 01:09:44 +03:00
|
|
|
WView *view = (WView *) x;
|
1998-02-27 07:54:42 +03:00
|
|
|
int result;
|
2002-10-31 01:48:59 +03:00
|
|
|
|
2005-02-08 01:09:44 +03:00
|
|
|
if (view_event (view, event, &result))
|
|
|
|
view_update (view);
|
1998-02-27 07:54:42 +03:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2002-10-07 22:50:27 +04:00
|
|
|
static void
|
1998-02-27 07:54:42 +03:00
|
|
|
view_adjust_size (Dlg_head *h)
|
|
|
|
{
|
2002-10-31 01:48:59 +03:00
|
|
|
WView *view;
|
1998-02-27 07:54:42 +03:00
|
|
|
WButtonBar *bar;
|
|
|
|
|
|
|
|
/* Look up the viewer and the buttonbar, we assume only two widgets here */
|
2005-06-28 03:19:32 +04:00
|
|
|
view = (WView *) find_widget_type (h, view_callback);
|
2002-11-13 02:33:15 +03:00
|
|
|
bar = find_buttonbar (h);
|
2002-10-31 01:48:59 +03:00
|
|
|
widget_set_size (&view->widget, 0, 0, LINES - 1, COLS);
|
2005-06-14 17:02:30 +04:00
|
|
|
widget_set_size ((Widget *) bar, LINES - 1, 0, 1, COLS);
|
1999-04-06 23:00:16 +04:00
|
|
|
|
2005-07-06 23:12:25 +04:00
|
|
|
view_compute_areas (view);
|
2002-10-31 01:48:59 +03:00
|
|
|
view_update_bytes_per_line (view);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2002-09-24 07:56:08 +04:00
|
|
|
/* Callback for the view dialog */
|
2003-09-08 01:24:01 +04:00
|
|
|
static cb_ret_t
|
|
|
|
view_dialog_callback (Dlg_head *h, dlg_msg_t msg, int parm)
|
2002-09-24 07:56:08 +04:00
|
|
|
{
|
|
|
|
switch (msg) {
|
|
|
|
case DLG_RESIZE:
|
|
|
|
view_adjust_size (h);
|
|
|
|
return MSG_HANDLED;
|
2003-09-08 01:24:01 +04:00
|
|
|
|
|
|
|
default:
|
|
|
|
return default_dlg_callback (h, msg, parm);
|
2002-09-24 07:56:08 +04:00
|
|
|
}
|
|
|
|
}
|
1998-03-12 06:29:45 +03:00
|
|
|
|
2005-08-19 23:32:02 +04:00
|
|
|
/* {{{ External interface }}} */
|
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
/* Real view only */
|
|
|
|
int
|
2005-08-01 00:29:35 +04:00
|
|
|
mc_internal_viewer (const char *command, const char *file,
|
|
|
|
int *move_dir_p, int start_line)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2009-02-06 01:46:07 +03:00
|
|
|
gboolean succeeded;
|
1998-02-27 07:54:42 +03:00
|
|
|
WView *wview;
|
|
|
|
WButtonBar *bar;
|
2002-09-24 07:56:08 +04:00
|
|
|
Dlg_head *view_dlg;
|
2002-09-04 00:19:22 +04:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
/* Create dialog and widgets, put them on the dialog */
|
2002-09-24 07:56:08 +04:00
|
|
|
view_dlg =
|
|
|
|
create_dlg (0, 0, LINES, COLS, NULL, view_dialog_callback,
|
2003-10-24 10:06:10 +04:00
|
|
|
"[Internal File Viewer]", NULL, DLG_WANT_TAB);
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2002-09-04 00:19:22 +04:00
|
|
|
wview = view_new (0, 0, COLS, LINES - 1, 0);
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2002-09-04 00:19:22 +04:00
|
|
|
bar = buttonbar_new (1);
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2002-09-24 07:56:08 +04:00
|
|
|
add_widget (view_dlg, bar);
|
2003-09-13 02:08:09 +04:00
|
|
|
add_widget (view_dlg, wview);
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2005-07-12 11:01:47 +04:00
|
|
|
succeeded = view_load (wview, command, file, start_line);
|
2005-04-17 13:35:41 +04:00
|
|
|
if (succeeded) {
|
2002-09-24 07:56:08 +04:00
|
|
|
run_dlg (view_dlg);
|
1998-02-27 07:54:42 +03:00
|
|
|
if (move_dir_p)
|
|
|
|
*move_dir_p = wview->move_dir;
|
2005-04-17 13:35:41 +04:00
|
|
|
} else {
|
|
|
|
if (move_dir_p)
|
|
|
|
*move_dir_p = 0;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
2002-09-24 07:56:08 +04:00
|
|
|
destroy_dlg (view_dlg);
|
2002-09-04 00:19:22 +04:00
|
|
|
|
2005-04-17 13:35:41 +04:00
|
|
|
return succeeded;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2005-08-19 23:32:02 +04:00
|
|
|
/* {{{ Miscellaneous functions }}} */
|
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
static void
|
|
|
|
view_hook (void *v)
|
|
|
|
{
|
|
|
|
WView *view = (WView *) v;
|
|
|
|
WPanel *panel;
|
|
|
|
|
|
|
|
/* If the user is busy typing, wait until he finishes to update the
|
|
|
|
screen */
|
2002-10-31 01:48:59 +03:00
|
|
|
if (!is_idle ()) {
|
1998-02-27 07:54:42 +03:00
|
|
|
if (!hook_present (idle_hook, view_hook))
|
|
|
|
add_hook (&idle_hook, view_hook, v);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
delete_hook (&idle_hook, view_hook);
|
2002-10-31 01:48:59 +03:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
if (get_current_type () == view_listing)
|
2003-10-26 09:45:59 +03:00
|
|
|
panel = current_panel;
|
1998-02-27 07:54:42 +03:00
|
|
|
else if (get_other_type () == view_listing)
|
|
|
|
panel = other_panel;
|
|
|
|
else
|
|
|
|
return;
|
|
|
|
|
2005-04-14 12:00:14 +04:00
|
|
|
view_load (view, 0, panel->dir.list[panel->selected].fname, 0);
|
1998-02-27 07:54:42 +03:00
|
|
|
display (view);
|
|
|
|
}
|
|
|
|
|
2005-08-19 23:32:02 +04:00
|
|
|
/* {{{ Event handling }}} */
|
|
|
|
|
2003-09-11 02:48:54 +04:00
|
|
|
static cb_ret_t
|
2005-06-28 03:19:32 +04:00
|
|
|
view_callback (Widget *w, widget_msg_t msg, int parm)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2005-06-28 03:19:32 +04:00
|
|
|
WView *view = (WView *) w;
|
2003-09-11 02:48:54 +04:00
|
|
|
cb_ret_t i;
|
2002-11-13 05:27:00 +03:00
|
|
|
Dlg_head *h = view->widget.parent;
|
2002-10-07 22:50:27 +04:00
|
|
|
|
2005-07-06 23:12:25 +04:00
|
|
|
view_compute_areas (view);
|
2005-01-26 01:40:50 +03:00
|
|
|
view_update_bytes_per_line (view);
|
|
|
|
|
2002-10-07 22:50:27 +04:00
|
|
|
switch (msg) {
|
1998-02-27 07:54:42 +03:00
|
|
|
case WIDGET_INIT:
|
2005-04-16 17:45:16 +04:00
|
|
|
if (view_is_in_panel (view))
|
1998-02-27 07:54:42 +03:00
|
|
|
add_hook (&select_file_hook, view_hook, view);
|
|
|
|
else
|
2005-08-29 00:38:53 +04:00
|
|
|
view->dpy_bbar_dirty = TRUE;
|
2003-09-11 02:48:54 +04:00
|
|
|
return MSG_HANDLED;
|
2002-10-07 22:50:27 +04:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
case WIDGET_DRAW:
|
|
|
|
display (view);
|
2003-09-11 02:48:54 +04:00
|
|
|
return MSG_HANDLED;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
case WIDGET_CURSOR:
|
|
|
|
if (view->hex_mode)
|
|
|
|
view_place_cursor (view);
|
2003-09-11 02:48:54 +04:00
|
|
|
return MSG_HANDLED;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
case WIDGET_KEY:
|
2003-09-11 02:48:54 +04:00
|
|
|
i = view_handle_key ((WView *) view, parm);
|
2005-06-28 02:38:03 +04:00
|
|
|
if (view->want_to_quit && !view_is_in_panel (view))
|
1998-03-14 03:42:23 +03:00
|
|
|
dlg_stop (h);
|
1998-02-27 07:54:42 +03:00
|
|
|
else {
|
2005-02-08 01:09:44 +03:00
|
|
|
view_update (view);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
return i;
|
|
|
|
|
|
|
|
case WIDGET_FOCUS:
|
2005-08-29 00:38:53 +04:00
|
|
|
view->dpy_bbar_dirty = TRUE;
|
|
|
|
view_update (view);
|
2003-09-11 02:48:54 +04:00
|
|
|
return MSG_HANDLED;
|
2002-10-07 22:50:27 +04:00
|
|
|
|
2003-09-10 22:21:40 +04:00
|
|
|
case WIDGET_DESTROY:
|
|
|
|
view_done (view);
|
2005-04-16 17:45:16 +04:00
|
|
|
if (view_is_in_panel (view))
|
2003-09-10 22:21:40 +04:00
|
|
|
delete_hook (&select_file_hook, view_hook);
|
2003-09-11 02:48:54 +04:00
|
|
|
return MSG_HANDLED;
|
2003-09-10 22:21:40 +04:00
|
|
|
|
|
|
|
default:
|
2003-09-11 02:48:54 +04:00
|
|
|
return default_proc (msg, parm);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-08-19 23:32:02 +04:00
|
|
|
/* {{{ External interface }}} */
|
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
WView *
|
|
|
|
view_new (int y, int x, int cols, int lines, int is_panel)
|
|
|
|
{
|
2001-06-25 15:24:49 +04:00
|
|
|
WView *view = g_new0 (WView, 1);
|
2005-08-15 22:58:18 +04:00
|
|
|
size_t i;
|
2002-10-31 01:48:59 +03:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
init_widget (&view->widget, y, x, lines, cols,
|
2005-06-28 03:19:32 +04:00
|
|
|
view_callback,
|
|
|
|
real_view_event);
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2005-04-14 12:00:14 +04:00
|
|
|
view->filename = NULL;
|
|
|
|
view->command = NULL;
|
|
|
|
|
|
|
|
view_set_datasource_none (view);
|
|
|
|
|
2005-08-15 22:58:18 +04:00
|
|
|
view->growbuf_in_use = FALSE;
|
|
|
|
/* leave the other growbuf fields uninitialized */
|
|
|
|
|
2005-08-28 23:10:00 +04:00
|
|
|
view->hex_mode = FALSE;
|
|
|
|
view->hexedit_mode = FALSE;
|
|
|
|
view->hexview_in_text = FALSE;
|
|
|
|
view->text_nroff_mode = FALSE;
|
|
|
|
view->text_wrap_mode = FALSE;
|
|
|
|
view->magic_mode = FALSE;
|
2005-08-15 22:58:18 +04:00
|
|
|
|
|
|
|
view->hexedit_lownibble = FALSE;
|
|
|
|
|
2005-04-16 17:45:16 +04:00
|
|
|
view->dpy_frame_size = is_panel ? 1 : 0;
|
2005-08-22 22:31:51 +04:00
|
|
|
view->dpy_start = 0;
|
2005-05-21 14:17:35 +04:00
|
|
|
view->dpy_text_column = 0;
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
view->dpy_end = 0;
|
2005-05-21 14:23:57 +04:00
|
|
|
view->hex_cursor = 0;
|
2005-04-14 12:00:14 +04:00
|
|
|
view->cursor_col = 0;
|
|
|
|
view->cursor_row = 0;
|
|
|
|
view->change_list = NULL;
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
view->converter = str_cnv_from_term;
|
2005-08-15 22:58:18 +04:00
|
|
|
|
|
|
|
/* {status,ruler,data}_area are left uninitialized */
|
|
|
|
|
2005-04-14 12:00:14 +04:00
|
|
|
view->dirty = 0;
|
2005-08-29 00:38:53 +04:00
|
|
|
view->dpy_bbar_dirty = TRUE;
|
2005-04-14 12:00:14 +04:00
|
|
|
view->bytes_per_line = 1;
|
|
|
|
|
|
|
|
view->search_start = 0;
|
patches by Rostislav Beneš: mc-30-view
experimental patch, completely different reading file, new cache structure,
shall view text in every encodings (remaped ctrl + t, new dialog need
localization).
1. to avoid backward reading, viewer keeps four following characters from
file: next, actual and two previous. This is enough to handle new lines
and nroff fortmatin correctly.
2. cache_line structure, that presents one line in file. cache_line stores,
where line starts and ends in file,number of line and width of line. Width
is at most equal to screen width, so longer lines are cached in more
cache_lines. This makes wrapping text very easy. Cache_lines are stored
in a linked list. file is loaded into cache_lines sequential, not whole at once.
It only provides navigation in file.
I found two problems in this solution:
1. slow first move to end in large files, because can not read files
backward. (loading in background may help)
2. it is slow with multibyte characters. I tried to eliminate calling iconv
to two, but it did not help (iconv is called on every byte). I think
caching some parts of file will be needed.
2008-12-29 02:55:48 +03:00
|
|
|
view->search_end = 0;
|
2005-04-14 12:00:14 +04:00
|
|
|
view->search_exp = NULL;
|
|
|
|
view->direction = 1; /* forward */
|
|
|
|
view->last_search = 0; /* it's a function */
|
|
|
|
|
2005-06-28 02:38:03 +04:00
|
|
|
view->want_to_quit = FALSE;
|
2005-04-14 12:00:14 +04:00
|
|
|
view->marker = 0;
|
2005-08-15 22:58:18 +04:00
|
|
|
for (i = 0; i < sizeof(view->marks) / sizeof(view->marks[0]); i++)
|
|
|
|
view->marks[i] = 0;
|
|
|
|
|
2005-04-14 12:00:14 +04:00
|
|
|
view->move_dir = 0;
|
|
|
|
view->update_steps = 0;
|
|
|
|
view->update_activate = 0;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2005-08-28 23:10:00 +04:00
|
|
|
if (default_hex_mode)
|
2005-08-29 00:38:53 +04:00
|
|
|
view_toggle_hex_mode (view);
|
2005-08-28 23:10:00 +04:00
|
|
|
if (default_nroff_flag)
|
2005-08-29 00:38:53 +04:00
|
|
|
view_toggle_nroff_mode (view);
|
2005-08-28 23:10:00 +04:00
|
|
|
if (global_wrap_mode)
|
2005-08-29 00:38:53 +04:00
|
|
|
view_toggle_wrap_mode (view);
|
2005-08-28 23:10:00 +04:00
|
|
|
if (default_magic_flag)
|
2005-08-29 00:38:53 +04:00
|
|
|
view_toggle_magic_mode (view);
|
2005-08-28 23:10:00 +04:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
return view;
|
|
|
|
}
|