Skip to content

Commit

Permalink
feat: tui
Browse files Browse the repository at this point in the history
  • Loading branch information
Gabriel Musat committed Dec 26, 2022
1 parent bc4eb1a commit 205c854
Show file tree
Hide file tree
Showing 18 changed files with 297 additions and 125 deletions.
11 changes: 7 additions & 4 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ package cmd

import (
"errors"
"fmt"
"strings"

"dep-tree/internal/graph"
"dep-tree/internal/js"
"dep-tree/internal/tui"

"github.com/spf13/cobra"
)
Expand Down Expand Up @@ -41,9 +41,12 @@ var Root = &cobra.Command{
if err != nil {
return err
}
_, content, err := graph.RenderGraph[js.Data](ctx, entrypoint, parser)
fmt.Print(content)
return err
_, board, err := graph.RenderGraph[js.Data](ctx, entrypoint, parser)
if err != nil {
return err
}

return tui.Loop(board)
} else {
return errors.New("file not supported")
}
Expand Down
8 changes: 7 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,21 @@ go 1.19
require (
github.com/alecthomas/participle/v2 v2.0.0-beta.5
github.com/elliotchance/orderedmap/v2 v2.2.0
github.com/gdamore/tcell/v2 v2.5.3
github.com/spf13/cobra v1.6.1
github.com/stretchr/testify v1.8.1
golang.org/x/text v0.5.0
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/gdamore/encoding v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.0.1 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
19 changes: 19 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,21 @@ 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/elliotchance/orderedmap/v2 v2.2.0 h1:7/2iwO98kYT4XkOjA9mBEIwvi4KpGB4cyHeOFOnj4Vk=
github.com/elliotchance/orderedmap/v2 v2.2.0/go.mod h1:85lZyVbpGaGvHvnKa7Qhx7zncAdBIBq6u56Hb1PRU5Q=
github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko=
github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
github.com/gdamore/tcell/v2 v2.5.3 h1:b9XQrT6QGbgI7JvZOJXFNczOQeIYbo8BfeSMzt2sAV0=
github.com/gdamore/tcell/v2 v2.5.3/go.mod h1:wSkrPaXoiIWZqW/g7Px4xc79di6FTcpB8tvaKJ6uGBo=
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA=
github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
Expand All @@ -25,8 +35,17 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220318055525-2edf467146b5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf h1:MZ2shdL+ZM/XzY3ZGOnh4Nlpnxz5GSOhOmtHo3iPU6M=
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM=
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Expand Down
33 changes: 14 additions & 19 deletions internal/board/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import (
)

const (
cellType = "cellType"
cellType = "cellType"

blockChar = "blockChar"
blockSpace = "blockSpace"
arrow = "arrow"
Expand All @@ -17,6 +18,7 @@ const (
type Block struct {
Id string
Label string
Tags map[string]string
Position utils.Vector
}

Expand All @@ -34,28 +36,25 @@ func (b *Block) Render(matrix *graphics.Matrix) error {
}
char := rune(b.Label[idIndex])
if char != ' ' {
cell.PlaceChar(char)
cell.Tag(cellType, blockChar)
cell.PlaceChar(char).
Tag(cellType, blockChar).
Tags(b.Tags)
} else {
cell.Tag(cellType, blockSpace)
cell.PlaceEmpty().
Tag(cellType, blockSpace)
}
}
}
return nil
}

