@@ -494,7 +494,88 @@ func (w *BufWindow) displayBuffer() {
494494 }
495495 bloc .X = bslice
496496
497- draw := func (r rune , combc []rune , style tcell.Style , highlight bool , showcursor bool ) {
497+ // returns the rune to be drawn, style of it and if the bg should be preserved
498+ getRuneStyle := func (r rune , style tcell.Style , isplaceholder bool ) (rune , tcell.Style , bool ) {
499+ if nColsBeforeStart > 0 || vloc .Y < 0 || isplaceholder {
500+ return r , style , false
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 , false
508+ } else {
509+ return r , style .Reverse (true ), false
510+ }
511+ } else {
512+ return r , style .Underline (true ), false
513+ }
514+ }
515+ }
516+
517+ if r != '\t' && r != ' ' {
518+ return r , style , false
519+ }
520+
521+ var drawrune 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+ drawrune = 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+ preservebg := false
542+ if b .Settings ["hltaberrors" ].(bool ) && bloc .X < leadingwsEnd {
543+ if s , ok := config .Colorscheme ["tab-error" ]; ok {
544+ if b .Settings ["tabstospaces" ].(bool ) && r == '\t' {
545+ fg , _ , _ := s .Decompose ()
546+ style = style .Background (fg )
547+ preservebg = true
548+ } else if ! b .Settings ["tabstospaces" ].(bool ) && r == ' ' {
549+ fg , _ , _ := s .Decompose ()
550+ style = style .Background (fg )
551+ preservebg = true
552+ }
553+ }
554+ }
555+
556+ if b .Settings ["hltrailingws" ].(bool ) {
557+ if s , ok := config .Colorscheme ["trailingws" ]; ok {
558+ if bloc .X >= trailingwsStart && bloc .X < blineLen {
559+ hl := true
560+ for _ , c := range cursors {
561+ if c .NewTrailingWsY == bloc .Y {
562+ hl = false
563+ break
564+ }
565+ }
566+ if hl {
567+ fg , _ , _ := s .Decompose ()
568+ style = style .Background (fg )
569+ preservebg = true
570+ }
571+ }
572+ }
573+ }
574+
575+ return drawrune , style , preservebg
576+ }
577+
578+ draw := func (r rune , combc []rune , style tcell.Style , highlight bool , showcursor bool , preservebg bool ) {
498579 if nColsBeforeStart <= 0 && vloc .Y >= 0 {
499580 if highlight {
500581 if w .Buf .HighlightSearch && w .Buf .SearchMatch (bloc ) {
@@ -509,37 +590,8 @@ func (w *BufWindow) displayBuffer() {
509590
510591 // syntax or hlsearch highlighting with non-default background takes precedence
511592 // 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- }
524- }
525-
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- }
541- }
542- }
593+ if preservebg && origBg != defBg {
594+ preservebg = true
543595 }
544596
545597 for _ , c := range cursors {
@@ -554,7 +606,7 @@ func (w *BufWindow) displayBuffer() {
554606 }
555607 }
556608
557- if b .Settings ["cursorline" ].(bool ) && w .active && ! dontOverrideBackground &&
609+ if b .Settings ["cursorline" ].(bool ) && w .active && ! preservebg &&
558610 ! c .HasSelection () && c .Y == bloc .Y {
559611 if s , ok := config .Colorscheme ["cursor-line" ]; ok {
560612 fg , _ , _ := s .Decompose ()
@@ -571,40 +623,12 @@ func (w *BufWindow) displayBuffer() {
571623 }
572624 }
573625
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- }
580-
581- r = indentrunes [0 ]
582- if s , ok := config .Colorscheme ["indent-char" ]; ok && r != ' ' {
583- fg , _ , _ := s .Decompose ()
584- style = style .Foreground (fg )
585- }
586- }
587-
588626 if s , ok := config .Colorscheme ["color-column" ]; ok {
589- if colorcolumn != 0 && vloc .X - w .gutterOffset + w .StartCol == colorcolumn && ! dontOverrideBackground {
627+ if colorcolumn != 0 && vloc .X - w .gutterOffset + w .StartCol == colorcolumn && ! preservebg {
590628 fg , _ , _ := s .Decompose ()
591629 style = style .Background (fg )
592630 }
593631 }
594-
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- }
607- }
608632 }
609633
610634 screen .SetContent (w .X + vloc .X , w .Y + vloc .Y , r , combc , style )
@@ -692,7 +716,7 @@ func (w *BufWindow) displayBuffer() {
692716 // If a word (or just a wide rune) does not fit in the window
693717 if vloc .X + wordwidth > maxWidth && vloc .X > w .gutterOffset {
694718 for vloc .X < maxWidth {
695- draw (' ' , nil , config .DefStyle , false , false )
719+ draw (' ' , nil , config .DefStyle , false , false , true )
696720 }
697721
698722 // We either stop or we wrap to draw the word in the next line
@@ -708,18 +732,17 @@ func (w *BufWindow) displayBuffer() {
708732 }
709733
710734 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 )
735+ drawrune , drawstyle , preservebg := getRuneStyle (r .r , r .style , false )
736+ draw (drawrune , r .combc , drawstyle , true , true , preservebg )
737+
738+ // Draw extra characters for tabs or wide runes
739+ for i := 1 ; i < r .width ; i ++ {
740+ if r .r == '\t' {
741+ drawrune , drawstyle , preservebg = getRuneStyle ('\t' , r .style , false )
742+ } else {
743+ drawrune , drawstyle , preservebg = getRuneStyle (' ' , r .style , true )
722744 }
745+ draw (drawrune , nil , drawstyle , true , false , preservebg )
723746 }
724747 bloc .X ++
725748 }
@@ -764,7 +787,8 @@ func (w *BufWindow) displayBuffer() {
764787
765788 if vloc .X != maxWidth {
766789 // Display newline within a selection
767- draw (' ' , nil , config .DefStyle , true , true )
790+ drawrune , drawstyle , preservebg := getRuneStyle (' ' , config .DefStyle , true )
791+ draw (drawrune , nil , drawstyle , true , true , preservebg )
768792 }
769793
770794 bloc .X = w .StartCol
0 commit comments