mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-07-17 01:42:45 +02:00
support unicode characters
This commit is contained in:
111
vendor/github.com/jesseduffield/gocui/edit.go
generated
vendored
111
vendor/github.com/jesseduffield/gocui/edit.go
generated
vendored
@ -4,7 +4,11 @@
|
||||
|
||||
package gocui
|
||||
|
||||
import "errors"
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/mattn/go-runewidth"
|
||||
)
|
||||
|
||||
const maxInt = int(^uint(0) >> 1)
|
||||
|
||||
@ -54,8 +58,9 @@ func simpleEditor(v *View, key Key, ch rune, mod Modifier) {
|
||||
|
||||
// EditWrite writes a rune at the cursor position.
|
||||
func (v *View) EditWrite(ch rune) {
|
||||
w := runewidth.RuneWidth(ch)
|
||||
v.writeRune(v.cx, v.cy, ch)
|
||||
v.MoveCursor(1, 0, true)
|
||||
v.moveCursor(w, 0, true)
|
||||
}
|
||||
|
||||
// EditDelete deletes a rune at the cursor position. back determines the
|
||||
@ -89,12 +94,12 @@ func (v *View) EditDelete(back bool) {
|
||||
v.MoveCursor(-1, 0, true)
|
||||
}
|
||||
} else { // wrapped line
|
||||
v.deleteRune(len(v.viewLines[y-1].line)-1, v.cy-1)
|
||||
v.MoveCursor(-1, 0, true)
|
||||
n, _ := v.deleteRune(len(v.viewLines[y-1].line)-1, v.cy-1)
|
||||
v.MoveCursor(-n, 0, true)
|
||||
}
|
||||
} else { // middle/end of the line
|
||||
v.deleteRune(v.cx-1, v.cy)
|
||||
v.MoveCursor(-1, 0, true)
|
||||
n, _ := v.deleteRune(v.cx-1, v.cy)
|
||||
v.MoveCursor(-n, 0, true)
|
||||
}
|
||||
} else {
|
||||
if x == len(v.viewLines[y].line) { // end of the line
|
||||
@ -116,35 +121,74 @@ func (v *View) EditNewLine() {
|
||||
// MoveCursor moves the cursor taking into account the width of the line/view,
|
||||
// displacing the origin if necessary.
|
||||
func (v *View) MoveCursor(dx, dy int, writeMode bool) {
|
||||
ox, oy := v.cx+v.ox, v.cy+v.oy
|
||||
x, y := ox+dx, oy+dy
|
||||
|
||||
if y < 0 || y >= len(v.viewLines) {
|
||||
v.moveCursor(dx, dy, writeMode)
|
||||
return
|
||||
}
|
||||
|
||||
// Removing newline.
|
||||
if x < 0 {
|
||||
var prevLen int
|
||||
if y-1 >= 0 && y-1 < len(v.viewLines) {
|
||||
prevLen = lineWidth(v.viewLines[y-1].line)
|
||||
}
|
||||
|
||||
v.MoveCursor(prevLen, -1, writeMode)
|
||||
return
|
||||
}
|
||||
|
||||
line := v.viewLines[y].line
|
||||
var col int
|
||||
var prevCol int
|
||||
for i := range line {
|
||||
prevCol = col
|
||||
col += runewidth.RuneWidth(line[i].chr)
|
||||
if dx > 0 {
|
||||
if x <= col {
|
||||
x = col
|
||||
break
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if x < col {
|
||||
x = prevCol
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
v.moveCursor(x-ox, y-oy, writeMode)
|
||||
}
|
||||
|
||||
func (v *View) moveCursor(dx, dy int, writeMode bool) {
|
||||
maxX, maxY := v.Size()
|
||||
cx, cy := v.cx+dx, v.cy+dy
|
||||
x, y := v.ox+cx, v.oy+cy
|
||||
|
||||
var curLineWidth, prevLineWidth int
|
||||
// get the width of the current line
|
||||
if writeMode {
|
||||
if v.Wrap {
|
||||
curLineWidth = maxX - 1
|
||||
} else {
|
||||
curLineWidth = maxInt
|
||||
}
|
||||
} else {
|
||||
curLineWidth = maxInt
|
||||
if v.Wrap {
|
||||
curLineWidth = maxX - 1
|
||||
}
|
||||
|
||||
if !writeMode {
|
||||
curLineWidth = 0
|
||||
if y >= 0 && y < len(v.viewLines) {
|
||||
curLineWidth = len(v.viewLines[y].line)
|
||||
curLineWidth = lineWidth(v.viewLines[y].line)
|
||||
if v.Wrap && curLineWidth >= maxX {
|
||||
curLineWidth = maxX - 1
|
||||
}
|
||||
} else {
|
||||
curLineWidth = 0
|
||||
}
|
||||
}
|
||||
// get the width of the previous line
|
||||
prevLineWidth = 0
|
||||
if y-1 >= 0 && y-1 < len(v.viewLines) {
|
||||
prevLineWidth = len(v.viewLines[y-1].line)
|
||||
} else {
|
||||
prevLineWidth = 0
|
||||
prevLineWidth = lineWidth(v.viewLines[y-1].line)
|
||||
}
|
||||
|
||||
// adjust cursor's x position and view's x origin
|
||||
if x > curLineWidth { // move to next line
|
||||
if dx > 0 { // horizontal movement
|
||||
@ -190,10 +234,9 @@ func (v *View) MoveCursor(dx, dy int, writeMode bool) {
|
||||
if !v.Wrap { // set origin so the EOL is visible
|
||||
nox := prevLineWidth - maxX + 1
|
||||
if nox < 0 {
|
||||
v.ox = 0
|
||||
} else {
|
||||
v.ox = nox
|
||||
nox = 0
|
||||
}
|
||||
v.ox = nox
|
||||
}
|
||||
v.cx = prevLineWidth
|
||||
} else {
|
||||
@ -275,19 +318,31 @@ func (v *View) writeRune(x, y int, ch rune) error {
|
||||
|
||||
// deleteRune removes a rune from the view's internal buffer, at the
|
||||
// position corresponding to the point (x, y).
|
||||
func (v *View) deleteRune(x, y int) error {
|
||||
// returns the amount of columns that where removed.
|
||||
func (v *View) deleteRune(x, y int) (int, error) {
|
||||
v.tainted = true
|
||||
|
||||
x, y, err := v.realPosition(x, y)
|
||||
if err != nil {
|
||||
return err
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if x < 0 || y < 0 || y >= len(v.lines) || x >= len(v.lines[y]) {
|
||||
return errors.New("invalid point")
|
||||
return 0, errors.New("invalid point")
|
||||
}
|
||||
v.lines[y] = append(v.lines[y][:x], v.lines[y][x+1:]...)
|
||||
return nil
|
||||
|
||||
var tw int
|
||||
for i := range v.lines[y] {
|
||||
w := runewidth.RuneWidth(v.lines[y][i].chr)
|
||||
tw += w
|
||||
if tw > x {
|
||||
v.lines[y] = append(v.lines[y][:i], v.lines[y][i+1:]...)
|
||||
return w, nil
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
// mergeLines merges the lines "y" and "y+1" if possible.
|
||||
|
Reference in New Issue
Block a user