diff --git a/TODO b/TODO index b28ee6c..4a50e44 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,6 @@ - [x] don't pass `0` line/col to kak -- [ ] add key bindings to delete buffers in `kks-buffers` +- [x] add key bindings to delete buffers in `kks-buffers` - [ ] add key bindings to create files in `kks-files` - [x] add extra fzf bindings in kks select diff --git a/cmd/attach.go b/cmd/attach.go index 084bee9..5f8691b 100644 --- a/cmd/attach.go +++ b/cmd/attach.go @@ -10,7 +10,8 @@ func NewAttachCmd() *AttachCmd { c := &AttachCmd{Cmd: Cmd{ fs: flag.NewFlagSet("attach", flag.ExitOnError), alias: []string{"a"}, - usageStr: "[options] [file] [+[:[:[:]]", + fs: flag.NewFlagSet("edit", flag.ExitOnError), + alias: []string{"e"}, + shortDesc: "Edit file. In session and client, if set.", + usageLine: "[options] [file] [+[:]]", }} // TODO add flag that allows creating new files (removes -existing) c.fs.StringVar(&c.session, "s", "", "session") @@ -28,12 +29,13 @@ type EditCmd struct { } func (c *EditCmd) Run() error { - fp, err := NewFilepath(c.fs.Args()) + fp, err := kak.NewFilepath(c.fs.Args()) if err != nil { return err } - switch c.session { + switch c.kakContext.Session.Name { + case "": var gitDirName string _, useGitDirSessions := os.LookupEnv("KKS_USE_GITDIR_SESSIONS") @@ -43,33 +45,51 @@ func (c *EditCmd) Run() error { } if gitDirName != "" { - if !sessionExists(gitDirName) { - sessionName, err := kak.Create(gitDirName) + gitDirSession := kak.Session{Name: gitDirName} + exists, err := gitDirSession.Exists() + if err != nil { + return err + } + + if !exists { + sessionName, err := kak.Start(gitDirSession.Name) if err != nil { return err } fmt.Println("git-dir session started:", sessionName) } - if err := kak.Connect(fp.Name, fp.Line, fp.Column, gitDirName); err != nil { + + kctx := &kak.Context{Session: gitDirSession} + + if err := kak.Connect(kctx, fp); err != nil { return err } + } else { - defaultSession := os.Getenv("KKS_DEFAULT_SESSION") - if defaultSession != "" && sessionExists(defaultSession) { - if err := kak.Connect(fp.Name, fp.Line, fp.Column, defaultSession); err != nil { + defaultSession := kak.Session{Name: os.Getenv("KKS_DEFAULT_SESSION")} + exists, err := defaultSession.Exists() + if err != nil { + return err + } + + if exists { + kctx := &kak.Context{Session: defaultSession} + if err := kak.Connect(kctx, fp); err != nil { return err } + } else { - if err := kak.Run(fp.Name, fp.Line, fp.Column); err != nil { + if err := kak.Run(fp); err != nil { return err } } } + default: - switch c.client { + switch c.kakContext.Client.Name { case "": // if no client, attach to session with new client - if err := kak.Connect(fp.Name, fp.Line, fp.Column, c.session); err != nil { + if err := kak.Connect(c.kakContext, fp); err != nil { return err } default: @@ -83,7 +103,7 @@ func (c *EditCmd) Run() error { sb.WriteString(fmt.Sprintf(" %d", fp.Column)) } - if err := kak.Send(sb.String(), "", c.session, c.client); err != nil { + if err := kak.Send(c.kakContext, sb.String()); err != nil { return err } } @@ -99,13 +119,3 @@ func parseGitToplevel() string { } return strings.TrimSpace(strings.ReplaceAll(path.Base(string(gitOut)), ".", "-")) } - -func sessionExists(name string) bool { - sessions, _ := kak.List() - for _, s := range sessions { - if s.Name == name { - return true - } - } - return false -} diff --git a/cmd/env.go b/cmd/env.go index b3d61eb..fc2d162 100644 --- a/cmd/env.go +++ b/cmd/env.go @@ -10,7 +10,8 @@ func NewEnvCmd() *EnvCmd { c := &EnvCmd{Cmd: Cmd{ fs: flag.NewFlagSet("env", flag.ExitOnError), alias: []string{""}, - usageStr: "[options]", + shortDesc: "Print current Kakoune context set by environment to stdout.", + usageLine: "[options]", sessionReq: true, }} c.fs.BoolVar(&c.json, "json", false, "json output") diff --git a/cmd/get.go b/cmd/get.go index 8c53f80..723f3c5 100644 --- a/cmd/get.go +++ b/cmd/get.go @@ -13,7 +13,8 @@ func NewGetCmd() *GetCmd { c := &GetCmd{Cmd: Cmd{ fs: flag.NewFlagSet("get", flag.ExitOnError), alias: []string{""}, - usageStr: "[options] (<%val{}> | <%opt{}> | <%reg{}> | <%sh{}>)", + shortDesc: "Get states from Kakoune context.", + usageLine: "[options] (<%val{..}> | <%opt{..}> | <%reg{..}> | <%sh{..}>)", sessionReq: true, // TODO maybe actually just use flags for args // or maybe create separate subcommands get-val, etc @@ -35,7 +36,7 @@ func (c *GetCmd) Run() error { return err } - resp, err := kak.Get(query, c.buffer, c.session, c.client) + resp, err := kak.Get(c.kakContext, query) if err != nil { return err } diff --git a/cmd/init.go b/cmd/init.go index be36ab8..dd5477c 100644 --- a/cmd/init.go +++ b/cmd/init.go @@ -11,9 +11,10 @@ var initKak string func NewInitCmd() *InitCmd { c := &InitCmd{Cmd: Cmd{ - fs: flag.NewFlagSet("init", flag.ExitOnError), - alias: []string{""}, - usageStr: "", + fs: flag.NewFlagSet("init", flag.ExitOnError), + alias: []string{""}, + shortDesc: "Print Kakoune command definitions to stdout.", + usageLine: "", }} return c } diff --git a/cmd/kill.go b/cmd/kill.go index 724057e..876f09b 100644 --- a/cmd/kill.go +++ b/cmd/kill.go @@ -8,9 +8,10 @@ import ( func NewKillCmd() *KillCmd { c := &KillCmd{Cmd: Cmd{ - fs: flag.NewFlagSet("kill", flag.ExitOnError), - alias: []string{""}, - usageStr: "[options]", + fs: flag.NewFlagSet("kill", flag.ExitOnError), + alias: []string{""}, + shortDesc: "Terminate Kakoune session.", + usageLine: "[options]", }} c.fs.StringVar(&c.session, "s", "", "session") c.fs.BoolVar(&c.allSessions, "a", false, "all sessions") @@ -23,21 +24,26 @@ type KillCmd struct { } func (c *KillCmd) Run() error { - kakCmd := "kill" + sendCmd := "kill" switch c.allSessions { case false: // TODO need to somehow trigger "no session" err - if err := kak.Send(kakCmd, "", c.session, ""); err != nil { + if err := kak.Send(c.kakContext, sendCmd); err != nil { return err } case true: - sessions, err := kak.List() + sessions, err := kak.Sessions() if err != nil { return err } - for _, sess := range sessions { - if err := kak.Send(kakCmd, "", sess.Name, ""); err != nil { + for _, s := range sessions { + sessCtx := &kak.Context{ + Session: s, + Client: c.kakContext.Client, + Buffer: c.kakContext.Buffer, + } + if err := kak.Send(sessCtx, sendCmd); err != nil { return err } } diff --git a/cmd/list.go b/cmd/list.go index 05b0ea7..73f48c9 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -12,9 +12,10 @@ import ( func NewListCmd() *ListCmd { c := &ListCmd{Cmd: Cmd{ - fs: flag.NewFlagSet("list", flag.ExitOnError), - alias: []string{"ls", "l"}, - usageStr: "[options]", + fs: flag.NewFlagSet("list", flag.ExitOnError), + alias: []string{"ls", "l"}, + shortDesc: "List Kakoune sessions and clients.", + usageLine: "[options]", }} c.fs.BoolVar(&c.json, "json", false, "json output") return c @@ -26,28 +27,49 @@ type ListCmd struct { } func (c *ListCmd) Run() error { - sessions, err := kak.List() + kakSessions, err := kak.Sessions() if err != nil { return err } switch c.json { + case true: + type session struct { + Name string `json:"name"` + Clients []string `json:"clients"` + Dir string `json:"dir"` + } + + sessions := []session{} + + for i, s := range kakSessions { + sessions = append(sessions, session{Name: s.Name, Clients: []string{}, Dir: s.Dir()}) + for _, c := range s.Clients() { + if c.Name != "" { + sessions[i].Clients = append(sessions[i].Clients, c.Name) + } + } + } + j, err := json.MarshalIndent(sessions, "", " ") if err != nil { return err } + fmt.Println(string(j)) + case false: w := new(tabwriter.Writer) w.Init(os.Stdout, 0, 8, 1, '\t', 0) - for _, s := range sessions { - if len(s.Clients) == 0 { - fmt.Fprintf(w, "%s\t: %s\t: %s\n", s.Name, " ", s.Dir) + for _, s := range kakSessions { + if len(s.Clients()) == 0 { + fmt.Fprintf(w, "%s\t: %s\t: %s\n", s.Name, " ", s.Dir()) } else { - for _, cl := range s.Clients { - fmt.Fprintf(w, "%s\t: %s\t: %s\n", s.Name, cl, s.Dir) + for _, cl := range s.Clients() { + clientCtx := kak.Context{Session: s, Client: cl} + fmt.Fprintf(w, "%s\t: %s\t: %s\n", s.Name, clientCtx.Client.Name, s.Dir()) } } } diff --git a/cmd/new.go b/cmd/new.go index db9f562..278fe92 100644 --- a/cmd/new.go +++ b/cmd/new.go @@ -10,9 +10,10 @@ import ( func NewNewCmd() *NewCmd { c := &NewCmd{Cmd: Cmd{ - fs: flag.NewFlagSet("new", flag.ExitOnError), - alias: []string{"n"}, - usageStr: "[name]", + fs: flag.NewFlagSet("new", flag.ExitOnError), + alias: []string{"n"}, + shortDesc: "Start new headless Kakoune session.", + usageLine: "[]", }} return c } @@ -25,14 +26,14 @@ type NewCmd struct { func (c *NewCmd) Run() error { c.name = c.fs.Arg(0) - sessions, err := kak.List() + sessions, err := kak.Sessions() for _, s := range sessions { if s.Name == c.name { return errors.New(fmt.Sprintf("session already exists: %s", c.name)) } } - sessionName, err := kak.Create(c.name) + sessionName, err := kak.Start(c.name) if err != nil { return err } diff --git a/cmd/send.go b/cmd/send.go index 9279f48..2de7c1c 100644 --- a/cmd/send.go +++ b/cmd/send.go @@ -9,9 +9,10 @@ import ( func NewSendCmd() *SendCmd { c := &SendCmd{Cmd: Cmd{ - fs: flag.NewFlagSet("send", flag.ExitOnError), - alias: []string{"s"}, - usageStr: "[options] ", + fs: flag.NewFlagSet("send", flag.ExitOnError), + alias: []string{"s"}, + shortDesc: "Send commands to Kakoune context.", + usageLine: "[options] ", }} c.fs.BoolVar(&c.allClients, "a", false, "send to all clients") c.fs.StringVar(&c.session, "s", "", "session") @@ -27,24 +28,26 @@ type SendCmd struct { func (c *SendCmd) Run() error { // TODO probably need to do some shell escaping here - kakCmd := strings.Join(c.fs.Args(), " ") + sendCmd := strings.Join(c.fs.Args(), " ") switch c.allClients { case true: - sessions, err := kak.List() + sessions, err := kak.Sessions() if err != nil { return err } - for _, sess := range sessions { - for _, cl := range sess.Clients { - if err := kak.Send(kakCmd, "", sess.Name, cl); err != nil { + for _, s := range sessions { + sessionCtx := kak.Context{Session: s} + for _, cl := range sessionCtx.Session.Clients() { + clientCtx := &kak.Context{Session: s, Client: cl} + if err := kak.Send(clientCtx, sendCmd); err != nil { return err } } } case false: // TODO: need to trigger "session not set" error - if err := kak.Send(kakCmd, c.buffer, c.session, c.client); err != nil { + if err := kak.Send(c.kakContext, sendCmd); err != nil { return err } } diff --git a/go.mod b/go.mod index 7037fa9..b84dfdb 100644 --- a/go.mod +++ b/go.mod @@ -7,4 +7,4 @@ require ( github.com/google/go-cmp v0.5.6 ) -require golang.org/x/sys v0.0.0-20210909193231-528a39cd75f3 // indirect +require golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect diff --git a/go.sum b/go.sum index e2e6575..038e82c 100644 --- a/go.sum +++ b/go.sum @@ -2,8 +2,7 @@ github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWp github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210909193231-528a39cd75f3 h1:3Ad41xy2WCESpufXwgs7NpDSu+vjxqLt2UFqUV+20bI= -golang.org/x/sys v0.0.0-20210909193231-528a39cd75f3/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/kak/connect.go b/kak/connect.go index f293771..3184eb2 100644 --- a/kak/connect.go +++ b/kak/connect.go @@ -7,20 +7,20 @@ import ( "syscall" ) -func Connect(file string, line int, col int, sess string) error { +func Connect(kctx *Context, fp *Filepath) error { kakBinary, err := exec.LookPath("kak") if err != nil { return err } kakExecArgs := []string{kakBinary} - kakExecArgs = append(kakExecArgs, "-c", sess) + kakExecArgs = append(kakExecArgs, "-c", kctx.Session.Name) - if file != "" { - kakExecArgs = append(kakExecArgs, file) + if fp.Name != "" { + kakExecArgs = append(kakExecArgs, fp.Name) - if line != 0 { - kakExecArgs = append(kakExecArgs, fmt.Sprintf("+%d:%d", line, col)) + if fp.Line != 0 { + kakExecArgs = append(kakExecArgs, fmt.Sprintf("+%d:%d", fp.Line, fp.Column)) } } diff --git a/cmd/filepath.go b/kak/filepath.go similarity index 89% rename from cmd/filepath.go rename to kak/filepath.go index b8ad79e..1e8b3f8 100644 --- a/cmd/filepath.go +++ b/kak/filepath.go @@ -1,4 +1,4 @@ -package cmd +package kak import ( "os" @@ -9,10 +9,10 @@ import ( ) type Filepath struct { - Name string `json:"name"` - Line int `json:"line"` - Column int `json:"column"` - Raw []string `json:"raw"` + Name string + Line int + Column int + Raw []string } func NewFilepath(args []string) (fp *Filepath, err error) { diff --git a/cmd/filepath_test.go b/kak/filepath_test.go similarity index 93% rename from cmd/filepath_test.go rename to kak/filepath_test.go index a9fe2d1..b73b85e 100644 --- a/cmd/filepath_test.go +++ b/kak/filepath_test.go @@ -1,4 +1,4 @@ -package cmd +package kak import ( "testing" @@ -13,7 +13,7 @@ func TestNewFilepath(t *testing.T) { }{ { []string{"file"}, - Filepath{Name: "/home/kkga/projects/kks/cmd/file", + Filepath{Name: "/home/kkga/projects/kks/kak/file", Raw: []string{"file"}}, }, { diff --git a/kak/get.go b/kak/get.go index 5bbe9e3..f97eb7e 100644 --- a/kak/get.go +++ b/kak/get.go @@ -2,27 +2,25 @@ package kak import ( "fmt" - "log" + "io/ioutil" "os" "strings" - - "github.com/fsnotify/fsnotify" ) -func Get(getStr, buf, session, client string) ([]string, error) { +func Get(kctx *Context, query string) ([]string, error) { // create a tmp file for kak to echo the value - f, err := os.CreateTemp("", "kks-tmp") + tmp, err := ioutil.TempFile("", "kks-tmp") if err != nil { return nil, err } // kak will output to file, so we create a chan for reading ch := make(chan string) - go ReadTmp(f, ch) + go ReadTmp(tmp, ch) // tell kak to echo the requested state - sendCmd := fmt.Sprintf("echo -quoting kakoune -to-file %s %%{ %s }", f.Name(), getStr) - if err := Send(sendCmd, buf, session, client); err != nil { + sendCmd := fmt.Sprintf("echo -quoting kakoune -to-file %s %%{ %s }", tmp.Name(), query) + if err := Send(kctx, sendCmd); err != nil { return nil, err } @@ -35,45 +33,8 @@ func Get(getStr, buf, session, client string) ([]string, error) { outStrs[i] = strings.Trim(val, "''") } - f.Close() - return outStrs, nil -} - -func ReadTmp(f *os.File, c chan string) { - // create a watcher - watcher, err := fsnotify.NewWatcher() - if err != nil { - log.Fatal(err) - } - defer watcher.Close() + tmp.Close() + os.Remove(tmp.Name()) - // add file to watch - err = watcher.Add(f.Name()) - if err != nil { - log.Fatal(err) - } - - // while we don't get the value - for { - select { - case event, ok := <-watcher.Events: - if !ok { - return - } - // if file written, read it and send to chan - if event.Op&fsnotify.Write == fsnotify.Write { - dat, err := os.ReadFile(f.Name()) - defer os.Remove(f.Name()) - if err != nil { - log.Fatal(err) - } - c <- string(dat) - } - case err, ok := <-watcher.Errors: - if !ok { - return - } - log.Println("error:", err) - } - } + return outStrs, nil } diff --git a/kak/kak.go b/kak/kak.go new file mode 100644 index 0000000..eaa9e80 --- /dev/null +++ b/kak/kak.go @@ -0,0 +1,66 @@ +package kak + +import ( + "os/exec" + "strings" +) + +type Context struct { + Session Session + Client Client + Buffer Buffer +} + +type Session struct{ Name string } +type Client struct{ Name string } +type Buffer struct{ Name string } + +func (s *Session) Exists() (bool, error) { + sessions, err := Sessions() + if err != nil { + return false, err + } + + for _, session := range sessions { + if session.Name == s.Name { + return true, nil + } + } + return false, nil +} + +func (s *Session) Clients() (clients []Client) { + sessCtx := &Context{Session: *s} + cl, err := Get(sessCtx, "%val{client_list}") + if err != nil { + return []Client{} + } + + for _, c := range cl { + clients = append(clients, Client{c}) + } + + return clients +} + +func (s *Session) Dir() string { + sessCtx := &Context{Session: *s} + dir, err := Get(sessCtx, "%sh{pwd}") + if err != nil { + return "" + } + return dir[0] +} + +func Sessions() (sessions []Session, err error) { + output, err := exec.Command("kak", "-l").Output() + if err != nil { + return nil, err + } + + for _, s := range strings.Split(strings.TrimSpace(string(output)), "\n") { + sessions = append(sessions, Session{Name: s}) + } + + return sessions, nil +} diff --git a/kak/list.go b/kak/list.go deleted file mode 100644 index c151bfe..0000000 --- a/kak/list.go +++ /dev/null @@ -1,44 +0,0 @@ -package kak - -import ( - "os/exec" - "strings" -) - -type KakSession struct { - Name string `json:"name"` - Clients []string `json:"clients"` - Dir string `json:"dir"` -} - -func List() ([]KakSession, error) { - out, err := exec.Command("kak", "-l").Output() - if err != nil { - return nil, err - } - kakSessions := strings.Split(strings.TrimSpace(string(out)), "\n") - - sessions := make([]KakSession, 0) - - for _, session := range kakSessions { - s := KakSession{Name: session} - - clients, err := Get("%val{client_list}", "", s.Name, "") - if err != nil { - return nil, err - } - if len(clients) > 0 && clients[0] != "" { - s.Clients = clients - } - - dir, err := Get("%sh{pwd}", "", s.Name, "") - if err != nil { - return nil, err - } - s.Dir = strings.Join(dir, "") - - sessions = append(sessions, s) - } - - return sessions, nil -} diff --git a/kak/run.go b/kak/run.go index 917ced9..48aed23 100644 --- a/kak/run.go +++ b/kak/run.go @@ -7,7 +7,7 @@ import ( "syscall" ) -func Run(file string, line int, col int) error { +func Run(fp *Filepath) error { kakBinary, err := exec.LookPath("kak") if err != nil { return err @@ -15,11 +15,11 @@ func Run(file string, line int, col int) error { kakExecArgs := []string{kakBinary} - if file != "" { - kakExecArgs = append(kakExecArgs, file) + if fp.Name != "" { + kakExecArgs = append(kakExecArgs, fp.Name) - if line != 0 { - kakExecArgs = append(kakExecArgs, fmt.Sprintf("+%d:%d", line, col)) + if fp.Line != 0 { + kakExecArgs = append(kakExecArgs, fmt.Sprintf("+%d:%d", fp.Line, fp.Column)) } } diff --git a/kak/send.go b/kak/send.go index 426ec97..0ca021e 100644 --- a/kak/send.go +++ b/kak/send.go @@ -6,8 +6,8 @@ import ( "os/exec" ) -func Send(kakCommand, buf, ses, cl string) error { - cmd := exec.Command("kak", "-p", ses) +func Send(kctx *Context, command string) error { + cmd := exec.Command("kak", "-p", kctx.Session.Name) // cmd.Stdout = os.Stdout // cmd.Stderr = os.Stderr @@ -16,13 +16,13 @@ func Send(kakCommand, buf, ses, cl string) error { go func() { io.WriteString(stdin, "evaluate-commands") - if buf != "" { - io.WriteString(stdin, fmt.Sprintf(" -buffer %s", buf)) - } else if cl != "" { - io.WriteString(stdin, fmt.Sprintf(" -try-client %s", cl)) + if kctx.Buffer.Name != "" { + io.WriteString(stdin, fmt.Sprintf(" -buffer %s", kctx.Buffer.Name)) + } else if kctx.Client.Name != "" { + io.WriteString(stdin, fmt.Sprintf(" -try-client %s", kctx.Client.Name)) } - io.WriteString(stdin, fmt.Sprintf(" %s", kakCommand)) + io.WriteString(stdin, fmt.Sprintf(" %s", command)) stdin.Close() }() diff --git a/kak/create.go b/kak/start.go similarity index 62% rename from kak/create.go rename to kak/start.go index 0e8c427..cd92f63 100644 --- a/kak/create.go +++ b/kak/start.go @@ -5,9 +5,10 @@ import ( "math/rand" "os/exec" "strings" + "time" ) -func Create(name string) (sessionName string, err error) { +func Start(name string) (sessionName string, err error) { sessionName = name if sessionName == "" { @@ -24,9 +25,34 @@ func Create(name string) (sessionName string, err error) { return "", err } + // Ensure session exists before returning + ch := make(chan bool) + go waitForSession(ch, sessionName) + + _ = <-ch + return } +func waitForSession(ch chan bool, name string) error { +out: + for { + sessions, err := Sessions() + if err != nil { + return err + } + for _, s := range sessions { + if s.Name == name { + ch <- true + break out + + } + } + time.Sleep(time.Millisecond * 10) + } + return nil +} + func uniqName() (name string, err error) { s, err := exec.Command("kak", "-l").Output() if err != nil { diff --git a/kak/tmp.go b/kak/tmp.go new file mode 100644 index 0000000..9e36709 --- /dev/null +++ b/kak/tmp.go @@ -0,0 +1,50 @@ +package kak + +import ( + "io/ioutil" + "log" + "os" + + "github.com/fsnotify/fsnotify" +) + +func ReadTmp(tmp *os.File, c chan string) { + // create a watcher + watcher, err := fsnotify.NewWatcher() + if err != nil { + log.Fatal(err) + } + defer watcher.Close() + + // add file to watch + err = watcher.Add(tmp.Name()) + if err != nil { + log.Fatal(err) + } + + // while we don't get the value + for { + select { + case event, ok := <-watcher.Events: + if !ok { + return + } + // if file written, read it, send to chan and close/clean + if event.Op&fsnotify.Write == fsnotify.Write { + dat, err := ioutil.ReadFile(tmp.Name()) + if err != nil { + log.Fatal(err) + } + c <- string(dat) + watcher.Close() + tmp.Close() + os.Remove(tmp.Name()) + } + case err, ok := <-watcher.Errors: + if !ok { + return + } + log.Println("error:", err) + } + } +} diff --git a/scripts/kks-buffers b/scripts/kks-buffers index 89a5495..b99d480 100755 --- a/scripts/kks-buffers +++ b/scripts/kks-buffers @@ -4,11 +4,13 @@ # # requires: # - fzf (https://github.com/junegunn/fzf) -# - highlight (faster than bat) (https://gitlab.com/saalen/highlight) +# - highlight (faster than bat, change to your liking) (https://gitlab.com/saalen/highlight) + +preview_cmd="highlight --line-range=1-100 -t 4 --force -O ansi -" kks get %val[buflist] | grep -F "$*" | - fzf --height 100% --prompt 'buf> ' --preview 'kks cat -b {} | highlight --line-range=1-100 --force -O ansi' \ + fzf --height 100% --prompt 'buf> ' --preview "kks cat -b {} | $preview_cmd" \ --header="[c-x] delete, [c-t] new scratch" \ --bind="ctrl-x:execute-silent(kks send -b {} delete-buffer)+reload(kks get %val[buflist])" \ --bind="ctrl-t:execute-silent(kks send edit -scratch {q})+reload(kks get %val[buflist])" | diff --git a/scripts/kks-files b/scripts/kks-files index 782ee89..3e42ec8 100755 --- a/scripts/kks-files +++ b/scripts/kks-files @@ -5,10 +5,12 @@ # requires: # - fd (https://github.com/sharkdp/fd) # - fzf (https://github.com/junegunn/fzf) -# - highlight (faster than bat) (https://gitlab.com/saalen/highlight) +# - highlight (faster than bat, change to your liking) (https://gitlab.com/saalen/highlight) + +preview_cmd="highlight --line-range=1-100 -t 4 --force -O ansi" fd --type file . "$@" | - fzf --multi --height 100% --prompt 'files> ' --preview 'highlight --line-range=1-100 --force -O ansi {}' | + fzf --multi --height 100% --prompt 'files> ' --preview "$preview_cmd {}" | while read -r file; do kks edit "$file" done diff --git a/scripts/kks-lines b/scripts/kks-lines index 26e56f3..8a7f65d 100755 --- a/scripts/kks-lines +++ b/scripts/kks-lines @@ -9,4 +9,4 @@ kks cat | nl -ba -w4 -s' │ ' | fzf --height 100% --prompt 'lines> ' | awk '{print $1}' | - xargs -r -I % kks send execute-keys %gx + xargs -r -I {} kks send "execute-keys '{}gx'" diff --git a/scripts/kks-mru b/scripts/kks-mru index 82e9e3f..d1141d0 100755 --- a/scripts/kks-mru +++ b/scripts/kks-mru @@ -15,5 +15,7 @@ # } # } -(fzf --height 100% --prompt 'mru> ' --preview 'highlight --line-range=1-100 --force -O ansi {}' | +preview_cmd="highlight --line-range=1-100 -t 4 --force -O ansi" + +(fzf --height 100% --prompt 'mru> ' --preview "$preview_cmd {}" | xargs -r kks edit) < ~/.cache/kak-mru