mirror of https://github.com/MidnightCommander/mc
Ticket #1652: autodetect line-endings
* On opening file, detect line-endings used by sampling some initial content. * If it happen to be CR or CRLF, skip fast load path, and in edit_insert_file() convert such line endings to '\n'. * Save detected line ending type for editor. Signed-off-by: Slava Zanko <slavazanko@gmail.com>
This commit is contained in:
parent
849fe8e4b1
commit
d1c1d6e2fb
|
@ -258,7 +258,7 @@ int edit_insert_column_of_text_from_file (WEdit * edit, int file,
|
|||
long *start_pos, long *end_pos, int *col1, int *col2);
|
||||
|
||||
char *edit_get_word_from_pos (WEdit * edit, long start_pos, long *start, gsize * len, gsize * cut);
|
||||
long edit_insert_file (WEdit * edit, const vfs_path_t * filename_vpath);
|
||||
long edit_insert_file (WEdit * edit, const vfs_path_t * filename_vpath, LineBreaks lb_type);
|
||||
gboolean edit_load_back_cmd (WEdit * edit);
|
||||
gboolean edit_load_forward_cmd (WEdit * edit);
|
||||
void edit_block_process_cmd (WEdit * edit, int macro_number);
|
||||
|
|
|
@ -114,6 +114,8 @@ const char VERTICAL_MAGIC[] = { '\1', '\1', '\1', '\1', '\n' };
|
|||
|
||||
#define space_width 1
|
||||
|
||||
#define DETECT_LB_TYPE_BUFLEN BUF_MEDIUM
|
||||
|
||||
/*** file scope type declarations ****************************************************************/
|
||||
|
||||
/*** file scope variables ************************************************************************/
|
||||
|
@ -415,6 +417,37 @@ check_file_access (WEdit * edit, const vfs_path_t * filename_vpath, struct stat
|
|||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* detect type of line breaks
|
||||
*
|
||||
*/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static LineBreaks
|
||||
detect_lb_type (const vfs_path_t *filename_vpath)
|
||||
{
|
||||
char buf[BUF_MEDIUM];
|
||||
ssize_t file, sz;
|
||||
|
||||
file = mc_open (filename_vpath, O_RDONLY | O_BINARY);
|
||||
if (file == -1)
|
||||
return LB_ASIS;
|
||||
|
||||
sz = mc_read (file, buf, sizeof (buf) - 1);
|
||||
mc_close (file);
|
||||
|
||||
if (sz <= 0)
|
||||
return LB_ASIS;
|
||||
|
||||
buf[(size_t) sz] = '\0';
|
||||
if (strstr (buf, "\r\n") != NULL)
|
||||
return LB_WIN;
|
||||
if (strchr (buf, '\r') != NULL)
|
||||
return LB_MAC;
|
||||
return LB_ASIS;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Open the file and load it into the buffers, either directly or using
|
||||
* a filter. Return TRUE on success, FALSE on error.
|
||||
|
@ -431,6 +464,7 @@ static gboolean
|
|||
edit_load_file (WEdit * edit)
|
||||
{
|
||||
gboolean fast_load = TRUE;
|
||||
LineBreaks lb_type = LB_ASIS;
|
||||
|
||||
/* Cannot do fast load if a filter is used */
|
||||
if (edit_find_filter (edit->filename_vpath) >= 0)
|
||||
|
@ -455,6 +489,10 @@ edit_load_file (WEdit * edit)
|
|||
edit_clean (edit);
|
||||
return FALSE;
|
||||
}
|
||||
lb_type = detect_lb_type (edit->filename_vpath);
|
||||
|
||||
if (lb_type != LB_ASIS && lb_type != LB_UNIX)
|
||||
fast_load = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -478,15 +516,16 @@ edit_load_file (WEdit * edit)
|
|||
&& *(vfs_path_get_by_index (edit->filename_vpath, 0)->path) != '\0')
|
||||
{
|
||||
edit->undo_stack_disable = 1;
|
||||
if (edit_insert_file (edit, edit->filename_vpath) < 0)
|
||||
if (edit_insert_file (edit, edit->filename_vpath, lb_type) < 0)
|
||||
{
|
||||
edit_clean (edit);
|
||||
return FALSE;
|
||||
}
|
||||
edit_set_markers (edit, 0, 0, 0, 0);
|
||||
edit->undo_stack_disable = 0;
|
||||
}
|
||||
}
|
||||
edit->lb = LB_ASIS;
|
||||
edit->lb = lb_type;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -1774,7 +1813,7 @@ user_menu (WEdit * edit, const char *menu_file, int selected_entry)
|
|||
{
|
||||
long ins_len;
|
||||
|
||||
ins_len = edit_insert_file (edit, block_file_vpath);
|
||||
ins_len = edit_insert_file (edit, block_file_vpath, LB_ASIS);
|
||||
if (nomark == 0 && ins_len > 0)
|
||||
edit_set_markers (edit, start_mark, start_mark + ins_len, 0, 0);
|
||||
}
|
||||
|
@ -2040,7 +2079,7 @@ edit_get_word_from_pos (WEdit * edit, long start_pos, long *start, gsize * len,
|
|||
/** inserts a file at the cursor, returns count of inserted bytes on success */
|
||||
|
||||
long
|
||||
edit_insert_file (WEdit * edit, const vfs_path_t * filename_vpath)
|
||||
edit_insert_file (WEdit * edit, const vfs_path_t * filename_vpath, LineBreaks lb_type)
|
||||
{
|
||||
char *p;
|
||||
long ins_len = 0;
|
||||
|
@ -2120,7 +2159,19 @@ edit_insert_file (WEdit * edit, const vfs_path_t * filename_vpath)
|
|||
while ((blocklen = mc_read (file, (char *) buf, TEMP_BUF_LEN)) > 0)
|
||||
{
|
||||
for (i = 0; i < blocklen; i++)
|
||||
edit_insert (edit, buf[i]);
|
||||
{
|
||||
if (buf[i] == '\r')
|
||||
{
|
||||
if (lb_type == LB_MAC)
|
||||
edit_insert (edit, '\n');
|
||||
else if (lb_type == LB_WIN)
|
||||
/* just skip */ ;
|
||||
else
|
||||
edit_insert (edit, '\r');
|
||||
}
|
||||
else
|
||||
edit_insert (edit, buf[i]);
|
||||
}
|
||||
}
|
||||
/* highlight inserted text then not persistent blocks */
|
||||
if (!option_persistent_selections && edit->modified)
|
||||
|
@ -2225,6 +2276,7 @@ edit_init (WEdit * edit, int y, int x, int lines, int cols, const vfs_path_t * f
|
|||
edit->redo_stack_size_mask = START_STACK_SIZE - 1;
|
||||
edit->redo_stack = g_malloc0 ((edit->redo_stack_size + 10) * sizeof (long));
|
||||
|
||||
edit->highlight = 0;
|
||||
edit->utf8 = 0;
|
||||
edit->converter = str_cnv_from_term;
|
||||
edit_set_codeset (edit);
|
||||
|
|
|
@ -449,7 +449,9 @@ edit_get_save_file_as (WEdit * edit)
|
|||
char *fname;
|
||||
vfs_path_t *ret_vpath;
|
||||
|
||||
edit->lb = cur_lb;
|
||||
/* Don't change current LB type (possibly autodetected), unless user asked to. */
|
||||
if (cur_lb != LB_ASIS)
|
||||
edit->lb = cur_lb;
|
||||
fname = tilde_expand (filename_res);
|
||||
g_free (filename_res);
|
||||
ret_vpath = vfs_path_from_str (fname);
|
||||
|
@ -3021,7 +3023,7 @@ edit_paste_from_X_buf_cmd (WEdit * edit)
|
|||
/* try use external clipboard utility */
|
||||
mc_event_raise (MCEVENT_GROUP_CORE, "clipboard_file_from_ext_clip", NULL);
|
||||
tmp = mc_config_get_full_vpath (EDIT_CLIP_FILE);
|
||||
edit_insert_file (edit, tmp);
|
||||
edit_insert_file (edit, tmp, LB_ASIS);
|
||||
vfs_path_free (tmp);
|
||||
}
|
||||
|
||||
|
@ -3136,7 +3138,7 @@ edit_insert_file_cmd (WEdit * edit)
|
|||
vfs_path_t *exp_vpath;
|
||||
|
||||
exp_vpath = vfs_path_from_str (exp);
|
||||
ret = (edit_insert_file (edit, exp_vpath) >= 0);
|
||||
ret = (edit_insert_file (edit, exp_vpath, LB_ASIS) >= 0);
|
||||
vfs_path_free (exp_vpath);
|
||||
|
||||
if (!ret)
|
||||
|
@ -3209,12 +3211,12 @@ edit_sort_cmd (WEdit * edit)
|
|||
|
||||
if (edit_block_delete_cmd (edit))
|
||||
return 1;
|
||||
|
||||
else
|
||||
{
|
||||
vfs_path_t *tmp_vpath;
|
||||
|
||||
tmp_vpath = mc_config_get_full_vpath (EDIT_TEMP_FILE);
|
||||
edit_insert_file (edit, tmp_vpath);
|
||||
edit_insert_file (edit, tmp_vpath, LB_ASIS);
|
||||
vfs_path_free (tmp_vpath);
|
||||
}
|
||||
return 0;
|
||||
|
@ -3251,16 +3253,15 @@ edit_ext_cmd (WEdit * edit)
|
|||
edit_error_dialog (_("External command"), get_sys_error (_("Cannot execute command")));
|
||||
return -1;
|
||||
}
|
||||
|
||||
edit->force |= REDRAW_COMPLETELY;
|
||||
|
||||
else
|
||||
{
|
||||
vfs_path_t *tmp_vpath;
|
||||
|
||||
tmp_vpath = mc_config_get_full_vpath (EDIT_TEMP_FILE);
|
||||
edit_insert_file (edit, tmp_vpath);
|
||||
edit_insert_file (edit, tmp_vpath, LB_ASIS);
|
||||
vfs_path_free (tmp_vpath);
|
||||
}
|
||||
edit->force |= REDRAW_COMPLETELY;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -112,6 +112,13 @@ status_string (WEdit * edit, char *s, int w)
|
|||
unsigned int cur_utf = 0;
|
||||
int cw = 1;
|
||||
|
||||
static const char *lb_names[LB_NAMES] = {
|
||||
"",
|
||||
"LF",
|
||||
"CRLF",
|
||||
"CR"
|
||||
};
|
||||
|
||||
/*
|
||||
* If we are at the end of file, print <EOF>,
|
||||
* otherwise print the current character as is (if printable),
|
||||
|
@ -151,7 +158,7 @@ status_string (WEdit * edit, char *s, int w)
|
|||
/* The field lengths just prevent the status line from shortening too much */
|
||||
if (simple_statusbar)
|
||||
g_snprintf (s, w,
|
||||
"%c%c%c%c %3ld %5ld/%ld %6ld/%ld %s %s",
|
||||
"%c%c%c%c %3ld %5ld/%ld %6ld/%ld %s %s %s",
|
||||
edit->mark1 != edit->mark2 ? (edit->column_highlight ? 'C' : 'B') : '-',
|
||||
edit->modified ? 'M' : '-',
|
||||
macro_index < 0 ? '-' : 'R',
|
||||
|
@ -161,14 +168,14 @@ status_string (WEdit * edit, char *s, int w)
|
|||
edit->total_lines + 1, edit->curs1, edit->last_byte, byte_str,
|
||||
#ifdef HAVE_CHARSET
|
||||
mc_global.source_codepage >=
|
||||
0 ? get_codepage_id (mc_global.source_codepage) : ""
|
||||
0 ? get_codepage_id (mc_global.source_codepage) : "",
|
||||
#else
|
||||
""
|
||||
"",
|
||||
#endif
|
||||
);
|
||||
lb_names[edit->lb]);
|
||||
else
|
||||
g_snprintf (s, w,
|
||||
"[%c%c%c%c] %2ld L:[%3ld+%2ld %3ld/%3ld] *(%-4ld/%4ldb) %s %s",
|
||||
"[%c%c%c%c] %2ld L:[%3ld+%2ld %3ld/%3ld] *(%-4ld/%4ldb) %s %s %s",
|
||||
edit->mark1 != edit->mark2 ? (edit->column_highlight ? 'C' : 'B') : '-',
|
||||
edit->modified ? 'M' : '-',
|
||||
macro_index < 0 ? '-' : 'R',
|
||||
|
@ -180,11 +187,11 @@ status_string (WEdit * edit, char *s, int w)
|
|||
edit->total_lines + 1, edit->curs1, edit->last_byte, byte_str,
|
||||
#ifdef HAVE_CHARSET
|
||||
mc_global.source_codepage >=
|
||||
0 ? get_codepage_id (mc_global.source_codepage) : ""
|
||||
0 ? get_codepage_id (mc_global.source_codepage) : "",
|
||||
#else
|
||||
""
|
||||
"",
|
||||
#endif
|
||||
);
|
||||
lb_names[edit->lb]);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
|
Loading…
Reference in New Issue