Fix highlighting of center changes
This commit is contained in:
parent
de9edb6ff5
commit
ccf1dfabbc
@ -103,9 +103,9 @@ func hash_for_path(path string) (string, error) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove all control codes except newlines
|
||||||
func sanitize_control_codes(x string) string {
|
func sanitize_control_codes(x string) string {
|
||||||
// exclude newlines, carriage returns and tabs
|
pat := utils.MustCompile("[\x00-\x09\x0b-\x1f\x7f\u0080-\u009f]")
|
||||||
pat := utils.MustCompile("[\x00-\x08\x0b\x0c\x0e-\x1f\x7f\u0080-\u009f]")
|
|
||||||
return pat.ReplaceAllLiteralString(x, "░")
|
return pat.ReplaceAllLiteralString(x, "░")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,8 +114,7 @@ func sanitize_tabs_and_carriage_returns(x string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func sanitize(x string) string {
|
func sanitize(x string) string {
|
||||||
x = sanitize_control_codes(x)
|
return sanitize_control_codes(sanitize_tabs_and_carriage_returns(x))
|
||||||
return sanitize_tabs_and_carriage_returns(x)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func text_to_lines(text string) []string {
|
func text_to_lines(text string) []string {
|
||||||
|
|||||||
@ -123,7 +123,7 @@ func ansi_formatter(w io.Writer, style *chroma.Style, it chroma.Iterator) error
|
|||||||
}
|
}
|
||||||
// independently format each line in a multiline token, needed for the diff kitten highlighting to work, also
|
// independently format each line in a multiline token, needed for the diff kitten highlighting to work, also
|
||||||
// pagers like less reset SGR formatting at line boundaries
|
// pagers like less reset SGR formatting at line boundaries
|
||||||
text := token.Value
|
text := sanitize(token.Value)
|
||||||
for text != "" {
|
for text != "" {
|
||||||
idx := strings.IndexByte(text, '\n')
|
idx := strings.IndexByte(text, '\n')
|
||||||
if idx < 0 {
|
if idx < 0 {
|
||||||
@ -152,7 +152,6 @@ func highlight_file(path string) (highlighted string, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
text = sanitize_control_codes(text)
|
|
||||||
lexer := lexers.Match(filename_for_detection)
|
lexer := lexers.Match(filename_for_detection)
|
||||||
if lexer == nil {
|
if lexer == nil {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@ -191,7 +190,7 @@ func highlight_file(path string) (highlighted string, err error) {
|
|||||||
w := strings.Builder{}
|
w := strings.Builder{}
|
||||||
w.Grow(len(text) * 2)
|
w.Grow(len(text) * 2)
|
||||||
err = formatter.Format(&w, style, iterator)
|
err = formatter.Format(&w, style, iterator)
|
||||||
// os.WriteFile(path+".highlighted", []byte(w.String()), 0o600)
|
// os.WriteFile(filepath.Base(path+".highlighted"), []byte(w.String()), 0o600)
|
||||||
return w.String(), err
|
return w.String(), err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,7 +201,7 @@ func highlight_all(paths []string) {
|
|||||||
path := paths[i]
|
path := paths[i]
|
||||||
raw, err := highlight_file(path)
|
raw, err := highlight_file(path)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
highlighted_lines_cache.Set(path, text_to_lines(sanitize_tabs_and_carriage_returns(raw)))
|
highlighted_lines_cache.Set(path, text_to_lines(raw))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -60,7 +60,7 @@ func set_diff_command(q string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type Center struct{ prefix_count, suffix_count int }
|
type Center struct{ offset, left_size, right_size int }
|
||||||
|
|
||||||
type Chunk struct {
|
type Chunk struct {
|
||||||
is_context bool
|
is_context bool
|
||||||
@ -82,18 +82,17 @@ func (self *Chunk) context_line() {
|
|||||||
self.right_count++
|
self.right_count++
|
||||||
}
|
}
|
||||||
|
|
||||||
func changed_center(left, right string) (ans struct{ prefix_count, suffix_count int }) {
|
func changed_center(left, right string) (ans Center) {
|
||||||
if len(left) > 0 && len(right) > 0 {
|
if len(left) > 0 && len(right) > 0 {
|
||||||
ll, rl := len(left), len(right)
|
ll, rl := len(left), len(right)
|
||||||
ml := utils.Min(ll, rl)
|
ml := utils.Min(ll, rl)
|
||||||
for ans.prefix_count < ml && left[ans.prefix_count] == right[ans.prefix_count] {
|
for ; ans.offset < ml && left[ans.offset] == right[ans.offset]; ans.offset++ {
|
||||||
ans.prefix_count++
|
|
||||||
}
|
}
|
||||||
if ans.prefix_count < ml {
|
suffix_count := 0
|
||||||
for ans.suffix_count < ml-ans.prefix_count && left[ll-1-ans.suffix_count] == right[rl-1-ans.suffix_count] {
|
for ; suffix_count < ml && left[ll-1-suffix_count] == right[rl-1-suffix_count]; suffix_count++ {
|
||||||
ans.suffix_count++
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
ans.left_size = ll - suffix_count - ans.offset
|
||||||
|
ans.right_size = rl - suffix_count - ans.offset
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@ package diff
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"kitty/tools/tui/sgr"
|
||||||
"kitty/tools/utils"
|
"kitty/tools/utils"
|
||||||
"kitty/tools/utils/style"
|
"kitty/tools/utils/style"
|
||||||
"kitty/tools/wcswidth"
|
"kitty/tools/wcswidth"
|
||||||
@ -71,7 +72,7 @@ func place_in(text string, sz int) string {
|
|||||||
return fill_in(fit_in(text, sz), sz)
|
return fill_in(fit_in(text, sz), sz)
|
||||||
}
|
}
|
||||||
|
|
||||||
var title_format, text_format, margin_format, added_format, removed_format, added_margin_format, removed_margin_format, filler_format, margin_filler_format, hunk_margin_format, hunk_format, added_center, removed_center, statusline_format, added_count_format, removed_count_format, message_format func(...any) string
|
var title_format, text_format, margin_format, added_format, removed_format, added_margin_format, removed_margin_format, filler_format, margin_filler_format, hunk_margin_format, hunk_format, statusline_format, added_count_format, removed_count_format, message_format func(...any) string
|
||||||
|
|
||||||
func create_formatters() {
|
func create_formatters() {
|
||||||
ctx := style.Context{AllowEscapeCodes: true}
|
ctx := style.Context{AllowEscapeCodes: true}
|
||||||
@ -94,31 +95,17 @@ func create_formatters() {
|
|||||||
hunk_format = ctx.SprintFunc(fmt.Sprintf("fg=%s bg=%s", conf.Margin_fg.AsRGBSharp(), conf.Hunk_bg.AsRGBSharp()))
|
hunk_format = ctx.SprintFunc(fmt.Sprintf("fg=%s bg=%s", conf.Margin_fg.AsRGBSharp(), conf.Hunk_bg.AsRGBSharp()))
|
||||||
hunk_margin_format = ctx.SprintFunc(fmt.Sprintf("fg=%s bg=%s", conf.Margin_fg.AsRGBSharp(), conf.Hunk_margin_bg.AsRGBSharp()))
|
hunk_margin_format = ctx.SprintFunc(fmt.Sprintf("fg=%s bg=%s", conf.Margin_fg.AsRGBSharp(), conf.Hunk_margin_bg.AsRGBSharp()))
|
||||||
message_format = ctx.SprintFunc("bold")
|
message_format = ctx.SprintFunc("bold")
|
||||||
make_bracketer := func(start, end string) func(...any) string {
|
|
||||||
s, e := ctx.SprintFunc(start), ctx.SprintFunc(end)
|
|
||||||
end = e(" ")
|
|
||||||
idx := strings.LastIndexByte(end, ' ')
|
|
||||||
end = end[:idx]
|
|
||||||
start = s(" ")
|
|
||||||
idx = strings.LastIndexByte(start, ' ')
|
|
||||||
start = start[:idx]
|
|
||||||
|
|
||||||
return func(args ...any) string {
|
|
||||||
return start + fmt.Sprint(args) + end
|
|
||||||
}
|
|
||||||
}
|
|
||||||
added_center = make_bracketer("bg="+conf.Highlight_added_bg.AsRGBSharp(), "bg="+conf.Added_bg.AsRGBSharp())
|
|
||||||
removed_center = make_bracketer("bg="+conf.Highlight_removed_bg.AsRGBSharp(), "bg="+conf.Removed_bg.AsRGBSharp())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func highlight_boundaries(ltype, text string) string {
|
func center_span(ltype string, offset, size int) *sgr.Span {
|
||||||
|
ans := sgr.NewSpan(offset, size)
|
||||||
switch ltype {
|
switch ltype {
|
||||||
case "add":
|
case "add":
|
||||||
return added_center(text)
|
ans.SetBackground(conf.Highlight_added_bg).SetClosingBackground(conf.Added_bg)
|
||||||
case "remove":
|
case "remove":
|
||||||
return removed_center(text)
|
ans.SetBackground(conf.Highlight_removed_bg).SetClosingBackground(conf.Removed_bg)
|
||||||
}
|
}
|
||||||
return text
|
return ans
|
||||||
}
|
}
|
||||||
|
|
||||||
func title_lines(left_path, right_path string, columns, margin_size int, ans []*LogicalLine) []*LogicalLine {
|
func title_lines(left_path, right_path string, columns, margin_size int, ans []*LogicalLine) []*LogicalLine {
|
||||||
@ -333,12 +320,13 @@ func splitlines(text string, width int) []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func render_half_line(line_number int, line, ltype string, margin_size, available_cols int, center Center, ans []string) []string {
|
func render_half_line(line_number int, line, ltype string, margin_size, available_cols int, center Center, ans []string) []string {
|
||||||
if center.prefix_count > 0 {
|
size := center.left_size
|
||||||
line_sz := len(line)
|
if ltype != "remove" {
|
||||||
if center.prefix_count+center.suffix_count < line_sz {
|
size = center.right_size
|
||||||
end := len(line) - center.suffix_count
|
}
|
||||||
line = line[:center.prefix_count] + highlight_boundaries(ltype, line[center.prefix_count:end]) + line[end:]
|
if size > 0 {
|
||||||
}
|
span := center_span(ltype, center.offset, size)
|
||||||
|
line = sgr.InsertFormatting(line, span)
|
||||||
}
|
}
|
||||||
lnum := strconv.Itoa(line_number + 1)
|
lnum := strconv.Itoa(line_number + 1)
|
||||||
for _, sc := range splitlines(line, available_cols) {
|
for _, sc := range splitlines(line, available_cols) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user