mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-15 21:14:35 +02:00
Refactor diff mouse selection to use new render layout
This commit is contained in:
@@ -6,10 +6,10 @@ import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"kitty"
|
||||
"kitty/tools/config"
|
||||
"kitty/tools/tui"
|
||||
"kitty/tools/tui/loop"
|
||||
"kitty/tools/utils"
|
||||
"kitty/tools/wcswidth"
|
||||
@@ -50,6 +50,38 @@ func (self *Handler) handle_wheel_event(up bool) {
|
||||
self.dispatch_action(`scroll_by`, strconv.Itoa(amt))
|
||||
}
|
||||
|
||||
type line_pos struct {
|
||||
min_x, max_x int
|
||||
y ScrollPos
|
||||
}
|
||||
|
||||
func (self *line_pos) MinX() int { return self.min_x }
|
||||
func (self *line_pos) MaxX() int { return self.max_x }
|
||||
func (self *line_pos) Equal(other tui.LinePos) bool {
|
||||
if o, ok := other.(*line_pos); ok {
|
||||
return self.y == o.y
|
||||
}
|
||||
return false
|
||||
}
|
||||
func (self *line_pos) LessThan(other tui.LinePos) bool {
|
||||
if o, ok := other.(*line_pos); ok {
|
||||
return self.y.Less(o.y)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *Handler) line_pos_from_pos(x int, pos ScrollPos) *line_pos {
|
||||
ans := line_pos{min_x: self.logical_lines.margin_size, y: pos}
|
||||
available_cols := self.logical_lines.columns / 2
|
||||
if x >= available_cols {
|
||||
ans.min_x += available_cols
|
||||
ans.max_x = utils.Max(ans.min_x, ans.min_x+self.logical_lines.ScreenLineAt(pos).right.wcswidth()-1)
|
||||
} else {
|
||||
ans.max_x = utils.Max(ans.min_x, ans.min_x+self.logical_lines.ScreenLineAt(pos).left.wcswidth()-1)
|
||||
}
|
||||
return &ans
|
||||
}
|
||||
|
||||
func (self *Handler) start_mouse_selection(ev *loop.MouseEvent) {
|
||||
available_cols := self.logical_lines.columns / 2
|
||||
if ev.Cell.Y >= self.screen_size.num_lines || ev.Cell.X < self.logical_lines.margin_size || (ev.Cell.X >= available_cols && ev.Cell.X < available_cols+self.logical_lines.margin_size) {
|
||||
@@ -61,14 +93,7 @@ func (self *Handler) start_mouse_selection(ev *loop.MouseEvent) {
|
||||
if ll.line_type == EMPTY_LINE || ll.line_type == IMAGE_LINE {
|
||||
return
|
||||
}
|
||||
|
||||
min_x := self.logical_lines.margin_size
|
||||
max_x := available_cols - 1
|
||||
if ev.Cell.X >= available_cols {
|
||||
min_x += available_cols
|
||||
max_x += available_cols
|
||||
}
|
||||
self.mouse_selection.StartNewSelection(ev, &pos, min_x, max_x, 0, self.screen_size.num_lines-1, self.screen_size.cell_width, self.screen_size.cell_height)
|
||||
self.mouse_selection.StartNewSelection(ev, self.line_pos_from_pos(ev.Cell.X, pos), 0, self.screen_size.num_lines-1, self.screen_size.cell_width, self.screen_size.cell_height)
|
||||
}
|
||||
|
||||
func (self *Handler) update_mouse_selection(ev *loop.MouseEvent) {
|
||||
@@ -79,7 +104,8 @@ func (self *Handler) update_mouse_selection(ev *loop.MouseEvent) {
|
||||
y := ev.Cell.Y
|
||||
y = utils.Max(0, utils.Min(y, self.screen_size.num_lines-1))
|
||||
self.logical_lines.IncrementScrollPosBy(&pos, y)
|
||||
self.mouse_selection.Update(ev, &pos)
|
||||
x := self.mouse_selection.StartLine().MinX()
|
||||
self.mouse_selection.Update(ev, self.line_pos_from_pos(x, pos))
|
||||
self.draw_screen()
|
||||
}
|
||||
|
||||
@@ -92,31 +118,39 @@ func (self *Handler) text_for_current_mouse_selection() string {
|
||||
return ""
|
||||
}
|
||||
text := make([]byte, 0, 2048)
|
||||
start, end := *self.mouse_selection.StartLine().(*ScrollPos), *self.mouse_selection.EndLine().(*ScrollPos)
|
||||
for pos, prev_ll_idx := start, start.logical_line; pos.Less(end) || pos.Equal(&end); self.logical_lines.IncrementScrollPosBy(&pos, 1) {
|
||||
start_pos, end_pos := *self.mouse_selection.StartLine().(*line_pos), *self.mouse_selection.EndLine().(*line_pos)
|
||||
start, end := start_pos.y, end_pos.y
|
||||
is_left := start_pos.min_x == self.logical_lines.margin_size
|
||||
|
||||
line_for_pos := func(pos ScrollPos) string {
|
||||
if is_left {
|
||||
return self.logical_lines.ScreenLineAt(pos).left.marked_up_text
|
||||
}
|
||||
return self.logical_lines.ScreenLineAt(pos).right.marked_up_text
|
||||
}
|
||||
|
||||
for pos, prev_ll_idx := start, start.logical_line; pos.Less(end) || pos == end; self.logical_lines.IncrementScrollPosBy(&pos, 1) {
|
||||
ll := self.logical_lines.At(pos.logical_line)
|
||||
var line string
|
||||
switch ll.line_type {
|
||||
case EMPTY_LINE:
|
||||
case IMAGE_LINE:
|
||||
if pos.screen_line < ll.image_lines_offset {
|
||||
line = self.logical_lines.ScreenLineAt(pos)
|
||||
line = line_for_pos(pos)
|
||||
}
|
||||
default:
|
||||
line = self.logical_lines.ScreenLineAt(pos)
|
||||
line = line_for_pos(pos)
|
||||
}
|
||||
line = wcswidth.StripEscapeCodes(line)
|
||||
s, e := self.mouse_selection.LineBounds(&pos)
|
||||
s, e := self.mouse_selection.LineBounds(self.line_pos_from_pos(start_pos.min_x, pos))
|
||||
s -= start_pos.min_x
|
||||
e -= start_pos.min_x
|
||||
line = wcswidth.TruncateToVisualLength(line, e+1)
|
||||
if s > 0 {
|
||||
prefix := wcswidth.TruncateToVisualLength(line, s)
|
||||
line = line[len(prefix):]
|
||||
}
|
||||
// TODO: look at the original line from the source and handle leading tabs and trailing spaces as per it
|
||||
tline := strings.TrimRight(line, " ")
|
||||
if len(tline) < len(line) {
|
||||
line = tline + " "
|
||||
}
|
||||
// TODO: look at the original line from the source and handle leading tabs as per it
|
||||
if pos.logical_line > prev_ll_idx {
|
||||
line = "\n" + line
|
||||
}
|
||||
@@ -140,6 +174,11 @@ func (self *Handler) finish_mouse_selection(ev *loop.MouseEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Handler) add_mouse_selection_to_line(line string, line_pos ScrollPos, y int) string {
|
||||
return line + self.mouse_selection.LineFormatSuffix(&line_pos, selection_sgr, y)
|
||||
func (self *Handler) add_mouse_selection_to_line(line_pos ScrollPos, y int) string {
|
||||
if self.mouse_selection.IsEmpty() {
|
||||
return ""
|
||||
}
|
||||
selection_sgr := format_as_sgr.selection
|
||||
x := self.mouse_selection.StartLine().MinX()
|
||||
return self.mouse_selection.LineFormatSuffix(self.line_pos_from_pos(x, line_pos), selection_sgr[2:len(selection_sgr)-1], y)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user