mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-01-04 03:48:07 +02:00
WIP using runDirectCommand with xdg-open
This commit is contained in:
parent
cff1dee6dc
commit
ae0d88f855
@ -73,7 +73,7 @@ func NewApp(config config.AppConfigurer) (*App, error) {
|
||||
}
|
||||
var err error
|
||||
app.Log = newLogger(config)
|
||||
app.OSCommand = commands.NewOSCommand(app.Log)
|
||||
app.OSCommand = commands.NewOSCommand(app.Log, config)
|
||||
|
||||
app.Tr = i18n.NewLocalizer(app.Log)
|
||||
|
||||
|
@ -6,7 +6,8 @@ import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/jesseduffield/lazygit/pkg/config"
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
|
||||
"github.com/mgutz/str"
|
||||
|
||||
@ -20,22 +21,25 @@ type Platform struct {
|
||||
shell string
|
||||
shellArg string
|
||||
escapedQuote string
|
||||
openCommand string
|
||||
}
|
||||
|
||||
// OSCommand holds all the os commands
|
||||
type OSCommand struct {
|
||||
Log *logrus.Entry
|
||||
Platform *Platform
|
||||
Config config.AppConfigurer
|
||||
command func(string, ...string) *exec.Cmd
|
||||
getGlobalGitConfig func(string) (string, error)
|
||||
getenv func(string) string
|
||||
}
|
||||
|
||||
// NewOSCommand os command runner
|
||||
func NewOSCommand(log *logrus.Entry) *OSCommand {
|
||||
func NewOSCommand(log *logrus.Entry, config config.AppConfigurer) *OSCommand {
|
||||
return &OSCommand{
|
||||
Log: log,
|
||||
Platform: getPlatform(),
|
||||
Config: config,
|
||||
command: exec.Command,
|
||||
getGlobalGitConfig: gitconfig.Global,
|
||||
getenv: os.Getenv,
|
||||
@ -74,12 +78,10 @@ func (c *OSCommand) FileType(path string) string {
|
||||
// RunDirectCommand wrapper around direct commands
|
||||
func (c *OSCommand) RunDirectCommand(command string) (string, error) {
|
||||
c.Log.WithField("command", command).Info("RunDirectCommand")
|
||||
args := str.ToArgv(c.Platform.shellArg + " " + command)
|
||||
c.Log.Info(spew.Sdump(args))
|
||||
|
||||
return sanitisedCommandOutput(
|
||||
exec.
|
||||
Command(c.Platform.shell, args...).
|
||||
Command(c.Platform.shell, c.Platform.shellArg, command).
|
||||
CombinedOutput(),
|
||||
)
|
||||
}
|
||||
@ -95,45 +97,23 @@ func sanitisedCommandOutput(output []byte, err error) (string, error) {
|
||||
}
|
||||
|
||||
// getOpenCommand get open command
|
||||
func (c *OSCommand) getOpenCommand() (string, string, error) {
|
||||
//NextStep open equivalents: xdg-open (linux), cygstart (cygwin), open (OSX)
|
||||
trailMap := map[string]string{
|
||||
"xdg-open": " &>/dev/null &",
|
||||
"cygstart": "",
|
||||
"open": "",
|
||||
func (c *OSCommand) getOpenCommand() string {
|
||||
if c.Config.GetUserConfig().IsSet("os.openCommand") {
|
||||
return c.Config.GetUserConfig().GetString("os.openCommand")
|
||||
}
|
||||
|
||||
for name, trail := range trailMap {
|
||||
if err := c.RunCommand("which " + name); err == nil {
|
||||
return name, trail, nil
|
||||
}
|
||||
}
|
||||
return "", "", errors.New("Unsure what command to use to open this file")
|
||||
}
|
||||
|
||||
// VsCodeOpenFile opens the file in code, with the -r flag to open in the
|
||||
// current window
|
||||
// each of these open files needs to have the same function signature because
|
||||
// they're being passed as arguments into another function,
|
||||
// but only editFile actually returns a *exec.Cmd
|
||||
func (c *OSCommand) VsCodeOpenFile(filename string) (*exec.Cmd, error) {
|
||||
return nil, c.RunCommand("code -r " + filename)
|
||||
}
|
||||
|
||||
// SublimeOpenFile opens the filein sublime
|
||||
// may be deprecated in the future
|
||||
func (c *OSCommand) SublimeOpenFile(filename string) (*exec.Cmd, error) {
|
||||
return nil, c.RunCommand("subl " + filename)
|
||||
return c.Platform.openCommand
|
||||
}
|
||||
|
||||
// OpenFile opens a file with the given
|
||||
func (c *OSCommand) OpenFile(filename string) error {
|
||||
cmdName, cmdTrail, err := c.getOpenCommand()
|
||||
if err != nil {
|
||||
return err
|
||||
commandTemplate := c.getOpenCommand()
|
||||
templateValues := map[string]string{
|
||||
"filename": c.Quote(filename),
|
||||
}
|
||||
|
||||
return c.RunCommand(cmdName + " " + c.Quote(filename) + cmdTrail) // TODO: test on linux
|
||||
command := utils.ResolvePlaceholderString(commandTemplate, templateValues)
|
||||
_, err := c.RunDirectCommand(command)
|
||||
return err
|
||||
}
|
||||
|
||||
// EditFile opens a file in a subprocess using whatever editor is available,
|
||||
|
@ -12,5 +12,6 @@ func getPlatform() *Platform {
|
||||
shell: "bash",
|
||||
shellArg: "-c",
|
||||
escapedQuote: "\"",
|
||||
openCommand: "open {{filename}}",
|
||||
}
|
||||
}
|
||||
|
15
pkg/commands/os_linux.go
Normal file
15
pkg/commands/os_linux.go
Normal file
@ -0,0 +1,15 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
)
|
||||
|
||||
func getPlatform() *Platform {
|
||||
return &Platform{
|
||||
os: runtime.GOOS,
|
||||
shell: "bash",
|
||||
shellArg: "-c",
|
||||
escapedQuote: "\"",
|
||||
openCommand: "xdg-open {{filename}} &>/dev/null &",
|
||||
}
|
||||
}
|
@ -6,5 +6,6 @@ func getPlatform() *Platform {
|
||||
shell: "cmd",
|
||||
shellArg: "/c",
|
||||
escapedQuote: "\\\"",
|
||||
openCommand: "cygstart {{filename}}",
|
||||
}
|
||||
}
|
||||
|
@ -218,9 +218,9 @@ func GetDefaultConfig() []byte {
|
||||
- white
|
||||
optionsTextColor:
|
||||
- blue
|
||||
git:
|
||||
# git:
|
||||
# stuff relating to git
|
||||
os:
|
||||
# os:
|
||||
# stuff relating to the OS
|
||||
update:
|
||||
method: prompt # can be: prompt | background | never
|
||||
|
@ -7,7 +7,6 @@ import (
|
||||
|
||||
// "strings"
|
||||
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/fatih/color"
|
||||
@ -250,11 +249,10 @@ func (gui *Gui) PrepareSubProcess(g *gocui.Gui, commands ...string) {
|
||||
})
|
||||
}
|
||||
|
||||
func (gui *Gui) genericFileOpen(g *gocui.Gui, v *gocui.View, filename string, open func(string) (*exec.Cmd, error)) error {
|
||||
|
||||
sub, err := open(filename)
|
||||
func (gui *Gui) editFile(filename string) error {
|
||||
sub, err := gui.OSCommand.EditFile(filename)
|
||||
if err != nil {
|
||||
return gui.createErrorPanel(g, err.Error())
|
||||
return gui.createErrorPanel(gui.g, err.Error())
|
||||
}
|
||||
if sub != nil {
|
||||
gui.SubProcess = sub
|
||||
@ -268,7 +266,8 @@ func (gui *Gui) handleFileEdit(g *gocui.Gui, v *gocui.View) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return gui.genericFileOpen(g, v, file.Name, gui.OSCommand.EditFile)
|
||||
|
||||
return gui.editFile(file.Name)
|
||||
}
|
||||
|
||||
func (gui *Gui) handleFileOpen(g *gocui.Gui, v *gocui.View) error {
|
||||
@ -279,22 +278,6 @@ func (gui *Gui) handleFileOpen(g *gocui.Gui, v *gocui.View) error {
|
||||
return gui.openFile(file.Name)
|
||||
}
|
||||
|
||||
func (gui *Gui) handleSublimeFileOpen(g *gocui.Gui, v *gocui.View) error {
|
||||
file, err := gui.getSelectedFile(g)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return gui.genericFileOpen(g, v, file.Name, gui.OSCommand.SublimeOpenFile)
|
||||
}
|
||||
|
||||
func (gui *Gui) handleVsCodeFileOpen(g *gocui.Gui, v *gocui.View) error {
|
||||
file, err := gui.getSelectedFile(g)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return gui.genericFileOpen(g, v, file.Name, gui.OSCommand.VsCodeOpenFile)
|
||||
}
|
||||
|
||||
func (gui *Gui) handleRefreshFiles(g *gocui.Gui, v *gocui.View) error {
|
||||
return gui.refreshFiles(g)
|
||||
}
|
||||
|
@ -34,8 +34,6 @@ func (gui *Gui) keybindings(g *gocui.Gui) error {
|
||||
{ViewName: "files", Key: 'm', Modifier: gocui.ModNone, Handler: gui.handleSwitchToMerge},
|
||||
{ViewName: "files", Key: 'e', Modifier: gocui.ModNone, Handler: gui.handleFileEdit},
|
||||
{ViewName: "files", Key: 'o', Modifier: gocui.ModNone, Handler: gui.handleFileOpen},
|
||||
{ViewName: "files", Key: 's', Modifier: gocui.ModNone, Handler: gui.handleSublimeFileOpen},
|
||||
{ViewName: "files", Key: 'v', Modifier: gocui.ModNone, Handler: gui.handleVsCodeFileOpen},
|
||||
{ViewName: "files", Key: 'i', Modifier: gocui.ModNone, Handler: gui.handleIgnoreFile},
|
||||
{ViewName: "files", Key: 'r', Modifier: gocui.ModNone, Handler: gui.handleRefreshFiles},
|
||||
{ViewName: "files", Key: 'S', Modifier: gocui.ModNone, Handler: gui.handleStashSave},
|
||||
|
@ -76,7 +76,7 @@ func (gui *Gui) handleOpenConfig(g *gocui.Gui, v *gocui.View) error {
|
||||
|
||||
func (gui *Gui) handleEditConfig(g *gocui.Gui, v *gocui.View) error {
|
||||
filename := gui.Config.GetUserConfig().ConfigFileUsed()
|
||||
return gui.genericFileOpen(g, v, filename, gui.OSCommand.EditFile)
|
||||
return gui.editFile(filename)
|
||||
}
|
||||
|
||||
func lazygitTitle() string {
|
||||
|
@ -90,3 +90,11 @@ func Loader() string {
|
||||
index := nanos / 50000000 % int64(len(characters))
|
||||
return characters[index : index+1]
|
||||
}
|
||||
|
||||
// ResolvePlaceholderString populates a template with values
|
||||
func ResolvePlaceholderString(str string, arguments map[string]string) string {
|
||||
for key, value := range arguments {
|
||||
str = strings.Replace(str, "{{"+key+"}}", value, -1)
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user