From 3eb0e7c5edaa3c70b3e42dfb8fb4321c35b48423 Mon Sep 17 00:00:00 2001 From: raziman Date: Sun, 21 Mar 2021 16:05:23 +0800 Subject: [PATCH] add Playlist, Queue and Player module --- anko/anko.go | 16 ++++++++++++++-- anko/anko_test.go | 12 ++++++------ command.go | 2 +- playlist.go | 27 ++++++++++++++++++++++++++- popup.go | 10 ++++++---- queue.go | 1 - start.go | 31 +++++++++++++++++++++++++------ test/config | 16 ++++++++++++++++ 8 files changed, 94 insertions(+), 21 deletions(-) diff --git a/anko/anko.go b/anko/anko.go index ad2338e..a8c82da 100644 --- a/anko/anko.go +++ b/anko/anko.go @@ -48,11 +48,23 @@ func NewAnko() *Anko { return &Anko{env} } -// Define defines new symbol and value to the Anko env. -func (a *Anko) Define(symbol string, value interface{}) error { +// DefineGlobal defines new symbol and value to the Anko env. +func (a *Anko) DefineGlobal(symbol string, value interface{}) error { return a.env.DefineGlobal(symbol, value) } +func (a *Anko) NewModule(name string) (*Anko, error) { + env, err := a.env.NewModule(name) + if err != nil { + return nil, err + } + return &Anko{env}, nil +} + +func (a *Anko) Define(name string, value interface{}) error { + return a.env.Define(name, value) +} + // Set sets new value to existing symbol. Use this when change value under an // existing symbol. func (a *Anko) Set(symbol string, value interface{}) error { diff --git a/anko/anko_test.go b/anko/anko_test.go index 037faa6..ecddd32 100644 --- a/anko/anko_test.go +++ b/anko/anko_test.go @@ -10,7 +10,7 @@ import ( func TestDefine(t *testing.T) { a := NewAnko() - err := a.Define("x", 12) + err := a.DefineGlobal("x", 12) if err != nil { t.Error(err) } @@ -18,7 +18,7 @@ func TestDefine(t *testing.T) { func TestSet(t *testing.T) { a := NewAnko() - err := a.Define("x", 12) + err := a.DefineGlobal("x", 12) if err != nil { t.Error(err) } @@ -33,7 +33,7 @@ func TestGet(t *testing.T) { a := NewAnko() expect := 12 - err := a.Define("x", expect) + err := a.DefineGlobal("x", expect) if err != nil { t.Error(err) } @@ -73,7 +73,7 @@ func TestGetInt(t *testing.T) { got = a.GetInt("S.y") assert.Equal(t, 0, got) - a.Define("z", expect) + a.DefineGlobal("z", expect) val := a.GetInt("z") assert.Equal(t, expect, val) @@ -102,7 +102,7 @@ func TestGetString(t *testing.T) { got = a.GetString("S.y") assert.Equal(t, "", got) - a.Define("z", expect) + a.DefineGlobal("z", expect) val := a.GetString("z") assert.Equal(t, expect, val) @@ -111,7 +111,7 @@ func TestGetString(t *testing.T) { func TestGetBool(t *testing.T) { expect := true a := NewAnko() - a.Define("x", expect) + a.DefineGlobal("x", expect) _, err := a.Execute(`module S { x = true }`) if err != nil { diff --git a/command.go b/command.go index 6735831..f99c466 100644 --- a/command.go +++ b/command.go @@ -452,7 +452,7 @@ func (c Command) defineCommands() { }) for name, cmd := range c.commands { - err := gomu.anko.Define(name, cmd) + err := gomu.anko.DefineGlobal(name, cmd) if err != nil { logError(err) } diff --git a/playlist.go b/playlist.go index 93f684d..bcf42e4 100644 --- a/playlist.go +++ b/playlist.go @@ -22,8 +22,11 @@ import ( "github.com/ztrue/tracerr" "github.com/issadarkthing/gomu/lyric" + "github.com/issadarkthing/gomu/player" ) +var _ player.Audio = (*AudioFile)(nil) + // AudioFile represents directories and mp3 files // isAudioFile equals to false if it is a directory type AudioFile struct { @@ -43,6 +46,29 @@ func (a *AudioFile) Path() string { return a.path } +func (a *AudioFile) IsAudioFile() bool { + return a.isAudioFile +} + +func (a *AudioFile) Len() time.Duration { + return a.length +} + +func (a *AudioFile) GetParent() *AudioFile { + if a.parent == nil { + return nil + } + return a.parent.GetReference().(*AudioFile) +} + +func (a *AudioFile) String() string { + if a == nil { + return "nil" + } + return fmt.Sprintf("%#v", a) +} + + // Playlist struct represents playlist panel // that shows the tree of the music directory type Playlist struct { @@ -206,7 +232,6 @@ func newPlaylist(args Args) *Playlist { }) return playlist - } // Returns the current file highlighted in the playlist diff --git a/popup.go b/popup.go index 0d417ad..a7c17fc 100644 --- a/popup.go +++ b/popup.go @@ -601,10 +601,11 @@ func infoPopup(message string) { defaultTimedPopup(" Info ", message) } -func inputPopup(prompt string, handler func(string)) { +func inputPopup(prompt, placeholder string, handler func(string)) { popupID := "general-input-popup" input := newInputPopup(popupID, "", prompt+": ", "") + input.SetText(placeholder) input.SetInputCapture(func(e *tcell.EventKey) *tcell.EventKey { switch e.Key() { @@ -640,16 +641,17 @@ func replPopup() { history := []string{} upCount := 0 - gomu.anko.Define("println", func(x ...interface{}) { + gomu.anko.DefineGlobal("println", func(x ...interface{}) { fmt.Fprintln(textview, x...) }) - gomu.anko.Define("print", func(x ...interface{}) { + gomu.anko.DefineGlobal("print", func(x ...interface{}) { fmt.Fprint(textview, x...) }) - gomu.anko.Define("printf", func(format string, x ...interface{}) { + gomu.anko.DefineGlobal("printf", func(format string, x ...interface{}) { fmt.Fprintf(textview, format, x...) }) + input.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { switch event.Key() { diff --git a/queue.go b/queue.go index 4ecfba7..4e5003a 100644 --- a/queue.go +++ b/queue.go @@ -414,7 +414,6 @@ func newQueue() *Queue { SetBackgroundColor(gomu.colors.background) return queue - } // Convert string to sha1. diff --git a/start.go b/start.go index 84a0fdc..f79baaf 100644 --- a/start.go +++ b/start.go @@ -58,12 +58,30 @@ func getArgs() Args { // built-in functions func defineBuiltins() { - gomu.anko.Define("debug_popup", debugPopup) - gomu.anko.Define("info_popup", infoPopup) - gomu.anko.Define("input_popup", inputPopup) - gomu.anko.Define("show_popup", defaultTimedPopup) - gomu.anko.Define("search_popup", searchPopup) - gomu.anko.Define("shell", shell) + gomu.anko.DefineGlobal("debug_popup", debugPopup) + gomu.anko.DefineGlobal("info_popup", infoPopup) + gomu.anko.DefineGlobal("input_popup", inputPopup) + gomu.anko.DefineGlobal("show_popup", defaultTimedPopup) + gomu.anko.DefineGlobal("search_popup", searchPopup) + gomu.anko.DefineGlobal("shell", shell) +} + +func defineInternals() { + playlist, _ := gomu.anko.NewModule("Playlist") + playlist.Define("get_focused", gomu.playlist.getCurrentFile) + + queue, _ := gomu.anko.NewModule("Queue") + queue.Define("get_focused", func() *AudioFile { + index := gomu.queue.GetCurrentItem() + if index < 0 || index > len(gomu.queue.items)-1 { + return nil + } + item := gomu.queue.items[index] + return item + }) + + player, _ := gomu.anko.NewModule("Player") + player.Define("current_audio", gomu.player.GetCurrentSong) } func setupHooks(hook *hook.EventHook, anko *anko.Anko) { @@ -326,6 +344,7 @@ func start(application *tview.Application, args Args) { tview.Styles.PrimitiveBackgroundColor = gomu.colors.popup gomu.initPanels(application, args) + defineInternals() gomu.player.SetSongStart(func(audio player.Audio) { diff --git a/test/config b/test/config index 5958ccc..299495a 100644 --- a/test/config +++ b/test/config @@ -122,6 +122,22 @@ Keybinds.def_q("i", func() { Keybinds.def_g("c", show_colors) +# better rename command which does not change the mtime of file +Keybinds.def_g("R", func() { + exec = import("os/exec") + os = import("os") + + file = Playlist.get_focused() + dir = file.GetParent().Path() + + input_popup("New name", file.Name(), func(new_name) { + cmd = exec.Command("cp", "-p", file.Path(), dir + "/" + new_name) + cmd.Run() + os.Remove(file.Path()) + refresh() + }) +}) + # you can get the syntax highlighting for this language here: # https://github.com/mattn/anko/tree/master/misc/vim # vim: ft=anko