-
Notifications
You must be signed in to change notification settings - Fork 331
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Multishell/Crossplatform handling of --
#1784
Comments
So this is what I found by looking at the history:
I agree that such high-level configuration options can be inflexible, and that it would be beneficial to provide a more low-level method of specifying the shell invocation. However, modifying the existing I think it might be better to introduce a new option (e.g. Click to expanddiff --git a/eval.go b/eval.go
index 23a6be5..ab8f1b0 100644
--- a/eval.go
+++ b/eval.go
@@ -368,6 +368,12 @@ func (e *setExpr) eval(app *app, args []string) {
return
}
gOpts.shellopts = strings.Split(e.val, ":")
+ case "shellcmd":
+ if e.val == "" {
+ gOpts.shellcmd = nil
+ return
+ }
+ gOpts.shellcmd = tokenize(e.val)
case "sortby":
method := sortMethod(e.val)
if !isValidSortMethod(method) {
diff --git a/opts.go b/opts.go
index 50db7b1..24d568a 100644
--- a/opts.go
+++ b/opts.go
@@ -94,6 +94,7 @@ var gOpts struct {
rulerfmt string
preserve []string
shellopts []string
+ shellcmd []string
keys map[string]expr
cmdkeys map[string]expr
cmds map[string]expr
@@ -240,6 +241,7 @@ func init() {
gOpts.rulerfmt = " %a| %p| \033[7;31m %m \033[0m| \033[7;33m %c \033[0m| \033[7;35m %s \033[0m| \033[7;34m %f \033[0m| %i/%t"
gOpts.preserve = []string{"mode"}
gOpts.shellopts = nil
+ gOpts.shellcmd = nil
gOpts.tempmarks = "'"
gOpts.numberfmt = "\033[33m"
gOpts.tagfmt = "\033[31m"
diff --git a/os.go b/os.go
index ac2d2f6..95fbe75 100644
--- a/os.go
+++ b/os.go
@@ -140,6 +140,21 @@ func shellCommand(s string, args []string) *exec.Cmd {
s = fmt.Sprintf("IFS='%s'; %s", gOpts.ifs, s)
}
+ if len(gOpts.shellcmd) > 0 {
+ var words []string
+ for _, word := range gOpts.shellcmd {
+ switch word {
+ case "$a":
+ words = append(words, args...)
+ case "$c":
+ words = append(words, s)
+ default:
+ words = append(words, word)
+ }
+ }
+ return exec.Command(words[0], words[1:]...)
+ }
+
args = append([]string{gOpts.shellflag, s, "--"}, args...)
args = append(gOpts.shellopts, args...)
Although I suppose we could just keep |
Thanks for the hint! Im going to implement it and we will see how it plays out |
I experimented a bit with Windows CMD, unfortunately it has its own way of dealing with quoted arguments and requires special handling. You can find some notes about it in the description for #1309. It might be better to implement the func shellCommand(s string, args []string) *exec.Cmd {
// Windows CMD requires special handling to deal with quoted arguments
if strings.HasPrefix(strings.ToLower(gOpts.shell), "cmd ") {
var quotedArgs []string
for _, arg := range args {
quotedArgs = append(quotedArgs, fmt.Sprintf(`"%s"`), arg)
}
cmdline := strings.ReplaceAll(gOpts.shell, "$c", s)
cmdline = strings.ReplaceAll(cmdline, "$a", strings.Join(quotedArgs, " "))
cmd := exec.Command("cmd")
cmd.SysProcAttr = &windows.SysProcAttr{CmdLine: cmdline}
return cmd
}
if strings.Contains(gOpts.shell, " ") {
var words []string
for _, word := range tokenize(gOpts.shell) {
switch word {
case "$a":
words = append(words, args...)
case "$c":
words = append(words, s)
default:
words = append(words, word)
}
}
return exec.Command(words[0], words[1:]...)
}
// original legacy configuration which uses shellopts and shellflag
args = append([]string{gOpts.shellflag, s}, args...)
args = append(gOpts.shellopts, args...)
return exec.Command(gOpts.shell, args...)
} This should work for Windows CMD: set shell 'cmd /c "$c $a"' And for PowerShell: set shell 'pwsh -CommandWithArgs $c $a' The only other suggestions I have are:
Anyway I think this is a great idea, and an improvement over the current design. Feel free to submit a PR if you get this working. |
…ndows - make `tokenize` to honor quotes - create function `firstField` to get only the first word from string - SlellCommand in os_windows.go now handles new type of gOpts.shell for example: `set shell 'cmd /c "%c %a"'` - tests for cmd.exe
I would like to reopen the discussion around the double-hyphen
--
placeholder #1606I found that when I use cygwin bash or any 'posix compliant' shell on windows, arguments to any shell command shift to the command_name
$0
because lf uses platform specific functions and doesn't add the--
placeholder on windows:Idea
My idea is to set shell as a template parameter for the entire shell invocation not just the shell path, options and args:
Than when invoking a script lf would replace placeholders for command $c and args $a inside the template
The text was updated successfully, but these errors were encountered: