@@ -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