Explorar o código

Replace bubble tea with tcell

Johan Rong hai 1 mes
pai
achega
2972d91593
Modificáronse 6 ficheiros con 159 adicións e 86 borrados
  1. 4 0
      go.mod
  2. 39 0
      go.sum
  3. 29 68
      internal/editor/action.go
  4. 11 10
      internal/editor/model.go
  5. 4 3
      internal/editor/update.go
  6. 72 5
      main.go

+ 4 - 0
go.mod

@@ -5,6 +5,7 @@ go 1.26.4
 require (
 	charm.land/bubbles/v2 v2.1.1
 	charm.land/bubbletea/v2 v2.0.8
+	github.com/gdamore/tcell/v3 v3.4.0
 	github.com/zyedidia/rope v0.0.0-20210616205215-37fbf22eab3a
 )
 
@@ -18,6 +19,7 @@ require (
 	github.com/charmbracelet/x/windows v0.2.2 // indirect
 	github.com/clipperhouse/displaywidth v0.11.0 // indirect
 	github.com/clipperhouse/uax29/v2 v2.7.0 // indirect
+	github.com/gdamore/encoding v1.0.1 // indirect
 	github.com/lucasb-eyer/go-colorful v1.4.0 // indirect
 	github.com/mattn/go-runewidth v0.0.24 // indirect
 	github.com/muesli/cancelreader v0.2.2 // indirect
@@ -25,4 +27,6 @@ require (
 	github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
 	golang.org/x/sync v0.21.0 // indirect
 	golang.org/x/sys v0.46.0 // indirect
+	golang.org/x/term v0.43.0 // indirect
+	golang.org/x/text v0.37.0 // indirect
 )

+ 39 - 0
go.sum

@@ -24,6 +24,10 @@ github.com/clipperhouse/displaywidth v0.11.0 h1:lBc6kY44VFw+TDx4I8opi/EtL9m20WSE
 github.com/clipperhouse/displaywidth v0.11.0/go.mod h1:bkrFNkf81G8HyVqmKGxsPufD3JhNl3dSqnGhOoSD/o0=
 github.com/clipperhouse/uax29/v2 v2.7.0 h1:+gs4oBZ2gPfVrKPthwbMzWZDaAFPGYK72F0NJv2v7Vk=
 github.com/clipperhouse/uax29/v2 v2.7.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM=
+github.com/gdamore/encoding v1.0.1 h1:YzKZckdBL6jVt2Gc+5p82qhrGiqMdG/eNs6Wy0u3Uhw=
+github.com/gdamore/encoding v1.0.1/go.mod h1:0Z0cMFinngz9kS1QfMjCP8TY7em3bZYeeklsSDPivEo=
+github.com/gdamore/tcell/v3 v3.4.0 h1:VUym1HQZiYodA5PGQrqLxF7QwqQndcAUwQD7G7XUy5E=
+github.com/gdamore/tcell/v3 v3.4.0/go.mod h1:fjKxNiIFwbzTxDU+i+AAMz+xPOgXVaZq5tbShsKseHc=
 github.com/lucasb-eyer/go-colorful v1.4.0 h1:UtrWVfLdarDgc44HcS7pYloGHJUjHV/4FwW4TvVgFr4=
 github.com/lucasb-eyer/go-colorful v1.4.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
 github.com/mattn/go-runewidth v0.0.24 h1:cpokDiIn0MGnhdHwuWnJBITySJ20QyNGnY2kR/ay2DU=
@@ -34,11 +38,46 @@ github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
 github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
 github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
 github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
 github.com/zyedidia/rope v0.0.0-20210616205215-37fbf22eab3a h1:+VbuFCNAjzVffErUlm0TIAZClFxFZwJ1il6qtWrnIg8=
 github.com/zyedidia/rope v0.0.0-20210616205215-37fbf22eab3a/go.mod h1:IKo1js3O2gdESAUH9F3B33wlrRBnpJMJR/gXyY0a3ho=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
 golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM=
 golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw=
 golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4=
+golang.org/x/term v0.43.0/go.mod h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc=
+golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

+ 29 - 68
internal/editor/action.go

@@ -1,152 +1,113 @@
 package editor
 
 import (
-	"charm.land/bubbles/v2/key"
-	tea "charm.land/bubbletea/v2"
+	//"charm.land/bubbles/v2/key"
+	//tea "charm.land/bubbletea/v2"
 )
 
 type Action = struct {
-	Binding  key.Binding
+	Binding  string
 	Command  string
 	HasArgs  bool
-	Callback func(*Model, []string) tea.Cmd
+	Callback func(*Model, []string)
 }
 
-//type Actionmap = struct {
-//	Left, Right, Up, Down, CursorUp, CursorDown, ClearCursors, Tab, Backtab, Newline, Delete, Quit Action
-//}
-
 func DefaultActions() []Action {
 	return []Action{
 		Action{
-			Binding: key.NewBinding(
-				key.WithKeys("left"),
-			),
+			Binding: "left",
 			Command: "TODO:",
 			HasArgs: false,
-			Callback: func(m *Model, args []string) tea.Cmd {
+			Callback: func(m *Model, args []string) {
 				m.Buffer.MoveHoriz(-1)	
-				return nil
 			},
 		},
 		Action{
-			Binding: key.NewBinding(
-				key.WithKeys("right"),
-			),
+			Binding: "right",
 			Command: "TODO:",
 			HasArgs: false,
-			Callback: func(m *Model, args []string) tea.Cmd {
+			Callback: func(m *Model, args []string) {
 				m.Buffer.MoveHoriz(1)
-				return nil
 			},
 		},
 		Action{
-			Binding: key.NewBinding(
-				key.WithKeys("up"),
-			),
+			Binding: "up",
 			Command: "TODO:",
 			HasArgs: false,
-			Callback: func(m *Model, args []string) tea.Cmd {
+			Callback: func(m *Model, args []string) {
 				m.Buffer.MoveVert(-1)
-				return nil
 			},
 		},
 		Action{
-			Binding: key.NewBinding(
-				key.WithKeys("down"),
-			),
+			Binding: "down",
 			Command: "TODO:",
 			HasArgs: false,
-			Callback: func(m *Model, args []string) tea.Cmd {
+			Callback: func(m *Model, args []string) {
 				m.Buffer.MoveVert(1)
-				return nil
 			},
 		},
 		Action{
-			Binding: key.NewBinding(
-				key.WithKeys("shift+up"),
-			),
+			Binding: "shift+up",
 			Command: "TODO:",
 			HasArgs: false,
-			Callback: func(m *Model, args []string) tea.Cmd {
+			Callback: func(m *Model, args []string) {
 				m.Buffer.AddCursorVert(-1)
-				return nil
 			},
 		},
 		Action{
-			Binding: key.NewBinding(
-				key.WithKeys("shift+down"),
-			),
+			Binding: "shift+down",
 			Command: "TODO:",
 			HasArgs: false,
-			Callback: func(m *Model, args []string) tea.Cmd {
+			Callback: func(m *Model, args []string) {
 				m.Buffer.AddCursorVert(1)
-				return nil
 			},
 		},
 		Action{
-			Binding: key.NewBinding(
-				key.WithKeys("esc"),
-			),
+			Binding: "esc",
 			Command: "TODO:",
 			HasArgs: false,
-			Callback: func(m *Model, args []string) tea.Cmd {
+			Callback: func(m *Model, args []string) {
 				m.Buffer.ClearCursors()
-				return nil
 			},
 		},
 		Action{
-			Binding: key.NewBinding(
-				key.WithKeys("tab"),
-			),
+			Binding: "tab",
 			Command: "TODO:",
 			HasArgs: false,
-			Callback: func(m *Model, args []string) tea.Cmd {
+			Callback: func(m *Model, args []string) {
 				//TODO: implement m.Buffer.
-				return nil
 			},
 		},
 		Action{
-			Binding: key.NewBinding(
-				key.WithKeys("shift+tab"),
-			),
+			Binding: "shift+tab",
 			Command: "TODO:",
 			HasArgs: false,
-			Callback: func(m *Model, args []string) tea.Cmd {
+			Callback: func(m *Model, args []string) {
 				// TODO: implement m.Buffer.
-				return nil
 			},
 		},
 		Action{
-			Binding: key.NewBinding(
-				key.WithKeys("backspace"),
-			),
+			Binding: "backspace",
 			Command: "TODO:",
 			HasArgs: false,
-			Callback: func(m *Model, args []string) tea.Cmd {
+			Callback: func(m *Model, args []string) {
 				m.Buffer.Delete()
-				return nil
 			},
 		},
 		Action{
-			Binding: key.NewBinding(
-				key.WithKeys("enter"),
-			),
+			Binding: "enter",
 			Command: "TODO:",
 			HasArgs: false,
-			Callback: func(m *Model, args []string) tea.Cmd {
+			Callback: func(m *Model, args []string) {
 				m.Buffer.Insert('\n')
-				return nil
 			},
 		},
 		Action{
-			Binding: key.NewBinding(
-				key.WithKeys("ctrl+c"),
-			),
+			Binding: "ctrl+c",
 			Command: "q",
 			HasArgs: false,
-			Callback: func(m *Model, args []string) tea.Cmd {
-				return tea.Quit
+			Callback: func(m *Model, args []string) {
+				m.Quit()
 			},
 		},
 	}

+ 11 - 10
internal/editor/model.go

@@ -2,20 +2,15 @@ package editor
 
 import (
 	"moose/internal/buffer"
-	"strings"
-	"unicode/utf8"
-
-	"charm.land/bubbles/v2/viewport"
-	tea "charm.land/bubbletea/v2"
 )
 
 type Model struct {
 	Buffer        buffer.Buffer
 	CommandBuffer buffer.Buffer
-	Viewport      viewport.Model
 	Actions       []Action
 	Width         int
 	Height        int
+	ShouldQuit   bool
 }
 
 func NewModel() Model {
@@ -27,19 +22,23 @@ func NewModel() Model {
 		},
 	}
 
-	vp := viewport.New()
-	vp.MouseWheelEnabled = false
+	//vp := viewport.New()
+	//vp.MouseWheelEnabled = false
 
 	model := Model{
 		Buffer:   initialBuf,
-		Viewport: vp,
 		Actions: DefaultActions(),
+		ShouldQuit: false,
 	}
 
-	model.Viewport.SetContent(model.renderedContent())
 	return model
 }
 
+func (m *Model) Quit() {
+	m.ShouldQuit = true
+}
+
+/*
 func (m Model) Init() tea.Cmd {
 	return nil
 }
@@ -102,3 +101,5 @@ func (m Model) renderedContent() string {
 
 	return out.String()
 }
+
+*/

+ 4 - 3
internal/editor/update.go

@@ -2,11 +2,11 @@ package editor
 
 import (
 	//"fmt"
-	"charm.land/bubbles/v2/key"
-	tea "charm.land/bubbletea/v2"
+	//"github.com/gdamore/tcell"
+
 )
 
-func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
+/*func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 	switch msg := msg.(type) {
 	case tea.WindowSizeMsg:
 		m.Width = msg.Width
@@ -47,3 +47,4 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 
 	return m, nil
 }
+*/

+ 72 - 5
main.go

@@ -6,15 +6,82 @@ import (
 
 	"moose/internal/editor"
 
-	tea "charm.land/bubbletea/v2"
+	//"unicode/utf8"
+	"strings"
+	"github.com/gdamore/tcell/v3"
+
+	//tea "charm.land/bubbletea/v2"
 )
 
 func main() {
-	model := editor.NewModel()
+	m := editor.NewModel()
 
-	p := tea.NewProgram(model)
-	if _, err := p.Run(); err != nil {
-		fmt.Printf("moose: error: %v", err)
+	s, err := tcell.NewScreen()
+	if err != nil {
+		fmt.Println("moose: error: %v", err)
+		os.Exit(1)
+	}
+	if err := s.Init(); err != nil {
+		fmt.Println("moose: error: %v", err)
 		os.Exit(1)
 	}
+
+	defStyle := tcell.StyleDefault.Background(tcell.ColorDefault).Foreground(tcell.ColorDefault)
+	s.SetStyle(defStyle)
+
+	s.EnableMouse()
+	s.Clear()
+
+	quit := func() {
+		maybePanic := recover()
+		s.Fini()
+		if maybePanic != nil {
+			panic(maybePanic)
+		}
+	}
+	defer quit()
+
+	for {
+		s.Clear()
+
+		if m.ShouldQuit {
+			s.PutStrStyled(0, 2, "tried to quit", defStyle)
+			return
+		}
+
+		ev := <-s.EventQ()
+
+		switch ev := ev.(type) {
+		case *tcell.EventResize:
+			s.Sync()
+		case *tcell.EventKey:
+			for i := range m.Actions {
+				action := m.Actions[i]
+
+				if strings.ToLower(ev.Name()) == strings.ToLower(action.Binding) {
+					s.PutStrStyled(0, 1, "found match", defStyle)
+					action.Callback(&m, []string{})
+					break
+				}
+			}
+
+			//if utf8.RuneCountInString(ev.Name()) == 1 {
+			if ev.Name() != "" {
+				for _, r := range ev.Name() {
+					m.Buffer.Insert(r)
+				}
+			}
+
+			s.PutStrStyled(0, 0, strings.ToLower(ev.Name()), defStyle)
+		}
+		s.Show()
+	}
+
+	//model := editor.NewModel()
+//
+	//p := tea.NewProgram(model)
+	//if _, err := p.Run(); err != nil {
+	//	fmt.Printf("moose: error: %v", err)
+	//	os.Exit(1)
+	//}
 }