Browse Source

chore: upgrade to gods v2

gods v2 uses go generics rather than interfaces which simplifies the
code considerably
Michael Yang 4 months ago
parent
commit
cb40d60469
5 changed files with 111 additions and 132 deletions
  1. 1 1
      go.mod
  2. 2 2
      go.sum
  3. 92 107
      readline/buffer.go
  4. 13 19
      readline/history.go
  5. 3 3
      readline/readline.go

+ 1 - 1
go.mod

@@ -4,7 +4,6 @@ go 1.23.4
 
 require (
 	github.com/containerd/console v1.0.3
-	github.com/emirpasic/gods v1.18.1
 	github.com/gin-gonic/gin v1.10.0
 	github.com/golang/protobuf v1.5.4 // indirect
 	github.com/google/uuid v1.6.0
@@ -18,6 +17,7 @@ require (
 require (
 	github.com/agnivade/levenshtein v1.1.1
 	github.com/d4l3k/go-bfloat16 v0.0.0-20211005043715-690c3bdd05f1
+	github.com/emirpasic/gods/v2 v2.0.0-alpha
 	github.com/google/go-cmp v0.6.0
 	github.com/mattn/go-runewidth v0.0.14
 	github.com/nlpodyssey/gopickle v0.3.0

+ 2 - 2
go.sum

@@ -42,8 +42,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g=
 github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
-github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
-github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
+github.com/emirpasic/gods/v2 v2.0.0-alpha h1:dwFlh8pBg1VMOXWGipNMRt8v96dKAIvBehtCt6OtunU=
+github.com/emirpasic/gods/v2 v2.0.0-alpha/go.mod h1:W0y4M2dtBB9U5z3YlghmpuUhiaZT2h6yoeE+C1sCp6A=
 github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=

+ 92 - 107
readline/buffer.go

@@ -4,7 +4,7 @@ import (
 	"fmt"
 	"os"
 
-	"github.com/emirpasic/gods/lists/arraylist"
+	"github.com/emirpasic/gods/v2/lists/arraylist"
 	"github.com/mattn/go-runewidth"
 	"golang.org/x/term"
 )
@@ -12,9 +12,9 @@ import (
 type Buffer struct {
 	DisplayPos int
 	Pos        int
-	Buf        *arraylist.List
+	Buf        *arraylist.List[rune]
 	// LineHasSpace is an arraylist of bools to keep track of whether a line has a space at the end
-	LineHasSpace *arraylist.List
+	LineHasSpace *arraylist.List[bool]
 	Prompt       *Prompt
 	LineWidth    int
 	Width        int
@@ -33,8 +33,8 @@ func NewBuffer(prompt *Prompt) (*Buffer, error) {
 	b := &Buffer{
 		DisplayPos:   0,
 		Pos:          0,
-		Buf:          arraylist.New(),
-		LineHasSpace: arraylist.New(),
+		Buf:          arraylist.New[rune](),
+		LineHasSpace: arraylist.New[bool](),
 		Prompt:       prompt,
 		Width:        width,
 		Height:       height,
@@ -46,40 +46,33 @@ func NewBuffer(prompt *Prompt) (*Buffer, error) {
 
 func (b *Buffer) GetLineSpacing(line int) bool {
 	hasSpace, _ := b.LineHasSpace.Get(line)
-
-	if hasSpace == nil {
-		return false
-	}
-
-	return hasSpace.(bool)
+	return hasSpace
 }
 
 func (b *Buffer) MoveLeft() {
 	if b.Pos > 0 {
 		// asserts that we retrieve a rune
-		if e, ok := b.Buf.Get(b.Pos - 1); ok {
-			if r, ok := e.(rune); ok {
-				rLength := runewidth.RuneWidth(r)
-
-				if b.DisplayPos%b.LineWidth == 0 {
-					fmt.Print(CursorUp + CursorBOL + CursorRightN(b.Width))
-					if rLength == 2 {
-						fmt.Print(CursorLeft)
-					}
+		if r, ok := b.Buf.Get(b.Pos - 1); ok {
+			rLength := runewidth.RuneWidth(r)
 
-					line := b.DisplayPos/b.LineWidth - 1
-					hasSpace := b.GetLineSpacing(line)
-					if hasSpace {
-						b.DisplayPos -= 1
-						fmt.Print(CursorLeft)
-					}
-				} else {
-					fmt.Print(CursorLeftN(rLength))
+			if b.DisplayPos%b.LineWidth == 0 {
+				fmt.Print(CursorUp + CursorBOL + CursorRightN(b.Width))
+				if rLength == 2 {
+					fmt.Print(CursorLeft)
 				}
 
-				b.Pos -= 1
-				b.DisplayPos -= rLength
+				line := b.DisplayPos/b.LineWidth - 1
+				hasSpace := b.GetLineSpacing(line)
+				if hasSpace {
+					b.DisplayPos -= 1
+					fmt.Print(CursorLeft)
+				}
+			} else {
+				fmt.Print(CursorLeftN(rLength))
 			}
+
+			b.Pos -= 1
+			b.DisplayPos -= rLength
 		}
 	}
 }
@@ -107,24 +100,22 @@ func (b *Buffer) MoveLeftWord() {
 
 func (b *Buffer) MoveRight() {
 	if b.Pos < b.Buf.Size() {
-		if e, ok := b.Buf.Get(b.Pos); ok {
-			if r, ok := e.(rune); ok {
-				rLength := runewidth.RuneWidth(r)
-				b.Pos += 1
-				hasSpace := b.GetLineSpacing(b.DisplayPos / b.LineWidth)
-				b.DisplayPos += rLength
-
-				if b.DisplayPos%b.LineWidth == 0 {
-					fmt.Print(CursorDown + CursorBOL + CursorRightN(len(b.Prompt.prompt())))
-				} else if (b.DisplayPos-rLength)%b.LineWidth == b.LineWidth-1 && hasSpace {
-					fmt.Print(CursorDown + CursorBOL + CursorRightN(len(b.Prompt.prompt())+rLength))
-					b.DisplayPos += 1
-				} else if b.LineHasSpace.Size() > 0 && b.DisplayPos%b.LineWidth == b.LineWidth-1 && hasSpace {
-					fmt.Print(CursorDown + CursorBOL + CursorRightN(len(b.Prompt.prompt())))
-					b.DisplayPos += 1
-				} else {
-					fmt.Print(CursorRightN(rLength))
-				}
+		if r, ok := b.Buf.Get(b.Pos); ok {
+			rLength := runewidth.RuneWidth(r)
+			b.Pos += 1
+			hasSpace := b.GetLineSpacing(b.DisplayPos / b.LineWidth)
+			b.DisplayPos += rLength
+
+			if b.DisplayPos%b.LineWidth == 0 {
+				fmt.Print(CursorDown + CursorBOL + CursorRightN(len(b.Prompt.prompt())))
+			} else if (b.DisplayPos-rLength)%b.LineWidth == b.LineWidth-1 && hasSpace {
+				fmt.Print(CursorDown + CursorBOL + CursorRightN(len(b.Prompt.prompt())+rLength))
+				b.DisplayPos += 1
+			} else if b.LineHasSpace.Size() > 0 && b.DisplayPos%b.LineWidth == b.LineWidth-1 && hasSpace {
+				fmt.Print(CursorDown + CursorBOL + CursorRightN(len(b.Prompt.prompt())))
+				b.DisplayPos += 1
+			} else {
+				fmt.Print(CursorRightN(rLength))
 			}
 		}
 	}
@@ -182,10 +173,8 @@ func (b *Buffer) MoveToEnd() {
 func (b *Buffer) DisplaySize() int {
 	sum := 0
 	for i := range b.Buf.Size() {
-		if e, ok := b.Buf.Get(i); ok {
-			if r, ok := e.(rune); ok {
-				sum += runewidth.RuneWidth(r)
-			}
+		if r, ok := b.Buf.Get(i); ok {
+			sum += runewidth.RuneWidth(r)
 		}
 	}
 
@@ -257,11 +246,9 @@ func (b *Buffer) countRemainingLineWidth(place int) int {
 	for place <= b.LineWidth {
 		counter += 1
 		sum += prevLen
-		if e, ok := b.Buf.Get(b.Pos + counter); ok {
-			if r, ok := e.(rune); ok {
-				place += runewidth.RuneWidth(r)
-				prevLen = len(string(r))
-			}
+		if r, ok := b.Buf.Get(b.Pos + counter); ok {
+			place += runewidth.RuneWidth(r)
+			prevLen = len(string(r))
 		} else {
 			break
 		}
@@ -346,64 +333,62 @@ func (b *Buffer) drawRemaining() {
 
 func (b *Buffer) Remove() {
 	if b.Buf.Size() > 0 && b.Pos > 0 {
-		if e, ok := b.Buf.Get(b.Pos - 1); ok {
-			if r, ok := e.(rune); ok {
-				rLength := runewidth.RuneWidth(r)
-				hasSpace := b.GetLineSpacing(b.DisplayPos/b.LineWidth - 1)
-
-				if b.DisplayPos%b.LineWidth == 0 {
-					// if the user backspaces over the word boundary, do this magic to clear the line
-					// and move to the end of the previous line
-					fmt.Print(CursorBOL + ClearToEOL + CursorUp + CursorBOL + CursorRightN(b.Width))
-
-					if b.DisplaySize()%b.LineWidth < (b.DisplaySize()-rLength)%b.LineWidth {
-						b.LineHasSpace.Remove(b.DisplayPos/b.LineWidth - 1)
-					}
+		if r, ok := b.Buf.Get(b.Pos - 1); ok {
+			rLength := runewidth.RuneWidth(r)
+			hasSpace := b.GetLineSpacing(b.DisplayPos/b.LineWidth - 1)
 
-					if hasSpace {
-						b.DisplayPos -= 1
-						fmt.Print(CursorLeft)
-					}
+			if b.DisplayPos%b.LineWidth == 0 {
+				// if the user backspaces over the word boundary, do this magic to clear the line
+				// and move to the end of the previous line
+				fmt.Print(CursorBOL + ClearToEOL + CursorUp + CursorBOL + CursorRightN(b.Width))
 
-					if rLength == 2 {
-						fmt.Print(CursorLeft + "  " + CursorLeftN(2))
-					} else {
-						fmt.Print(" " + CursorLeft)
-					}
-				} else if (b.DisplayPos-rLength)%b.LineWidth == 0 && hasSpace {
-					fmt.Print(CursorBOL + ClearToEOL + CursorUp + CursorBOL + CursorRightN(b.Width))
+				if b.DisplaySize()%b.LineWidth < (b.DisplaySize()-rLength)%b.LineWidth {
+					b.LineHasSpace.Remove(b.DisplayPos/b.LineWidth - 1)
+				}
 
-					if b.Pos == b.Buf.Size() {
-						b.LineHasSpace.Remove(b.DisplayPos/b.LineWidth - 1)
-					}
+				if hasSpace {
 					b.DisplayPos -= 1
+					fmt.Print(CursorLeft)
+				}
+
+				if rLength == 2 {
+					fmt.Print(CursorLeft + "  " + CursorLeftN(2))
 				} else {
-					fmt.Print(CursorLeftN(rLength))
-					for range rLength {
-						fmt.Print(" ")
-					}
-					fmt.Print(CursorLeftN(rLength))
+					fmt.Print(" " + CursorLeft)
 				}
+			} else if (b.DisplayPos-rLength)%b.LineWidth == 0 && hasSpace {
+				fmt.Print(CursorBOL + ClearToEOL + CursorUp + CursorBOL + CursorRightN(b.Width))
 
-				var eraseExtraLine bool
-				if (b.DisplaySize()-1)%b.LineWidth == 0 || (rLength == 2 && ((b.DisplaySize()-2)%b.LineWidth == 0)) || b.DisplaySize()%b.LineWidth == 0 {
-					eraseExtraLine = true
+				if b.Pos == b.Buf.Size() {
+					b.LineHasSpace.Remove(b.DisplayPos/b.LineWidth - 1)
+				}
+				b.DisplayPos -= 1
+			} else {
+				fmt.Print(CursorLeftN(rLength))
+				for range rLength {
+					fmt.Print(" ")
 				}
+				fmt.Print(CursorLeftN(rLength))
+			}
 
-				b.Pos -= 1
-				b.DisplayPos -= rLength
-				b.Buf.Remove(b.Pos)
-
-				if b.Pos < b.Buf.Size() {
-					b.drawRemaining()
-					// this erases a line which is left over when backspacing in the middle of a line and there
-					// are trailing characters which go over the line width boundary
-					if eraseExtraLine {
-						remainingLines := (b.DisplaySize() - b.DisplayPos) / b.LineWidth
-						fmt.Print(CursorDownN(remainingLines+1) + CursorBOL + ClearToEOL)
-						place := b.DisplayPos % b.LineWidth
-						fmt.Print(CursorUpN(remainingLines+1) + CursorRightN(place+len(b.Prompt.prompt())))
-					}
+			var eraseExtraLine bool
+			if (b.DisplaySize()-1)%b.LineWidth == 0 || (rLength == 2 && ((b.DisplaySize()-2)%b.LineWidth == 0)) || b.DisplaySize()%b.LineWidth == 0 {
+				eraseExtraLine = true
+			}
+
+			b.Pos -= 1
+			b.DisplayPos -= rLength
+			b.Buf.Remove(b.Pos)
+
+			if b.Pos < b.Buf.Size() {
+				b.drawRemaining()
+				// this erases a line which is left over when backspacing in the middle of a line and there
+				// are trailing characters which go over the line width boundary
+				if eraseExtraLine {
+					remainingLines := (b.DisplaySize() - b.DisplayPos) / b.LineWidth
+					fmt.Print(CursorDownN(remainingLines+1) + CursorBOL + ClearToEOL)
+					place := b.DisplayPos % b.LineWidth
+					fmt.Print(CursorUpN(remainingLines+1) + CursorRightN(place+len(b.Prompt.prompt())))
 				}
 			}
 		}
@@ -536,7 +521,7 @@ func (b *Buffer) StringNM(n, m int) string {
 	}
 	for cnt := n; cnt < m; cnt++ {
 		c, _ := b.Buf.Get(cnt)
-		s += string(c.(rune))
+		s += string(c)
 	}
 	return s
 }

+ 13 - 19
readline/history.go

@@ -3,16 +3,17 @@ package readline
 import (
 	"bufio"
 	"errors"
+	"fmt"
 	"io"
 	"os"
 	"path/filepath"
 	"strings"
 
-	"github.com/emirpasic/gods/lists/arraylist"
+	"github.com/emirpasic/gods/v2/lists/arraylist"
 )
 
 type History struct {
-	Buf      *arraylist.List
+	Buf      *arraylist.List[string]
 	Autosave bool
 	Pos      int
 	Limit    int
@@ -22,7 +23,7 @@ type History struct {
 
 func NewHistory() (*History, error) {
 	h := &History{
-		Buf:      arraylist.New(),
+		Buf:      arraylist.New[string](),
 		Limit:    100, // resizeme
 		Autosave: true,
 		Enabled:  true,
@@ -73,14 +74,14 @@ func (h *History) Init() error {
 			continue
 		}
 
-		h.Add([]rune(line))
+		h.Add(line)
 	}
 
 	return nil
 }
 
-func (h *History) Add(l []rune) {
-	h.Buf.Add(l)
+func (h *History) Add(s string) {
+	h.Buf.Add(s)
 	h.Compact()
 	h.Pos = h.Size()
 	if h.Autosave {
@@ -101,22 +102,18 @@ func (h *History) Clear() {
 	h.Buf.Clear()
 }
 
-func (h *History) Prev() []rune {
-	var line []rune
+func (h *History) Prev() (line string) {
 	if h.Pos > 0 {
 		h.Pos -= 1
 	}
-	v, _ := h.Buf.Get(h.Pos)
-	line, _ = v.([]rune)
+	line, _ = h.Buf.Get(h.Pos)
 	return line
 }
 
-func (h *History) Next() []rune {
-	var line []rune
+func (h *History) Next() (line string) {
 	if h.Pos < h.Buf.Size() {
 		h.Pos += 1
-		v, _ := h.Buf.Get(h.Pos)
-		line, _ = v.([]rune)
+		line, _ = h.Buf.Get(h.Pos)
 	}
 	return line
 }
@@ -140,11 +137,8 @@ func (h *History) Save() error {
 
 	buf := bufio.NewWriter(f)
 	for cnt := range h.Size() {
-		v, _ := h.Buf.Get(cnt)
-		line, _ := v.([]rune)
-		if _, err := buf.WriteString(string(line) + "\n"); err != nil {
-			return err
-		}
+		line, _ := h.Buf.Get(cnt)
+		fmt.Fprintln(buf, line)
 	}
 	buf.Flush()
 	f.Close()

+ 3 - 3
readline/readline.go

@@ -120,11 +120,11 @@ func (i *Instance) Readline() (string, error) {
 					if i.History.Pos == i.History.Size() {
 						currentLineBuf = []rune(buf.String())
 					}
-					buf.Replace(i.History.Prev())
+					buf.Replace([]rune(i.History.Prev()))
 				}
 			case KeyDown:
 				if i.History.Pos < i.History.Size() {
-					buf.Replace(i.History.Next())
+					buf.Replace([]rune(i.History.Next()))
 					if i.History.Pos == i.History.Size() {
 						buf.Replace(currentLineBuf)
 					}
@@ -220,7 +220,7 @@ func (i *Instance) Readline() (string, error) {
 		case CharEnter, CharCtrlJ:
 			output := buf.String()
 			if output != "" {
-				i.History.Add([]rune(output))
+				i.History.Add(output)
 			}
 			buf.MoveToEnd()
 			fmt.Println()