📄 cmd.c
字号:
/* Routines invoked by a function key
They normally operate on the current panel.
Copyright (C) 1994, 1995 Miguel de Icaza
Copyright (C) 1994, 1995 Janne Kukonlehto
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.
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
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <config.h>
#ifdef __os2__
# define INCL_DOSFILEMGR
# define INCL_DOSMISC
# define INCL_DOSERROR
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include "tty.h"
#include <stdio.h>
#include <stdlib.h> /* getenv (), rand */
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
#if defined(_MSC_VER)
#include <sys/time.h___>
#else
#include <time.h>
#endif
#include <malloc.h>
#include <string.h>
#include <fcntl.h> /* open, O_RDWR */
#include <errno.h>
#ifdef OS2_NT
# include <io.h>
#endif
#ifdef USE_NETCODE
#include <netdb.h>
#endif
#ifdef HAVE_MMAP
# include <sys/mman.h>
#endif
#include "mad.h"
#include "dir.h"
#include "util.h"
#include "panel.h"
#include "cmd.h" /* Our definitions */
#include "view.h" /* view() */
#include "dialog.h" /* query_dialog, message */
#include "file.h" /* the file operations */
#include "find.h" /* do_find */
#include "hotlist.h"
#include "tree.h"
#include "subshell.h" /* use_subshell */
#include "cons.saver.h"
#include "global.h"
#include "dlg.h" /* required by wtools.h */
#include "widget.h" /* required by wtools.h */
#include "wtools.h" /* listbox */
#include "command.h" /* for input_w */
#include "win.h" /* do_exit_ca_mode */
#include "layout.h" /* get_current/other_type */
#include "ext.h" /* regex_command */
#include "view.h" /* view */
#include "key.h" /* get_key_code */
#include "help.h" /* interactive_display */
#include "fs.h"
#include "boxes.h" /* cd_dialog */
#include "color.h"
#include "user.h"
#include "setup.h"
#include "x.h"
#include "profile.h"
#define MIDNIGHT
#ifdef USE_INTERNAL_EDIT
extern int edit (const char *file, int line);
#endif
#include "../vfs/vfs.h"
#define WANT_WIDGETS
#include "main.h" /* global variables, global functions */
#ifndef MAP_FILE
# define MAP_FILE 0
#endif
#ifdef HAVE_TK
# include "tkscreen.h"
#endif
/* If set and you don't have subshell support,then C-o will give you a shell */
int output_starts_shell = 0;
/* Source routing destination */
int source_route = 0;
/* If set, use the builtin editor */
int use_internal_edit = 1;
/* Ugly hack in order to distinguish between left and right panel in menubar */
int is_right;
#define MENU_PANEL_IDX (is_right ? 1 : 0)
#ifndef PORT_HAS_FILTER_CHANGED
# define x_filter_changed(p)
#endif
/* This is used since the parameter panel on some of the commands */
/* defined in this file may receive a 0 parameter if they are invoked */
/* The drop down menu */
WPanel *get_a_panel (WPanel *panel)
{
if (panel)
return panel;
if (get_current_type () == view_listing){
return cpanel;
} else
return other_panel;
}
/* view_file (filename, normal, internal)
*
* Inputs:
* filename: The file name to view
* plain_view: If set does not do any fancy pre-processing (no filtering) and
* always invokes the internal viewer.
* internal: If set uses the internal viewer, otherwise an external viewer.
*/
int view_file_at_line (char *filename, int plain_view, int internal, int start_line)
{
static char *viewer = 0;
int move_dir = 0;
if (plain_view) {
int changed_hex_mode = 0;
int changed_nroff_flag = 0;
int changed_magic_flag = 0;
altered_hex_mode = 0;
altered_nroff_flag = 0;
altered_magic_flag = 0;
if (default_hex_mode)
changed_hex_mode = 1;
if (default_nroff_flag)
changed_nroff_flag = 1;
if (default_magic_flag)
changed_magic_flag = 1;
default_hex_mode = 0;
default_nroff_flag = 0;
default_magic_flag = 0;
view (0, filename, &move_dir, start_line);
if (changed_hex_mode && !altered_hex_mode)
default_hex_mode = 1;
if (changed_nroff_flag && !altered_nroff_flag)
default_nroff_flag = 1;
if (changed_magic_flag && !altered_magic_flag)
default_magic_flag = 1;
repaint_screen ();
return move_dir;
}
if (internal){
char view_entry [32];
if (start_line != 0)
sprintf (view_entry, "View:%d", start_line);
else
strcpy (view_entry, "View");
if (!regex_command (filename, view_entry, NULL, &move_dir)){
view (0, filename, &move_dir, start_line);
repaint_screen ();
}
} else {
char *localcopy;
if (!viewer){
viewer = getenv ("PAGER");
if (!viewer)
viewer = "view";
}
/* The file may be a non local file, get a copy */
if (!vfs_file_is_local (filename)){
localcopy = mc_getlocalcopy (filename);
if (localcopy == NULL){
message (1, MSG_ERROR, _(" Can not fetch a local copy of %s "), filename);
return 0;
}
execute_internal (viewer, localcopy);
mc_ungetlocalcopy (filename, localcopy, 0);
} else
execute_internal (viewer, filename);
}
return move_dir;
}
int
view_file (char *filename, int plain_view, int internal)
{
return view_file_at_line (filename, plain_view, internal, 0);
}
/* scan_for_file (panel, idx, direction)
*
* Inputs:
* panel: pointer to the panel on which we operate
* idx: starting file.
* direction: 1, or -1
*/
static int scan_for_file (WPanel *panel, int idx, int direction)
{
int i = idx + direction;
while (i != idx){
if (i < 0)
i = panel->count - 1;
if (i == panel->count)
i = 0;
if (!S_ISDIR (panel->dir.list [i].buf.st_mode))
return i;
i += direction;
}
return i;
}
/* do_view: Invoked as the F3/F13 key. */
static void do_view_cmd (WPanel *panel, int normal)
{
int dir, file_idx;
panel = get_a_panel (panel);
/* Directories are viewed by changing to them */
if (S_ISDIR (selection (panel)->buf.st_mode) ||
link_isdir (selection (panel))){
if (confirm_view_dir && (panel->marked || panel->dirs_marked)){
if (query_dialog (_(" CD "), _("Files tagged, want to cd?"),
0, 2, _("&Yes"), _("&No")) == 1){
return;
}
}
do_cd (selection (panel)->fname, cd_exact);
return;
}
file_idx = panel->selected;
while (1) {
char *filename;
filename = panel->dir.list [file_idx].fname;
dir = view_file (filename, normal, use_internal_view);
if (dir == 0)
break;
file_idx = scan_for_file (panel, file_idx, dir);
}
}
void view_cmd (WPanel *panel)
{
do_view_cmd (panel, 0);
}
void view_simple_cmd (WPanel *panel)
{
do_view_cmd (panel, 1);
}
void filtered_view_cmd (WPanel *panel)
{
char *command;
panel = get_a_panel (panel);
command = input_dialog (_(" Filtered view "), _(" Filter command and arguments:"),
selection (panel)->fname);
if (!command)
return;
view (command, "", 0, 0);
free (command);
}
void filtered_view_cmd_cpanel (void)
{
filtered_view_cmd (cpanel);
}
void do_edit_at_line (const char *what, int start_line)
{
static char *editor = 0;
#ifdef USE_INTERNAL_EDIT
if (use_internal_edit){
edit (what, start_line);
reread_cmd ();
return;
}
#endif
if (!editor){
editor = getenv ("EDITOR");
if (!editor)
editor = get_default_editor ();
}
execute_internal (editor, what);
reread_cmd ();
}
void
do_edit (const char *what)
{
do_edit_at_line (what, 1);
}
void edit_cmd (WPanel *panel)
{
panel = get_a_panel(panel);
if (!regex_command (selection (panel)->fname, "Edit", NULL, 0))
do_edit (selection (panel)->fname);
}
void edit_cmd_new (WPanel *panel)
{
do_edit ("");
}
void copy_cmd (void)
{
save_cwds_stat ();
if (panel_operate (cpanel, OP_COPY, NULL)){
update_panels (UP_OPTIMIZE, UP_KEEPSEL);
repaint_screen ();
}
}
void ren_cmd (void)
{
save_cwds_stat ();
if (panel_operate (cpanel, OP_MOVE, NULL)){
update_panels (UP_OPTIMIZE, UP_KEEPSEL);
repaint_screen ();
}
}
void copymove_cmd_with_default (int copy, char *thedefault)
{
save_cwds_stat ();
if (panel_operate (cpanel, copy ? OP_COPY : OP_MOVE, thedefault)){
update_panels (UP_OPTIMIZE, UP_KEEPSEL);
repaint_screen ();
}
}
void mkdir_cmd (WPanel *panel)
{
char *dir;
panel = get_a_panel (panel);
dir = input_expand_dialog (_(" Mkdir "), _(" Enter directory name:") , "");
if (!dir)
return;
save_cwds_stat ();
if (my_mkdir (dir, 0777) == 0){
update_panels (UP_OPTIMIZE, dir);
repaint_screen ();
select_item (cpanel);
free (dir);
return;
}
free (dir);
message (1, MSG_ERROR, " %s ", unix_error_string (errno));
}
void delete_cmd (void)
{
save_cwds_stat ();
if (panel_operate (cpanel, OP_DELETE, NULL)){
update_panels (UP_OPTIMIZE, UP_KEEPSEL);
repaint_screen ();
}
}
void find_cmd (void)
{
do_find ();
}
void
set_panel_filter_to (WPanel *p, char *allocated_filter_string)
{
if (p->filter){
free (p->filter);
p->filter = 0;
}
if (!(allocated_filter_string [0] == '*' && allocated_filter_string [1] == 0))
p->filter = allocated_filter_string;
else
free (allocated_filter_string);
reread_cmd ();
x_filter_changed (p);
}
/* Set a given panel filter expression */
void set_panel_filter (WPanel *p)
{
char *reg_exp;
char *x;
x = p->filter ? p->filter : easy_patterns ? "*" : ".";
reg_exp = input_dialog (_(" Filter "), _(" Set expression for filtering filenames"), x);
if (!reg_exp)
return;
set_panel_filter_to (p, reg_exp);
}
/* Invoked from the left/right menus */
void filter_cmd (void)
{
WPanel *p;
if (!SELECTED_IS_PANEL)
return;
p = MENU_PANEL;
set_panel_filter (p);
}
void reread_cmd (void)
{
int flag;
mad_check (__FILE__, __LINE__);
if (get_current_type () == view_listing &&
get_other_type () == view_listing)
flag = strcmp (cpanel->cwd, opanel->cwd) ? UP_ONLY_CURRENT : 0;
else
flag = UP_ONLY_CURRENT;
update_panels (UP_RELOAD|flag, UP_KEEPSEL);
repaint_screen ();
}
/* Panel sorting related routines */
void do_re_sort (WPanel *panel)
{
char *filename;
int i;
panel = get_a_panel (panel);
filename = strdup (selection (cpanel)->fname);
unselect_item (panel);
do_sort (&panel->dir, panel->sort_type, panel->count-1, panel->reverse, panel->case_sensitive);
panel->selected = -1;
for (i = panel->count; i; i--){
if (!strcmp (panel->dir.list [i-1].fname, filename)){
panel->selected = i-1;
break;
}
}
free (filename);
cpanel->top_file = cpanel->selected - ITEMS (cpanel)/2;
if (cpanel->top_file < 0)
cpanel->top_file = 0;
select_item (panel);
panel_update_contents (panel);
}
void reverse_selection_cmd_panel (WPanel *panel)
{
file_entry *file;
int i;
for (i = 0; i < panel->count; i++){
file = &panel->dir.list [i];
if (S_ISDIR (file->buf.st_mode))
continue;
do_file_mark (panel, i, !file->f.marked);
}
paint_panel (panel);
}
void reverse_selection_cmd (void)
{
reverse_selection_cmd_panel (cpanel);
}
void select_cmd_panel (WPanel *panel)
{
char *reg_exp, *reg_exp_t;
int i;
int c;
int dirflag = 0;
reg_exp = input_dialog (_(" Select "), "", easy_patterns ? "*" : ".");
if (!reg_exp)
return;
reg_exp_t = reg_exp;
/* Check if they specified a directory */
if (*reg_exp_t == PATH_SEP){
dirflag = 1;
reg_exp_t++;
}
if (reg_exp_t [strlen(reg_exp_t) - 1] == PATH_SEP){
dirflag = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -