2017-08-05 16:23:55 +00:00
|
|
|
// +build !windows
|
|
|
|
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2017-08-06 08:05:46 +00:00
|
|
|
"log"
|
2017-08-05 16:23:55 +00:00
|
|
|
"os"
|
|
|
|
"os/exec"
|
2017-08-06 08:05:46 +00:00
|
|
|
"os/user"
|
2017-08-05 16:23:55 +00:00
|
|
|
"path/filepath"
|
2018-03-02 20:15:36 +00:00
|
|
|
"runtime"
|
2019-03-17 17:16:19 +00:00
|
|
|
"strings"
|
2018-03-02 20:15:36 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
2018-06-28 18:51:24 +00:00
|
|
|
envOpener = os.Getenv("OPENER")
|
2018-03-02 20:15:36 +00:00
|
|
|
envEditor = os.Getenv("EDITOR")
|
|
|
|
envPager = os.Getenv("PAGER")
|
|
|
|
envShell = os.Getenv("SHELL")
|
2017-08-05 16:23:55 +00:00
|
|
|
)
|
|
|
|
|
2017-08-06 08:05:46 +00:00
|
|
|
var (
|
2018-02-17 17:04:30 +00:00
|
|
|
gDefaultShell = "sh"
|
2017-08-06 08:05:46 +00:00
|
|
|
gDefaultSocketProt = "unix"
|
|
|
|
gDefaultSocketPath string
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
2018-06-28 16:37:19 +00:00
|
|
|
gUser *user.User
|
|
|
|
gConfigPaths []string
|
2018-07-11 17:09:26 +00:00
|
|
|
gMarksPath string
|
2018-07-11 17:49:55 +00:00
|
|
|
gHistoryPath string
|
2017-08-06 08:05:46 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func init() {
|
2018-06-28 18:51:24 +00:00
|
|
|
if envOpener == "" {
|
|
|
|
if runtime.GOOS == "darwin" {
|
|
|
|
envOpener = "open"
|
|
|
|
} else {
|
|
|
|
envOpener = "xdg-open"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if envEditor == "" {
|
|
|
|
envEditor = "vi"
|
|
|
|
}
|
|
|
|
|
|
|
|
if envPager == "" {
|
|
|
|
envPager = "less"
|
|
|
|
}
|
|
|
|
|
|
|
|
if envShell == "" {
|
|
|
|
envShell = "sh"
|
|
|
|
}
|
|
|
|
|
2017-11-19 18:55:13 +00:00
|
|
|
u, err := user.Current()
|
2017-08-06 08:05:46 +00:00
|
|
|
if err != nil {
|
|
|
|
log.Printf("user: %s", err)
|
2018-08-27 16:36:40 +00:00
|
|
|
if os.Getenv("HOME") == "" {
|
|
|
|
log.Print("$HOME variable is empty or not set")
|
|
|
|
}
|
|
|
|
if os.Getenv("USER") == "" {
|
|
|
|
log.Print("$USER variable is empty or not set")
|
|
|
|
}
|
2017-08-06 08:05:46 +00:00
|
|
|
}
|
2017-11-19 18:55:13 +00:00
|
|
|
gUser = u
|
2017-08-06 08:05:46 +00:00
|
|
|
|
|
|
|
config := os.Getenv("XDG_CONFIG_HOME")
|
|
|
|
if config == "" {
|
|
|
|
config = filepath.Join(gUser.HomeDir, ".config")
|
|
|
|
}
|
|
|
|
|
2018-06-28 16:37:19 +00:00
|
|
|
gConfigPaths = []string{
|
2018-07-13 19:46:37 +00:00
|
|
|
filepath.Join("/etc", "lf", "lfrc"),
|
2018-06-28 16:37:19 +00:00
|
|
|
filepath.Join(config, "lf", "lfrc"),
|
|
|
|
}
|
2017-08-06 08:05:46 +00:00
|
|
|
|
2018-07-11 17:09:26 +00:00
|
|
|
data := os.Getenv("XDG_DATA_HOME")
|
|
|
|
if data == "" {
|
|
|
|
data = filepath.Join(gUser.HomeDir, ".local", "share")
|
|
|
|
}
|
|
|
|
|
|
|
|
gMarksPath = filepath.Join(data, "lf", "marks")
|
2018-07-11 17:49:55 +00:00
|
|
|
gHistoryPath = filepath.Join(data, "lf", "history")
|
2018-07-11 17:09:26 +00:00
|
|
|
|
2017-08-06 08:05:46 +00:00
|
|
|
gDefaultSocketPath = filepath.Join(os.TempDir(), fmt.Sprintf("lf.%s.sock", gUser.Username))
|
|
|
|
}
|
2017-08-05 16:23:55 +00:00
|
|
|
|
2018-07-31 21:21:55 +00:00
|
|
|
func detachedCommand(name string, arg ...string) *exec.Cmd {
|
|
|
|
return exec.Command(name, arg...)
|
|
|
|
}
|
|
|
|
|
2017-08-05 16:23:55 +00:00
|
|
|
func pauseCommand() *exec.Cmd {
|
2018-05-20 17:30:41 +00:00
|
|
|
cmd := `echo
|
|
|
|
echo -n 'Press any key to continue'
|
|
|
|
old=$(stty -g)
|
|
|
|
stty raw -echo
|
|
|
|
eval "ignore=\$(dd bs=1 count=1 2> /dev/null)"
|
|
|
|
stty $old
|
|
|
|
echo`
|
|
|
|
|
|
|
|
return exec.Command(gOpts.shell, "-c", cmd)
|
2017-08-05 16:23:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func shellCommand(s string, args []string) *exec.Cmd {
|
|
|
|
if len(gOpts.ifs) != 0 {
|
|
|
|
s = fmt.Sprintf("IFS='%s'; %s", gOpts.ifs, s)
|
|
|
|
}
|
|
|
|
|
|
|
|
args = append([]string{"-c", s, "--"}, args...)
|
|
|
|
|
2018-06-26 18:14:55 +00:00
|
|
|
args = append(gOpts.shellopts, args...)
|
|
|
|
|
2017-08-05 16:23:55 +00:00
|
|
|
return exec.Command(gOpts.shell, args...)
|
|
|
|
}
|
|
|
|
|
2018-03-02 20:15:36 +00:00
|
|
|
func setDefaults() {
|
2018-06-28 18:51:24 +00:00
|
|
|
gOpts.cmds["open"] = &execExpr{"&", `$OPENER "$f"`}
|
|
|
|
gOpts.keys["e"] = &execExpr{"$", `$EDITOR "$f"`}
|
|
|
|
gOpts.keys["i"] = &execExpr{"$", `$PAGER "$f"`}
|
|
|
|
gOpts.keys["w"] = &execExpr{"$", "$SHELL"}
|
2018-07-07 14:50:47 +00:00
|
|
|
|
|
|
|
gOpts.cmds["doc"] = &execExpr{"$", "lf -doc | $PAGER"}
|
|
|
|
gOpts.keys["<f-1>"] = &callExpr{"doc", nil, 1}
|
2018-03-02 20:15:36 +00:00
|
|
|
}
|
|
|
|
|
2017-08-05 16:23:55 +00:00
|
|
|
func moveCursor(y, x int) {
|
|
|
|
fmt.Printf("\033[%d;%dH", y, x)
|
|
|
|
}
|
2018-06-28 21:12:54 +00:00
|
|
|
|
|
|
|
func isExecutable(f os.FileInfo) bool {
|
|
|
|
return f.Mode()&0111 != 0
|
|
|
|
}
|
2019-03-17 17:16:19 +00:00
|
|
|
|
2020-06-10 23:52:15 +00:00
|
|
|
func isHidden(f os.FileInfo, path string) (hidden bool) {
|
|
|
|
for _, pattern := range gOpts.hiddenfiles {
|
|
|
|
if len(pattern) == 0 {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
matched := matchPattern(strings.TrimPrefix(pattern, "!"), f.Name(), path)
|
|
|
|
if pattern[0] == '!' && matched {
|
|
|
|
hidden = false
|
|
|
|
} else if matched {
|
|
|
|
hidden = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return hidden
|
|
|
|
}
|
|
|
|
|
|
|
|
func matchPattern(pattern, name, path string) bool {
|
|
|
|
matchStr := name
|
|
|
|
|
|
|
|
if pattern[0] == '~' {
|
|
|
|
pattern = gUser.HomeDir + strings.TrimPrefix(pattern, "~")
|
|
|
|
}
|
|
|
|
if pattern[0] == filepath.Separator {
|
|
|
|
matchStr = filepath.Join(path, name)
|
|
|
|
}
|
|
|
|
|
2020-06-11 00:14:45 +00:00
|
|
|
// pattern errors are checked when 'hiddenfiles' option is set
|
|
|
|
matched, _ := filepath.Match(pattern, matchStr)
|
|
|
|
|
|
|
|
return matched
|
2019-03-31 20:39:41 +00:00
|
|
|
}
|
|
|
|
|
2019-03-17 17:16:19 +00:00
|
|
|
func exportFiles(f string, fs []string) {
|
|
|
|
envFile := f
|
|
|
|
envFiles := strings.Join(fs, gOpts.filesep)
|
|
|
|
|
|
|
|
os.Setenv("f", envFile)
|
|
|
|
os.Setenv("fs", envFiles)
|
|
|
|
|
|
|
|
if len(fs) == 0 {
|
|
|
|
os.Setenv("fx", envFile)
|
|
|
|
} else {
|
|
|
|
os.Setenv("fx", envFiles)
|
|
|
|
}
|
|
|
|
}
|