Skip to content
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

Add save as command #194

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion command/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func Bindables(cmdr command.Commander, driver gxui.Driver, theme *basic.Theme) [
&caret.Mover{},
&scroll.Scroller{},
focus.NewLocation(driver),
FileHook{Theme: theme},
FileHook{Theme: theme, Driver: driver},
EditHook{Theme: theme, Driver: driver},
ViewHook{},
NavHook{Commander: cmdr},
Expand Down
5 changes: 4 additions & 1 deletion command/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
package command

import (
"github.com/nelsam/gxui"
"github.com/nelsam/gxui/themes/basic"
"github.com/nelsam/vidar/commander/bind"
)

type FileHook struct {
Theme *basic.Theme
Theme *basic.Theme
Driver gxui.Driver
}

func (h FileHook) Name() string {
Expand All @@ -24,6 +26,7 @@ func (h FileHook) OpName() string {
func (h FileHook) FileBindables(string) []bind.Bindable {
return []bind.Bindable{
NewSave(h.Theme),
NewSaveAs(h.Driver, h.Theme),
NewSaveAll(h.Theme),
NewCloseTab(),
&EditorRedraw{},
Expand Down
118 changes: 118 additions & 0 deletions command/save_as.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
// This is free and unencumbered software released into the public
// domain. For more information, see <http://unlicense.org> or the
// accompanying UNLICENSE file.

package command

import (
"errors"
"fmt"
"os"

"github.com/nelsam/gxui"
"github.com/nelsam/gxui/themes/basic"
"github.com/nelsam/vidar/command/focus"
"github.com/nelsam/vidar/command/fs"
"github.com/nelsam/vidar/commander/bind"
"github.com/nelsam/vidar/plugin/status"
)

type Binder interface {
Pop() []bind.Bindable
Execute(bind.Bindable)
}

type FileCopySaver struct {
status.General

driver gxui.Driver

file *fs.Locator
input <-chan gxui.Focusable

focuser Focuser
closer CurrentEditorCloser
binder Binder
}

func NewSaveAs(driver gxui.Driver, theme *basic.Theme) *FileCopySaver {
o := &FileCopySaver{
driver: driver,
}
o.file = fs.NewLocator(driver, theme, fs.All)
o.Theme = theme
return o
}

func (s *FileCopySaver) Name() string {
return "save-as"
}

func (s *FileCopySaver) Menu() string {
return "File"
}

func (s *FileCopySaver) Defaults() []fmt.Stringer {
return []fmt.Stringer{gxui.KeyboardEvent{
Modifier: gxui.ModControl | gxui.ModShift,
Key: gxui.KeyC,
}}
}

func (f *FileCopySaver) Start(control gxui.Control) gxui.Control {
f.file.LoadDir(control)
input := make(chan gxui.Focusable, 1)
f.input = input
input <- f.file
close(input)
return nil
}

func (f *FileCopySaver) Next() gxui.Focusable {
return <-f.input
}

func (f *FileCopySaver) Reset() {
f.focuser = nil
f.closer = nil
f.binder = nil
}

func (f *FileCopySaver) Store(elem interface{}) bind.Status {
switch src := elem.(type) {
case Focuser:
f.focuser = src
case Binder:
f.binder = src
case CurrentEditorCloser:
f.closer = src
}

if f.focuser == nil || f.binder == nil || f.closer == nil {
return bind.Waiting
}
return bind.Executing
}

func (f *FileCopySaver) Exec() error {
filepath := f.file.Path()
if filepath == "" {
f.Err = "command.FileCopySaver: No file path provided"
return errors.New(f.Err)
}
out, err := os.Create(filepath)
if err != nil {
f.Err = fmt.Sprintf("Could not open %s for writing: %s", filepath, err)
return errors.New(f.Err)
}
if _, err := out.WriteString(f.closer.CurrentEditor().Text()); err != nil {
f.Err = fmt.Sprintf("Could not write to file %s: %s", filepath, err)
return errors.New(f.Err)
}
out.Close()
f.closer.CloseCurrentEditor()
f.binder.Pop()
f.binder.Execute(f.focuser.For(focus.Path(filepath)))
f.Info = fmt.Sprintf("Successfully saved %s", filepath)
return nil
}