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

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