Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 69 additions & 12 deletions components/input.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package components

import (
"strings"

"github.com/erroneousboat/termui"
runewidth "github.com/mattn/go-runewidth"
)
Expand All @@ -9,21 +11,26 @@ import (
type Input struct {
Par *termui.Par
Text []rune
Lines [][]rune
CursorPositionScreen int
CursorPositionText int
Offset int
Line int
}

// CreateInput is the constructor of the Input struct
func CreateInputComponent() *Input {
input := &Input{
Par: termui.NewPar(""),
Text: make([]rune, 0),
Lines: make([][]rune, 1),
CursorPositionScreen: 0,
CursorPositionText: 0,
Offset: 0,
Line: 0,
}

input.Lines[0] = input.Text
input.Par.Height = 3

return input
Expand Down Expand Up @@ -77,36 +84,82 @@ func (i *Input) Insert(key rune) {
left = append(left, key)

// Combine left and right side
i.Text = append(left, i.Text[i.CursorPositionText:]...)
i.UpdateText(append(left, i.Text[i.CursorPositionText:]...))

i.MoveCursorRight()
}

func (i *Input) UpdateText(txt []rune) {
i.Text = txt
i.Lines[i.Line] = i.Text
}

func (i *Input) UpdatePar() {
i.Par.Text = string(i.Text[i.Offset:])
}

// Backspace will remove a character in front of the CursorPositionText
func (i *Input) Backspace() {
if i.CursorPositionText > 0 {
i.MoveCursorLeft()
i.Text = append(i.Text[0:i.CursorPositionText], i.Text[i.CursorPositionText+1:]...)
i.Par.Text = string(i.Text[i.Offset:])
i.UpdateText(append(i.Text[0:i.CursorPositionText], i.Text[i.CursorPositionText+1:]...))
i.UpdatePar()
} else if i.Line > 0 {
// Delete this line if there's one before
var prev = i.Lines[:i.Line + 1]
var newlines [][]rune
if i.Line + 1 < len(i.Lines) {
newlines = append(prev, i.Lines[i.Line + 1:]...)
} else {
newlines = prev
}
i.Lines = newlines
i.MoveCursorUp()
}
}

// Delete will remove a character at the CursorPositionText
func (i *Input) Delete() {
if i.CursorPositionText < len(i.Text) {
i.Text = append(i.Text[0:i.CursorPositionText], i.Text[i.CursorPositionText+1:]...)
i.Par.Text = string(i.Text[i.Offset:])
i.UpdateText(append(i.Text[0:i.CursorPositionText], i.Text[i.CursorPositionText+1:]...))
i.UpdatePar()
}
}

func (i *Input) MoveCursorUp() {
if i.Line > 0 {
i.Line--
i.CursorPositionText = 0
i.CursorPositionScreen = 0
i.Offset = 0
i.Text = i.Lines[i.Line]
}

i.UpdatePar()
}

func (i *Input) MoveCursorDown() {
if i.Line + 1 >= len(i.Lines) {
// Make a new line
i.Lines = append(i.Lines, make([]rune, 0))
}
// Go to the line below
i.Line++
i.CursorPositionText = 0
i.CursorPositionScreen = 0
i.Offset = 0
i.Text = i.Lines[i.Line]
i.UpdatePar()
}

// MoveCursorRight will increase the current CursorPositionText with 1
func (i *Input) MoveCursorRight() {
if i.CursorPositionText < len(i.Text) {
i.CursorPositionText++
i.ScrollRight()
}

i.Par.Text = string(i.Text[i.Offset:])
i.UpdatePar()
}

// MoveCursorLeft will decrease the current CursorPositionText with 1
Expand All @@ -116,7 +169,7 @@ func (i *Input) MoveCursorLeft() {
i.ScrollLeft()
}

i.Par.Text = string(i.Text[i.Offset:])
i.UpdatePar()
}

func (i *Input) ScrollLeft() {
Expand Down Expand Up @@ -182,24 +235,28 @@ func (i *Input) GetRuneWidthRight() int {

// IsEmpty will return true when the input is empty
func (i *Input) IsEmpty() bool {
if i.Par.Text == "" {
return true
}
return false
return len(i.Text) == 0 && len(i.Lines) == 1
}

// Clear will empty the input and move the cursor to the start position
func (i *Input) Clear() {
i.Text = make([]rune, 0)
i.Lines = make([][]rune, 1)
i.Lines[0] = i.Text
i.Par.Text = ""
i.CursorPositionScreen = 0
i.CursorPositionText = 0
i.Offset = 0
i.Line = 0
}

// GetText returns the text currently in the input
func (i *Input) GetText() string {
return string(i.Text)
var fulltext = make([]string, len(i.Lines))
for i, txt := range i.Lines {
fulltext[i] = string(txt)
}
return strings.Join(fulltext, "\n")
}

// GetMaxWidth returns the maximum number of positions
Expand Down
2 changes: 2 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ func getDefaultConfig() Config {
"insert": {
"<left>": "cursor-left",
"<right>": "cursor-right",
"<up>": "cursor-up",
"<down>": "cursor-down",
"<enter>": "send",
"<escape>": "mode-command",
"<backspace>": "backspace",
Expand Down
12 changes: 12 additions & 0 deletions handlers/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ var actionMap = map[string]func(*context.AppContext){
"space": actionSpace,
"backspace": actionBackSpace,
"delete": actionDelete,
"cursor-up": actionMoveCursorUp,
"cursor-down": actionMoveCursorDown,
"cursor-right": actionMoveCursorRight,
"cursor-left": actionMoveCursorLeft,
"send": actionSend,
Expand Down Expand Up @@ -229,6 +231,16 @@ func actionMoveCursorRight(ctx *context.AppContext) {
termui.Render(ctx.View.Input)
}

func actionMoveCursorUp(ctx *context.AppContext) {
ctx.View.Input.MoveCursorUp()
termui.Render(ctx.View.Input)
}

func actionMoveCursorDown(ctx *context.AppContext) {
ctx.View.Input.MoveCursorDown()
termui.Render(ctx.View.Input)
}

func actionMoveCursorLeft(ctx *context.AppContext) {
ctx.View.Input.MoveCursorLeft()
termui.Render(ctx.View.Input)
Expand Down