Allowed open-right to work on all columns

Previously it only worked on the right-most column.  Also bounded this command to "O" (this might change).
This commit is contained in:
Leon Mika 2022-07-01 16:15:54 +10:00
parent 975955236f
commit 5424a6b927
6 changed files with 163 additions and 9 deletions

View file

@ -187,11 +187,7 @@ func (cm *CommandMapping) RegisterViewCommands() {
grid := ctx.Frame().Grid()
cellX, _ := grid.CellPosition()
height, width := ctx.ModelVC().Model().Dimensions()
if cellX == width-1 {
return ctx.ModelVC().Resize(height, width+1)
}
return nil
return ctx.ModelVC().OpenRight(cellX)
})
cm.Define("open-down", "Inserts a row below the curser", "", func(ctx *CommandContext) error {
@ -277,7 +273,7 @@ func (cm *CommandMapping) RegisterViewCommands() {
cm.Define("enter-command", "Enter command", "", func(ctx *CommandContext) error {
ctx.Frame().Prompt(PromptOptions{
Prompt: ":",
Prompt: ":",
CancelOnEmptyBackspace: true,
}, func(res string) error {
return cm.Eval(ctx, res)
@ -407,6 +403,7 @@ func (cm *CommandMapping) RegisterViewKeyBindings() {
cm.MapKey('a', cm.Command("append"))
cm.MapKey('O', cm.Command("open-right"))
cm.MapKey('D', cm.Command("delete-row"))
cm.MapKey('/', cm.Command("search"))

1
go.mod
View file

@ -7,4 +7,5 @@ require (
github.com/lmika/shellwords v0.0.0-20140714114018-ce258dd729fe
github.com/mattn/go-runewidth v0.0.10 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/stretchr/testify v1.7.5 // indirect
)

15
go.sum
View file

@ -1,3 +1,6 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
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/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko=
github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
github.com/gdamore/tcell v1.4.0 h1:vUnHwJRvcPQa3tzi+0QI4U9JINXYJlOz9yiaiPQ2wMU=
@ -9,11 +12,23 @@ github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.10 h1:CoZ3S2P7pvtP45xOtBw+/mDL2z0RKI576gSkzRRpdGg=
github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
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.1.0 h1:+2KBaVoUmb9XzDsrx/Ct0W/EYOSFf/nWTauy++DprtY=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.5 h1:s5PTfem8p8EbKQOctVV53k6jCJt3UX4IEJzwh+C324Q=
github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756 h1:9nuHUbU8dRnRRfj9KjWUVrJeoexdbeMjttk6Oh1rD10=
golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
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=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View file

@ -14,12 +14,20 @@ type StdModel struct {
//
func NewSingleCellStdModel() *StdModel {
sm := new(StdModel)
sm.appendStr([]string { "" })
sm.appendStr([]string{""})
sm.dirty = false
return sm
}
func NewStdModelFromSlice(str [][]string) *StdModel {
sm := new(StdModel)
for _, r := range str {
sm.appendStr(r)
}
return sm
}
/**
* The dimensions of the model (height, width).
*/
@ -73,7 +81,7 @@ func (sm *StdModel) SetCellValue(r, c int, value string) {
func (sm *StdModel) appendStr(row []string) {
if len(sm.Cells) == 0 {
cells := sm.strSliceToCell(row, len(row))
sm.Cells = [][]Cell{ cells }
sm.Cells = [][]Cell{cells}
return
}

View file

@ -44,7 +44,9 @@ func (gvm *ModelViewCtrl) SetRowAttrs(row int, newAttrs SliceAttr) {
}
func (gvm *ModelViewCtrl) SetColAttrs(col int, newAttrs SliceAttr) {
gvm.colAttrs[col] = newAttrs
if col >= 0 && col < len(gvm.colAttrs) {
gvm.colAttrs[col] = newAttrs
}
}
func (gvm *ModelViewCtrl) SetCellValue(r, c int, newValue string) error {
@ -69,6 +71,39 @@ func (gvm *ModelViewCtrl) Resize(newRow, newCol int) error {
return nil
}
func (gvm *ModelViewCtrl) OpenRight(col int) error {
if col < 0 {
return errors.New("col out of bound")
}
return gvm.insertColumn(col + 1)
}
func (gvm *ModelViewCtrl) insertColumn(col int) error {
rwModel, isRWModel := gvm.model.(RWModel)
if !isRWModel {
return ErrModelReadOnly
}
dr, dc := rwModel.Dimensions()
if col < 0 || col > dc {
return errors.New("col out of bound")
}
rwModel.Resize(dr, dc+1)
for c := dc; c >= col; c-- {
for r := 0; r < dr; r++ {
if c == col {
rwModel.SetCellValue(r, c, "")
} else {
rwModel.SetCellValue(r, c, rwModel.CellValue(r, c-1))
}
}
}
return nil
}
// Deletes a row of a model
func (gvm *ModelViewCtrl) DeleteRow(row int) error {
rwModel, isRWModel := gvm.model.(RWModel)

98
viewmodel_test.go Normal file
View file

@ -0,0 +1,98 @@
package main
import (
"fmt"
"github.com/stretchr/testify/assert"
"testing"
)
func TestModelViewCtrl_OpenRight(t *testing.T) {
t.Run("should move cols to the right within the model", func(t *testing.T) {
rwModel := NewStdModelFromSlice([][]string{
{"letters", "numbers", "greek"},
{"a", "1", "alpha"},
{"b", "2", "bravo"},
{"c", "3", "charlie"},
})
mvc := NewGridViewModel(rwModel)
err := mvc.OpenRight(1)
assert.NoError(t, err)
assertModel(t, rwModel, [][]string{
{"letters", "numbers", "", "greek"},
{"a", "1", "", "alpha"},
{"b", "2", "", "bravo"},
{"c", "3", "", "charlie"},
})
})
t.Run("should move cols to the right at the left of the model", func(t *testing.T) {
rwModel := NewStdModelFromSlice([][]string{
{"letters", "numbers", "greek"},
{"a", "1", "alpha"},
{"b", "2", "bravo"},
{"c", "3", "charlie"},
})
mvc := NewGridViewModel(rwModel)
err := mvc.OpenRight(0)
assert.NoError(t, err)
assertModel(t, rwModel, [][]string{
{"letters", "", "numbers", "greek"},
{"a", "", "1", "alpha"},
{"b", "", "2", "bravo"},
{"c", "", "3", "charlie"},
})
})
t.Run("should move cols to the right at the right of the model", func(t *testing.T) {
rwModel := NewStdModelFromSlice([][]string{
{"letters", "numbers", "greek"},
{"a", "1", "alpha"},
{"b", "2", "bravo"},
{"c", "3", "charlie"},
})
mvc := NewGridViewModel(rwModel)
err := mvc.OpenRight(2)
assert.NoError(t, err)
assertModel(t, rwModel, [][]string{
{"letters", "numbers", "greek", ""},
{"a", "1", "alpha", ""},
{"b", "2", "bravo", ""},
{"c", "3", "charlie", ""},
})
})
t.Run("should return error if row out of bounds", func(t *testing.T) {
scenario := []int{-1, 3, 12}
for _, scenario := range scenario {
t.Run(fmt.Sprint(scenario), func(t *testing.T) {
rwModel := NewStdModelFromSlice([][]string{
{"letters", "numbers", "greek"},
{"a", "1", "alpha"},
{"b", "2", "bravo"},
{"c", "3", "charlie"},
})
mvc := NewGridViewModel(rwModel)
err := mvc.OpenRight(scenario)
assert.Error(t, err)
})
}
})
}
func assertModel(t *testing.T, actual Model, expected [][]string) {
dr, dc := actual.Dimensions()
assert.Equalf(t, len(expected), dr, "number of rows in model")
for r, row := range expected {
assert.Equalf(t, len(row), dc, "number of cols in row %v", r)
for c, cell := range row {
assert.Equalf(t, cell, actual.CellValue(r, c), "cell value at row %v, col %v", r, c)
}
}
}