Comments (3)
So this is what I found by looking at the history:
shellopts
was introduced because of #102, to allow specifying additional options when invoking the shell (e.g.-f
to disable globbing).shellflag
was introduced because of #597, to override the default-c
option (/c
for Windows), primarily to allow the use of other shells in Windows.
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 shell
configuration option is a breaking change, and given that the shell is a core feature of lf
, I am not sure if this is a good idea.
I think it might be better to introduce a new option (e.g. shellcmd
) instead, implemented like below (similar changes required for os_windows.go
):
Click to expand
diff --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 shell
as a string option and apply the new handling logic based on whether it consists of a single word or not. I could be convinced either way on this.
from lf.
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 shell
option as a string value, something like below:
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:
- Whether to implement this as a new command, or just use the existing
shell
command (must be backwards compatible) - Whether to use short names for the placeholders (
$c
and$a
) or something longer like$cmd
and$args
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.
from lf.
Thanks for the hint! Im going to implement it and we will see how it plays out
from lf.
Related Issues (20)
- lf image preview flickering HOT 5
- Duplicate icon
- Mouse buttons don't work
- Preview window colors HOT 14
- Yank path w/filename, filename, and file (As in Ranger) in Powershell HOT 6
- [QUESTION] Paste with overwrite for multiple files HOT 5
- Main Column Line Numbers Only HOT 8
- Outdated file information for recreated directories HOT 9
- directories have another font type HOT 2
- Feature request: highlighting of cursors when inactive HOT 3
- Feature request: add an lfrc switch to move duplicate copy suffixes at the beginning of filename. HOT 4
- `autoquit` should be enabled by default HOT 6
- how to use fribidi within lf.
- sixel preview writes out of bounds
- Broken characters of dir when I use `-print-last-dir` option / change drive option `/d` in `lfcd.cmd` HOT 3
- Issue with scrolling using alt key HOT 6
- Feature request: precalculate previews for files around the cursor HOT 3
- lf does not open terminal text editor when going right HOT 4
- how to use `lf -remote` in cmd? HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from lf.