mirror of
https://github.com/MidnightCommander/mc
synced 2024-12-22 20:36:50 +03:00
Open several files in mc editor from command line.
Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
This commit is contained in:
parent
109f07465e
commit
84aa04fa6e
257
src/args.c
257
src/args.c
@ -1,11 +1,12 @@
|
||||
/*
|
||||
Handle command line arguments.
|
||||
|
||||
Copyright (C) 2009, 2011
|
||||
Copyright (C) 2009, 2010, 2011, 2012
|
||||
The Free Software Foundation, Inc.
|
||||
|
||||
Written by:
|
||||
Slava Zanko <slavazanko@gmail.com>, 2009.
|
||||
Andrew Borodin <aborodin@vmail.ru>, 2011, 2012.
|
||||
|
||||
This file is part of the Midnight Commander.
|
||||
|
||||
@ -60,9 +61,6 @@ gboolean mc_args__force_colors = FALSE;
|
||||
/* Don't load keymap form file and use default one */
|
||||
gboolean mc_args__nokeymap = FALSE;
|
||||
|
||||
/* Line to start the editor on */
|
||||
int mc_args__edit_start_line = 0;
|
||||
|
||||
char *mc_args__last_wd_file = NULL;
|
||||
|
||||
/* when enabled NETCODE, use folowing file as logfile */
|
||||
@ -179,10 +177,10 @@ static const GOptionEntry argument_main_table[] = {
|
||||
},
|
||||
|
||||
{
|
||||
"edit", 'e', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK,
|
||||
"edit", 'e', G_OPTION_FLAG_IN_MAIN | G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
|
||||
parse_mc_e_argument,
|
||||
N_("Edits one file"),
|
||||
"<file>"},
|
||||
N_("Edit files"),
|
||||
"<file> ..." },
|
||||
|
||||
{
|
||||
NULL, '\0', 0, 0, NULL, NULL, NULL /* Complete struct initialization */
|
||||
@ -443,11 +441,11 @@ static gboolean
|
||||
parse_mc_e_argument (const gchar * option_name, const gchar * value, gpointer data, GError ** error)
|
||||
{
|
||||
(void) option_name;
|
||||
(void) value;
|
||||
(void) data;
|
||||
(void) error;
|
||||
|
||||
mc_global.mc_run_mode = MC_RUN_EDITOR;
|
||||
mc_run_param0 = g_strdup (value);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -467,6 +465,113 @@ parse_mc_v_argument (const gchar * option_name, const gchar * value, gpointer da
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Get list of filenames (and line numbers) from command line, when mc called as editor
|
||||
*
|
||||
* @param argc count of all arguments
|
||||
* @param argv array of strings, contains arguments
|
||||
* @return list of mcedit_arg_t objects
|
||||
*/
|
||||
|
||||
static GList *
|
||||
parse_mcedit_arguments (int argc, char **argv)
|
||||
{
|
||||
GList *flist = NULL;
|
||||
int i;
|
||||
int first_line_number = -1;
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
char *tmp;
|
||||
char *end, *p;
|
||||
mcedit_arg_t *arg;
|
||||
|
||||
tmp = argv[i];
|
||||
|
||||
/*
|
||||
* First, try to get line number as +lineno.
|
||||
*/
|
||||
if (*tmp == '+')
|
||||
{
|
||||
long lineno;
|
||||
char *error;
|
||||
|
||||
lineno = strtol (tmp + 1, &error, 10);
|
||||
|
||||
if (*error == '\0')
|
||||
{
|
||||
/* this is line number */
|
||||
first_line_number = (int) lineno;
|
||||
continue;
|
||||
}
|
||||
/* this is file name */
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for filename:lineno, followed by an optional colon.
|
||||
* This format is used by many programs (especially compilers)
|
||||
* in error messages and warnings. It is supported so that
|
||||
* users can quickly copy and paste file locations.
|
||||
*/
|
||||
end = tmp + strlen (tmp);
|
||||
p = end;
|
||||
|
||||
if (p > tmp && p[-1] == ':')
|
||||
p--;
|
||||
while (p > tmp && g_ascii_isdigit ((gchar) p[-1]))
|
||||
p--;
|
||||
|
||||
if (tmp < p && p < end && p[-1] == ':')
|
||||
{
|
||||
char *fname;
|
||||
vfs_path_t *tmp_vpath, *fname_vpath;
|
||||
struct stat st;
|
||||
|
||||
fname = g_strndup (tmp, p - 1 - tmp);
|
||||
tmp_vpath = vfs_path_from_str (tmp);
|
||||
fname_vpath = vfs_path_from_str (fname);
|
||||
|
||||
/*
|
||||
* Check that the file before the colon actually exists.
|
||||
* If it doesn't exist, create new file.
|
||||
*/
|
||||
if (mc_stat (tmp_vpath, &st) == -1 && mc_stat (fname_vpath, &st) != -1)
|
||||
{
|
||||
arg = mcedit_arg_vpath_new (fname_vpath, atoi (p));
|
||||
vfs_path_free (tmp_vpath);
|
||||
}
|
||||
else
|
||||
{
|
||||
arg = mcedit_arg_vpath_new (tmp_vpath, 1);
|
||||
vfs_path_free (fname_vpath);
|
||||
}
|
||||
|
||||
g_free (fname);
|
||||
}
|
||||
else
|
||||
arg = mcedit_arg_new (tmp, 1);
|
||||
|
||||
flist = g_list_prepend (flist, arg);
|
||||
}
|
||||
|
||||
if (flist == NULL)
|
||||
flist = g_list_prepend (flist, mcedit_arg_new (NULL, 1));
|
||||
else if (first_line_number != -1)
|
||||
{
|
||||
/* overwrite line number for first file */
|
||||
GList *l;
|
||||
|
||||
if (first_line_number == 0)
|
||||
first_line_number = 1;
|
||||
|
||||
l = g_list_last (flist);
|
||||
((mcedit_arg_t *) l->data)->line_number = first_line_number;
|
||||
}
|
||||
|
||||
return flist;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/*** public functions ****************************************************************************/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
@ -633,84 +738,7 @@ mc_setup_by_args (int argc, char **argv, GError ** error)
|
||||
{
|
||||
/* mce* or vi is link to mc */
|
||||
|
||||
mc_run_param0 = g_strdup ("");
|
||||
if (tmp != NULL)
|
||||
{
|
||||
/*
|
||||
* Check for filename:lineno, followed by an optional colon.
|
||||
* This format is used by many programs (especially compilers)
|
||||
* in error messages and warnings. It is supported so that
|
||||
* users can quickly copy and paste file locations.
|
||||
*/
|
||||
char *end, *p;
|
||||
|
||||
end = tmp + strlen (tmp);
|
||||
p = end;
|
||||
|
||||
if (p > tmp && p[-1] == ':')
|
||||
p--;
|
||||
while (p > tmp && g_ascii_isdigit ((gchar) p[-1]))
|
||||
p--;
|
||||
if (tmp < p && p < end && p[-1] == ':')
|
||||
{
|
||||
char *fname;
|
||||
struct stat st;
|
||||
vfs_path_t *tmp_vpath, *fname_vpath;
|
||||
gboolean ok;
|
||||
|
||||
fname = g_strndup (tmp, p - 1 - tmp);
|
||||
tmp_vpath = vfs_path_from_str (tmp);
|
||||
fname_vpath = vfs_path_from_str (fname);
|
||||
/*
|
||||
* Check that the file before the colon actually exists.
|
||||
* If it doesn't exist, revert to the old behavior.
|
||||
*/
|
||||
ok = mc_stat (tmp_vpath, &st) == -1 && mc_stat (fname_vpath, &st) != -1;
|
||||
vfs_path_free (tmp_vpath);
|
||||
vfs_path_free (fname_vpath);
|
||||
|
||||
if (ok)
|
||||
{
|
||||
mc_run_param0 = fname;
|
||||
mc_args__edit_start_line = atoi (p);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_free (fname);
|
||||
goto try_plus_filename;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
try_plus_filename:
|
||||
if (*tmp == '+' && g_ascii_isdigit ((gchar) tmp[1]))
|
||||
{
|
||||
int start_line;
|
||||
|
||||
start_line = atoi (tmp);
|
||||
|
||||
/*
|
||||
* If start_line is zero, position the cursor at the
|
||||
* beginning of the file as other editors (vi, nano)
|
||||
*/
|
||||
if (start_line == 0)
|
||||
start_line++;
|
||||
|
||||
if (start_line > 0)
|
||||
{
|
||||
char *file;
|
||||
|
||||
file = (argc > 1) ? argv[2] : NULL;
|
||||
if (file != NULL)
|
||||
{
|
||||
tmp = file;
|
||||
mc_args__edit_start_line = start_line;
|
||||
}
|
||||
}
|
||||
}
|
||||
mc_run_param0 = g_strdup (tmp);
|
||||
}
|
||||
}
|
||||
mc_run_param0 = parse_mcedit_arguments (argc - 1, &argv[1]);
|
||||
mc_global.mc_run_mode = MC_RUN_EDITOR;
|
||||
}
|
||||
else if (strncmp (base, "mcv", 3) == 0 || strcmp (base, "view") == 0)
|
||||
@ -755,8 +783,11 @@ mc_setup_by_args (int argc, char **argv, GError ** error)
|
||||
switch (mc_global.mc_run_mode)
|
||||
{
|
||||
case MC_RUN_EDITOR:
|
||||
mc_run_param0 = parse_mcedit_arguments (argc - 1, &argv[1]);
|
||||
break;
|
||||
|
||||
case MC_RUN_VIEWER:
|
||||
/* mc_run_param0 is set up in parse_mc_e_argument() and parse_mc_v_argument() */
|
||||
/* mc_run_param0 is set up in parse_mc_v_argument() */
|
||||
break;
|
||||
|
||||
case MC_RUN_DIFFVIEWER:
|
||||
@ -782,3 +813,55 @@ mc_setup_by_args (int argc, char **argv, GError ** error)
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Create mcedit_arg_t object from file name and the line number.
|
||||
*
|
||||
* @param file_name file name
|
||||
* @param line_number line number
|
||||
* @return mcedit_arg_t object
|
||||
*/
|
||||
|
||||
mcedit_arg_t *
|
||||
mcedit_arg_new (const char *file_name, int line_number)
|
||||
{
|
||||
return mcedit_arg_vpath_new (vfs_path_from_str (file_name), line_number);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Create mcedit_arg_t object from vfs_path_t object and the line number.
|
||||
*
|
||||
* @param file_vpath file path object
|
||||
* @param line_number line number
|
||||
* @return mcedit_arg_t object
|
||||
*/
|
||||
|
||||
mcedit_arg_t *
|
||||
mcedit_arg_vpath_new (vfs_path_t * file_vpath, int line_number)
|
||||
{
|
||||
mcedit_arg_t *arg;
|
||||
|
||||
arg = g_new (mcedit_arg_t, 1);
|
||||
arg->file_vpath = file_vpath;
|
||||
if (line_number == 0)
|
||||
line_number = 1;
|
||||
arg->line_number = line_number;
|
||||
|
||||
return arg;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Free the mcedit_arg_t object.
|
||||
*
|
||||
* @param arg mcedit_arg_t object
|
||||
*/
|
||||
|
||||
void
|
||||
mcedit_arg_free (mcedit_arg_t * arg)
|
||||
{
|
||||
vfs_path_free (arg->file_vpath);
|
||||
g_free (arg);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
13
src/args.h
13
src/args.h
@ -2,6 +2,7 @@
|
||||
#define MC__ARGS_H
|
||||
|
||||
#include "lib/global.h" /* gboolean */
|
||||
#include "lib/vfs/vfs.h" /* vfs_path_t */
|
||||
|
||||
/*** typedefs(not structures) and defined constants **********************************************/
|
||||
|
||||
@ -9,13 +10,18 @@
|
||||
|
||||
/*** structures declarations (and typedefs of structures)*****************************************/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vfs_path_t *file_vpath;
|
||||
int line_number;
|
||||
} mcedit_arg_t;
|
||||
|
||||
/*** global variables defined in .c file *********************************************************/
|
||||
|
||||
extern gboolean mc_args__force_xterm;
|
||||
extern gboolean mc_args__nomouse;
|
||||
extern gboolean mc_args__force_colors;
|
||||
extern gboolean mc_args__nokeymap;
|
||||
extern int mc_args__edit_start_line;
|
||||
extern char *mc_args__last_wd_file;
|
||||
extern char *mc_args__netfs_logfile;
|
||||
extern char *mc_args__keymap_file;
|
||||
@ -27,5 +33,10 @@ gboolean mc_args_parse (int *argc, char ***argv, const char *translation_domain,
|
||||
gboolean mc_args_show_info (void);
|
||||
gboolean mc_setup_by_args (int argc, char **argv, GError ** error);
|
||||
|
||||
mcedit_arg_t *mcedit_arg_new (const char *file_name, int line_number);
|
||||
mcedit_arg_t *mcedit_arg_vpath_new (vfs_path_t * file_vpath, int line_number);
|
||||
void mcedit_arg_free (mcedit_arg_t * arg);
|
||||
|
||||
/*** inline functions ****************************************************************************/
|
||||
|
||||
#endif /* MC__ARGS_H */
|
||||
|
@ -61,7 +61,8 @@ extern int show_right_margin;
|
||||
void edit_stack_init (void);
|
||||
void edit_stack_free (void);
|
||||
|
||||
gboolean edit_file (const vfs_path_t * _file_vpath, int line);
|
||||
gboolean edit_file (const vfs_path_t * file_vpath, int line);
|
||||
gboolean edit_files (const GList * files);
|
||||
|
||||
char *edit_get_file_name (const WEdit * edit);
|
||||
int edit_get_curs_col (const WEdit * edit);
|
||||
|
@ -59,6 +59,7 @@
|
||||
#include "src/main.h" /* home_dir */
|
||||
#include "src/filemanager/cmd.h" /* view_other_cmd(), save_setup_cmd() */
|
||||
#include "src/learn.h" /* learn_keys() */
|
||||
#include "src/args.h" /* mcedit_arg_t */
|
||||
|
||||
#include "edit-impl.h"
|
||||
#include "editwidget.h"
|
||||
@ -1013,14 +1014,37 @@ edit_callback (Widget * w, widget_msg_t msg, int parm)
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/*** public functions ****************************************************************************/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Edit one file.
|
||||
*
|
||||
* @param file_vpath file object
|
||||
* @param line line number
|
||||
* @return TRUE if no errors was occured, FALSE otherwise
|
||||
*/
|
||||
|
||||
gboolean
|
||||
edit_file (const vfs_path_t * _file_vpath, int line)
|
||||
edit_file (const vfs_path_t * file_vpath, int line)
|
||||
{
|
||||
mcedit_arg_t arg = { (vfs_path_t *) file_vpath, line };
|
||||
GList *files;
|
||||
gboolean ok;
|
||||
|
||||
files = g_list_prepend (NULL, &arg);
|
||||
ok = edit_files (files);
|
||||
g_list_free (files);
|
||||
|
||||
return ok;
|
||||
}
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
gboolean
|
||||
edit_files (const GList *files)
|
||||
{
|
||||
static gboolean made_directory = FALSE;
|
||||
Dlg_head *edit_dlg;
|
||||
WMenuBar *menubar;
|
||||
gboolean ok;
|
||||
const GList *file;
|
||||
gboolean ok = FALSE;
|
||||
|
||||
if (!made_directory)
|
||||
{
|
||||
@ -1053,8 +1077,17 @@ edit_file (const vfs_path_t * _file_vpath, int line)
|
||||
|
||||
add_widget (edit_dlg, buttonbar_new (TRUE));
|
||||
|
||||
ok = edit_add_window (edit_dlg, edit_dlg->y + 1, edit_dlg->x,
|
||||
edit_dlg->lines - 2, edit_dlg->cols, _file_vpath, line);
|
||||
for (file = files; file != NULL; file = g_list_next (file))
|
||||
{
|
||||
mcedit_arg_t *f = (mcedit_arg_t *) file->data;
|
||||
gboolean f_ok;
|
||||
|
||||
f_ok = edit_add_window (edit_dlg, edit_dlg->y + 1, edit_dlg->x,
|
||||
edit_dlg->lines - 2, edit_dlg->cols,
|
||||
f->file_vpath, f->line_number);
|
||||
/* at least one file has been opened succefully */
|
||||
ok = ok || f_ok;
|
||||
}
|
||||
|
||||
if (ok)
|
||||
run_dlg (edit_dlg);
|
||||
|
@ -580,7 +580,7 @@ create_panels (void)
|
||||
current_mode = startup_left_mode;
|
||||
other_mode = startup_right_mode;
|
||||
/* if mc_run_param0 is NULL, working directory will be used for the left panel */
|
||||
current_dir = mc_run_param0;
|
||||
current_dir = (char *) mc_run_param0;
|
||||
/* mc_run_param1 is never NULL. It is setup from command line or from panels.ini
|
||||
* (value of other_dir). mc_run_param1 will be used for the right panel */
|
||||
other_dir = mc_run_param1;
|
||||
@ -600,7 +600,7 @@ create_panels (void)
|
||||
if (mc_run_param0 != NULL)
|
||||
{
|
||||
current_dir = NULL;
|
||||
other_dir = mc_run_param0;
|
||||
other_dir = (char *) mc_run_param0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -973,29 +973,21 @@ prepend_cwd_on_local (const char *filename)
|
||||
static gboolean
|
||||
mc_maybe_editor_or_viewer (void)
|
||||
{
|
||||
int ret;
|
||||
gboolean ret;
|
||||
|
||||
switch (mc_global.mc_run_mode)
|
||||
{
|
||||
#ifdef USE_INTERNAL_EDIT
|
||||
case MC_RUN_EDITOR:
|
||||
{
|
||||
vfs_path_t *vpath = NULL;
|
||||
|
||||
if (mc_run_param0 != NULL && *mc_run_param0 != '\0')
|
||||
vpath = vfs_path_from_str (mc_run_param0);
|
||||
|
||||
ret = edit_file (vpath, mc_args__edit_start_line);
|
||||
vfs_path_free (vpath);
|
||||
}
|
||||
ret = edit_files ((GList *) mc_run_param0);
|
||||
break;
|
||||
#endif /* USE_INTERNAL_EDIT */
|
||||
case MC_RUN_VIEWER:
|
||||
{
|
||||
vfs_path_t *vpath = NULL;
|
||||
|
||||
if (mc_run_param0 != NULL && *mc_run_param0 != '\0')
|
||||
vpath = prepend_cwd_on_local (mc_run_param0);
|
||||
if (mc_run_param0 != NULL && *(char *) mc_run_param0 != '\0')
|
||||
vpath = prepend_cwd_on_local ((char *) mc_run_param0);
|
||||
|
||||
ret = view_file (vpath, 0, 1);
|
||||
vfs_path_free (vpath);
|
||||
@ -1007,10 +999,10 @@ mc_maybe_editor_or_viewer (void)
|
||||
break;
|
||||
#endif /* USE_DIFF_VIEW */
|
||||
default:
|
||||
ret = 0;
|
||||
ret = FALSE;
|
||||
}
|
||||
|
||||
return (ret != 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
@ -96,7 +96,7 @@ int use_internal_view = 1;
|
||||
/* If set, use the builtin editor */
|
||||
int use_internal_edit = 1;
|
||||
|
||||
char *mc_run_param0 = NULL;
|
||||
void *mc_run_param0 = NULL;
|
||||
char *mc_run_param1 = NULL;
|
||||
|
||||
/* The user's shell */
|
||||
@ -630,7 +630,13 @@ main (int argc, char *argv[])
|
||||
|
||||
str_uninit_strings ();
|
||||
|
||||
if (mc_global.mc_run_mode != MC_RUN_EDITOR)
|
||||
g_free (mc_run_param0);
|
||||
else
|
||||
{
|
||||
g_list_foreach ((GList *) mc_run_param0, (GFunc) mcedit_arg_free, NULL);
|
||||
g_list_free ((GList *) mc_run_param0);
|
||||
}
|
||||
g_free (mc_run_param1);
|
||||
|
||||
mc_config_deinit_config_paths ();
|
||||
|
@ -42,11 +42,11 @@ struct mc_fhl_struct;
|
||||
|
||||
/*
|
||||
* MC_RUN_FULL: dir for left panel
|
||||
* MC_RUN_EDITOR: file to edit
|
||||
* MC_RUN_EDITOR: list of files to edit
|
||||
* MC_RUN_VIEWER: file to view
|
||||
* MC_RUN_DIFFVIEWER: first file to compare
|
||||
*/
|
||||
extern char *mc_run_param0;
|
||||
extern void *mc_run_param0;
|
||||
/*
|
||||
* MC_RUN_FULL: dir for right panel
|
||||
* MC_RUN_EDITOR: unused
|
||||
|
Loading…
Reference in New Issue
Block a user