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_set_default_colors
  5. 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-2024
   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 <http://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"           /* DEFAULT_COLOR */
  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 input_colors_t command_colors;
  72 
  73 /* --------------------------------------------------------------------------------------------- */
  74 /*** file scope functions ************************************************************************/
  75 /* --------------------------------------------------------------------------------------------- */
  76 
  77 /** Handle Enter on the command line
  78  *
  79  * @param lc_cmdline string for handling
  80  * @return MSG_HANDLED on success else MSG_NOT_HANDLED
  81  */
  82 
  83 static cb_ret_t
  84 enter (WInput * lc_cmdline)
     /* [previous][next][first][last][top][bottom][index][help]  */
  85 {
  86     const char *cmd;
  87 
  88     if (!command_prompt)
  89         return MSG_HANDLED;
  90 
  91     cmd = input_get_ctext (lc_cmdline);
  92 
  93     /* Any initial whitespace should be removed at this point */
  94     while (whiteness (*cmd))
  95         cmd++;
  96 
  97     if (*cmd == '\0')
  98         return MSG_HANDLED;
  99 
 100     if (strncmp (cmd, "cd", 2) == 0 && (cmd[2] == '\0' || whitespace (cmd[2])))
 101     {
 102         cd_to (cmd + 2);
 103         input_clean (lc_cmdline);
 104         return MSG_HANDLED;
 105     }
 106     else if (strcmp (cmd, "exit") == 0)
 107     {
 108         input_assign_text (lc_cmdline, "");
 109         if (!quiet_quit_cmd ())
 110             return MSG_NOT_HANDLED;
 111     }
 112     else
 113     {
 114         GString *command;
 115         size_t i;
 116 
 117         if (!vfs_current_is_local ())
 118         {
 119             message (D_ERROR, MSG_ERROR, _("Cannot execute commands on non-local filesystems"));
 120             return MSG_NOT_HANDLED;
 121         }
 122 #ifdef ENABLE_SUBSHELL
 123         /* Check this early before we clean command line
 124          * (will be checked again by shell_execute) */
 125         if (mc_global.tty.use_subshell && subshell_state != INACTIVE)
 126         {
 127             message (D_ERROR, MSG_ERROR, _("The shell is already running a command"));
 128             return MSG_NOT_HANDLED;
 129         }
 130 #endif
 131         command = g_string_sized_new (32);
 132 
 133         for (i = 0; cmd[i] != '\0'; i++)
 134         {
 135             if (cmd[i] != '%')
 136                 g_string_append_c (command, cmd[i]);
 137             else
 138             {
 139                 char *s;
 140 
 141                 s = expand_format (NULL, cmd[++i], TRUE);
 142                 if (s != NULL)
 143                 {
 144                     g_string_append (command, s);
 145                     g_free (s);
 146                 }
 147             }
 148         }
 149 
 150         input_clean (lc_cmdline);
 151         shell_execute (command->str, 0);
 152         g_string_free (command, TRUE);
 153 
 154 #ifdef ENABLE_SUBSHELL
 155         if ((quit & SUBSHELL_EXIT) != 0)
 156         {
 157             if (quiet_quit_cmd ())
 158                 return MSG_HANDLED;
 159 
 160             quit = 0;
 161             /* restart subshell */
 162             if (mc_global.tty.use_subshell)
 163                 init_subshell ();
 164         }
 165 
 166         if (mc_global.tty.use_subshell)
 167             do_load_prompt ();
 168 #endif
 169     }
 170     return MSG_HANDLED;
 171 }
 172 
 173 /* --------------------------------------------------------------------------------------------- */
 174 
 175 /**
 176  * Default command line callback
 177  *
 178  * @param w Widget object
 179  * @param msg message for handling
 180  * @param parm extra parameter such as key code
 181  *
 182  * @return MSG_NOT_HANDLED on fail else MSG_HANDLED
 183  */
 184 
 185 static cb_ret_t
 186 command_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *data)
     /* [previous][next][first][last][top][bottom][index][help]  */
 187 {
 188     switch (msg)
 189     {
 190     case MSG_KEY:
 191         /* Special case: we handle the enter key */
 192         if (parm == '\n')
 193             return enter (INPUT (w));
 194         MC_FALLTHROUGH;
 195 
 196     default:
 197         return input_callback (w, sender, msg, parm, data);
 198     }
 199 }
 200 
 201 /* --------------------------------------------------------------------------------------------- */
 202 /*** public functions ****************************************************************************/
 203 /* --------------------------------------------------------------------------------------------- */
 204 
 205 WInput *
 206 command_new (int y, int x, int cols)
     /* [previous][next][first][last][top][bottom][index][help]  */
 207 {
 208     WInput *cmd;
 209     Widget *w;
 210 
 211     cmd = input_new (y, x, command_colors, cols, "", "cmdline",
 212                      INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_VARIABLES | INPUT_COMPLETE_USERNAMES
 213                      | INPUT_COMPLETE_HOSTNAMES | INPUT_COMPLETE_CD | INPUT_COMPLETE_COMMANDS |
 214                      INPUT_COMPLETE_SHELL_ESC);
 215     w = WIDGET (cmd);
 216     /* Don't set WOP_SELECTABLE up, otherwise panels will be unselected */
 217     widget_set_options (w, WOP_SELECTABLE, FALSE);
 218     /* Add our hooks */
 219     w->callback = command_callback;
 220 
 221     return cmd;
 222 }
 223 
 224 /* --------------------------------------------------------------------------------------------- */
 225 /**
 226  * Set colors for the command line.
 227  */
 228 
 229 void
 230 command_set_default_colors (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 231 {
 232     command_colors[WINPUTC_MAIN] = DEFAULT_COLOR;
 233     command_colors[WINPUTC_MARK] = COMMAND_MARK_COLOR;
 234     command_colors[WINPUTC_UNCHANGED] = DEFAULT_COLOR;
 235     command_colors[WINPUTC_HISTORY] = COMMAND_HISTORY_COLOR;
 236 }
 237 
 238 /* --------------------------------------------------------------------------------------------- */
 239 /**
 240  * Insert quoted text in input line.  The function is meant for the
 241  * command line, so the percent sign is quoted as well.
 242  *
 243  * @param in WInput object
 244  * @param text string for insertion
 245  * @param insert_extra_space add extra space
 246  */
 247 
 248 void
 249 command_insert (WInput * in, const char *text, gboolean insert_extra_space)
     /* [previous][next][first][last][top][bottom][index][help]  */
 250 {
 251     char *quoted_text;
 252 
 253     quoted_text = name_quote (text, TRUE);
 254     if (quoted_text != NULL)
 255     {
 256         input_insert (in, quoted_text, insert_extra_space);
 257         g_free (quoted_text);
 258     }
 259 }
 260 
 261 /* --------------------------------------------------------------------------------------------- */

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