func (b *Board) AddBlock(
id string,
label string,
x int,
y int,
) error {
if _, ok := b.blocks.Get(id); ok {
return fmt.Errorf("blockChar %s is already present", id)
func (b *Board) AddBlock(block *Block) error {
if _, ok := b.blocks.Get(block.Id); ok {
return fmt.Errorf("blockChar %s is already present", block.Id)
}

newW := x + len(label)
newH := y + 1
newW := block.Position.X + len(block.Label)
newH := block.Position.Y + 1

if newW > b.w {
b.w = newW
Expand All @@ -64,10 +63,6 @@ func (b *Board) AddBlock(
b.h = newH
}

b.blocks.Set(id, &Block{
Id: id,
Label: label,
Position: utils.Vec(x, y),
})
b.blocks.Set(block.Id, block)
return nil
}
21 changes: 13 additions & 8 deletions internal/board/board.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,33 +23,38 @@ func MakeBoard() *Board {
}
}

func (b *Board) Render() (string, error) {
// 1. Create Cell matrix.
func (b *Board) makeMatrix() (*graphics.Matrix, error) {
matrix := graphics.NewMatrix(b.w, b.h)

// 2. Render blocks.
for _, k := range b.blocks.Keys() {
block, _ := b.blocks.Get(k)
err := block.Render(matrix)
if err != nil {
return matrix.Render(), fmt.Errorf("error rendering blockChar %s: %w", block.Label, err)
return matrix, fmt.Errorf("error rendering blockChar %s: %w", block.Label, err)
}
}

// 3. Render connectors.
for _, k := range b.connectors.Keys() {
connector, _ := b.connectors.Get(k)
err := connector.Render(matrix)
if err != nil {
return matrix.Render(), fmt.Errorf(
return matrix, fmt.Errorf(
"error rendering connector from %s to %s: %w",
strings.TrimSpace(connector.from.Label),
strings.TrimSpace(connector.to.Label),
err,
)
}
}
return matrix, nil
}

// 4. dump Cells to a string.
return matrix.Render(), nil
func (b *Board) Cells() ([][]graphics.CellStack, error) {
matrix, err := b.makeMatrix()
return matrix.Cells(), err
}

func (b *Board) Render() (string, error) {
matrix, err := b.makeMatrix()
return matrix.Render(), err
}
10 changes: 8 additions & 2 deletions internal/board/board_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"testing"

"github.com/stretchr/testify/require"

"dep-tree/internal/utils"
)

const RebuildTestsEnv = "REBUILD_TESTS"
Expand Down Expand Up @@ -238,14 +240,18 @@ func TestBoard(t *testing.T) {
a := require.New(t)
board := MakeBoard()
for _, block := range tt.Blocks {
err := board.AddBlock(block.name, block.name, block.x, block.y)
err := board.AddBlock(&Block{
Id: block.name,
Label: block.name,
Position: utils.Vec(block.x, block.y),
})
a.NoError(err)
}
for _, connections := range tt.Connections {
from := tt.Blocks[connections.from]
for _, toI := range connections.to {
to := tt.Blocks[toI]
err := board.AddConnector(from.name, to.name)
err := board.AddConnector(from.name, to.name, nil)
a.NoError(err)
}
}
Expand Down
29 changes: 14 additions & 15 deletions internal/board/connector.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,10 @@ import (
"dep-tree/internal/utils"
)

const (
noCrossOwnership = "noCrossOwnership"
)

type Connector struct {
from *Block
to *Block
tags map[string]string
}

func checkCollision(
Expand All @@ -29,10 +26,6 @@ func checkCollision(
cellType: func(value string) bool {
return utils.InArray(value, []string{blockChar, arrow})
},
// if there is a line, belonging to another connector which claimed ownership, then hit.
noCrossOwnership: func(value string) bool {
return value != from.Id
},
},
to.Position.Y-from.Position.Y,
)
Expand All @@ -52,9 +45,11 @@ func (c *Connector) Render(matrix *graphics.Matrix) error {
} else {
from.X += utils.PrefixN(c.from.Label, ' ')
}

// 2. start with just one vertical step.
tracer := graphics.NewLineTracer(from)
tracer := graphics.
NewLineTracer(from).
WithTags(c.tags)

var cur utils.Vector
if reverseY {
cur = tracer.MoveHorizontal(false)
Expand Down Expand Up @@ -88,13 +83,11 @@ func (c *Connector) Render(matrix *graphics.Matrix) error {
if cell == nil {
return fmt.Errorf("moved to invalid position (%d, %d) while tracing horizontal line. This error should not be reachable", cur.X, cur.Y)
}
cell.Tag(noCrossOwnership, c.from.Id)
}

// 4. displacing vertically until aligned...
for cur.Y != c.to.Position.Y && cur.Y >= 0 && cur.Y < matrix.H() {
cur = tracer.MoveVertical(cur.Y > c.to.Position.Y)
matrix.Cell(cur).Tag(noCrossOwnership, c.from.Id)
}

// 5. moving horizontally until meeting target node...
Expand All @@ -113,13 +106,18 @@ func (c *Connector) Render(matrix *graphics.Matrix) error {
// 6. placing arrow in target node...
cell = matrix.Cell(cur)
if cell != nil {
cell.PlaceArrow(reverseX)
cell.Tag(cellType, arrow)
cell.PlaceArrow(reverseX).
Tag(cellType, arrow).
Tags(c.tags)
}
return nil
}

func (b *Board) AddConnector(from string, to string) error {
func (b *Board) AddConnector(
from string,
to string,
tags map[string]string,
) error {
var fromBlock *Block
var toBlock *Block
if block, ok := b.blocks.Get(from); ok {
Expand All @@ -140,6 +138,7 @@ func (b *Board) AddConnector(from string, to string) error {
b.connectors.Set(key, &Connector{
from: fromBlock,
to: toBlock,
tags: tags,
})
return nil
}
39 changes: 34 additions & 5 deletions internal/board/graphics/cell.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package graphics

import "dep-tree/internal/utils"

const (
charCell = iota
linesCell
arrowCell
emptyCell
)

type Lines struct {
Expand All @@ -14,15 +17,41 @@ type Lines struct {
cross bool
}

type Char struct {
runes []rune
}

type Cell struct {
t int
char Char
char rune
lines Lines
arrowInverted bool

tags map[string]string
}

func (c *Cell) Tags(tags map[string]string) *Cell {
if c.tags == nil {
c.tags = tags
} else {
utils.Merge(c.tags, tags)
}
return c
}

func (c *Cell) Tag(key string, value string) *Cell {
if c.tags == nil {
c.tags = map[string]string{key: value}
} else {
c.tags[key] = value
}
return c
}

func (c *Cell) Is(key string, value string) bool {
if c.tags == nil {
return false
} else if v, ok := c.tags[key]; ok {
return value == v
} else {
return false
}
}

func LinesCell(lines Lines) *Cell {
Expand Down
14 changes: 14 additions & 0 deletions internal/board/graphics/cell_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,17 @@ func TestCell_mergeLines(t *testing.T) {
a.Equal(cell.lines.b, true)
a.Equal(cell.lines.cross, true)
}

func TestCell_Tag(t *testing.T) {
a := require.New(t)
c := Cell{}

a.Equal(false, c.Is("key", "foo"))
c.Tag("key", "bar")
a.Equal(false, c.Is("key", "foo"))
a.Equal(true, c.Is("key", "bar"))
c.Tag("key", "foo")
c.Tag("otherKey", "bar")
a.Equal(true, c.Is("key", "foo"))
a.Equal(true, c.Is("otherKey", "bar"))
}
Loading

0 comments on commit 205c854

Please sign in to comment.