Merge pull request #72 from liamg/fix-selection-bugs

fix selections
This commit is contained in:
Liam Galvin 2018-11-27 10:25:39 +00:00 committed by GitHub
commit e9164f2732
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 62 additions and 32 deletions

View File

@ -48,9 +48,11 @@ func NewBuffer(viewCols uint16, viewLines uint16, attr CellAttributes) *Buffer {
return b return b
} }
func (buffer *Buffer) GetURLAtPosition(col uint16, row uint16) string { func (buffer *Buffer) GetURLAtPosition(col uint16, viewRow uint16) string {
cell := buffer.GetCell(col, row) row := buffer.convertViewLineToRawLine((viewRow)) - uint64(buffer.scrollLinesFromBottom)
cell := buffer.GetRawCell(col, row)
if cell == nil || cell.Rune() == 0x00 { if cell == nil || cell.Rune() == 0x00 {
return "" return ""
} }
@ -58,7 +60,7 @@ func (buffer *Buffer) GetURLAtPosition(col uint16, row uint16) string {
candidate := "" candidate := ""
for i := col; i >= 0; i-- { for i := col; i >= 0; i-- {
cell := buffer.GetCell(i, row) cell := buffer.GetRawCell(i, row)
if cell == nil { if cell == nil {
break break
} }
@ -69,7 +71,7 @@ func (buffer *Buffer) GetURLAtPosition(col uint16, row uint16) string {
} }
for i := col + 1; i < buffer.viewWidth; i++ { for i := col + 1; i < buffer.viewWidth; i++ {
cell := buffer.GetCell(i, row) cell := buffer.GetRawCell(i, row)
if cell == nil { if cell == nil {
break break
} }
@ -91,9 +93,11 @@ func (buffer *Buffer) GetURLAtPosition(col uint16, row uint16) string {
return candidate return candidate
} }
func (buffer *Buffer) SelectWordAtPosition(col uint16, row uint16) { func (buffer *Buffer) SelectWordAtPosition(col uint16, viewRow uint16) {
cell := buffer.GetCell(col, row) row := buffer.convertViewLineToRawLine(viewRow) - uint64(buffer.scrollLinesFromBottom)
cell := buffer.GetRawCell(col, row)
if cell == nil || cell.Rune() == 0x00 { if cell == nil || cell.Rune() == 0x00 {
return return
} }
@ -102,7 +106,7 @@ func (buffer *Buffer) SelectWordAtPosition(col uint16, row uint16) {
end := col end := col
for i := col; i >= 0; i-- { for i := col; i >= 0; i-- {
cell := buffer.GetCell(i, row) cell := buffer.GetRawCell(i, row)
if cell == nil { if cell == nil {
break break
} }
@ -113,7 +117,7 @@ func (buffer *Buffer) SelectWordAtPosition(col uint16, row uint16) {
} }
for i := col; i < buffer.viewWidth; i++ { for i := col; i < buffer.viewWidth; i++ {
cell := buffer.GetCell(i, row) cell := buffer.GetRawCell(i, row)
if cell == nil { if cell == nil {
break break
} }
@ -125,11 +129,11 @@ func (buffer *Buffer) SelectWordAtPosition(col uint16, row uint16) {
buffer.selectionStart = &Position{ buffer.selectionStart = &Position{
Col: int(start), Col: int(start),
Line: int(buffer.convertViewLineToRawLine(row)), Line: int(row),
} }
buffer.selectionEnd = &Position{ buffer.selectionEnd = &Position{
Col: int(end), Col: int(end),
Line: int(buffer.convertViewLineToRawLine(row)), Line: int(row),
} }
buffer.emitDisplayChange() buffer.emitDisplayChange()
@ -161,7 +165,21 @@ func (buffer *Buffer) GetSelectedText() string {
text := "" text := ""
for row := buffer.selectionStart.Line; row <= buffer.selectionEnd.Line; row++ { var x1, x2, y1, y2 int
if buffer.selectionStart.Line > buffer.selectionEnd.Line || (buffer.selectionStart.Line == buffer.selectionEnd.Line && buffer.selectionStart.Col > buffer.selectionEnd.Col) {
y2 = buffer.selectionStart.Line
y1 = buffer.selectionEnd.Line
x2 = buffer.selectionStart.Col
x1 = buffer.selectionEnd.Col
} else {
y1 = buffer.selectionStart.Line
y2 = buffer.selectionEnd.Line
x1 = buffer.selectionStart.Col
x2 = buffer.selectionEnd.Col
}
for row := y1; row <= y2; row++ {
if row >= len(buffer.lines) { if row >= len(buffer.lines) {
break break
@ -171,13 +189,13 @@ func (buffer *Buffer) GetSelectedText() string {
minX := 0 minX := 0
maxX := int(buffer.viewWidth) - 1 maxX := int(buffer.viewWidth) - 1
if row == buffer.selectionStart.Line { if row == y1 {
minX = buffer.selectionStart.Col minX = x1
} else if !line.wrapped { } else if !line.wrapped {
text += "\n" text += "\n"
} }
if row == buffer.selectionEnd.Line { if row == y2 {
maxX = buffer.selectionEnd.Col maxX = x2
} }
for col := minX; col <= maxX; col++ { for col := minX; col <= maxX; col++ {
@ -193,24 +211,26 @@ func (buffer *Buffer) GetSelectedText() string {
return text return text
} }
func (buffer *Buffer) StartSelection(col uint16, row uint16) { func (buffer *Buffer) StartSelection(col uint16, viewRow uint16) {
row := buffer.convertViewLineToRawLine(viewRow) - uint64(buffer.scrollLinesFromBottom)
if buffer.selectionComplete { if buffer.selectionComplete {
buffer.selectionEnd = nil buffer.selectionEnd = nil
if buffer.selectionStart != nil && time.Since(buffer.selectionClickTime) < time.Millisecond*500 { if buffer.selectionStart != nil && time.Since(buffer.selectionClickTime) < time.Millisecond*500 {
if buffer.selectionExpanded { if buffer.selectionExpanded {
//select whole line! //select whole line!
buffer.selectionStart = &Position{ buffer.selectionStart = &Position{
Col: 0, Col: 0,
Line: int(buffer.convertViewLineToRawLine(row)), Line: int(row),
} }
buffer.selectionEnd = &Position{ buffer.selectionEnd = &Position{
Col: int(buffer.ViewWidth() - 1), Col: int(buffer.ViewWidth() - 1),
Line: int(buffer.convertViewLineToRawLine(row)), Line: int(row),
} }
buffer.emitDisplayChange() buffer.emitDisplayChange()
} else { } else {
buffer.SelectWordAtPosition(col, row) buffer.SelectWordAtPosition(col, viewRow)
buffer.selectionExpanded = true buffer.selectionExpanded = true
} }
return return
@ -222,12 +242,12 @@ func (buffer *Buffer) StartSelection(col uint16, row uint16) {
buffer.selectionComplete = false buffer.selectionComplete = false
buffer.selectionStart = &Position{ buffer.selectionStart = &Position{
Col: int(col), Col: int(col),
Line: int(buffer.convertViewLineToRawLine(row)), Line: int(row),
} }
buffer.selectionClickTime = time.Now() buffer.selectionClickTime = time.Now()
} }
func (buffer *Buffer) EndSelection(col uint16, row uint16, complete bool) { func (buffer *Buffer) EndSelection(col uint16, viewRow uint16, complete bool) {
if buffer.selectionComplete { if buffer.selectionComplete {
return return
@ -242,13 +262,15 @@ func (buffer *Buffer) EndSelection(col uint16, row uint16, complete bool) {
return return
} }
if int(col) == buffer.selectionStart.Col && int(buffer.convertViewLineToRawLine(row)) == int(buffer.selectionStart.Line) && complete { row := buffer.convertViewLineToRawLine(viewRow) - uint64(buffer.scrollLinesFromBottom)
if int(col) == buffer.selectionStart.Col && int(row) == int(buffer.selectionStart.Line) && complete {
return return
} }
buffer.selectionEnd = &Position{ buffer.selectionEnd = &Position{
Col: int(col), Col: int(col),
Line: int(buffer.convertViewLineToRawLine(row)), Line: int(row),
} }
} }
@ -273,7 +295,7 @@ func (buffer *Buffer) InSelection(col uint16, row uint16) bool {
x2 = buffer.selectionEnd.Col x2 = buffer.selectionEnd.Col
} }
rawY := int(buffer.convertViewLineToRawLine(row)) rawY := int(buffer.convertViewLineToRawLine(row) - uint64(buffer.scrollLinesFromBottom))
return (rawY > y1 || (rawY == y1 && int(col) >= x1)) && (rawY < y2 || (rawY == y2 && int(col) <= x2)) return (rawY > y1 || (rawY == y1 && int(col) >= x1)) && (rawY < y2 || (rawY == y2 && int(col) <= x2))
} }
@ -369,8 +391,11 @@ func (buffer *Buffer) CursorAttr() *CellAttributes {
} }
func (buffer *Buffer) GetCell(viewCol uint16, viewRow uint16) *Cell { func (buffer *Buffer) GetCell(viewCol uint16, viewRow uint16) *Cell {
rawLine := buffer.convertViewLineToRawLine(viewRow) rawLine := buffer.convertViewLineToRawLine(viewRow)
return buffer.GetRawCell(viewCol, rawLine)
}
func (buffer *Buffer) GetRawCell(viewCol uint16, rawLine uint64) *Cell {
if viewCol < 0 || rawLine < 0 || int(rawLine) >= len(buffer.lines) { if viewCol < 0 || rawLine < 0 || int(rawLine) >= len(buffer.lines) {
return nil return nil

View File

@ -7,17 +7,19 @@ import (
"github.com/liamg/aminal/hints" "github.com/liamg/aminal/hints"
) )
func (buffer *Buffer) GetHintAtPosition(col uint16, row uint16) *hints.Hint { func (buffer *Buffer) GetHintAtPosition(col uint16, viewRow uint16) *hints.Hint {
cell := buffer.GetCell(col, row) row := buffer.convertViewLineToRawLine(viewRow) - uint64(buffer.scrollLinesFromBottom)
cell := buffer.GetRawCell(col, row)
if cell == nil || cell.Rune() == 0x00 { if cell == nil || cell.Rune() == 0x00 {
return nil return nil
} }
candidate := "" candidate := ""
for i := col; i >= 0; i-- { for i := int(col); i >= 0; i-- {
cell := buffer.GetCell(i, row) cell := buffer.GetRawCell(uint16(i), row)
if cell == nil { if cell == nil {
break break
} }
@ -31,7 +33,7 @@ func (buffer *Buffer) GetHintAtPosition(col uint16, row uint16) *hints.Hint {
sx := col - uint16(len(trimmed)-1) sx := col - uint16(len(trimmed)-1)
for i := col + 1; i < buffer.viewWidth; i++ { for i := col + 1; i < buffer.viewWidth; i++ {
cell := buffer.GetCell(i, row) cell := buffer.GetRawCell(i, row)
if cell == nil { if cell == nil {
break break
} }
@ -42,8 +44,8 @@ func (buffer *Buffer) GetHintAtPosition(col uint16, row uint16) *hints.Hint {
candidate = fmt.Sprintf("%s%c", candidate, cell.Rune()) candidate = fmt.Sprintf("%s%c", candidate, cell.Rune())
} }
line := buffer.lines[buffer.convertViewLineToRawLine(row)] line := buffer.lines[row]
return hints.Get(strings.Trim(candidate, " "), line.String(), sx, row) return hints.Get(strings.Trim(candidate, " "), line.String(), sx, viewRow)
} }

View File

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"os" "os"
"os/exec" "os/exec"
"runtime"
"syscall" "syscall"
"github.com/kr/pty" "github.com/kr/pty"
@ -14,6 +15,8 @@ import (
func main() { func main() {
runtime.LockOSThread()
conf := getConfig() conf := getConfig()
logger, err := getLogger(conf) logger, err := getLogger(conf)
if err != nil { if err != nil {