Skip to content

Commit a3adeb7

Browse files
authored
Merge pull request #59 from jesseduffield/improve-mouse-handling-in-editable-views
Improve mouse handling in editable views
2 parents 49cc572 + 2845e65 commit a3adeb7

File tree

2 files changed

+46
-13
lines changed

2 files changed

+46
-13
lines changed

gui.go

+31-6
Original file line numberDiff line numberDiff line change
@@ -1327,23 +1327,48 @@ func (g *Gui) onKey(ev *GocuiEvent) error {
13271327
}
13281328
}
13291329

1330+
// newCx and newCy are relative to the view port, i.e. to the visible area of the view
13301331
newCx := mx - v.x0 - 1
13311332
newCy := my - v.y0 - 1
1332-
// if view is editable don't go further than the furthest character for that line
1333-
if v.Editable && newCy >= 0 && newCy <= len(v.lines)-1 {
1334-
lastCharForLine := len(v.lines[newCy])
1335-
if lastCharForLine < newCx {
1336-
newCx = lastCharForLine
1333+
// newX and newY are relative to the view's content, independent of its scroll position
1334+
newX := newCx + v.ox
1335+
newY := newCy + v.oy
1336+
// if view is editable don't go further than the furthest character for that line
1337+
if v.Editable {
1338+
if newY < 0 {
1339+
newY = 0
1340+
newCy = -v.oy
1341+
} else if newY >= len(v.lines) {
1342+
newY = len(v.lines) - 1
1343+
newCy = newY - v.oy
1344+
}
1345+
1346+
lastCharForLine := len(v.lines[newY])
1347+
for lastCharForLine > 0 && v.lines[newY][lastCharForLine-1].chr == 0 {
1348+
lastCharForLine--
1349+
}
1350+
if lastCharForLine < newX {
1351+
newX = lastCharForLine
1352+
newCx = lastCharForLine - v.ox
13371353
}
13381354
}
13391355
if !IsMouseScrollKey(ev.Key) {
13401356
if err := v.SetCursor(newCx, newCy); err != nil {
13411357
return err
13421358
}
1359+
if v.Editable {
1360+
v.TextArea.SetCursor2D(newX, newY)
1361+
1362+
// SetCursor2D might have adjusted the text area's cursor to the
1363+
// left to move left from a soft line break, so we need to
1364+
// update the view's cursor to match the text area's cursor.
1365+
cX, _ := v.TextArea.GetCursorXY()
1366+
v.SetCursorX(cX)
1367+
}
13431368
}
13441369

13451370
if IsMouseKey(ev.Key) {
1346-
opts := ViewMouseBindingOpts{X: newCx + v.ox, Y: newCy + v.oy}
1371+
opts := ViewMouseBindingOpts{X: newX, Y: newY}
13471372
matched, err := g.execMouseKeybindings(v, ev, opts)
13481373
if err != nil {
13491374
return err

text_area.go

+15-7
Original file line numberDiff line numberDiff line change
@@ -282,13 +282,7 @@ func (self *TextArea) GoToEndOfLine() {
282282

283283
self.cursor = self.closestNewlineOnRight()
284284

285-
// If the end of line is a soft line break, we need to move left by one so
286-
// that we end up at the last whitespace before the line break. Otherwise
287-
// we'd be at the start of the next line, since the newline character
288-
// doesn't really exist in the real content.
289-
if self.cursor < len(self.content) && self.content[self.cursor] != '\n' {
290-
self.cursor--
291-
}
285+
self.moveLeftFromSoftLineBreak()
292286
}
293287

294288
func (self *TextArea) closestNewlineOnRight() int {
@@ -303,6 +297,16 @@ func (self *TextArea) closestNewlineOnRight() int {
303297
return len(self.content)
304298
}
305299

300+
func (self *TextArea) moveLeftFromSoftLineBreak() {
301+
// If the end of line is a soft line break, we need to move left by one so
302+
// that we end up at the last whitespace before the line break. Otherwise
303+
// we'd be at the start of the next line, since the newline character
304+
// doesn't really exist in the real content.
305+
if self.cursor < len(self.content) && self.content[self.cursor] != '\n' {
306+
self.cursor--
307+
}
308+
}
309+
306310
func (self *TextArea) atLineStart() bool {
307311
return self.cursor == 0 ||
308312
(len(self.content) > self.cursor-1 && self.content[self.cursor-1] == '\n')
@@ -420,12 +424,16 @@ func (self *TextArea) SetCursor2D(x int, y int) {
420424
for _, r := range self.wrappedContent {
421425
if x <= 0 && y == 0 {
422426
self.cursor = self.wrappedCursorToOrigCursor(newCursor)
427+
if self.wrappedContent[newCursor] == '\n' {
428+
self.moveLeftFromSoftLineBreak()
429+
}
423430
return
424431
}
425432

426433
if r == '\n' {
427434
if y == 0 {
428435
self.cursor = self.wrappedCursorToOrigCursor(newCursor)
436+
self.moveLeftFromSoftLineBreak()
429437
return
430438
}
431439
y--

0 commit comments

Comments
 (0)