2016-08-13 12:49:04 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bufio"
|
|
|
|
"fmt"
|
2017-09-17 11:48:27 +00:00
|
|
|
"io"
|
2016-08-13 12:49:04 +00:00
|
|
|
"log"
|
|
|
|
"net"
|
|
|
|
"os"
|
2016-10-29 23:20:35 +00:00
|
|
|
"strings"
|
2016-08-13 12:49:04 +00:00
|
|
|
|
|
|
|
"github.com/nsf/termbox-go"
|
|
|
|
)
|
|
|
|
|
2017-11-19 18:55:13 +00:00
|
|
|
func run() {
|
2018-05-20 17:30:41 +00:00
|
|
|
f, err := os.Create(gLogPath)
|
2016-08-13 12:49:04 +00:00
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2016-11-22 18:01:29 +00:00
|
|
|
defer os.Remove(gLogPath)
|
2018-05-20 17:30:41 +00:00
|
|
|
defer f.Close()
|
|
|
|
log.SetOutput(f)
|
2016-08-13 12:49:04 +00:00
|
|
|
|
|
|
|
log.Print("hi!")
|
|
|
|
|
|
|
|
if err := termbox.Init(); err != nil {
|
|
|
|
log.Fatalf("initializing termbox: %s", err)
|
|
|
|
}
|
|
|
|
defer termbox.Close()
|
|
|
|
|
2017-12-31 22:10:00 +00:00
|
|
|
termbox.SetOutputMode(termbox.Output256)
|
|
|
|
|
2016-10-27 19:24:42 +00:00
|
|
|
app := newApp()
|
2016-08-13 12:49:04 +00:00
|
|
|
|
2018-06-28 16:37:19 +00:00
|
|
|
for _, path := range gConfigPaths {
|
|
|
|
if _, err := os.Stat(path); !os.IsNotExist(err) {
|
|
|
|
app.readFile(path)
|
|
|
|
}
|
2017-02-11 10:42:16 +00:00
|
|
|
}
|
|
|
|
|
2018-07-11 17:09:26 +00:00
|
|
|
if err := app.nav.readMarks(); err != nil {
|
|
|
|
app.ui.printf("reading marks file: %s", err)
|
|
|
|
}
|
|
|
|
|
2018-07-11 17:49:55 +00:00
|
|
|
if err := app.readHistory(); err != nil {
|
|
|
|
app.ui.printf("reading history file: %s", err)
|
|
|
|
}
|
|
|
|
|
2017-11-19 18:55:13 +00:00
|
|
|
app.loop()
|
2016-08-13 12:49:04 +00:00
|
|
|
}
|
|
|
|
|
2017-11-19 18:55:13 +00:00
|
|
|
func readExpr() <-chan expr {
|
2016-12-17 21:47:37 +00:00
|
|
|
ch := make(chan expr)
|
2016-10-29 23:20:35 +00:00
|
|
|
|
|
|
|
go func() {
|
2017-11-19 18:55:13 +00:00
|
|
|
c, err := net.Dial(gSocketProt, gSocketPath)
|
|
|
|
if err != nil {
|
|
|
|
log.Printf(fmt.Sprintf("connecting server: %s", err))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2016-12-17 21:47:37 +00:00
|
|
|
fmt.Fprintf(c, "conn %d\n", gClientID)
|
2016-10-29 23:20:35 +00:00
|
|
|
|
2018-04-12 15:04:37 +00:00
|
|
|
ch <- &callExpr{"sync", nil, 1}
|
2017-11-19 18:55:13 +00:00
|
|
|
|
2016-10-29 23:20:35 +00:00
|
|
|
s := bufio.NewScanner(c)
|
|
|
|
for s.Scan() {
|
2016-11-06 14:06:25 +00:00
|
|
|
log.Printf("recv: %s", s.Text())
|
2016-10-29 23:20:35 +00:00
|
|
|
p := newParser(strings.NewReader(s.Text()))
|
|
|
|
if p.parse() {
|
|
|
|
ch <- p.expr
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
c.Close()
|
|
|
|
}()
|
|
|
|
|
|
|
|
return ch
|
|
|
|
}
|
|
|
|
|
2018-06-27 18:15:34 +00:00
|
|
|
func saveFiles(list []string, cp bool) error {
|
2017-07-20 22:26:36 +00:00
|
|
|
c, err := net.Dial(gSocketProt, gSocketPath)
|
2016-08-13 12:49:04 +00:00
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("dialing to save files: %s", err)
|
|
|
|
}
|
|
|
|
defer c.Close()
|
|
|
|
|
|
|
|
log.Printf("saving files: %v", list)
|
|
|
|
|
2017-07-24 20:55:44 +00:00
|
|
|
fmt.Fprintln(c, "save")
|
2016-08-13 12:49:04 +00:00
|
|
|
|
2018-06-27 18:15:34 +00:00
|
|
|
if cp {
|
2017-07-24 20:55:44 +00:00
|
|
|
fmt.Fprintln(c, "copy")
|
2016-08-13 12:49:04 +00:00
|
|
|
} else {
|
2017-07-24 20:55:44 +00:00
|
|
|
fmt.Fprintln(c, "move")
|
2016-08-13 12:49:04 +00:00
|
|
|
}
|
|
|
|
|
2017-07-24 20:55:44 +00:00
|
|
|
for _, f := range list {
|
|
|
|
fmt.Fprintln(c, f)
|
|
|
|
}
|
|
|
|
fmt.Fprintln(c)
|
2016-08-13 12:49:04 +00:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2018-06-27 18:15:34 +00:00
|
|
|
func loadFiles() (list []string, cp bool, err error) {
|
2017-07-20 22:26:36 +00:00
|
|
|
c, e := net.Dial(gSocketProt, gSocketPath)
|
2016-08-13 12:49:04 +00:00
|
|
|
if e != nil {
|
|
|
|
err = fmt.Errorf("dialing to load files: %s", e)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
defer c.Close()
|
|
|
|
|
|
|
|
fmt.Fprintln(c, "load")
|
|
|
|
|
|
|
|
s := bufio.NewScanner(c)
|
|
|
|
|
2016-11-06 18:32:14 +00:00
|
|
|
s.Scan()
|
|
|
|
|
2017-07-24 20:55:44 +00:00
|
|
|
switch s.Text() {
|
2016-11-06 18:32:14 +00:00
|
|
|
case "copy":
|
2018-06-27 18:15:34 +00:00
|
|
|
cp = true
|
2016-08-13 12:49:04 +00:00
|
|
|
case "move":
|
2018-06-27 18:15:34 +00:00
|
|
|
cp = false
|
2016-08-13 12:49:04 +00:00
|
|
|
default:
|
2017-07-24 20:55:44 +00:00
|
|
|
err = fmt.Errorf("unexpected option to copy file(s): %s", s.Text())
|
2016-08-13 12:49:04 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2017-07-24 20:55:44 +00:00
|
|
|
for s.Scan() && s.Text() != "" {
|
|
|
|
list = append(list, s.Text())
|
|
|
|
}
|
2016-08-13 12:49:04 +00:00
|
|
|
|
|
|
|
if s.Err() != nil {
|
|
|
|
err = fmt.Errorf("scanning file list: %s", s.Err())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Printf("loading files: %v", list)
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
2016-11-10 20:25:03 +00:00
|
|
|
|
2016-12-19 18:28:57 +00:00
|
|
|
func sendRemote(cmd string) error {
|
2017-07-20 22:26:36 +00:00
|
|
|
c, err := net.Dial(gSocketProt, gSocketPath)
|
2016-11-10 20:25:03 +00:00
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("dialing to send server: %s", err)
|
|
|
|
}
|
|
|
|
|
2016-11-18 20:38:38 +00:00
|
|
|
fmt.Fprintln(c, cmd)
|
2016-11-10 20:25:03 +00:00
|
|
|
|
2017-09-17 11:48:27 +00:00
|
|
|
// XXX: Standard net.Conn interface does not include a CloseWrite method
|
|
|
|
// but net.UnixConn and net.TCPConn implement it so the following should be
|
|
|
|
// safe as long as we do not use other types of connections. We need
|
|
|
|
// CloseWrite to notify the server that this is not a persistent connection
|
|
|
|
// and it should be closed after the response.
|
|
|
|
if v, ok := c.(interface {
|
|
|
|
CloseWrite() error
|
|
|
|
}); ok {
|
|
|
|
v.CloseWrite()
|
|
|
|
}
|
|
|
|
|
|
|
|
io.Copy(os.Stdout, c)
|
|
|
|
|
|
|
|
c.Close()
|
|
|
|
|
2016-11-10 20:25:03 +00:00
|
|
|
return nil
|
|
|
|
}
|