📄 main.c
字号:
return i;
}
return -1;
}
/* Called by parse_control_file */
static void select_by_index (WPanel *panel, int i)
{
if (i >= panel->count)
return;
unselect_item (panel);
panel->selected = i;
#ifndef HAVE_X
while (panel->selected - panel->top_file >= ITEMS (panel)){
/* Scroll window half screen */
panel->top_file += ITEMS (panel)/2;
paint_dir (panel);
select_item (panel);
}
while (panel->selected < panel->top_file){
/* Scroll window half screen */
panel->top_file -= ITEMS (panel)/2;
if (panel->top_file < 0) panel->top_file = 0;
paint_dir (panel);
}
#endif
select_item (panel);
}
/* Called by my_system
No error reporting, just exits on the first sign of trouble */
static void parse_control_file (void)
{
char *data, *current;
WPanel *panel;
file_entry *list;
int i;
FILE *file;
struct stat s;
if ((file = fopen (control_file, "r")) == NULL){
return;
}
/* Use of fstat prevents race conditions */
if (fstat (fileno (file), &s) != 0){
fclose (file);
return;
}
#ifndef OS2_NT
/* Security: Check that the user owns the control file to prevent
other users from playing tricks on him/her. */
if (s.st_uid != getuid ()){
fclose (file);
return;
}
#endif
data = (char *) xmalloc (s.st_size+1, "main, parse_control_file");
if (!data){
fclose (file);
return;
}
if (s.st_size != fread (data, 1, s.st_size, file)){
free (data);
fclose (file);
return;
}
data [s.st_size] = 0;
fclose (file);
/* The Control file has now been loaded to memory -> start parsing. */
current = strtok (data, " \t\n");
while (current && *current){
if (isupper (*current)){
if (get_other_type () != view_listing)
break;
else
panel = other_panel;
} else
panel = cpanel;
list = panel->dir.list;
*current = tolower (*current);
if (strcmp (current, "clear_tags") == 0){
unmark_files (panel);
} else if (strcmp (current, "tag") == 0){
i = index_by_name (list, panel->count);
if (i >= 0) {
do_file_mark (panel, i, 1);
}
} else if (strcmp (current, "untag") == 0){
i = index_by_name (list, panel->count);
if (i >= 0){
do_file_mark (panel, i, 0);
}
} else if (strcmp (current, "select") == 0){
i = index_by_name (list, panel->count);
if (i >= 0){
select_by_index (panel, i);
}
} else if (strcmp (current, "change_panel") == 0){
change_panel ();
} else if (strcmp (current, "cd") == 0){
int change = 0;
current = strtok (NULL, " \t\n");
if (!current) break;
if (cpanel != panel){
change_panel ();
change = 1;
}
do_cd (current, cd_parse_command);
if (change)
change_panel ();
} else {
/* Unknown command -> let's give up */
break;
}
current = strtok (NULL, " \t\n");
}
free (data);
paint_panel (cpanel);
paint_panel (opanel);
}
#else
#define parse_control_file()
#endif /* WANT_PARSE */
/* Sets up the terminal before executing a program */
static void
pre_exec (void)
{
use_dash (0);
edition_pre_exec ();
}
/* Save current stat of directories to avoid reloading the panels */
/* when no modifications have taken place */
void
save_cwds_stat (void)
{
if (fast_reload){
mc_stat (cpanel->cwd, &(cpanel->dir_stat));
if (get_other_type () == view_listing)
mc_stat (opanel->cwd, &(opanel->dir_stat));
}
}
#ifdef HAVE_SUBSHELL_SUPPORT
void
do_possible_cd (char *new_dir)
{
if (!do_cd (new_dir, cd_exact))
message (1, _(" Warning "),
_(" The Commander can't change to the directory that \n"
" the subshell claims you are in. Perhaps you have \n"
" deleted your working directory, or given yourself \n"
" extra access permissions with the \"su\" command? "));
}
void
do_update_prompt ()
{
if (update_prompt){
printf ("%s", subshell_prompt);
fflush (stdout);
update_prompt = 0;
}
}
#endif
void
restore_console (void)
{
handle_console (CONSOLE_RESTORE);
}
void
exec_shell ()
{
do_execute (shell, 0, 0);
}
void
do_execute (const char *shell, const char *command, int flags)
{
#ifdef HAVE_SUBSHELL_SUPPORT
char *new_dir = NULL;
#endif
#ifdef USE_VFS
char *old_vfs_dir = 0;
if (!vfs_current_is_local ())
old_vfs_dir = strdup (vfs_get_current_dir ());
#endif
save_cwds_stat ();
pre_exec ();
if (console_flag)
restore_console ();
#ifndef __os2__
unlink (control_file);
#endif
if (!use_subshell && !(flags & EXECUTE_INTERNAL)){
printf ("%s%s%s\n", last_paused ? "\r\n":"", prompt, command);
last_paused = 0;
}
#ifdef HAVE_SUBSHELL_SUPPORT
if (use_subshell && !(flags & EXECUTE_INTERNAL)){
do_update_prompt ();
/* We don't care if it died, higher level takes care of this */
#ifdef USE_VFS
invoke_subshell (command, VISIBLY, old_vfs_dir ? 0 : &new_dir);
#else
invoke_subshell (command, VISIBLY, &new_dir);
#endif
} else
#endif
my_system (flags, shell, command);
#ifndef HAVE_GNOME
if (!(flags & EXECUTE_INTERNAL)){
if ((pause_after_run == pause_always ||
(pause_after_run == pause_on_dumb_terminals &&
!xterm_flag && !console_flag)) && !quit){
printf (_("Press any key to continue..."));
last_paused = 1;
fflush (stdout);
mc_raw_mode ();
xgetch ();
}
if (console_flag){
if (output_lines && keybar_visible) {
putchar('\n');
fflush(stdout);
}
}
}
#endif
if (console_flag)
handle_console (CONSOLE_SAVE);
edition_post_exec ();
#ifdef HAVE_SUBSHELL_SUPPORT
if (new_dir)
do_possible_cd (new_dir);
#endif
#ifdef USE_VFS
if (old_vfs_dir){
mc_chdir (old_vfs_dir);
free (old_vfs_dir);
}
#endif
update_panels (UP_OPTIMIZE, UP_KEEPSEL);
parse_control_file ();
#ifndef __os2__
unlink (control_file);
#endif
do_refresh ();
use_dash (TRUE);
}
/* Executes a command */
void
shell_execute (char *command, int flags)
{
#ifdef HAVE_SUBSHELL_SUPPORT
if (use_subshell)
if (subshell_state == INACTIVE || force_subshell_execution)
do_execute (shell, command, flags | EXECUTE_AS_SHELL);
else
message (1, MSG_ERROR, _(" The shell is already running a command "));
else
#endif
do_execute (shell, command, flags | EXECUTE_AS_SHELL);
}
void
execute (char *command)
{
shell_execute (command, 0);
}
void
change_panel (void)
{
free_completions (input_w (cmdline));
dlg_one_down (midnight_dlg);
}
static int
quit_cmd_internal (int quiet)
{
int q = quit;
if (quiet || !confirm_exit){
q = 1;
} else {
if (query_dialog (_(" The Midnight Commander "),
_(" Do you really want to quit the Midnight Commander? "),
0, 2, _("&Yes"), _("&No")) == 0)
q = 1;
}
if (q){
#ifdef HAVE_SUBSHELL_SUPPORT
if (!use_subshell)
midnight_dlg->running = 0;
else
if ((q = exit_subshell ()))
#endif
midnight_dlg->running = 0;
}
if (q)
quit |= 1;
return quit;
}
int quit_cmd (void)
{
quit_cmd_internal (0);
return quit;
}
int quiet_quit_cmd (void)
{
print_last_revert = 1;
quit_cmd_internal (1);
return quit;
}
/*
* Touch window and refresh window functions
*/
/* This routine untouches the first line on both panels in order */
/* to avoid the refreshing the menu bar */
#ifdef HAVE_X
void
untouch_bar (void)
{
}
void
repaint_screen (void)
{
do_refresh ();
}
#else /* HAVE_X */
void
untouch_bar (void)
{
do_refresh ();
}
void
repaint_screen (void)
{
do_refresh ();
mc_refresh ();
}
#endif /* HAVE_X */
/* Wrapper for do_subshell_chdir, check for availability of subshell */
void
subshell_chdir (char *directory)
{
#ifdef HAVE_SUBSHELL_SUPPORT
if (use_subshell){
if (vfs_current_is_local ())
do_subshell_chdir (directory, 0, 1);
}
#endif
}
void
directory_history_add (WPanel * panel, char *s)
{
if (!panel->dir_history) {
panel->dir_history = malloc (sizeof (Hist));
memset (panel->dir_history, 0, sizeof (Hist));
panel->dir_history->text = strdup (s);
return;
}
if (!strcmp (panel->dir_history->text, s))
return;
if (panel->dir_history->next) {
if (panel->dir_history->next->text) {
free (panel->dir_history->next->text);
panel->dir_history->next->text = 0;
}
} else {
panel->dir_history->next = malloc (sizeof (Hist));
memset (panel->dir_history->next, 0, sizeof (Hist));
panel->dir_history->next->prev = panel->dir_history;
}
panel->dir_history = panel->dir_history->next;
panel->dir_history->text = strdup (s);
panel_update_marks (panel);
}
/* Changes the current panel directory */
int
_do_panel_cd (WPanel *panel, char *new_dir, enum cd_enum cd_type)
{
char *directory, *olddir;
char temp [MC_MAXPATHLEN];
#ifdef USE_VFS
vfs *oldvfs;
vfsid oldvfsid;
struct vfs_stamping *parent;
#endif
olddir = strdup (panel->cwd);
/* Convert *new_path to a suitable pathname, handle ~user */
if (cd_type == cd_parse_command){
while (*new_dir == ' ')
new_dir++;
if (!strcmp (new_dir, "-")){
strcpy (temp, panel->lwd);
new_dir = temp;
}
}
directory = *new_dir ? new_dir : home_dir;
if (mc_chdir (directory) == -1){
strcpy (panel->cwd, olddir);
free (olddir);
return 0;
}
/* Success: save previous directory, shutdown status of previous dir */
strcpy (panel->lwd, olddir);
free_completions (input_w (cmdline));
mc_get_current_wd (panel->cwd, sizeof (panel->cwd) - 2);
#ifdef USE_VFS
oldvfs = vfs_type (olddir);
oldvfsid = vfs_ncs_getid (oldvfs, olddir, &parent);
vfs_add_noncurrent_stamps (oldvfs, oldvfsid, parent);
vfs_rm_parents (parent);
#endif
free (olddir);
subshell_chdir (panel->cwd);
/* Reload current panel */
clean_dir (&panel->dir, panel->count);
panel->count = do_load_dir (&panel->dir, panel->sort_type,
panel->reverse, panel->case_sensitive, panel->filter);
panel->top_file = 0;
panel->selected = 0;
panel->marked = 0;
panel->dirs_marked = 0;
panel->total = 0;
panel->searching = 0;
cd_try_to_select (panel);
load_hint ();
panel_update_contents (panel);
return 1;
}
int
do_panel_cd (WPanel *panel, char *new_dir, enum cd_enum cd_type)
{
int r;
r = _do_panel_cd (panel, new_dir, cd_type);
if (r)
directory_history_add (cpanel, cpanel->cwd);
return r;
}
int
do_cd (char *new_dir, enum cd_enum exact)
{
return (do_panel_cd (cpanel, new_dir, exact));
}
void
directory_history_next (WPanel * panel)
{
if (!panel->dir_history->next)
return;
if (_do_panel_cd (panel, panel->dir_history->next->text, cd_exact))
panel->dir_history = panel->dir_history->next;
panel_update_marks (panel);
}
void
directory_history_prev (WPanel * panel)
{
if (!panel->dir_history->prev)
return;
if (_do_panel_cd (panel, panel->dir_history->prev->text, cd_exact))
panel->dir_history = panel->dir_history->prev;
panel_update_marks (panel);
}
void
directory_history_list (WPanel * panel)
{
char *s;
/* must be at least two to show a history */
if (panel->dir_history) {
if (panel->dir_history->prev || panel->dir_history->next) {
s = show_hist (panel->dir_history, panel->widget.x, panel->widget.y);
if (s) {
int r;
r = _do_panel_cd (panel, s, cd_exact);
if (r)
directory_history_add (panel, panel->cwd);
free (s);
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -