Manual pages: mcmcdiffmceditmcview

root/src/filemanager/command.c

/* [previous][next][first][last][top][bottom][index][help]  */

DEFINITIONS

This source file includes following definitions.
  1. enter
  2. command_callback
  3. command_new
  4. command_insert

   1 /*
   2    Command line widget.
   3    This widget is derived from the WInput widget, it's used to cope
   4    with all the magic of the command input line, we depend on some
   5    help from the program's callback.
   6 
   7    Copyright (C) 1995-2025
   8    Free Software Foundation, Inc.
   9 
  10    Written by:
  11    Slava Zanko <slavazanko@gmail.com>, 2013
  12    Andrew Borodin <aborodin@vmail.ru>, 2011-2022
  13 
  14    This file is part of the Midnight Commander.
  15 
  16    The Midnight Commander is free software: you can redistribute it
  17    and/or modify it under the terms of the GNU General Public License as
  18    published by the Free Software Foundation, either version 3 of the License,
  19    or (at your option) any later version.
  20 
  21    The Midnight Commander is distributed in the hope that it will be useful,
  22    but WITHOUT ANY WARRANTY; without even the implied warranty of
  23    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  24    GNU General Public License for more details.
  25 
  26    You should have received a copy of the GNU General Public License
  27    along with this program.  If not, see <https://www.gnu.org/licenses/>.
  28  */
  29 
  30 /** \file command.c
  31  *  \brief Source: command line widget
  32  */
  33 
  34 #include <config.h>
  35 
  36 #include <stdlib.h>
  37 #include <string.h>
  38 
  39 #include "lib/global.h"
  40 #include "lib/vfs/vfs.h"  // vfs_current_is_local()
  41 #include "lib/skin.h"
  42 #include "lib/util.h"  // whitespace()
  43 #include "lib/widget.h"
  44 
  45 #include "src/setup.h"  // quit
  46 #ifdef ENABLE_SUBSHELL
  47 #include "src/subshell/subshell.h"
  48 #endif
  49 #include "src/execute.h"   // shell_execute()
  50 #include "src/usermenu.h"  // expand_format()
  51 
  52 #include "filemanager.h"  // quiet_quit_cmd(), layout.h
  53 #include "cd.h"           // cd_to()
  54 
  55 #include "command.h"
  56 
  57 /*** global variables ****************************************************************************/
  58 
  59 /* This holds the command line */
  60 WInput *cmdline;
  61 
  62 /*** file scope macro definitions ****************************************************************/
  63 
  64 /*** file scope type declarations ****************************************************************/
  65 
  66 /*** forward declarations (file scope functions) *************************************************/
  67 
  68 /*** file scope variables ************************************************************************/
  69 
  70 /* Color styles command line */
  71 static const input_colors_t command_colors = {
  72     [INPUT_COLOR_MAIN] = CORE_COMMANDLINE_COLOR,
  73     [INPUT_COLOR_MARK] = CORE_COMMANDLINE_MARK_COLOR,
  74     [INPUT_COLOR_UNCHANGED] = CORE_COMMANDLINE_COLOR,
  75     [INPUT_COLOR_HISTORY] = CORE_COMMAND_HISTORY_COLOR,
  76 };
  77 
  78 /* --------------------------------------------------------------------------------------------- */
  79 /*** file scope functions ************************************************************************/
  80 /* --------------------------------------------------------------------------------------------- */
  81 
  82 /** Handle Enter on the command line
  83  *
  84  * @param lc_cmdline string for handling
  85  * @return MSG_HANDLED on success else MSG_NOT_HANDLED
  86  */
  87 
  88 static cb_ret_t
  89 enter (WInput *lc_cmdline)
     /* [previous][next][first][last][top][bottom][index][help]  */
  90 {
  91     const char *cmd;
  92 
  93     if (!command_prompt)
  94         return MSG_HANDLED;
  95 
  96     cmd = input_get_ctext (lc_cmdline);
  97 
  98     // Any initial whitespace should be removed at this point
  99     while (whiteness (*cmd))
 100         cmd++;
 101 
 102     if (*cmd == '\0')
 103         return MSG_HANDLED;
 104 
 105     if (strncmp (cmd, "cd", 2) == 0 && (cmd[2] == '\0' || whitespace (cmd[2])))
 106     {
 107         cd_to (cmd + 2);
 108         input_clean (lc_cmdline);
 109         return MSG_HANDLED;
 110     }
 111     else if (strcmp (cmd, "exit") == 0)
 112     {
 113         input_assign_text (lc_cmdline, "");
 114         if (!quiet_quit_cmd (FALSE))
 115             return MSG_NOT_HANDLED;
 116     }
 117     else
 118     {
 119         GString *command;
 120         size_t i;
 121 
 122         if (!vfs_current_is_local ())
 123         {
 124             message (D_ERROR, MSG_ERROR, _ ("Cannot execute commands on non-local filesystems"));
 125             return MSG_NOT_HANDLED;
 126         }
 127 #ifdef ENABLE_SUBSHELL
 128         /* Check this early before we clean command line
 129          * (will be checked again by shell_execute) */
 130         if (mc_global.tty.use_subshell && subshell_state != INACTIVE)
 131         {
 132             message (D_ERROR, MSG_ERROR, _ ("The shell is already running a command"));
 133             return MSG_NOT_HANDLED;
 134         }
 135 #endif
 136         command = g_string_sized_new (32);
 137 
 138         for (i = 0; cmd[i] != '\0'; i++)
 139         {
 140             if (cmd[i] != '%')
 141                 g_string_append_c (command, cmd[i]);
 142             else
 143             {
 144                 char *s;
 145 
 146                 s = expand_format (NULL, cmd[++i], TRUE);
 147                 if (s != NULL)
 148                 {
 149                     g_string_append (command, s);
 150                     g_free (s);
 151                 }
 152             }
 153         }
 154 
 155         input_clean (lc_cmdline);
 156         shell_execute (command->str, 0);
 157         g_string_free (command, TRUE);
 158 
 159 #ifdef ENABLE_SUBSHELL
 160         if ((quit & SUBSHELL_EXIT) != 0)
 161         {
 162             if (quiet_quit_cmd (FALSE))
 163                 return MSG_HANDLED;
 164 
 165             quit = 0;
 166             // restart subshell
 167             if (mc_global.tty.use_subshell)
 168                 init_subshell ();
 169         }
 170 
 171         if (mc_global.tty.use_subshell)
 172             do_load_prompt ();
 173 #endif
 174     }
 175     return MSG_HANDLED;
 176 }
 177 
 178 /* --------------------------------------------------------------------------------------------- */
 179 
 180 /**
 181  * Default command line callback
 182  *
 183  * @param w Widget object
 184  * @param msg message for handling
 185  * @param parm extra parameter such as key code
 186  *
 187  * @return MSG_NOT_HANDLED on fail else MSG_HANDLED
 188  */
 189 
 190 static cb_ret_t
 191 command_callback (Widget *w, Widget *sender, widget_msg_t msg, int parm, void *data)
     /* [previous][next][first][last][top][bottom][index][help]  */
 192 {
 193     switch (msg)
 194     {
 195     case MSG_KEY:
 196         // Special case: we handle the enter key
 197         if (parm == '\n')
 198             return enter (INPUT (w));
 199         MC_FALLTHROUGH;
 200 
 201     default:
 202         return input_callback (w, sender, msg, parm, data);
 203     }
 204 }
 205 
 206 /* --------------------------------------------------------------------------------------------- */
 207 /*** public functions ****************************************************************************/
 208 /* --------------------------------------------------------------------------------------------- */
 209 
 210 WInput *
 211 command_new (int y, int x, int cols)
     /* [previous][next][first][last][top][bottom][index][help]  */
 212 {
 213     WInput *cmd;
 214     Widget *w;
 215 
 216     cmd = input_new (y, x, command_colors, cols, "", "cmdline",
 217                      INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_VARIABLES | INPUT_COMPLETE_USERNAMES
 218                          | INPUT_COMPLETE_HOSTNAMES | INPUT_COMPLETE_CD | INPUT_COMPLETE_COMMANDS
 219                          | INPUT_COMPLETE_SHELL_ESC);
 220     w = WIDGET (cmd);
 221     // Don't set WOP_SELECTABLE up, otherwise panels will be unselected
 222     widget_set_options (w, WOP_SELECTABLE, FALSE);
 223     // Add our hooks
 224     w->callback = command_callback;
 225 
 226     return cmd;
 227 }
 228 
 229 /* --------------------------------------------------------------------------------------------- */
 230 /**
 231  * Insert quoted text in input line.  The function is meant for the
 232  * command line, so the percent sign is quoted as well.
 233  *
 234  * @param in WInput object
 235  * @param text string for insertion
 236  * @param insert_extra_space add extra space
 237  */
 238 
 239 void
 240 command_insert (WInput *in, const char *text, gboolean insert_extra_space)
     /* [previous][next][first][last][top][bottom][index][help]  */
 241 {
 242     char *quoted_text;
 243 
 244     quoted_text = name_quote (text, TRUE);
 245     if (quoted_text != NULL)
 246     {
 247         input_insert (in, quoted_text, insert_extra_space);
 248         g_free (quoted_text);
 249     }
 250 }
 251 
 252 /* --------------------------------------------------------------------------------------------- */

/* [previous][next][first][last][top][bottom][index][help]  */