More work on porting diff kitten
This commit is contained in:
parent
e4d936b5ed
commit
ee82cb5a52
@ -163,17 +163,17 @@ func (self *Collection) Len() int { return len(self.all_paths) }
|
|||||||
|
|
||||||
func (self *Collection) Items() int { return len(self.all_paths) }
|
func (self *Collection) Items() int { return len(self.all_paths) }
|
||||||
|
|
||||||
func (self *Collection) Apply(f func(path, typ, data string) error) error {
|
func (self *Collection) Apply(f func(path, typ, changed_path string) error) error {
|
||||||
for _, path := range self.all_paths {
|
for _, path := range self.all_paths {
|
||||||
typ := self.type_map[path]
|
typ := self.type_map[path]
|
||||||
data := ""
|
changed_path := ""
|
||||||
switch typ {
|
switch typ {
|
||||||
case "diff":
|
case "diff":
|
||||||
data = self.changes[path]
|
changed_path = self.changes[path]
|
||||||
case "rename":
|
case "rename":
|
||||||
data = self.renames[path]
|
changed_path = self.renames[path]
|
||||||
}
|
}
|
||||||
if err := f(path, typ, data); err != nil {
|
if err := f(path, typ, changed_path); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -63,6 +63,7 @@ func get_ssh_file(hostname, rpath string) (string, error) {
|
|||||||
}
|
}
|
||||||
cmd = append(cmd, rpath)
|
cmd = append(cmd, rpath)
|
||||||
c := exec.Command(cmd[0], cmd[1:]...)
|
c := exec.Command(cmd[0], cmd[1:]...)
|
||||||
|
c.Stdin, c.Stderr = os.Stdin, os.Stderr
|
||||||
stdout, err := c.Output()
|
stdout, err := c.Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("Failed to ssh into remote host %s to get file %s with error: %w", hostname, rpath, err)
|
return "", fmt.Errorf("Failed to ssh into remote host %s to get file %s with error: %w", hostname, rpath, err)
|
||||||
@ -134,12 +135,15 @@ func main(_ *cli.Command, opts_ *Options, args []string) (rc int, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return 1, err
|
return 1, err
|
||||||
}
|
}
|
||||||
|
h := Handler{left: left, right: right, lp: lp}
|
||||||
lp.OnInitialize = func() (string, error) {
|
lp.OnInitialize = func() (string, error) {
|
||||||
lp.SetCursorVisible(false)
|
lp.SetCursorVisible(false)
|
||||||
lp.AllowLineWrapping(false)
|
lp.AllowLineWrapping(false)
|
||||||
lp.SetWindowTitle(fmt.Sprintf("%s vs. %s", left, right))
|
lp.SetWindowTitle(fmt.Sprintf("%s vs. %s", left, right))
|
||||||
|
h.initialize()
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
lp.OnWakeup = h.on_wakeup
|
||||||
lp.OnFinalize = func() string {
|
lp.OnFinalize = func() string {
|
||||||
lp.SetCursorVisible(true)
|
lp.SetCursorVisible(true)
|
||||||
return ""
|
return ""
|
||||||
|
|||||||
@ -321,7 +321,9 @@ func do_diff(file1, file2 string, context_count int) (ans *Patch, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func diff(jobs []struct{ file1, file2 string }, context_count int) (ans map[string]*Patch, err error) {
|
type diff_job struct{ file1, file2 string }
|
||||||
|
|
||||||
|
func diff(jobs []diff_job, context_count int) (ans map[string]*Patch, err error) {
|
||||||
ans = make(map[string]*Patch)
|
ans = make(map[string]*Patch)
|
||||||
ctx := images.Context{}
|
ctx := images.Context{}
|
||||||
type result struct {
|
type result struct {
|
||||||
|
|||||||
125
tools/cmd/diff/ui.go
Normal file
125
tools/cmd/diff/ui.go
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
// License: GPLv3 Copyright: 2023, Kovid Goyal, <kovid at kovidgoyal.net>
|
||||||
|
|
||||||
|
package diff
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"kitty/tools/tui/loop"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = fmt.Print
|
||||||
|
|
||||||
|
type ResultType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
COLLECTION ResultType = iota
|
||||||
|
DIFF
|
||||||
|
HIGHLIGHT
|
||||||
|
)
|
||||||
|
|
||||||
|
type Reference struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
type AsyncResult struct {
|
||||||
|
err error
|
||||||
|
rtype ResultType
|
||||||
|
collection *Collection
|
||||||
|
diff_map map[string]*Patch
|
||||||
|
}
|
||||||
|
|
||||||
|
type Handler struct {
|
||||||
|
async_results chan AsyncResult
|
||||||
|
left, right string
|
||||||
|
collection *Collection
|
||||||
|
diff_map map[string]*Patch
|
||||||
|
lp *loop.Loop
|
||||||
|
current_context_count, original_context_count int
|
||||||
|
added_count, removed_count int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Handler) calculate_statistics() {
|
||||||
|
self.added_count, self.removed_count = self.collection.added_count, self.collection.removed_count
|
||||||
|
for _, patch := range self.diff_map {
|
||||||
|
self.added_count += patch.added_count
|
||||||
|
self.removed_count += patch.removed_count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Handler) initialize() {
|
||||||
|
self.current_context_count = opts.Context
|
||||||
|
if self.current_context_count < 0 {
|
||||||
|
self.current_context_count = int(conf.Num_context_lines)
|
||||||
|
}
|
||||||
|
self.original_context_count = self.current_context_count
|
||||||
|
self.lp.SetDefaultColor(loop.FOREGROUND, conf.Foreground)
|
||||||
|
self.lp.SetDefaultColor(loop.CURSOR, conf.Foreground)
|
||||||
|
self.lp.SetDefaultColor(loop.BACKGROUND, conf.Background)
|
||||||
|
self.lp.SetDefaultColor(loop.SELECTION_BG, conf.Select_bg)
|
||||||
|
if !conf.Select_fg.IsNull {
|
||||||
|
self.lp.SetDefaultColor(loop.SELECTION_FG, conf.Select_fg.Color)
|
||||||
|
}
|
||||||
|
self.async_results = make(chan AsyncResult, 32)
|
||||||
|
go func() {
|
||||||
|
r := AsyncResult{}
|
||||||
|
r.collection, r.err = create_collection(self.left, self.right)
|
||||||
|
self.async_results <- r
|
||||||
|
self.lp.WakeupMainThread()
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Handler) generate_diff() {
|
||||||
|
self.diff_map = nil
|
||||||
|
jobs := make([]diff_job, 0, 32)
|
||||||
|
self.collection.Apply(func(path, typ, changed_path string) error {
|
||||||
|
if typ == "diff" {
|
||||||
|
if is_path_text(path) && is_path_text(changed_path) {
|
||||||
|
jobs = append(jobs, diff_job{path, changed_path})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
go func() {
|
||||||
|
r := AsyncResult{rtype: DIFF}
|
||||||
|
r.diff_map, r.err = diff(jobs, self.current_context_count)
|
||||||
|
self.async_results <- r
|
||||||
|
self.lp.WakeupMainThread()
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Handler) on_wakeup() error {
|
||||||
|
var r AsyncResult
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case r = <-self.async_results:
|
||||||
|
if r.err != nil {
|
||||||
|
return r.err
|
||||||
|
}
|
||||||
|
r.err = self.handle_async_result(r)
|
||||||
|
if r.err != nil {
|
||||||
|
return r.err
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Handler) handle_async_result(r AsyncResult) error {
|
||||||
|
switch r.rtype {
|
||||||
|
case COLLECTION:
|
||||||
|
self.collection = r.collection
|
||||||
|
self.generate_diff()
|
||||||
|
case DIFF:
|
||||||
|
self.diff_map = r.diff_map
|
||||||
|
self.calculate_statistics()
|
||||||
|
self.render_diff()
|
||||||
|
self.scroll_pos = 0
|
||||||
|
if self.restore_position != nil {
|
||||||
|
self.set_current_position(self.restore_position)
|
||||||
|
self.restore_position = nil
|
||||||
|
}
|
||||||
|
self.draw_screen()
|
||||||
|
case HIGHLIGHT:
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@ -22,6 +22,7 @@ import (
|
|||||||
"kitty/tools/cli"
|
"kitty/tools/cli"
|
||||||
"kitty/tools/config"
|
"kitty/tools/config"
|
||||||
"kitty/tools/tty"
|
"kitty/tools/tty"
|
||||||
|
"kitty/tools/tui/loop"
|
||||||
"kitty/tools/tui/subseq"
|
"kitty/tools/tui/subseq"
|
||||||
"kitty/tools/utils"
|
"kitty/tools/utils"
|
||||||
"kitty/tools/utils/style"
|
"kitty/tools/utils/style"
|
||||||
@ -716,7 +717,7 @@ func ColorSettingsAsEscapeCodes(settings map[string]string) string {
|
|||||||
w.WriteString(sharp)
|
w.WriteString(sharp)
|
||||||
}
|
}
|
||||||
|
|
||||||
set_default_color := func(name, defval string, num int) {
|
set_default_color := func(name, defval string, num loop.DefaultColor) {
|
||||||
w.WriteString("\033]")
|
w.WriteString("\033]")
|
||||||
defer func() { w.WriteString("\033\\") }()
|
defer func() { w.WriteString("\033\\") }()
|
||||||
val, found := settings[name]
|
val, found := settings[name]
|
||||||
@ -726,20 +727,20 @@ func ColorSettingsAsEscapeCodes(settings map[string]string) string {
|
|||||||
if val != "" {
|
if val != "" {
|
||||||
rgba, err := style.ParseColor(val)
|
rgba, err := style.ParseColor(val)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
w.WriteString(strconv.Itoa(num))
|
w.WriteString(strconv.Itoa(int(num)))
|
||||||
w.WriteByte(';')
|
w.WriteByte(';')
|
||||||
w.WriteString(rgba.AsRGBSharp())
|
w.WriteString(rgba.AsRGBSharp())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
w.WriteByte('1')
|
w.WriteByte('1')
|
||||||
w.WriteString(strconv.Itoa(num))
|
w.WriteString(strconv.Itoa(int(num)))
|
||||||
}
|
}
|
||||||
set_default_color("foreground", style.DefaultColors.Foreground, 10)
|
set_default_color("foreground", style.DefaultColors.Foreground, loop.FOREGROUND)
|
||||||
set_default_color("background", style.DefaultColors.Background, 11)
|
set_default_color("background", style.DefaultColors.Background, loop.BACKGROUND)
|
||||||
set_default_color("cursor", style.DefaultColors.Cursor, 12)
|
set_default_color("cursor", style.DefaultColors.Cursor, loop.CURSOR)
|
||||||
set_default_color("selection_background", style.DefaultColors.SelectionBg, 17)
|
set_default_color("selection_background", style.DefaultColors.SelectionBg, loop.SELECTION_BG)
|
||||||
set_default_color("selection_foreground", style.DefaultColors.SelectionFg, 19)
|
set_default_color("selection_foreground", style.DefaultColors.SelectionFg, loop.SELECTION_FG)
|
||||||
|
|
||||||
w.WriteString("\033]4")
|
w.WriteString("\033]4")
|
||||||
for i := 0; i < 256; i++ {
|
for i := 0; i < 256; i++ {
|
||||||
|
|||||||
@ -381,3 +381,17 @@ func (self *Loop) Quit(exit_code int) {
|
|||||||
self.exit_code = exit_code
|
self.exit_code = exit_code
|
||||||
self.keep_going = false
|
self.keep_going = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DefaultColor int
|
||||||
|
|
||||||
|
const (
|
||||||
|
BACKGROUND DefaultColor = 11
|
||||||
|
FOREGROUND = 10
|
||||||
|
CURSOR = 12
|
||||||
|
SELECTION_BG = 17
|
||||||
|
SELECTION_FG = 18
|
||||||
|
)
|
||||||
|
|
||||||
|
func (self *Loop) SetDefaultColor(which DefaultColor, val style.RGBA) {
|
||||||
|
self.QueueWriteString(fmt.Sprintf("\033]%d;%s\033\\", int(which), val.AsRGBSharp()))
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user