From 4efc47c0fb5ac938b052bce859971b66a4a1b3de Mon Sep 17 00:00:00 2001 From: Zachary Yedidia Date: Fri, 18 Mar 2016 20:01:05 -0400 Subject: [PATCH] Add selection with click and drag --- cursor.go | 24 +++++++++++++++++++----- view.go | 23 ++++++++++++++++++----- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/cursor.go b/cursor.go index da782963..48c8bbe5 100644 --- a/cursor.go +++ b/cursor.go @@ -13,8 +13,10 @@ type Cursor struct { y int loc int - selectionStart int - selectionEnd int + selectionStart int + selectionStartX int + selectionStartY int + selectionEnd int } func (c *Cursor) resetSelection() { @@ -23,11 +25,19 @@ func (c *Cursor) resetSelection() { } func (c *Cursor) hasSelection() bool { - return (c.selectionEnd - c.selectionStart) != 0 + return c.selectionEnd != c.selectionStart } func (c *Cursor) deleteSelected() { - // TODO: Implement this + if c.selectionStart > c.selectionEnd { + c.v.buf.remove(c.selectionEnd, c.selectionStart+1) + // Since the cursor is already at the selection start we don't need to move + } else { + c.v.buf.remove(c.selectionStart, c.selectionEnd+1) + c.loc -= c.selectionEnd - c.selectionStart + c.x = c.selectionStartX + c.y = c.selectionStartY + } } func (c *Cursor) runeUnder() rune { @@ -101,7 +111,11 @@ func (c *Cursor) getCharPosInLine(lineNum, visualPos int) int { visualPos = count(visualLine) } numTabs := numOccurences(visualLine[:visualPos], '\t') - return visualPos - (tabSize-1)*numTabs + if visualPos >= (tabSize-1)*numTabs { + return visualPos - (tabSize-1)*numTabs + } else { + return visualPos / tabSize + } } func (c *Cursor) getVisualX() int { diff --git a/view.go b/view.go index 9dea952c..68b306af 100644 --- a/view.go +++ b/view.go @@ -94,7 +94,11 @@ func (v *View) handleEvent(event tcell.Event) int { v.cursor.right() ret = 2 case tcell.KeyBackspace2: - if v.cursor.loc > 0 { + if v.cursor.hasSelection() { + v.cursor.deleteSelected() + v.cursor.resetSelection() + ret = 2 + } else if v.cursor.loc > 0 { v.cursor.left() v.buf.remove(v.cursor.loc, v.cursor.loc+1) ret = 2 @@ -111,6 +115,10 @@ func (v *View) handleEvent(event tcell.Event) int { // Need to redraw the status line ret = 1 case tcell.KeyRune: + if v.cursor.hasSelection() { + v.cursor.deleteSelected() + v.cursor.resetSelection() + } v.buf.insert(v.cursor.loc, string(e.Rune())) v.cursor.right() ret = 2 @@ -145,6 +153,8 @@ func (v *View) handleEvent(event tcell.Event) int { if v.mouseReleased { v.cursor.selectionStart = v.cursor.loc + v.cursor.selectionStartX = v.cursor.x + v.cursor.selectionStartY = v.cursor.y } v.cursor.selectionEnd = v.cursor.loc v.mouseReleased = false @@ -175,24 +185,27 @@ func (v *View) handleEvent(event tcell.Event) int { } func (v *View) display() { - var charNum int + charNum := v.cursor.loc + v.cursor.distance(0, v.topline) for lineN := 0; lineN < v.height; lineN++ { if lineN+v.topline >= len(v.buf.lines) { break } // line := strings.Replace(v.buf.lines[lineN+v.topline], "\t", emptyString(tabSize), -1) line := v.buf.lines[lineN+v.topline] - var tabchars int + tabchars := 0 for colN, ch := range line { st := tcell.StyleDefault - if v.cursor.hasSelection() && charNum >= v.cursor.selectionStart && charNum <= v.cursor.selectionEnd { + if v.cursor.hasSelection() && + (charNum >= v.cursor.selectionStart && charNum <= v.cursor.selectionEnd || + charNum <= v.cursor.selectionStart && charNum >= v.cursor.selectionEnd) { st = st.Reverse(true) } if ch == '\t' { + v.s.SetContent(colN+tabchars, lineN, ' ', nil, st) for i := 0; i < tabSize-1; i++ { - v.s.SetContent(colN+tabchars, lineN, ' ', nil, st) tabchars++ + v.s.SetContent(colN+tabchars, lineN, ' ', nil, st) } } else { v.s.SetContent(colN+tabchars, lineN, ch, nil, st)