Skip to content

Commit

Permalink
Rename item, merge Item map, indent map, local, into Cursor, replace …
Browse files Browse the repository at this point in the history
…hardcoded ints with padding values
  • Loading branch information
kepler471 committed Oct 23, 2020
1 parent ceefa61 commit 41e399e
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 157 deletions.
53 changes: 34 additions & 19 deletions cursor.go
Original file line number Diff line number Diff line change
@@ -1,30 +1,40 @@
package main

// Cursor maintains the state of the view of the Item tree structure
type Cursor struct {
x int
y int
i *item
buffer string
m EditMode
lks string
mks string
// TODO: compose item with cursor?
x int
y int
i *Item
root *Item
local *Item
buffer string
editMode bool
lks string
mks string
m map[int]*Item
f map[int]int
// TODO: compose Item with cursor?
// makes changes globally and test.
//*item
//*Item
}

func NewCursor(i *item) Cursor {
return Cursor{
i: i.Children[0],
m: EditMode(false),
func NewCursor(i *Item) *Cursor {
m := make(map[int]*Item)
f := make(map[int]int)
return &Cursor{
i: i.Children[0],
root: i,
local: i,
m: m,
f: f,
}
}

// TODO: Support Indent and Unindent with cursor movement
// There may be circumstances where the cursor will need to move after
// these actions (thinking mainly about when collapsibility is added.

// Down moves cursor down a single row, and selects the correct item.
// Down moves cursor down a single row, and selects the correct Item.
func (c *Cursor) Down() {
if len(c.i.Children) > 0 {
c.i = c.i.Children[0]
Expand All @@ -35,9 +45,9 @@ func (c *Cursor) Down() {
c.i = c.SearchDown(c.i)
}

// searchDown finds the next item in an ordered tree. If it cannot
// find a suitable next item, it returns the original item.
func (c *Cursor) SearchDown(i *item) *item {
// searchDown finds the next Item in an ordered tree. If it cannot
// find a suitable next Item, it returns the original Item.
func (c *Cursor) SearchDown(i *Item) *Item {
index := i.Locate()
if len(i.Parent.Children) >= index+2 { // Can it move along parent's tail?
i = i.Parent.Children[index+1]
Expand Down Expand Up @@ -65,13 +75,13 @@ func (c *Cursor) Up() {
c.i = c.SearchUp(c.i.Parent.Children[index-1]) // search on preceding sibling
}

func (c *Cursor) SearchUp(i *item) *item {
func (c *Cursor) SearchUp(i *Item) *Item {
if len(i.Children) == 0 {
c.ResetX()
c.y--
return i
}
return c.SearchUp(i.Children[len(i.Children)-1]) // recurse on the last item in the tail
return c.SearchUp(i.Children[len(i.Children)-1]) // recurse on the last Item in the tail
}

func (c *Cursor) ResetX() {
Expand All @@ -91,4 +101,9 @@ func (c *Cursor) UnsetBuffer() {
c.ClearBuffer()
}

func changeMode(c *Cursor) error {
c.editMode = !c.editMode
return nil
}

// TODO: add c.x inc/dec methods
5 changes: 2 additions & 3 deletions drawing.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ func drawBox(s tcell.Screen, x1, y1, x2, y2 int, style tcell.Style, r rune) {
}
}

func drawInfo(s tcell.Screen, c *Cursor, local *item) {
func drawInfo(s tcell.Screen, c *Cursor, local *Item) {
width, _ := s.Size()
// Info bar
emitStr(s, lpad, fily, black, "File: "+local.Text)
Expand All @@ -113,10 +113,9 @@ func drawInfo(s tcell.Screen, c *Cursor, local *item) {
emitStr(s, width-(boxl-boxr), crsr, white, fmt.Sprintf(crsfmt, c.x, c.y, string(c.i.Text[c.x])))
emitStr(s, width-(boxl-boxr), keys, white, fmt.Sprintf(keyfmt, c.lks))
emitStr(s, width-(boxl-boxr), mods, white, fmt.Sprintf(modfmt, c.mks))

}

func (i *item) Plot(s tcell.Screen, m map[*item]int, style tcell.Style) {
func (i *Item) Plot(s tcell.Screen, m map[*Item]int, style tcell.Style) {
if len(i.Children) > 0 {
for _, t := range i.Children {
depth := len(t.Path()) - 1
Expand Down
64 changes: 21 additions & 43 deletions keyboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,46 +3,24 @@ package main
import (
"github.com/gdamore/tcell/v2"
"os"
"strconv"
"strings"
)

// EditMode is a flag used to restrict keyboard actions. In edit mode, the user
// can write text to an item. Outside of edit mode, the user can perform all
// the tree manipulation actions.
type EditMode bool
// TODO: change inner conditional branches to switch cases

// ModeError is used to catch an error during mode switch
type ModeError struct {
EditMode EditMode
}

func (m *ModeError) Error() string {
return "EditMode was " + strconv.FormatBool(bool(m.EditMode)) + " but was not flipped to " + strconv.FormatBool(bool(!m.EditMode))
}

func changeMode(c *Cursor) error {
clone := c
c.m = !c.m
if clone != c {
return &ModeError{EditMode: c.m}
}
return nil
}

func handleEventKey(ev *tcell.EventKey, s tcell.Screen, c *Cursor, local *item) {
if c.m {
handleEdit(ev, s, c, local)
func handleEventKey(ev *tcell.EventKey, s tcell.Screen, c *Cursor) {
if c.editMode {
handleEdit(ev, s, c)
} else {
handleSelect(ev, s, c, local)
handleSelect(ev, s, c)
}
}

// handleEdit controls the keyboard actions in EditMode.
// Text editing is handled in a naive manner, writing directly to the item head,
// Text editing is handled in a naive manner, writing directly to the Item head,
// and moving the cursor as an index of the head string, c.x. c.x will point to
// the position
func handleEdit(ev *tcell.EventKey, s tcell.Screen, c *Cursor, local *item) {
func handleEdit(ev *tcell.EventKey, s tcell.Screen, c *Cursor) {
switch ev.Key() {
// TODO: add some comments describing key actions
case tcell.KeyEnter:
Expand All @@ -51,11 +29,11 @@ func handleEdit(ev *tcell.EventKey, s tcell.Screen, c *Cursor, local *item) {
if ev.Modifiers() == 1 {
switch {
case c.x == 0:
c.i = c.i.AddSibling(&item{Parent: c.i.Parent, Text: " "}, c.i.Locate())
c.i = c.i.AddSibling(&Item{Parent: c.i.Parent, Text: " "}, c.i.Locate())
case len(c.i.Children) > 0:
c.i = c.i.Children[0].AddSibling(&item{Parent: c.i, Text: " "}, 0)
c.i = c.i.Children[0].AddSibling(&Item{Parent: c.i, Text: " "}, 0)
case len(c.i.Children) == 0:
c.i = c.i.AddSibling(&item{Parent: c.i.Parent, Text: " "}, c.i.Locate()+1)
c.i = c.i.AddSibling(&Item{Parent: c.i.Parent, Text: " "}, c.i.Locate()+1)
}
c.ResetX()
return // to maintain editing state
Expand All @@ -78,7 +56,7 @@ func handleEdit(ev *tcell.EventKey, s tcell.Screen, c *Cursor, local *item) {

// If c.x = 0, then pressing up again could take you out of edit mode?
// Maybe on a double press? Same with down? What if they
// also take you to the next item? This may start to blur
// also take you to the next Item? This may start to blur
// the line between edit and selection mode, which could
// lead to removing the separate modes.

Expand Down Expand Up @@ -125,7 +103,7 @@ func handleEdit(ev *tcell.EventKey, s tcell.Screen, c *Cursor, local *item) {
c.i.Unindent()

case tcell.KeyCtrlS:
treeToTxt(local, "text/example")
treeToTxt(c.local, "text/example")

case tcell.KeyCtrlQ:
s.Fini()
Expand All @@ -134,14 +112,14 @@ func handleEdit(ev *tcell.EventKey, s tcell.Screen, c *Cursor, local *item) {
}

// handleSelect controls the keyboard actions when not in EditMode
func handleSelect(ev *tcell.EventKey, s tcell.Screen, c *Cursor, local *item) {
func handleSelect(ev *tcell.EventKey, s tcell.Screen, c *Cursor) {
switch ev.Key() {
case tcell.KeyEnter:
if ev.Modifiers() == 1 {
if len(c.i.Children) > 0 {
c.i = c.i.Children[0].AddSibling(&item{Parent: c.i, Text: " "}, 0)
c.i = c.i.Children[0].AddSibling(&Item{Parent: c.i, Text: " "}, 0)
} else {
c.i = c.i.AddSibling(&item{Parent: c.i.Parent, Text: " "}, c.i.Locate()+1)
c.i = c.i.AddSibling(&Item{Parent: c.i.Parent, Text: " "}, c.i.Locate()+1)
}
}

Expand All @@ -167,9 +145,9 @@ func handleSelect(ev *tcell.EventKey, s tcell.Screen, c *Cursor, local *item) {

case tcell.KeyLeft:
if ev.Modifiers() == 2 {
// Increase scope to parent of current top level item (dive out)
// Increase scope to parent of current top level Item (dive out)
if c.i.Parent != nil {
local = c.i.Parent
c.local = c.i.Parent
}
return
}
Expand All @@ -182,10 +160,10 @@ func handleSelect(ev *tcell.EventKey, s tcell.Screen, c *Cursor, local *item) {

case tcell.KeyRight:
if ev.Modifiers() == 2 {
// Set selected item as top level item (dive in)
// Set selected Item as top level Item (dive in)
// For now, limit to non-leaf items, as unsure how app handles for empty tails
if len(c.i.Children) != 0 {
local = c.i
c.local = c.i
}
return
}
Expand All @@ -203,7 +181,7 @@ func handleSelect(ev *tcell.EventKey, s tcell.Screen, c *Cursor, local *item) {
c.i.Unindent()

case tcell.KeyCtrlS:
treeToTxt(local, "text/example")
treeToTxt(c.local, "text/example")

case tcell.KeyCtrlQ:
s.Fini()
Expand All @@ -212,7 +190,7 @@ func handleSelect(ev *tcell.EventKey, s tcell.Screen, c *Cursor, local *item) {
case tcell.KeyRune:
switch strings.ToLower(string(ev.Rune())) {
case "d":
// Duplicate selected item
// Duplicate selected Item

case ",":
c.i.Unindent()
Expand Down
Loading

0 comments on commit 41e399e

Please sign in to comment.