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.
7 Copyright (C) 1995-2024
8 Free Software Foundation, Inc.
11 Slava Zanko <slavazanko@gmail.com>, 2013
12 Andrew Borodin <aborodin@vmail.ru>, 2011-2022
14 This file is part of the Midnight Commander.
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.
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.
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/>.
31 * \brief Source: command line widget
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"
45 #include "src/setup.h" /* quit */
46 #ifdef ENABLE_SUBSHELL
47 #include "src/subshell/subshell.h"
49 #include "src/execute.h" /* shell_execute() */
50 #include "src/usermenu.h" /* expand_format() */
52 #include "filemanager.h" /* quiet_quit_cmd(), layout.h */
53 #include "cd.h" /* cd_to() */
57 /*** global variables ****************************************************************************/
59 /* This holds the command line */
62 /*** file scope macro definitions ****************************************************************/
64 /*** file scope type declarations ****************************************************************/
66 /*** forward declarations (file scope functions) *************************************************/
68 /*** file scope variables ************************************************************************/
70 /* Color styles command line */
71 static input_colors_t command_colors
;
73 /* --------------------------------------------------------------------------------------------- */
74 /*** file scope functions ************************************************************************/
75 /* --------------------------------------------------------------------------------------------- */
77 /** Handle Enter on the command line
79 * @param lc_cmdline string for handling
80 * @return MSG_HANDLED on success else MSG_NOT_HANDLED
84 enter (WInput
*lc_cmdline
)
91 cmd
= input_get_ctext (lc_cmdline
);
93 /* Any initial whitespace should be removed at this point */
94 while (whiteness (*cmd
))
100 if (strncmp (cmd
, "cd", 2) == 0 && (cmd
[2] == '\0' || whitespace (cmd
[2])))
103 input_clean (lc_cmdline
);
106 else if (strcmp (cmd
, "exit") == 0)
108 input_assign_text (lc_cmdline
, "");
109 if (!quiet_quit_cmd ())
110 return MSG_NOT_HANDLED
;
117 if (!vfs_current_is_local ())
119 message (D_ERROR
, MSG_ERROR
, _("Cannot execute commands on non-local filesystems"));
120 return MSG_NOT_HANDLED
;
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
)
127 message (D_ERROR
, MSG_ERROR
, _("The shell is already running a command"));
128 return MSG_NOT_HANDLED
;
131 command
= g_string_sized_new (32);
133 for (i
= 0; cmd
[i
] != '\0'; i
++)
136 g_string_append_c (command
, cmd
[i
]);
141 s
= expand_format (NULL
, cmd
[++i
], TRUE
);
144 g_string_append (command
, s
);
150 input_clean (lc_cmdline
);
151 shell_execute (command
->str
, 0);
152 g_string_free (command
, TRUE
);
154 #ifdef ENABLE_SUBSHELL
155 if ((quit
& SUBSHELL_EXIT
) != 0)
157 if (quiet_quit_cmd ())
161 /* restart subshell */
162 if (mc_global
.tty
.use_subshell
)
166 if (mc_global
.tty
.use_subshell
)
173 /* --------------------------------------------------------------------------------------------- */
176 * Default command line callback
178 * @param w Widget object
179 * @param msg message for handling
180 * @param parm extra parameter such as key code
182 * @return MSG_NOT_HANDLED on fail else MSG_HANDLED
186 command_callback (Widget
*w
, Widget
*sender
, widget_msg_t msg
, int parm
, void *data
)
191 /* Special case: we handle the enter key */
193 return enter (INPUT (w
));
197 return input_callback (w
, sender
, msg
, parm
, data
);
201 /* --------------------------------------------------------------------------------------------- */
202 /*** public functions ****************************************************************************/
203 /* --------------------------------------------------------------------------------------------- */
206 command_new (int y
, int x
, int cols
)
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
);
216 /* Don't set WOP_SELECTABLE up, otherwise panels will be unselected */
217 widget_set_options (w
, WOP_SELECTABLE
, FALSE
);
219 w
->callback
= command_callback
;
224 /* --------------------------------------------------------------------------------------------- */
226 * Set colors for the command line.
230 command_set_default_colors (void)
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
;
238 /* --------------------------------------------------------------------------------------------- */
240 * Insert quoted text in input line. The function is meant for the
241 * command line, so the percent sign is quoted as well.
243 * @param in WInput object
244 * @param text string for insertion
245 * @param insert_extra_space add extra space
249 command_insert (WInput
*in
, const char *text
, gboolean insert_extra_space
)
253 quoted_text
= name_quote (text
, TRUE
);
254 if (quoted_text
!= NULL
)
256 input_insert (in
, quoted_text
, insert_extra_space
);
257 g_free (quoted_text
);
261 /* --------------------------------------------------------------------------------------------- */