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

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