aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/os/shell.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/os/shell.c')
-rw-r--r--src/nvim/os/shell.c42
1 files changed, 29 insertions, 13 deletions
diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c
index 81e15bf841..d885c8476f 100644
--- a/src/nvim/os/shell.c
+++ b/src/nvim/os/shell.c
@@ -11,7 +11,6 @@
#include "auto/config.h"
#include "klib/kvec.h"
#include "nvim/ascii.h"
-#include "nvim/buffer_defs.h"
#include "nvim/charset.h"
#include "nvim/eval.h"
#include "nvim/eval/typval_defs.h"
@@ -32,7 +31,7 @@
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/message.h"
-#include "nvim/option_defs.h"
+#include "nvim/option_vars.h"
#include "nvim/os/fs.h"
#include "nvim/os/os_defs.h"
#include "nvim/os/shell.h"
@@ -134,6 +133,8 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
#define STYLE_VIMGLOB 2 // use "vimglob", for Posix sh
#define STYLE_PRINT 3 // use "print -N", for zsh
#define STYLE_BT 4 // `cmd` expansion, execute the pattern directly
+#define STYLE_GLOBSTAR 5 // use extended shell glob for bash (this uses extended
+ // globbing functionality with globstar, needs bash > 4)
int shell_style = STYLE_ECHO;
int check_spaces;
static bool did_find_nul = false;
@@ -141,6 +142,9 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
// vimglob() function to define for Posix shell
static char *sh_vimglob_func =
"vimglob() { while [ $# -ge 1 ]; do echo \"$1\"; shift; done }; vimglob >";
+ // vimglob() function with globstar setting enabled, only for bash >= 4.X
+ static char *sh_globstar_opt =
+ "[[ ${BASH_VERSINFO[0]} -ge 4 ]] && shopt -s globstar; ";
bool is_fish_shell =
#if defined(UNIX)
@@ -190,6 +194,8 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
// If we use *zsh, "print -N" will work better than "glob".
// STYLE_VIMGLOB: NL separated
// If we use *sh*, we define "vimglob()".
+ // STYLE_GLOBSTAR: NL separated
+ // If we use *bash*, we define "vimglob() and enable globstar option".
// STYLE_ECHO: space separated.
// A shell we don't know, stay safe and use "echo".
if (num_pat == 1 && *pat[0] == '`'
@@ -203,9 +209,12 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
shell_style = STYLE_PRINT;
}
}
- if (shell_style == STYLE_ECHO
- && strstr(path_tail(p_sh), "sh") != NULL) {
- shell_style = STYLE_VIMGLOB;
+ if (shell_style == STYLE_ECHO) {
+ if (strstr(path_tail(p_sh), "bash") != NULL) {
+ shell_style = STYLE_GLOBSTAR;
+ } else if (strstr(path_tail(p_sh), "sh") != NULL) {
+ shell_style = STYLE_VIMGLOB;
+ }
}
// Compute the length of the command. We need 2 extra bytes: for the
@@ -214,6 +223,8 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
len = strlen(tempname) + 29;
if (shell_style == STYLE_VIMGLOB) {
len += strlen(sh_vimglob_func);
+ } else if (shell_style == STYLE_GLOBSTAR) {
+ len += strlen(sh_vimglob_func) + strlen(sh_globstar_opt);
}
for (i = 0; i < num_pat; i++) {
@@ -281,6 +292,9 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
STRCAT(command, "print -N >");
} else if (shell_style == STYLE_VIMGLOB) {
STRCAT(command, sh_vimglob_func);
+ } else if (shell_style == STYLE_GLOBSTAR) {
+ STRCAT(command, sh_globstar_opt);
+ STRCAT(command, sh_vimglob_func);
} else {
STRCAT(command, "echo >");
}
@@ -364,7 +378,7 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
if (!(flags & EW_SILENT)) {
msg_putchar('\n'); // clear bottom line quickly
cmdline_row = Rows - 1; // continue on last line
- msg(_(e_wildexpand));
+ msg(_(e_wildexpand), 0);
msg_start(); // don't overwrite this message
}
@@ -381,7 +395,7 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
if (fd == NULL) {
// Something went wrong, perhaps a file name with a special char.
if (!(flags & EW_SILENT)) {
- msg(_(e_wildexpand));
+ msg(_(e_wildexpand), 0);
msg_start(); // don't overwrite this message
}
xfree(tempname);
@@ -430,7 +444,9 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
p = skipwhite(p); // skip to next entry
}
// file names are separated with NL
- } else if (shell_style == STYLE_BT || shell_style == STYLE_VIMGLOB) {
+ } else if (shell_style == STYLE_BT
+ || shell_style == STYLE_VIMGLOB
+ || shell_style == STYLE_GLOBSTAR) {
buffer[len] = NUL; // make sure the buffer ends in NUL
p = buffer;
for (i = 0; *p != NUL; i++) { // count number of entries
@@ -496,7 +512,7 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
(*file)[i] = p;
// Space or NL separates
if (shell_style == STYLE_ECHO || shell_style == STYLE_BT
- || shell_style == STYLE_VIMGLOB) {
+ || shell_style == STYLE_VIMGLOB || shell_style == STYLE_GLOBSTAR) {
while (!(shell_style == STYLE_ECHO && *p == ' ')
&& *p != '\n' && *p != NUL) {
p++;
@@ -715,7 +731,7 @@ int call_shell(char *cmd, ShellOpts opts, char *extra_shell_arg)
if (p_verbose > 3) {
verbose_enter();
- smsg(_("Executing command: \"%s\""), cmd == NULL ? p_sh : cmd);
+ smsg(0, _("Executing command: \"%s\""), cmd == NULL ? p_sh : cmd);
msg_putchar('\n');
verbose_leave();
}
@@ -876,9 +892,9 @@ static int do_os_system(char **argv, const char *input, size_t len, char **outpu
// Failed, probably 'shell' is not executable.
if (!silent) {
msg_puts(_("\nshell failed to start: "));
- msg_outtrans(os_strerror(status));
+ msg_outtrans(os_strerror(status), 0);
msg_puts(": ");
- msg_outtrans(prog);
+ msg_outtrans(prog, 0);
msg_putchar('\n');
}
multiqueue_free(events);
@@ -1127,7 +1143,7 @@ static void out_data_append_to_screen(char *output, size_t *count, bool eof)
goto end;
}
- (void)msg_outtrans_len_attr(p, i, 0);
+ (void)msg_outtrans_len(p, i, 0);
p += i;
}
}