1998-02-27 04:54:42 +00:00
|
|
|
/* User Menu implementation
|
2007-09-26 10:22:25 +00:00
|
|
|
Copyright (C) 1994, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
|
|
|
|
2006, 2007 Free Software Foundation, Inc.
|
2010-06-10 13:42:37 +04:00
|
|
|
|
1998-02-27 04:54:42 +00: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.
|
2010-06-10 13:42:37 +04:00
|
|
|
|
1998-02-27 04:54:42 +00: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 03:35:10 +00:00
|
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
1998-02-27 04:54:42 +00:00
|
|
|
|
2009-02-05 20:28:18 +02:00
|
|
|
/** \file user.c
|
|
|
|
* \brief Source: user menu implementation
|
|
|
|
*/
|
|
|
|
|
1998-02-27 04:54:42 +00:00
|
|
|
#include <config.h>
|
2005-02-08 09:04:03 +00:00
|
|
|
|
1998-02-27 04:54:42 +00:00
|
|
|
#include <ctype.h>
|
|
|
|
#include <errno.h>
|
2009-02-27 14:54:26 +03:00
|
|
|
#include <stdlib.h>
|
2005-02-08 09:04:03 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
2001-09-03 05:07:40 +00:00
|
|
|
|
2010-01-20 17:11:52 +02:00
|
|
|
#include "lib/global.h"
|
2010-01-08 16:47:19 +02:00
|
|
|
#include "lib/tty/tty.h"
|
2010-01-21 15:06:15 +02:00
|
|
|
#include "lib/skin.h"
|
|
|
|
#include "lib/search.h"
|
2010-01-21 14:17:26 +02:00
|
|
|
#include "lib/vfs/mc-vfs/vfs.h"
|
|
|
|
#include "lib/strutil.h"
|
|
|
|
|
2010-06-10 13:42:37 +04:00
|
|
|
#include "src/editor/edit.h" /* WEdit, BLOCK_FILE */
|
|
|
|
#include "src/viewer/mcviewer.h" /* for default_* externs */
|
2010-01-21 14:17:26 +02:00
|
|
|
|
1998-02-27 04:54:42 +00:00
|
|
|
#include "dir.h"
|
|
|
|
#include "panel.h"
|
|
|
|
#include "main.h"
|
|
|
|
#include "user.h"
|
|
|
|
#include "layout.h"
|
2003-06-22 09:17:46 +00:00
|
|
|
#include "execute.h"
|
1998-11-18 02:31:23 +00:00
|
|
|
#include "setup.h"
|
2009-01-24 21:59:58 +01:00
|
|
|
#include "history.h"
|
2002-11-29 03:03:53 +00:00
|
|
|
|
2003-10-24 23:20:30 +00:00
|
|
|
#include "dialog.h"
|
2010-04-18 14:58:18 +04:00
|
|
|
#include "dialog-switch.h"
|
1998-02-27 04:54:42 +00:00
|
|
|
#include "widget.h"
|
|
|
|
#include "wtools.h"
|
|
|
|
|
1999-11-01 20:49:03 +00:00
|
|
|
#define MAX_ENTRIES 16
|
1998-02-27 04:54:42 +00:00
|
|
|
#define MAX_ENTRY_LEN 60
|
|
|
|
|
|
|
|
static int debug_flag = 0;
|
|
|
|
static int debug_error = 0;
|
2000-05-25 16:21:42 +00:00
|
|
|
static char *menu = NULL;
|
1998-02-27 04:54:42 +00:00
|
|
|
|
|
|
|
/* Formats defined:
|
|
|
|
%% The % character
|
|
|
|
%f The current file (if non-local vfs, file will be copied locally and
|
2010-06-10 13:42:37 +04:00
|
|
|
%f will be full path to it).
|
1998-02-27 04:54:42 +00:00
|
|
|
%p The current file
|
|
|
|
%d The current working directory
|
|
|
|
%s "Selected files"; the tagged files if any, otherwise the current file
|
|
|
|
%t Tagged files
|
|
|
|
%u Tagged files (and they are untagged on return from expand_format)
|
2001-07-19 21:25:40 +00:00
|
|
|
%view Runs the commands and pipes standard output to the view command.
|
2010-06-10 13:42:37 +04:00
|
|
|
If %view is immediately followed by '{', recognize keywords
|
|
|
|
ascii, hex, nroff and unform
|
1998-02-27 04:54:42 +00:00
|
|
|
|
|
|
|
If the format letter is in uppercase, it refers to the other panel.
|
2010-06-10 13:42:37 +04:00
|
|
|
|
1998-02-27 04:54:42 +00:00
|
|
|
With a number followed the % character you can turn quoting on (default)
|
|
|
|
and off. For example:
|
2010-06-10 13:42:37 +04:00
|
|
|
%f quote expanded macro
|
|
|
|
%1f ditto
|
|
|
|
%0f don't quote expanded macro
|
1998-02-27 04:54:42 +00:00
|
|
|
|
|
|
|
expand_format returns a memory block that must be free()d.
|
2010-06-10 13:42:37 +04:00
|
|
|
*/
|
1998-02-27 04:54:42 +00:00
|
|
|
|
|
|
|
/* Returns how many characters we should advance if %view was found */
|
2010-06-10 13:42:37 +04:00
|
|
|
int
|
|
|
|
check_format_view (const char *p)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
1999-10-19 04:21:26 +00:00
|
|
|
const char *q = p;
|
2010-06-10 13:42:37 +04:00
|
|
|
if (!strncmp (p, "view", 4))
|
|
|
|
{
|
|
|
|
q += 4;
|
|
|
|
if (*q == '{')
|
|
|
|
{
|
|
|
|
for (q++; *q && *q != '}'; q++)
|
|
|
|
{
|
|
|
|
if (!strncmp (q, "ascii", 5))
|
|
|
|
{
|
|
|
|
mcview_default_hex_mode = 0;
|
|
|
|
q += 4;
|
|
|
|
}
|
|
|
|
else if (!strncmp (q, "hex", 3))
|
|
|
|
{
|
|
|
|
mcview_default_hex_mode = 1;
|
|
|
|
q += 2;
|
|
|
|
}
|
|
|
|
else if (!strncmp (q, "nroff", 5))
|
|
|
|
{
|
|
|
|
mcview_default_nroff_flag = 1;
|
|
|
|
q += 4;
|
|
|
|
}
|
|
|
|
else if (!strncmp (q, "unform", 6))
|
|
|
|
{
|
|
|
|
mcview_default_nroff_flag = 0;
|
|
|
|
q += 5;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (*q == '}')
|
|
|
|
q++;
|
|
|
|
}
|
|
|
|
return q - p;
|
1999-10-19 04:21:26 +00:00
|
|
|
}
|
|
|
|
return 0;
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
|
|
|
|
2010-06-10 13:42:37 +04:00
|
|
|
int
|
|
|
|
check_format_cd (const char *p)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
1999-10-19 04:21:26 +00:00
|
|
|
return (strncmp (p, "cd", 2)) ? 0 : 3;
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if p has a "^var\{var-name\}" */
|
|
|
|
/* Returns the number of skipped characters (zero on not found) */
|
|
|
|
/* V will be set to the expanded variable name */
|
2010-06-10 13:42:37 +04:00
|
|
|
int
|
|
|
|
check_format_var (const char *p, char **v)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
1999-10-19 04:21:26 +00:00
|
|
|
const char *q = p;
|
1998-02-27 04:54:42 +00:00
|
|
|
char *var_name;
|
2004-09-25 13:46:23 +00:00
|
|
|
const char *value;
|
1999-10-19 04:21:26 +00:00
|
|
|
const char *dots = 0;
|
2010-06-10 13:42:37 +04:00
|
|
|
|
1998-02-27 04:54:42 +00:00
|
|
|
*v = 0;
|
2010-06-10 13:42:37 +04:00
|
|
|
if (!strncmp (p, "var{", 4))
|
|
|
|
{
|
|
|
|
for (q += 4; *q && *q != '}'; q++)
|
|
|
|
{
|
|
|
|
if (*q == ':')
|
|
|
|
dots = q + 1;
|
|
|
|
}
|
|
|
|
if (!*q)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (!dots || dots == q + 5)
|
|
|
|
{
|
|
|
|
message (D_ERROR,
|
|
|
|
_("Format error on file Extensions File"),
|
|
|
|
!dots ? _("The %%var macro has no default")
|
|
|
|
: _("The %%var macro has no variable"));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Copy the variable name */
|
|
|
|
var_name = g_strndup (p + 4, dots - 2 - (p + 3));
|
|
|
|
|
|
|
|
value = getenv (var_name);
|
|
|
|
g_free (var_name);
|
|
|
|
if (value)
|
|
|
|
{
|
|
|
|
*v = g_strdup (value);
|
|
|
|
return q - p;
|
|
|
|
}
|
|
|
|
var_name = g_strndup (dots, q - dots);
|
|
|
|
*v = var_name;
|
|
|
|
return q - p;
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* strip file's extension */
|
1998-12-02 21:27:27 +00:00
|
|
|
static char *
|
2010-06-10 13:42:37 +04:00
|
|
|
strip_ext (char *ss)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
|
|
|
register char *s = ss;
|
|
|
|
char *e = NULL;
|
2010-06-10 13:42:37 +04:00
|
|
|
while (*s)
|
|
|
|
{
|
|
|
|
if (*s == '.')
|
|
|
|
e = s;
|
|
|
|
if (*s == PATH_SEP && e)
|
|
|
|
e = NULL; /* '.' in *directory* name */
|
1998-02-27 04:54:42 +00:00
|
|
|
s++;
|
|
|
|
}
|
2010-06-10 13:42:37 +04:00
|
|
|
if (e)
|
|
|
|
*e = 0;
|
1998-02-27 04:54:42 +00:00
|
|
|
return ss;
|
|
|
|
}
|
|
|
|
|
2002-08-24 17:25:27 +00:00
|
|
|
char *
|
2010-02-02 10:48:08 +00:00
|
|
|
expand_format (struct WEdit *edit_widget, char c, gboolean do_quote)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
2005-06-22 21:38:52 +00:00
|
|
|
WPanel *panel = NULL;
|
2002-08-24 17:25:27 +00:00
|
|
|
char *(*quote_func) (const char *, int);
|
2009-06-14 19:18:27 +04:00
|
|
|
char *fname = NULL;
|
2004-11-12 11:56:21 +00:00
|
|
|
char *result;
|
|
|
|
char c_lc;
|
1998-02-27 04:54:42 +00:00
|
|
|
|
2009-11-14 14:54:11 +01:00
|
|
|
#ifndef USE_INTERNAL_EDIT
|
|
|
|
(void) edit_widget;
|
|
|
|
#endif
|
|
|
|
|
1998-02-27 04:54:42 +00:00
|
|
|
if (c == '%')
|
2010-06-10 13:42:37 +04:00
|
|
|
return g_strdup ("%");
|
|
|
|
|
|
|
|
if (mc_run_mode == MC_RUN_FULL)
|
|
|
|
{
|
|
|
|
if (g_ascii_islower ((gchar) c))
|
|
|
|
panel = current_panel;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (get_other_type () != view_listing)
|
|
|
|
return g_strdup ("");
|
|
|
|
panel = other_panel;
|
|
|
|
}
|
|
|
|
fname = panel->dir.list[panel->selected].fname;
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
2009-07-28 10:53:26 +04:00
|
|
|
#ifdef USE_INTERNAL_EDIT
|
2010-06-09 21:42:08 +04:00
|
|
|
else if (mc_run_mode == MC_RUN_EDITOR)
|
2010-06-10 13:42:37 +04:00
|
|
|
fname = str_unconst (edit_get_file_name (edit_widget));
|
2009-07-28 10:53:26 +04:00
|
|
|
#endif
|
1998-02-27 04:54:42 +00:00
|
|
|
|
2010-02-02 10:48:08 +00:00
|
|
|
if (do_quote)
|
2010-06-10 13:42:37 +04:00
|
|
|
quote_func = name_quote;
|
1999-11-01 20:49:03 +00:00
|
|
|
else
|
2010-06-10 13:42:37 +04:00
|
|
|
quote_func = fake_name_quote;
|
1999-11-01 20:49:03 +00:00
|
|
|
|
patches by Rostislav Beneš: mc-28-fix
rest of fixes in files cmc.c, main.c (xterm title), panelize.c, subshell.c,
tree.c, tty.c, user.c, util.c, win.c
now, basic mc's function should work well, editor and view are still broken.
2008-12-29 01:53:08 +02:00
|
|
|
c_lc = g_ascii_tolower ((gchar) c);
|
2002-08-24 17:25:27 +00:00
|
|
|
|
2010-06-10 13:42:37 +04:00
|
|
|
switch (c_lc)
|
|
|
|
{
|
2002-08-24 17:25:27 +00:00
|
|
|
case 'f':
|
|
|
|
case 'p':
|
2010-06-10 13:42:37 +04:00
|
|
|
return (*quote_func) (fname, 0);
|
2002-08-24 17:25:27 +00:00
|
|
|
case 'x':
|
2010-06-10 13:42:37 +04:00
|
|
|
return (*quote_func) (extension (fname), 0);
|
2002-08-24 17:25:27 +00:00
|
|
|
case 'd':
|
2010-06-10 13:42:37 +04:00
|
|
|
{
|
|
|
|
char *cwd;
|
|
|
|
char *qstr;
|
2005-06-22 21:38:52 +00:00
|
|
|
|
2010-06-10 13:42:37 +04:00
|
|
|
cwd = g_malloc (MC_MAXPATHLEN + 1);
|
2005-06-22 21:38:52 +00:00
|
|
|
|
2010-06-10 13:42:37 +04:00
|
|
|
if (panel)
|
|
|
|
g_strlcpy (cwd, panel->cwd, MC_MAXPATHLEN + 1);
|
|
|
|
else
|
|
|
|
mc_get_current_wd (cwd, MC_MAXPATHLEN + 1);
|
2005-06-22 21:38:52 +00:00
|
|
|
|
2010-06-10 13:42:37 +04:00
|
|
|
qstr = (*quote_func) (cwd, 0);
|
2005-06-22 21:38:52 +00:00
|
|
|
|
2010-06-10 13:42:37 +04:00
|
|
|
g_free (cwd);
|
2005-06-22 21:38:52 +00:00
|
|
|
|
2010-06-10 13:42:37 +04:00
|
|
|
return qstr;
|
|
|
|
}
|
|
|
|
case 'i': /* indent equal number cursor position in line */
|
2009-07-28 10:53:26 +04:00
|
|
|
#ifdef USE_INTERNAL_EDIT
|
2010-06-10 13:42:37 +04:00
|
|
|
if (edit_widget)
|
|
|
|
return g_strnfill (edit_get_curs_col (edit_widget), ' ');
|
2009-07-28 10:53:26 +04:00
|
|
|
#endif
|
2010-06-10 13:42:37 +04:00
|
|
|
break;
|
|
|
|
case 'y': /* syntax type */
|
2009-07-28 10:53:26 +04:00
|
|
|
#ifdef USE_INTERNAL_EDIT
|
2010-06-10 13:42:37 +04:00
|
|
|
if (edit_widget)
|
|
|
|
{
|
|
|
|
const char *syntax_type = edit_get_syntax_type (edit_widget);
|
|
|
|
if (syntax_type != NULL)
|
|
|
|
return g_strdup (syntax_type);
|
|
|
|
}
|
2009-07-28 10:53:26 +04:00
|
|
|
#endif
|
2010-06-10 13:42:37 +04:00
|
|
|
break;
|
|
|
|
case 'k': /* block file name */
|
|
|
|
case 'b': /* block file name / strip extension */
|
|
|
|
{
|
2009-07-28 10:53:26 +04:00
|
|
|
#ifdef USE_INTERNAL_EDIT
|
2010-06-10 13:42:37 +04:00
|
|
|
if (edit_widget)
|
|
|
|
{
|
|
|
|
char *file = concat_dir_and_file (home_dir, EDIT_BLOCK_FILE);
|
|
|
|
fname = (*quote_func) (file, 0);
|
|
|
|
g_free (file);
|
|
|
|
return fname;
|
|
|
|
}
|
2009-07-28 10:53:26 +04:00
|
|
|
#endif
|
2010-06-10 13:42:37 +04:00
|
|
|
if (c_lc == 'b')
|
|
|
|
return strip_ext ((*quote_func) (fname, 0));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 'n': /* strip extension in editor */
|
2009-07-28 10:53:26 +04:00
|
|
|
#ifdef USE_INTERNAL_EDIT
|
2010-06-10 13:42:37 +04:00
|
|
|
if (edit_widget)
|
|
|
|
return strip_ext ((*quote_func) (fname, 0));
|
2009-07-28 10:53:26 +04:00
|
|
|
#endif
|
2010-06-10 13:42:37 +04:00
|
|
|
break;
|
|
|
|
case 'm': /* menu file name */
|
|
|
|
if (menu)
|
|
|
|
return (*quote_func) (menu, 0);
|
|
|
|
break;
|
2002-08-24 17:25:27 +00:00
|
|
|
case 's':
|
2010-06-10 13:42:37 +04:00
|
|
|
if (!panel || !panel->marked)
|
|
|
|
return (*quote_func) (fname, 0);
|
1998-02-27 04:54:42 +00:00
|
|
|
|
2010-06-10 13:42:37 +04:00
|
|
|
/* Fall through */
|
1998-02-27 04:54:42 +00:00
|
|
|
|
|
|
|
case 't':
|
|
|
|
case 'u':
|
2010-06-10 13:42:37 +04:00
|
|
|
{
|
|
|
|
int length = 2, i;
|
|
|
|
char *block, *tmp;
|
|
|
|
|
|
|
|
if (!panel)
|
|
|
|
return g_strdup ("");
|
|
|
|
|
|
|
|
for (i = 0; i < panel->count; i++)
|
|
|
|
if (panel->dir.list[i].f.marked)
|
|
|
|
length += strlen (panel->dir.list[i].fname) + 1; /* for space */
|
|
|
|
|
|
|
|
block = g_malloc (length * 2 + 1);
|
|
|
|
*block = 0;
|
|
|
|
for (i = 0; i < panel->count; i++)
|
|
|
|
if (panel->dir.list[i].f.marked)
|
|
|
|
{
|
|
|
|
tmp = (*quote_func) (panel->dir.list[i].fname, 0);
|
|
|
|
strcat (block, tmp);
|
|
|
|
g_free (tmp);
|
|
|
|
strcat (block, " ");
|
|
|
|
if (c_lc == 'u')
|
|
|
|
do_file_mark (panel, i, 0);
|
|
|
|
}
|
|
|
|
return block;
|
|
|
|
} /* sub case block */
|
|
|
|
} /* switch */
|
2009-02-05 23:40:32 +01:00
|
|
|
result = g_strdup ("% ");
|
2004-11-12 11:56:21 +00:00
|
|
|
result[1] = c;
|
|
|
|
return result;
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
|
|
|
|
2002-09-26 23:33:22 +00:00
|
|
|
/*
|
|
|
|
* Check for the "shell_patterns" directive. If it's found and valid,
|
|
|
|
* interpret it and move the pointer past the directive. Return the
|
|
|
|
* current pointer.
|
|
|
|
*/
|
2002-09-26 21:23:55 +00:00
|
|
|
static char *
|
|
|
|
check_patterns (char *p)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
2002-09-26 21:23:55 +00:00
|
|
|
static const char def_name[] = "shell_patterns=";
|
2002-09-26 23:33:22 +00:00
|
|
|
char *p0 = p;
|
1998-02-27 04:54:42 +00:00
|
|
|
|
2002-09-26 23:33:22 +00:00
|
|
|
if (strncmp (p, def_name, sizeof (def_name) - 1) != 0)
|
2010-06-10 13:42:37 +04:00
|
|
|
return p0;
|
2002-09-26 23:33:22 +00:00
|
|
|
|
|
|
|
p += sizeof (def_name) - 1;
|
|
|
|
if (*p == '1')
|
2010-06-10 13:42:37 +04:00
|
|
|
easy_patterns = 1;
|
2002-09-26 23:33:22 +00:00
|
|
|
else if (*p == '0')
|
2010-06-10 13:42:37 +04:00
|
|
|
easy_patterns = 0;
|
2002-09-26 23:33:22 +00:00
|
|
|
else
|
2010-06-10 13:42:37 +04:00
|
|
|
return p0;
|
2002-09-26 23:33:22 +00:00
|
|
|
|
|
|
|
/* Skip spaces */
|
|
|
|
p++;
|
2002-09-26 21:23:55 +00:00
|
|
|
while (*p == '\n' || *p == '\t' || *p == ' ')
|
2010-06-10 13:42:37 +04:00
|
|
|
p++;
|
1998-02-27 04:54:42 +00:00
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Copies a whitespace separated argument from p to arg. Returns the
|
|
|
|
point after argument. */
|
2010-06-10 13:42:37 +04:00
|
|
|
static char *
|
|
|
|
extract_arg (char *p, char *arg, int size)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
patches by Rostislav Beneš: mc-28-fix
rest of fixes in files cmc.c, main.c (xterm title), panelize.c, subshell.c,
tree.c, tty.c, user.c, util.c, win.c
now, basic mc's function should work well, editor and view are still broken.
2008-12-29 01:53:08 +02:00
|
|
|
char *np;
|
|
|
|
|
1998-02-27 04:54:42 +00:00
|
|
|
while (*p && (*p == ' ' || *p == '\t' || *p == '\n'))
|
2010-06-10 13:42:37 +04:00
|
|
|
p++;
|
|
|
|
/* support quote space .mnu */
|
|
|
|
while (*p && (*p != ' ' || *(p - 1) == '\\') && *p != '\t' && *p != '\n')
|
|
|
|
{
|
|
|
|
np = str_get_next_char (p);
|
|
|
|
if (np - p >= size)
|
|
|
|
break;
|
|
|
|
memcpy (arg, p, np - p);
|
|
|
|
arg += np - p;
|
|
|
|
size -= np - p;
|
|
|
|
p = np;
|
2004-03-07 06:24:14 +00:00
|
|
|
}
|
1998-02-27 04:54:42 +00:00
|
|
|
*arg = 0;
|
|
|
|
if (!*p || *p == '\n')
|
2010-06-10 13:42:37 +04:00
|
|
|
str_prev_char (&p);
|
1998-02-27 04:54:42 +00:00
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Tests whether the selected file in the panel is of any of the types
|
|
|
|
specified in argument. */
|
2010-06-10 13:42:37 +04:00
|
|
|
static int
|
|
|
|
test_type (WPanel * panel, char *arg)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
2010-06-10 13:42:37 +04:00
|
|
|
int result = 0; /* False by default */
|
|
|
|
int st_mode = panel->dir.list[panel->selected].st.st_mode;
|
|
|
|
|
|
|
|
for (; *arg != 0; arg++)
|
|
|
|
{
|
|
|
|
switch (*arg)
|
|
|
|
{
|
|
|
|
case 'n': /* Not a directory */
|
|
|
|
result |= !S_ISDIR (st_mode);
|
|
|
|
break;
|
|
|
|
case 'r': /* Regular file */
|
|
|
|
result |= S_ISREG (st_mode);
|
|
|
|
break;
|
|
|
|
case 'd': /* Directory */
|
|
|
|
result |= S_ISDIR (st_mode);
|
|
|
|
break;
|
|
|
|
case 'l': /* Link */
|
|
|
|
result |= S_ISLNK (st_mode);
|
|
|
|
break;
|
|
|
|
case 'c': /* Character special */
|
|
|
|
result |= S_ISCHR (st_mode);
|
|
|
|
break;
|
|
|
|
case 'b': /* Block special */
|
|
|
|
result |= S_ISBLK (st_mode);
|
|
|
|
break;
|
|
|
|
case 'f': /* Fifo (named pipe) */
|
|
|
|
result |= S_ISFIFO (st_mode);
|
|
|
|
break;
|
|
|
|
case 's': /* Socket */
|
|
|
|
result |= S_ISSOCK (st_mode);
|
|
|
|
break;
|
|
|
|
case 'x': /* Executable */
|
|
|
|
result |= (st_mode & 0111) ? 1 : 0;
|
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
result |= panel->marked ? 1 : 0;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
debug_error = 1;
|
|
|
|
break;
|
|
|
|
}
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Calculates the truth value of the next condition starting from
|
|
|
|
p. Returns the point after condition. */
|
2009-07-28 10:53:26 +04:00
|
|
|
static char *
|
2010-06-10 13:42:37 +04:00
|
|
|
test_condition (WEdit * edit_widget, char *p, int *condition)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
|
|
|
WPanel *panel;
|
2010-06-10 13:42:37 +04:00
|
|
|
char arg[256];
|
2009-06-14 20:29:42 +00:00
|
|
|
mc_search_type_t search_type;
|
|
|
|
|
2010-06-10 13:42:37 +04:00
|
|
|
if (easy_patterns)
|
|
|
|
{
|
|
|
|
search_type = MC_SEARCH_T_GLOB;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
search_type = MC_SEARCH_T_REGEX;
|
2009-06-14 20:29:42 +00:00
|
|
|
}
|
1998-02-27 04:54:42 +00:00
|
|
|
|
|
|
|
/* Handle one condition */
|
2010-06-10 13:42:37 +04:00
|
|
|
for (; *p != '\n' && *p != '&' && *p != '|'; p++)
|
|
|
|
{
|
|
|
|
/* support quote space .mnu */
|
|
|
|
if ((*p == ' ' && *(p - 1) != '\\') || *p == '\t')
|
|
|
|
continue;
|
|
|
|
if (*p >= 'a')
|
|
|
|
panel = current_panel;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (get_other_type () == view_listing)
|
|
|
|
panel = other_panel;
|
|
|
|
else
|
|
|
|
panel = NULL;
|
|
|
|
}
|
|
|
|
*p |= 0x20;
|
|
|
|
|
|
|
|
switch (*p++)
|
|
|
|
{
|
|
|
|
case '!':
|
|
|
|
p = test_condition (edit_widget, p, condition);
|
|
|
|
*condition = !*condition;
|
|
|
|
str_prev_char (&p);
|
|
|
|
break;
|
|
|
|
case 'f': /* file name pattern */
|
|
|
|
p = extract_arg (p, arg, sizeof (arg));
|
|
|
|
*condition = panel
|
|
|
|
&& mc_search (arg, panel->dir.list[panel->selected].fname, search_type);
|
|
|
|
break;
|
|
|
|
case 'y': /* syntax pattern */
|
2009-07-28 10:53:26 +04:00
|
|
|
#ifdef USE_INTERNAL_EDIT
|
2010-06-10 13:42:37 +04:00
|
|
|
if (edit_widget)
|
|
|
|
{
|
|
|
|
const char *syntax_type = edit_get_syntax_type (edit_widget);
|
|
|
|
if (syntax_type != NULL)
|
|
|
|
{
|
|
|
|
p = extract_arg (p, arg, sizeof (arg));
|
|
|
|
*condition = panel && mc_search (arg, syntax_type, MC_SEARCH_T_NORMAL);
|
|
|
|
}
|
|
|
|
}
|
2009-07-28 10:53:26 +04:00
|
|
|
#endif
|
2004-03-07 06:24:14 +00:00
|
|
|
break;
|
2010-06-10 13:42:37 +04:00
|
|
|
case 'd':
|
|
|
|
p = extract_arg (p, arg, sizeof (arg));
|
|
|
|
*condition = panel && mc_search (arg, panel->cwd, search_type);
|
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
p = extract_arg (p, arg, sizeof (arg));
|
|
|
|
*condition = panel && test_type (panel, arg);
|
|
|
|
break;
|
|
|
|
case 'x': /* executable */
|
|
|
|
{
|
|
|
|
struct stat status;
|
|
|
|
|
|
|
|
p = extract_arg (p, arg, sizeof (arg));
|
|
|
|
if (stat (arg, &status) == 0)
|
|
|
|
*condition = is_exe (status.st_mode);
|
|
|
|
else
|
|
|
|
*condition = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
debug_error = 1;
|
|
|
|
break;
|
|
|
|
} /* switch */
|
|
|
|
|
|
|
|
} /* while */
|
1998-02-27 04:54:42 +00:00
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* General purpose condition debug output handler */
|
1998-12-02 21:27:27 +00:00
|
|
|
static void
|
|
|
|
debug_out (char *start, char *end, int cond)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
2004-09-01 23:25:21 +00:00
|
|
|
static char *msg;
|
1998-02-27 04:54:42 +00:00
|
|
|
int len;
|
|
|
|
|
2010-06-10 13:42:37 +04:00
|
|
|
if (start == NULL && end == NULL)
|
|
|
|
{
|
|
|
|
/* Show output */
|
|
|
|
if (debug_flag && msg)
|
|
|
|
{
|
|
|
|
len = strlen (msg);
|
|
|
|
if (len)
|
|
|
|
msg[len - 1] = 0;
|
|
|
|
message (D_NORMAL, _("Debug"), "%s", msg);
|
|
|
|
|
|
|
|
}
|
|
|
|
debug_flag = 0;
|
|
|
|
g_free (msg);
|
|
|
|
msg = NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
const char *type;
|
|
|
|
char *p;
|
|
|
|
|
|
|
|
/* Save debug info for later output */
|
|
|
|
if (!debug_flag)
|
|
|
|
return;
|
|
|
|
/* Save the result of the condition */
|
|
|
|
if (debug_error)
|
|
|
|
{
|
|
|
|
type = _("ERROR:");
|
|
|
|
debug_error = 0;
|
|
|
|
}
|
|
|
|
else if (cond)
|
|
|
|
type = _("True:");
|
|
|
|
else
|
|
|
|
type = _("False:");
|
|
|
|
/* This is for debugging, don't need to be super efficient. */
|
|
|
|
if (end == NULL)
|
|
|
|
p = g_strdup_printf ("%s %s %c \n", msg ? msg : "", type, *start);
|
|
|
|
else
|
|
|
|
p = g_strdup_printf ("%s %s %.*s \n", msg ? msg : "", type, (int) (end - start), start);
|
|
|
|
g_free (msg);
|
|
|
|
msg = p;
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Calculates the truth value of one lineful of conditions. Returns
|
|
|
|
the point just before the end of line. */
|
2009-07-28 10:53:26 +04:00
|
|
|
static char *
|
2010-06-10 13:42:37 +04:00
|
|
|
test_line (WEdit * edit_widget, char *p, int *result)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
|
|
|
int condition;
|
|
|
|
char operator;
|
|
|
|
char *debug_start, *debug_end;
|
|
|
|
|
|
|
|
/* Repeat till end of line */
|
2010-06-10 13:42:37 +04:00
|
|
|
while (*p && *p != '\n')
|
|
|
|
{
|
2000-05-04 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
* src/user.c: Add macro %k it is block file name
Add macro %e it is error file name
Add macro %i it is cursor column indent of spaces, only for edit
Add macro %y, it is syntax of current file in editor, only for edit
Add condition y , it is syntax pattern of current file in edit
Add macro %x it is extension of current file
Add macro %m it is current menu filename
2000-05-04 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
* gtkedit/editcmd.c: Modify External Formatter (was C indent formatter) .
Autocreate a scripts in home, from templates /usr/lib/mc/edit.indent.rc,
edit.ispell.rc, etc. Remove leading and trailing spaces into _(""),
(the message of David H. Martin <dmartina@usa.net>)
2000-05-05 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
* src/user.c: Add condition (x filename) into mc.menu .
for "Open next a free console" and like.
2000-05-04 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
src/user.c: fix segfault in chunk_alloc of glibc, when into condition
of .mnu we have quoted space. (~.mc/menu: + f \.\ test$).
2000-05-04 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
* gtkedit/edit.c:
Add ability user edit menus: system: /usr/lib/mc/cedit.menu,
* gtkedit/editmenu.c: home: ~/.cedit.menu, local: .cedit.menu
Marked block is access now from an user edit menu
Access ~/.cedit/cooledit.block for insert to cursor place from
user edit menu.
Created system cedit.menu
2000-05-04 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
* gtkedit/editdraw.c:
Improved a status string of cool editor for best understand,
and to add char,hex view.
2000-05-04 Richard Hestilow <hestgray@ionet.net>
* gnome/gdesktop.c: Fixes snap to grid.
2000-05-09 01:18:27 +00:00
|
|
|
/* support quote space .mnu */
|
2010-06-10 13:42:37 +04:00
|
|
|
while ((*p == ' ' && *(p - 1) != '\\') || *p == '\t')
|
|
|
|
p++;
|
|
|
|
if (!*p || *p == '\n')
|
|
|
|
break;
|
|
|
|
operator = *p++;
|
|
|
|
if (*p == '?')
|
|
|
|
{
|
|
|
|
debug_flag = 1;
|
|
|
|
p++;
|
|
|
|
}
|
2000-05-04 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
* src/user.c: Add macro %k it is block file name
Add macro %e it is error file name
Add macro %i it is cursor column indent of spaces, only for edit
Add macro %y, it is syntax of current file in editor, only for edit
Add condition y , it is syntax pattern of current file in edit
Add macro %x it is extension of current file
Add macro %m it is current menu filename
2000-05-04 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
* gtkedit/editcmd.c: Modify External Formatter (was C indent formatter) .
Autocreate a scripts in home, from templates /usr/lib/mc/edit.indent.rc,
edit.ispell.rc, etc. Remove leading and trailing spaces into _(""),
(the message of David H. Martin <dmartina@usa.net>)
2000-05-05 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
* src/user.c: Add condition (x filename) into mc.menu .
for "Open next a free console" and like.
2000-05-04 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
src/user.c: fix segfault in chunk_alloc of glibc, when into condition
of .mnu we have quoted space. (~.mc/menu: + f \.\ test$).
2000-05-04 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
* gtkedit/edit.c:
Add ability user edit menus: system: /usr/lib/mc/cedit.menu,
* gtkedit/editmenu.c: home: ~/.cedit.menu, local: .cedit.menu
Marked block is access now from an user edit menu
Access ~/.cedit/cooledit.block for insert to cursor place from
user edit menu.
Created system cedit.menu
2000-05-04 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
* gtkedit/editdraw.c:
Improved a status string of cool editor for best understand,
and to add char,hex view.
2000-05-04 Richard Hestilow <hestgray@ionet.net>
* gnome/gdesktop.c: Fixes snap to grid.
2000-05-09 01:18:27 +00:00
|
|
|
/* support quote space .mnu */
|
2010-06-10 13:42:37 +04:00
|
|
|
while ((*p == ' ' && *(p - 1) != '\\') || *p == '\t')
|
|
|
|
p++;
|
|
|
|
if (!*p || *p == '\n')
|
|
|
|
break;
|
|
|
|
condition = 1; /* True by default */
|
|
|
|
|
|
|
|
debug_start = p;
|
|
|
|
p = test_condition (edit_widget, p, &condition);
|
|
|
|
debug_end = p;
|
|
|
|
/* Add one debug statement */
|
|
|
|
debug_out (debug_start, debug_end, condition);
|
|
|
|
|
|
|
|
switch (operator)
|
|
|
|
{
|
|
|
|
case '+':
|
|
|
|
case '=':
|
|
|
|
/* Assignment */
|
|
|
|
*result = condition;
|
|
|
|
break;
|
|
|
|
case '&': /* Logical and */
|
|
|
|
*result &= condition;
|
|
|
|
break;
|
|
|
|
case '|': /* Logical or */
|
|
|
|
*result |= condition;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
debug_error = 1;
|
|
|
|
break;
|
|
|
|
} /* switch */
|
|
|
|
/* Add one debug statement */
|
|
|
|
debug_out (&operator, NULL, *result);
|
|
|
|
|
|
|
|
} /* while (*p != '\n') */
|
1998-02-27 04:54:42 +00:00
|
|
|
/* Report debug message */
|
|
|
|
debug_out (NULL, NULL, 1);
|
|
|
|
|
|
|
|
if (!*p || *p == '\n')
|
2010-06-10 13:42:37 +04:00
|
|
|
str_prev_char (&p);
|
1998-02-27 04:54:42 +00:00
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* FIXME: recode this routine on version 3.0, it could be cleaner */
|
1998-12-02 21:27:27 +00:00
|
|
|
static void
|
2010-06-10 13:42:37 +04:00
|
|
|
execute_menu_command (WEdit * edit_widget, const char *commands)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
|
|
|
FILE *cmd_file;
|
2010-06-10 13:42:37 +04:00
|
|
|
int cmd_file_fd;
|
|
|
|
int expand_prefix_found = 0;
|
1999-11-01 20:49:03 +00:00
|
|
|
char *parameter = 0;
|
2010-02-02 10:48:08 +00:00
|
|
|
gboolean do_quote = FALSE;
|
2010-06-10 13:42:37 +04:00
|
|
|
char lc_prompt[80];
|
|
|
|
int col;
|
2004-11-18 17:47:55 +00:00
|
|
|
char *file_name;
|
2003-09-04 17:02:21 +00:00
|
|
|
int run_view = 0;
|
2003-07-23 03:22:32 +00:00
|
|
|
|
1999-11-01 20:49:03 +00:00
|
|
|
/* Skip menu entry title line */
|
|
|
|
commands = strchr (commands, '\n');
|
2010-06-10 13:42:37 +04:00
|
|
|
if (!commands)
|
|
|
|
{
|
|
|
|
return;
|
1999-11-01 20:49:03 +00:00
|
|
|
}
|
1999-04-22 04:36:11 +00:00
|
|
|
|
2003-09-04 17:02:21 +00:00
|
|
|
cmd_file_fd = mc_mkstemps (&file_name, "mcusr", SCRIPT_SUFFIX);
|
1998-02-27 04:54:42 +00:00
|
|
|
|
2010-06-10 13:42:37 +04:00
|
|
|
if (cmd_file_fd == -1)
|
|
|
|
{
|
|
|
|
message (D_ERROR, MSG_ERROR, _("Cannot create temporary command file\n%s"),
|
|
|
|
unix_error_string (errno));
|
|
|
|
return;
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
1998-04-24 01:08:06 +00:00
|
|
|
cmd_file = fdopen (cmd_file_fd, "w");
|
2004-01-23 17:33:36 +00:00
|
|
|
fputs ("#! /bin/sh\n", cmd_file);
|
1998-02-27 04:54:42 +00:00
|
|
|
commands++;
|
2010-06-10 13:42:37 +04:00
|
|
|
|
|
|
|
for (col = 0; *commands; commands++)
|
|
|
|
{
|
|
|
|
if (col == 0)
|
|
|
|
{
|
|
|
|
if (*commands != ' ' && *commands != '\t')
|
|
|
|
break;
|
|
|
|
while (*commands == ' ' || *commands == '\t')
|
|
|
|
commands++;
|
|
|
|
if (*commands == 0)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
col++;
|
|
|
|
if (*commands == '\n')
|
|
|
|
col = 0;
|
|
|
|
if (parameter)
|
|
|
|
{
|
|
|
|
if (*commands == '}')
|
|
|
|
{
|
|
|
|
char *tmp;
|
|
|
|
*parameter = 0;
|
|
|
|
parameter =
|
|
|
|
input_dialog (_("Parameter"), lc_prompt, MC_HISTORY_FM_MENU_EXEC_PARAM, "");
|
|
|
|
if (!parameter || !*parameter)
|
|
|
|
{
|
|
|
|
/* User canceled */
|
|
|
|
fclose (cmd_file);
|
|
|
|
unlink (file_name);
|
2009-02-05 23:27:37 +01:00
|
|
|
g_free (file_name);
|
2010-06-10 13:42:37 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (do_quote)
|
|
|
|
{
|
|
|
|
tmp = name_quote (parameter, 0);
|
|
|
|
fputs (tmp, cmd_file);
|
|
|
|
g_free (tmp);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
fputs (parameter, cmd_file);
|
|
|
|
g_free (parameter);
|
|
|
|
parameter = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (parameter < &lc_prompt[sizeof (lc_prompt) - 1])
|
|
|
|
{
|
|
|
|
*parameter++ = *commands;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (expand_prefix_found)
|
|
|
|
{
|
|
|
|
expand_prefix_found = 0;
|
|
|
|
if (g_ascii_isdigit ((gchar) * commands))
|
|
|
|
{
|
|
|
|
do_quote = (atoi (commands) != 0);
|
|
|
|
while (g_ascii_isdigit ((gchar) * commands))
|
|
|
|
commands++;
|
|
|
|
}
|
|
|
|
if (*commands == '{')
|
|
|
|
parameter = lc_prompt;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
char *text = expand_format (edit_widget, *commands, do_quote);
|
|
|
|
fputs (text, cmd_file);
|
|
|
|
g_free (text);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (*commands == '%')
|
|
|
|
{
|
|
|
|
int i = check_format_view (commands + 1);
|
|
|
|
if (i)
|
|
|
|
{
|
|
|
|
commands += i;
|
|
|
|
run_view = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
do_quote = TRUE; /* Default: Quote expanded macro */
|
|
|
|
expand_prefix_found = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
fputc (*commands, cmd_file);
|
|
|
|
}
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
|
|
|
fclose (cmd_file);
|
|
|
|
chmod (file_name, S_IRWXU);
|
2010-06-10 13:42:37 +04:00
|
|
|
if (run_view)
|
2010-04-18 14:58:18 +04:00
|
|
|
{
|
2010-05-01 16:37:06 +04:00
|
|
|
mcview_viewer (file_name, NULL, 0);
|
2010-04-18 14:58:18 +04:00
|
|
|
dialog_switch_process_pending ();
|
|
|
|
}
|
2010-06-10 13:42:37 +04:00
|
|
|
else
|
|
|
|
{
|
|
|
|
/* execute the command indirectly to allow execution even
|
|
|
|
* on no-exec filesystems. */
|
|
|
|
char *cmd = g_strconcat ("/bin/sh ", file_name, (char *) NULL);
|
|
|
|
shell_execute (cmd, EXECUTE_HIDE);
|
|
|
|
g_free (cmd);
|
2003-09-04 17:02:21 +00:00
|
|
|
}
|
1998-02-27 04:54:42 +00:00
|
|
|
unlink (file_name);
|
2009-02-05 23:27:37 +01:00
|
|
|
g_free (file_name);
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2010-06-10 13:42:37 +04:00
|
|
|
** Check owner of the menu file. Using menu file is allowed, if
|
|
|
|
** owner of the menu is root or the actual user. In either case
|
|
|
|
** file should not be group and word-writable.
|
|
|
|
**
|
|
|
|
** Q. Should we apply this routine to system and home menu (and .ext files)?
|
|
|
|
*/
|
1998-02-27 04:54:42 +00:00
|
|
|
static int
|
2010-06-10 13:42:37 +04:00
|
|
|
menu_file_own (char *path)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
1999-11-01 20:49:03 +00:00
|
|
|
struct stat st;
|
1998-02-27 04:54:42 +00:00
|
|
|
|
1999-11-01 20:49:03 +00:00
|
|
|
if (stat (path, &st) == 0
|
2010-06-10 13:42:37 +04:00
|
|
|
&& (!st.st_uid || (st.st_uid == geteuid ())) && ((st.st_mode & (S_IWGRP | S_IWOTH)) == 0))
|
|
|
|
{
|
|
|
|
return 1;
|
1999-11-01 20:49:03 +00:00
|
|
|
}
|
|
|
|
if (verbose)
|
|
|
|
{
|
2010-06-10 13:42:37 +04:00
|
|
|
message (D_NORMAL, _("Warning -- ignoring file"),
|
|
|
|
_("File %s is not owned by root or you or is world writable.\n"
|
|
|
|
"Using it may compromise your security"), path);
|
1999-11-01 20:49:03 +00:00
|
|
|
}
|
|
|
|
return 0;
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
|
|
|
|
2000-05-04 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
* src/user.c: Add macro %k it is block file name
Add macro %e it is error file name
Add macro %i it is cursor column indent of spaces, only for edit
Add macro %y, it is syntax of current file in editor, only for edit
Add condition y , it is syntax pattern of current file in edit
Add macro %x it is extension of current file
Add macro %m it is current menu filename
2000-05-04 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
* gtkedit/editcmd.c: Modify External Formatter (was C indent formatter) .
Autocreate a scripts in home, from templates /usr/lib/mc/edit.indent.rc,
edit.ispell.rc, etc. Remove leading and trailing spaces into _(""),
(the message of David H. Martin <dmartina@usa.net>)
2000-05-05 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
* src/user.c: Add condition (x filename) into mc.menu .
for "Open next a free console" and like.
2000-05-04 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
src/user.c: fix segfault in chunk_alloc of glibc, when into condition
of .mnu we have quoted space. (~.mc/menu: + f \.\ test$).
2000-05-04 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
* gtkedit/edit.c:
Add ability user edit menus: system: /usr/lib/mc/cedit.menu,
* gtkedit/editmenu.c: home: ~/.cedit.menu, local: .cedit.menu
Marked block is access now from an user edit menu
Access ~/.cedit/cooledit.block for insert to cursor place from
user edit menu.
Created system cedit.menu
2000-05-04 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
* gtkedit/editdraw.c:
Improved a status string of cool editor for best understand,
and to add char,hex view.
2000-05-04 Richard Hestilow <hestgray@ionet.net>
* gnome/gdesktop.c: Fixes snap to grid.
2000-05-09 01:18:27 +00:00
|
|
|
/*
|
2002-09-26 20:55:51 +00:00
|
|
|
* If edit_widget is NULL then we are called from the mc menu,
|
|
|
|
* otherwise we are called from the mcedit menu.
|
|
|
|
*/
|
2002-11-29 03:03:53 +00:00
|
|
|
void
|
2010-02-02 10:48:08 +00:00
|
|
|
user_menu_cmd (struct WEdit *edit_widget)
|
1998-02-27 04:54:42 +00:00
|
|
|
{
|
2000-05-04 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
* src/user.c: Add macro %k it is block file name
Add macro %e it is error file name
Add macro %i it is cursor column indent of spaces, only for edit
Add macro %y, it is syntax of current file in editor, only for edit
Add condition y , it is syntax pattern of current file in edit
Add macro %x it is extension of current file
Add macro %m it is current menu filename
2000-05-04 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
* gtkedit/editcmd.c: Modify External Formatter (was C indent formatter) .
Autocreate a scripts in home, from templates /usr/lib/mc/edit.indent.rc,
edit.ispell.rc, etc. Remove leading and trailing spaces into _(""),
(the message of David H. Martin <dmartina@usa.net>)
2000-05-05 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
* src/user.c: Add condition (x filename) into mc.menu .
for "Open next a free console" and like.
2000-05-04 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
src/user.c: fix segfault in chunk_alloc of glibc, when into condition
of .mnu we have quoted space. (~.mc/menu: + f \.\ test$).
2000-05-04 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
* gtkedit/edit.c:
Add ability user edit menus: system: /usr/lib/mc/cedit.menu,
* gtkedit/editmenu.c: home: ~/.cedit.menu, local: .cedit.menu
Marked block is access now from an user edit menu
Access ~/.cedit/cooledit.block for insert to cursor place from
user edit menu.
Created system cedit.menu
2000-05-04 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
* gtkedit/editdraw.c:
Improved a status string of cool editor for best understand,
and to add char,hex view.
2000-05-04 Richard Hestilow <hestgray@ionet.net>
* gnome/gdesktop.c: Fixes snap to grid.
2000-05-09 01:18:27 +00:00
|
|
|
char *p;
|
1999-11-01 20:49:03 +00:00
|
|
|
char *data, **entries;
|
2010-06-10 13:42:37 +04:00
|
|
|
int max_cols, menu_lines, menu_limit;
|
|
|
|
int col, i, accept_entry = 1;
|
|
|
|
int selected, old_patterns;
|
1998-02-27 04:54:42 +00:00
|
|
|
Listbox *listbox;
|
2010-06-10 13:42:37 +04:00
|
|
|
|
|
|
|
if (!vfs_current_is_local ())
|
|
|
|
{
|
|
|
|
message (D_ERROR, MSG_ERROR, "%s", _("Cannot execute commands on non-local filesystems"));
|
|
|
|
return;
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
2009-07-28 10:53:26 +04:00
|
|
|
|
2009-06-14 19:18:27 +04:00
|
|
|
menu = g_strdup (edit_widget ? EDIT_LOCAL_MENU : MC_LOCAL_MENU);
|
2010-06-10 13:42:37 +04:00
|
|
|
if (!exist_file (menu) || !menu_file_own (menu))
|
|
|
|
{
|
|
|
|
g_free (menu);
|
|
|
|
if (edit_widget)
|
|
|
|
menu = concat_dir_and_file (home_dir, EDIT_HOME_MENU);
|
|
|
|
else
|
|
|
|
menu = g_build_filename (home_dir, MC_USERCONF_DIR, MC_USERMENU_FILE, NULL);
|
|
|
|
|
|
|
|
|
|
|
|
if (!exist_file (menu))
|
|
|
|
{
|
|
|
|
g_free (menu);
|
|
|
|
menu = concat_dir_and_file (mc_home, edit_widget ? EDIT_GLOBAL_MENU : MC_GLOBAL_MENU);
|
|
|
|
if (!exist_file (menu))
|
|
|
|
{
|
|
|
|
g_free (menu);
|
|
|
|
menu = concat_dir_and_file
|
|
|
|
(mc_home_alt, edit_widget ? EDIT_GLOBAL_MENU : MC_GLOBAL_MENU);
|
|
|
|
}
|
|
|
|
}
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
|
|
|
|
2010-03-30 22:59:41 +04:00
|
|
|
data = load_file (menu);
|
2010-06-10 13:42:37 +04:00
|
|
|
if (data == NULL)
|
|
|
|
{
|
|
|
|
message (D_ERROR, MSG_ERROR, _("Cannot open file%s\n%s"), menu, unix_error_string (errno));
|
|
|
|
g_free (menu);
|
|
|
|
menu = NULL;
|
|
|
|
return;
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
2009-07-28 10:53:26 +04:00
|
|
|
|
1998-02-27 04:54:42 +00:00
|
|
|
max_cols = 0;
|
|
|
|
selected = 0;
|
1999-11-01 20:49:03 +00:00
|
|
|
menu_limit = 0;
|
|
|
|
entries = 0;
|
1998-02-27 04:54:42 +00:00
|
|
|
|
|
|
|
/* Parse the menu file */
|
|
|
|
old_patterns = easy_patterns;
|
|
|
|
p = check_patterns (data);
|
2010-06-10 13:42:37 +04:00
|
|
|
for (menu_lines = col = 0; *p; str_next_char (&p))
|
|
|
|
{
|
|
|
|
if (menu_lines >= menu_limit)
|
|
|
|
{
|
|
|
|
char **new_entries;
|
|
|
|
|
|
|
|
menu_limit += MAX_ENTRIES;
|
|
|
|
new_entries = g_try_realloc (entries, sizeof (new_entries[0]) * menu_limit);
|
|
|
|
|
|
|
|
if (new_entries == NULL)
|
|
|
|
break;
|
|
|
|
|
|
|
|
entries = new_entries;
|
|
|
|
new_entries += menu_limit;
|
|
|
|
while (--new_entries >= &entries[menu_lines])
|
|
|
|
*new_entries = NULL;
|
|
|
|
}
|
|
|
|
if (col == 0 && !entries[menu_lines])
|
|
|
|
{
|
|
|
|
if (*p == '#')
|
|
|
|
{
|
|
|
|
/* A commented menu entry */
|
|
|
|
accept_entry = 1;
|
|
|
|
}
|
|
|
|
else if (*p == '+')
|
|
|
|
{
|
|
|
|
if (*(p + 1) == '=')
|
|
|
|
{
|
|
|
|
/* Combined adding and default */
|
|
|
|
p = test_line (edit_widget, p + 1, &accept_entry);
|
|
|
|
if (selected == 0 && accept_entry)
|
|
|
|
selected = menu_lines;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* A condition for adding the entry */
|
|
|
|
p = test_line (edit_widget, p, &accept_entry);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (*p == '=')
|
|
|
|
{
|
|
|
|
if (*(p + 1) == '+')
|
|
|
|
{
|
|
|
|
/* Combined adding and default */
|
|
|
|
p = test_line (edit_widget, p + 1, &accept_entry);
|
|
|
|
if (selected == 0 && accept_entry)
|
|
|
|
selected = menu_lines;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* A condition for making the entry default */
|
|
|
|
i = 1;
|
|
|
|
p = test_line (edit_widget, p, &i);
|
|
|
|
if (selected == 0 && i)
|
|
|
|
selected = menu_lines;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (*p != ' ' && *p != '\t' && str_isprint (p))
|
|
|
|
{
|
|
|
|
/* A menu entry title line */
|
|
|
|
if (accept_entry)
|
|
|
|
entries[menu_lines] = p;
|
|
|
|
else
|
|
|
|
accept_entry = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (*p == '\n')
|
|
|
|
{
|
|
|
|
if (entries[menu_lines])
|
|
|
|
{
|
|
|
|
menu_lines++;
|
|
|
|
accept_entry = 1;
|
|
|
|
}
|
|
|
|
max_cols = max (max_cols, col);
|
|
|
|
col = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (*p == '\t')
|
|
|
|
*p = ' ';
|
|
|
|
col++;
|
|
|
|
}
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|
2000-05-25 16:21:42 +00:00
|
|
|
|
2009-07-28 10:53:26 +04:00
|
|
|
if (menu_lines == 0)
|
2010-06-10 13:42:37 +04:00
|
|
|
message (D_ERROR, MSG_ERROR, _("No suitable entries found in %s"), menu);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
max_cols = min (max (max_cols, col), MAX_ENTRY_LEN);
|
|
|
|
|
|
|
|
/* Create listbox */
|
|
|
|
listbox = create_listbox_window (menu_lines, max_cols + 2, _("User menu"),
|
|
|
|
"[Menu File Edit]");
|
|
|
|
/* insert all the items found */
|
|
|
|
for (i = 0; i < menu_lines; i++)
|
|
|
|
{
|
|
|
|
p = entries[i];
|
|
|
|
LISTBOX_APPEND_TEXT (listbox, (unsigned char) p[0],
|
|
|
|
extract_line (p, p + MAX_ENTRY_LEN), p);
|
|
|
|
}
|
|
|
|
/* Select the default entry */
|
|
|
|
listbox_select_entry (listbox->list, selected);
|
|
|
|
|
|
|
|
selected = run_listbox (listbox);
|
|
|
|
if (selected >= 0)
|
|
|
|
execute_menu_command (edit_widget, entries[selected]);
|
|
|
|
|
|
|
|
do_refresh ();
|
2000-05-25 16:21:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
easy_patterns = old_patterns;
|
2009-02-05 23:27:37 +01:00
|
|
|
g_free (menu);
|
2000-05-25 16:21:42 +00:00
|
|
|
menu = NULL;
|
2009-02-05 23:27:37 +01:00
|
|
|
g_free (entries);
|
|
|
|
g_free (data);
|
1998-02-27 04:54:42 +00:00
|
|
|
}
|