Skip to content

Commit

Permalink
Use/demo history from PR for golang/go#68780
Browse files Browse the repository at this point in the history
  • Loading branch information
ldemailly committed Aug 8, 2024
1 parent c1304b2 commit 77eee7b
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 7 deletions.
4 changes: 3 additions & 1 deletion example/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"errors"
"flag"
"fmt"
"io"
"os"
Expand Down Expand Up @@ -56,7 +57,7 @@ func autoCompleteCallback(line string, pos int, key rune) (newLine string, newPo

func Main() int {
// Pending https://github.com/golang/go/issues/68780
// flagHistory := flag.String("history", "", "History `file` to use")
flagHistory := flag.String("history", "/tmp/terminal_history", "History `file` to use")
cli.Main()
t, err := terminal.Open()
if err != nil {
Expand All @@ -65,6 +66,7 @@ func Main() int {
defer t.Close()
t.SetPrompt("Terminal demo> ")
t.LoggerSetup()
t.SetHistoryFile(*flagHistory)
fmt.Fprintf(t.Out, "Terminal is open\nis valid %t\nuse exit or ^D or ^C to exit\n", t.IsTerminal())
fmt.Fprintf(t.Out, "Use 'prompt <new prompt>' to change the prompt\n")
fmt.Fprintf(t.Out, "Try 'after duration text...' to see text showing in the middle of edits after said duration\n")
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ require (
)

// replace fortio.org/cli => ../cli
replace golang.org/x/term => github.com/ldemailly/term v0.0.0-20240808164309-1ca6c26d14bf

require (
fortio.org/struct2env v0.4.1 // indirect
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ fortio.org/version v1.0.4 h1:FWUMpJ+hVTNc4RhvvOJzb0xesrlRmG/a+D6bjbQ4+5U=
fortio.org/version v1.0.4/go.mod h1:2JQp9Ax+tm6QKiGuzR5nJY63kFeANcgrZ0osoQFDVm0=
github.com/kortschak/goroutine v1.1.2 h1:lhllcCuERxMIK5cYr8yohZZScL1na+JM5JYPRclWjck=
github.com/kortschak/goroutine v1.1.2/go.mod h1:zKpXs1FWN/6mXasDQzfl7g0LrGFIOiA6cLs9eXKyaMY=
github.com/ldemailly/term v0.0.0-20240808164309-1ca6c26d14bf h1:tSC3QHTyGX/bno3fLgNBikbqJ5+/qBh8bFJVnCXsBrw=
github.com/ldemailly/term v0.0.0-20240808164309-1ca6c26d14bf/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk=
golang.org/x/crypto/x509roots/fallback v0.0.0-20240626151235-a6a393ffd658 h1:i7K6wQLN/0oxF7FT3tKkfMCstxoT4VGG36YIB9ZKLzI=
golang.org/x/crypto/x509roots/fallback v0.0.0-20240626151235-a6a393ffd658/go.mod h1:kNa9WdvYnzFwC79zRpLRMJbdEFlhyM5RPFBBZp/wWH8=
golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM=
golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU=
golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk=
72 changes: 68 additions & 4 deletions terminal.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
package terminal // import "fortio.org/terminal"

import (
"bufio"
"io"
"os"

Expand All @@ -10,10 +11,11 @@ import (
)

type Terminal struct {
fd int
oldState *term.State
term *term.Terminal
Out io.Writer
fd int
oldState *term.State
term *term.Terminal
Out io.Writer
historyFile string
}

// CRWriter is a writer that adds \r before each \n.
Expand Down Expand Up @@ -100,13 +102,75 @@ func (t *Terminal) LoggerSetup() {
log.SetColorMode()
}

func (t *Terminal) SetHistoryFile(f string) {
t.historyFile = f
entries := readOrCreateHistory(f)
for _, e := range entries {
t.term.AddToHistory(e)
}
log.Infof("Loaded %d history entries from %s", len(entries), f)
}

func readOrCreateHistory(f string) []string {
if f == "" {
log.Infof("No history file specified")
return nil
}
// open file or create it
h, err := os.OpenFile(f, os.O_RDWR|os.O_CREATE, 0o600)
if err != nil {
log.Errf("Error opening history file %s: %v", f, err)
return nil
}
defer h.Close()
// read lines separated by \n
var lines []string
scanner := bufio.NewScanner(h)
for scanner.Scan() {
lines = append(lines, scanner.Text())
}
if err := scanner.Err(); err != nil {
log.Errf("Error reading history file %s: %v", f, err)
return nil
}
return lines
}

func saveHistory(f string, h []string) {
if f == "" {
log.Infof("No history file specified")
return
}
// open file or create it
hf, err := os.OpenFile(f, os.O_RDWR|os.O_CREATE, 0o600)
if err != nil {
log.Errf("Error opening history file %s: %v", f, err)
return
}
defer hf.Close()
// write lines separated by \n
for _, l := range h {
_, err := hf.WriteString(l + "\n")
if err != nil {
log.Errf("Error writing history file %s: %v", f, err)
return
}
}
}

func (t *Terminal) Close() error {
if t.oldState == nil {
return nil
}
err := term.Restore(t.fd, t.oldState)
t.oldState = nil
t.Out = os.Stderr
// saving history if any
if t.historyFile != "" {
h := t.term.History()
log.Infof("Saving history (%d commands) to %s", len(h), t.historyFile)
saveHistory(t.historyFile, h)
}
return err
}

Expand Down

0 comments on commit 77eee7b

Please sign in to comment.