@@ -2,6 +2,7 @@ package display
22
33import (
44 "strconv"
5+ "strings"
56
67 runewidth "github.com/mattn/go-runewidth"
78 "github.com/micro-editor/tcell/v2"
@@ -450,6 +451,30 @@ func (w *BufWindow) displayBuffer() {
450451 cursors := b .GetCursors ()
451452
452453 curStyle := config .DefStyle
454+
455+ // Parse showchars which is in the format of key1=val1,key2=val2,...
456+ spacechars := " "
457+ tabchars := b .Settings ["indentchar" ].(string )
458+ var indentspacechars string
459+ var indenttabchars string
460+ for _ , entry := range strings .Split (b .Settings ["showchars" ].(string ), "," ) {
461+ split := strings .SplitN (entry , "=" , 2 )
462+ if len (split ) < 2 {
463+ continue
464+ }
465+ key , val := split [0 ], split [1 ]
466+ switch key {
467+ case "space" :
468+ spacechars = val
469+ case "tab" :
470+ tabchars = val
471+ case "ispace" :
472+ indentspacechars = val
473+ case "itab" :
474+ indenttabchars = val
475+ }
476+ }
477+
453478 for ; vloc .Y < w .bufHeight ; vloc .Y ++ {
454479 vloc .X = 0
455480
@@ -495,7 +520,7 @@ func (w *BufWindow) displayBuffer() {
495520 bloc .X = bslice
496521
497522 // 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 ) {
523+ getRuneStyle := func (r rune , style tcell.Style , showoffset int , linex int , isplaceholder bool ) (rune , tcell.Style , bool ) {
499524 if nColsBeforeStart > 0 || vloc .Y < 0 || isplaceholder {
500525 return r , style , false
501526 }
@@ -518,21 +543,35 @@ func (w *BufWindow) displayBuffer() {
518543 return r , style , false
519544 }
520545
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 {' ' }
546+ var indentrunes []rune
547+ switch r {
548+ case '\t' :
549+ if bloc .X < leadingwsEnd && indenttabchars != "" {
550+ indentrunes = []rune (indenttabchars )
551+ } else {
552+ indentrunes = []rune (tabchars )
527553 }
528-
529- drawrune = indentrunes [ 0 ]
530- if s , ok := config . Colorscheme [ "indent-char" ]; ok {
531- fg , _ , _ := s . Decompose ()
532- style = style . Foreground ( fg )
554+ case ' ' :
555+ if linex % tabsize == 0 && bloc . X < leadingwsEnd && indentspacechars != "" {
556+ indentrunes = [] rune ( indentspacechars )
557+ } else {
558+ indentrunes = [] rune ( spacechars )
533559 }
534560 }
535561
562+ var drawrune rune
563+ if showoffset < len (indentrunes ) {
564+ drawrune = indentrunes [showoffset ]
565+ } else {
566+ // use space if no showchars or after we showed showchars
567+ drawrune = ' '
568+ }
569+
570+ if s , ok := config .Colorscheme ["indent-char" ]; ok {
571+ fg , _ , _ := s .Decompose ()
572+ style = style .Foreground (fg )
573+ }
574+
536575 preservebg := false
537576 if b .Settings ["hltaberrors" ].(bool ) && bloc .X < leadingwsEnd {
538577 if s , ok := config .Colorscheme ["tab-error" ]; ok {
@@ -692,6 +731,7 @@ func (w *BufWindow) displayBuffer() {
692731
693732 width := 0
694733
734+ linex := totalwidth
695735 switch r {
696736 case '\t' :
697737 ts := tabsize - (totalwidth % tabsize )
@@ -732,15 +772,15 @@ func (w *BufWindow) displayBuffer() {
732772 }
733773
734774 for _ , r := range word {
735- drawrune , drawstyle , preservebg := getRuneStyle (r .r , r .style , false )
775+ drawrune , drawstyle , preservebg := getRuneStyle (r .r , r .style , 0 , linex , false )
736776 draw (drawrune , r .combc , drawstyle , true , true , preservebg )
737777
738778 // Draw extra characters for tabs or wide runes
739779 for i := 1 ; i < r .width ; i ++ {
740780 if r .r == '\t' {
741- drawrune , drawstyle , preservebg = getRuneStyle ('\t' , r .style , false )
781+ drawrune , drawstyle , preservebg = getRuneStyle ('\t' , r .style , i , linex + i , false )
742782 } else {
743- drawrune , drawstyle , preservebg = getRuneStyle (' ' , r .style , true )
783+ drawrune , drawstyle , preservebg = getRuneStyle (' ' , r .style , i , linex + i , true )
744784 }
745785 draw (drawrune , nil , drawstyle , true , false , preservebg )
746786 }
@@ -787,7 +827,7 @@ func (w *BufWindow) displayBuffer() {
787827
788828 if vloc .X != maxWidth {
789829 // Display newline within a selection
790- drawrune , drawstyle , preservebg := getRuneStyle (' ' , config .DefStyle , true )
830+ drawrune , drawstyle , preservebg := getRuneStyle (' ' , config .DefStyle , 0 , totalwidth , true )
791831 draw (drawrune , nil , drawstyle , true , true , preservebg )
792832 }
793833
0 commit comments