Skip to content

Commit ef34601

Browse files
Splitting draw out to getRuneStyle in bufwindow, removing @ for wide rune in bufwindow
1 parent 98ff79d commit ef34601

File tree

1 file changed

+138
-110
lines changed

1 file changed

+138
-110
lines changed

internal/display/bufwindow.go

Lines changed: 138 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -494,133 +494,161 @@ func (w *BufWindow) displayBuffer() {
494494
}
495495
bloc.X = bslice
496496

497-
draw := func(r rune, combc []rune, style tcell.Style, highlight bool, showcursor bool) {
498-
if nColsBeforeStart <= 0 && vloc.Y >= 0 {
499-
if highlight {
500-
if w.Buf.HighlightSearch && w.Buf.SearchMatch(bloc) {
501-
style = config.DefStyle.Reverse(true)
502-
if s, ok := config.Colorscheme["hlsearch"]; ok {
503-
style = s
497+
getRuneStyle := func(r rune, style tcell.Style, isplaceholder bool) (rune, tcell.Style, bool) {
498+
bgoverridable := true
499+
if nColsBeforeStart > 0 || vloc.Y < 0 || isplaceholder {
500+
return r, style, bgoverridable
501+
}
502+
503+
for _, mb := range matchingBraces {
504+
if mb.X == bloc.X && mb.Y == bloc.Y {
505+
if b.Settings["matchbracestyle"].(string) == "highlight" {
506+
if s, ok := config.Colorscheme["match-brace"]; ok {
507+
return r, s, bgoverridable
508+
} else {
509+
return r, style.Reverse(true), bgoverridable
504510
}
511+
} else {
512+
return r, style.Underline(true), bgoverridable
505513
}
514+
}
515+
}
506516

507-
_, origBg, _ := style.Decompose()
508-
_, defBg, _ := config.DefStyle.Decompose()
509-
510-
// syntax or hlsearch highlighting with non-default background takes precedence
511-
// over cursor-line and color-column
512-
dontOverrideBackground := origBg != defBg
513-
514-
if b.Settings["hltaberrors"].(bool) {
515-
if s, ok := config.Colorscheme["tab-error"]; ok {
516-
isTab := (r == '\t') || (r == ' ' && !showcursor)
517-
if (b.Settings["tabstospaces"].(bool) && isTab) ||
518-
(!b.Settings["tabstospaces"].(bool) && bloc.X < leadingwsEnd && r == ' ' && !isTab) {
519-
fg, _, _ := s.Decompose()
520-
style = style.Background(fg)
521-
dontOverrideBackground = true
522-
}
523-
}
517+
if r != '\t' && r != ' '{
518+
return r, style, bgoverridable
519+
}
520+
521+
var returnrune rune
522+
if r == '\t' {
523+
indentrunes := []rune(b.Settings["indentchar"].(string))
524+
// if empty indentchar settings, use space
525+
if len(indentrunes) == 0 {
526+
indentrunes = []rune{' '}
527+
}
528+
529+
returnrune = indentrunes[0]
530+
if s, ok := config.Colorscheme["indent-char"]; ok && r != ' ' {
531+
fg, _, _ := s.Decompose()
532+
style = style.Foreground(fg)
533+
}
534+
535+
if s, ok := config.Colorscheme["indent-char"]; ok {
536+
fg, _, _ := s.Decompose()
537+
style = style.Foreground(fg)
538+
}
539+
}
540+
541+
if b.Settings["hltaberrors"].(bool) && bloc.X < leadingwsEnd {
542+
if s, ok := config.Colorscheme["tab-error"]; ok {
543+
if b.Settings["tabstospaces"].(bool) && r == '\t' {
544+
fg, _, _ := s.Decompose()
545+
style = style.Background(fg)
546+
bgoverridable = false
547+
} else if !b.Settings["tabstospaces"].(bool) && r == ' ' {
548+
fg, _, _ := s.Decompose()
549+
style = style.Background(fg)
550+
bgoverridable = false
524551
}
552+
}
553+
}
525554

526-
if b.Settings["hltrailingws"].(bool) {
527-
if s, ok := config.Colorscheme["trailingws"]; ok {
528-
if bloc.X >= trailingwsStart && bloc.X < blineLen {
529-
hl := true
530-
for _, c := range cursors {
531-
if c.NewTrailingWsY == bloc.Y {
532-
hl = false
533-
break
534-
}
535-
}
536-
if hl {
537-
fg, _, _ := s.Decompose()
538-
style = style.Background(fg)
539-
dontOverrideBackground = true
540-
}
555+
if b.Settings["hltrailingws"].(bool) {
556+
if s, ok := config.Colorscheme["trailingws"]; ok {
557+
if bloc.X >= trailingwsStart && bloc.X < blineLen {
558+
hl := true
559+
for _, c := range cursors {
560+
if c.NewTrailingWsY == bloc.Y {
561+
hl = false
562+
break
541563
}
542564
}
565+
if hl {
566+
fg, _, _ := s.Decompose()
567+
style = style.Background(fg)
568+
bgoverridable = false
569+
}
543570
}
571+
}
572+
}
544573

545-
for _, c := range cursors {
546-
if c.HasSelection() &&
547-
(bloc.GreaterEqual(c.CurSelection[0]) && bloc.LessThan(c.CurSelection[1]) ||
548-
bloc.LessThan(c.CurSelection[0]) && bloc.GreaterEqual(c.CurSelection[1])) {
549-
// The current character is selected
550-
style = config.DefStyle.Reverse(true)
574+
return returnrune, style, bgoverridable
575+
}
551576

552-
if s, ok := config.Colorscheme["selection"]; ok {
553-
style = s
554-
}
555-
}
577+
draw := func(r rune, combc []rune, style tcell.Style, highlight bool, showcursor bool, bgoverridable bool) {
578+
defer func() {
579+
if nColsBeforeStart <= 0 {
580+
vloc.X++
581+
}
582+
nColsBeforeStart--
583+
}()
556584

557-
if b.Settings["cursorline"].(bool) && w.active && !dontOverrideBackground &&
558-
!c.HasSelection() && c.Y == bloc.Y {
559-
if s, ok := config.Colorscheme["cursor-line"]; ok {
560-
fg, _, _ := s.Decompose()
561-
style = style.Background(fg)
562-
}
563-
}
564-
}
585+
if nColsBeforeStart > 0 || vloc.Y < 0 {
586+
return
587+
}
565588

566-
for _, m := range b.Messages {
567-
if bloc.GreaterEqual(m.Start) && bloc.LessThan(m.End) ||
568-
bloc.LessThan(m.End) && bloc.GreaterEqual(m.Start) {
569-
style = style.Underline(true)
570-
break
571-
}
589+
if highlight {
590+
if w.Buf.HighlightSearch && w.Buf.SearchMatch(bloc) {
591+
style = config.DefStyle.Reverse(true)
592+
if s, ok := config.Colorscheme["hlsearch"]; ok {
593+
style = s
572594
}
595+
}
573596

574-
if r == '\t' {
575-
indentrunes := []rune(b.Settings["indentchar"].(string))
576-
// if empty indentchar settings, use space
577-
if len(indentrunes) == 0 {
578-
indentrunes = []rune{' '}
579-
}
597+
_, origBg, _ := style.Decompose()
598+
_, defBg, _ := config.DefStyle.Decompose()
580599

581-
r = indentrunes[0]
582-
if s, ok := config.Colorscheme["indent-char"]; ok && r != ' ' {
583-
fg, _, _ := s.Decompose()
584-
style = style.Foreground(fg)
600+
// syntax or hlsearch highlighting with non-default background takes precedence
601+
// over cursor-line and color-column
602+
if bgoverridable {
603+
bgoverridable = origBg == defBg
604+
}
605+
606+
for _, c := range cursors {
607+
if c.HasSelection() &&
608+
(bloc.GreaterEqual(c.CurSelection[0]) && bloc.LessThan(c.CurSelection[1]) ||
609+
bloc.LessThan(c.CurSelection[0]) && bloc.GreaterEqual(c.CurSelection[1])) {
610+
// The current character is selected
611+
style = config.DefStyle.Reverse(true)
612+
613+
if s, ok := config.Colorscheme["selection"]; ok {
614+
style = s
585615
}
586616
}
587617

588-
if s, ok := config.Colorscheme["color-column"]; ok {
589-
if colorcolumn != 0 && vloc.X-w.gutterOffset+w.StartCol == colorcolumn && !dontOverrideBackground {
618+
if b.Settings["cursorline"].(bool) && w.active && bgoverridable &&
619+
!c.HasSelection() && c.Y == bloc.Y {
620+
if s, ok := config.Colorscheme["cursor-line"]; ok {
590621
fg, _, _ := s.Decompose()
591622
style = style.Background(fg)
592623
}
593624
}
625+
}
594626

595-
for _, mb := range matchingBraces {
596-
if mb.X == bloc.X && mb.Y == bloc.Y {
597-
if b.Settings["matchbracestyle"].(string) == "highlight" {
598-
if s, ok := config.Colorscheme["match-brace"]; ok {
599-
style = s
600-
} else {
601-
style = style.Reverse(true)
602-
}
603-
} else {
604-
style = style.Underline(true)
605-
}
606-
}
627+
for _, m := range b.Messages {
628+
if bloc.GreaterEqual(m.Start) && bloc.LessThan(m.End) ||
629+
bloc.LessThan(m.End) && bloc.GreaterEqual(m.Start) {
630+
style = style.Underline(true)
631+
break
607632
}
608633
}
609634

610-
screen.SetContent(w.X+vloc.X, w.Y+vloc.Y, r, combc, style)
611-
612-
if showcursor {
613-
for _, c := range cursors {
614-
if c.X == bloc.X && c.Y == bloc.Y && !c.HasSelection() {
615-
w.showCursor(w.X+vloc.X, w.Y+vloc.Y, c.Num == 0)
616-
}
635+
if s, ok := config.Colorscheme["color-column"]; ok {
636+
if colorcolumn != 0 && vloc.X-w.gutterOffset+w.StartCol == colorcolumn && bgoverridable {
637+
fg, _, _ := s.Decompose()
638+
style = style.Background(fg)
617639
}
618640
}
619641
}
620-
if nColsBeforeStart <= 0 {
621-
vloc.X++
642+
643+
screen.SetContent(w.X+vloc.X, w.Y+vloc.Y, r, combc, style)
644+
645+
if showcursor {
646+
for _, c := range cursors {
647+
if c.X == bloc.X && c.Y == bloc.Y && !c.HasSelection() {
648+
w.showCursor(w.X+vloc.X, w.Y+vloc.Y, c.Num == 0)
649+
}
650+
}
622651
}
623-
nColsBeforeStart--
624652
}
625653

626654
wrap := func() {
@@ -692,7 +720,7 @@ func (w *BufWindow) displayBuffer() {
692720
// If a word (or just a wide rune) does not fit in the window
693721
if vloc.X+wordwidth > maxWidth && vloc.X > w.gutterOffset {
694722
for vloc.X < maxWidth {
695-
draw(' ', nil, config.DefStyle, false, false)
723+
draw(' ', nil, config.DefStyle, false, false, true)
696724
}
697725

698726
// We either stop or we wrap to draw the word in the next line
@@ -708,18 +736,17 @@ func (w *BufWindow) displayBuffer() {
708736
}
709737

710738
for _, r := range word {
711-
draw(r.r, r.combc, r.style, true, true)
712-
713-
// Draw any extra characters either spaces for tabs or @ for incomplete wide runes
714-
if r.width > 1 {
715-
char := ' '
716-
if r.r != '\t' {
717-
char = '@'
718-
}
719-
720-
for i := 1; i < r.width; i++ {
721-
draw(char, nil, r.style, true, false)
739+
drawrune, drawstyle, bgoverridable := getRuneStyle(r.r, r.style, false)
740+
draw(drawrune, r.combc, drawstyle, true, true, bgoverridable)
741+
742+
// Draw extra characters for tabs or wide runes
743+
for i := 1; i < r.width; i++ {
744+
if r.r == '\t' {
745+
drawrune, drawstyle, bgoverridable = getRuneStyle('\t', r.style, false)
746+
} else {
747+
drawrune, drawstyle, bgoverridable = getRuneStyle(' ', r.style, true)
722748
}
749+
draw(drawrune, nil, drawstyle, true, false, bgoverridable)
723750
}
724751
bloc.X++
725752
}
@@ -764,7 +791,8 @@ func (w *BufWindow) displayBuffer() {
764791

765792
if vloc.X != maxWidth {
766793
// Display newline within a selection
767-
draw(' ', nil, config.DefStyle, true, true)
794+
drawrune, drawstyle, bgoverridable := getRuneStyle(' ', config.DefStyle, true)
795+
draw(drawrune, nil, drawstyle, true, true, bgoverridable)
768796
}
769797

770798
bloc.X = w.StartCol

0 commit comments

Comments
 (0)