@@ -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
@@ -494,7 +519,7 @@ func (w *BufWindow) displayBuffer() {
494519 }
495520 bloc .X = bslice
496521
497- getRuneStyle := func (r rune , style tcell.Style , isplaceholder bool ) (rune , tcell.Style , bool ) {
522+ getRuneStyle := func (r rune , style tcell.Style , showoffset int , isplaceholder bool ) (rune , tcell.Style , bool ) {
498523 bgoverridable := true
499524 if nColsBeforeStart > 0 || vloc .Y < 0 || isplaceholder {
500525 return r , style , bgoverridable
@@ -514,28 +539,45 @@ func (w *BufWindow) displayBuffer() {
514539 }
515540 }
516541
517- if r != '\t' && r != ' ' {
542+ if r != '\t' && r != ' ' {
518543 return r , style , bgoverridable
519544 }
520545
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 {' ' }
546+ var indentrunes []rune
547+ switch r {
548+ case '\t' :
549+ if bloc .X < leadingwsEnd {
550+ if indenttabchars != "" {
551+ indentrunes = []rune (indenttabchars )
552+ } else {
553+ indentrunes = []rune (tabchars )
554+ }
555+ } else {
556+ indentrunes = []rune (tabchars )
527557 }
528-
529- returnrune = indentrunes [0 ]
530- if s , ok := config .Colorscheme ["indent-char" ]; ok && r != ' ' {
531- fg , _ , _ := s .Decompose ()
532- style = style .Foreground (fg )
558+ case ' ' :
559+ if bloc .X % tabsize == 0 && bloc .X < leadingwsEnd {
560+ if indentspacechars != "" {
561+ indentrunes = []rune (indentspacechars )
562+ } else {
563+ indentrunes = []rune (spacechars )
564+ }
565+ } else {
566+ indentrunes = []rune (spacechars )
533567 }
568+ }
534569
535- if s , ok := config .Colorscheme ["indent-char" ]; ok {
536- fg , _ , _ := s .Decompose ()
537- style = style .Foreground (fg )
538- }
570+ var returnrune rune
571+ if showoffset < len (indentrunes ) {
572+ returnrune = indentrunes [showoffset ]
573+ } else {
574+ // use space if no showchars or after we showed showchars
575+ returnrune = ' '
576+ }
577+
578+ if s , ok := config .Colorscheme ["indent-char" ]; ok {
579+ fg , _ , _ := s .Decompose ()
580+ style = style .Foreground (fg )
539581 }
540582
541583 if b .Settings ["hltaberrors" ].(bool ) && bloc .X < leadingwsEnd {
@@ -736,15 +778,15 @@ func (w *BufWindow) displayBuffer() {
736778 }
737779
738780 for _ , r := range word {
739- drawrune , drawstyle , bgoverridable := getRuneStyle (r .r , r .style , false )
781+ drawrune , drawstyle , bgoverridable := getRuneStyle (r .r , r .style , 0 , false )
740782 draw (drawrune , r .combc , drawstyle , true , true , bgoverridable )
741783
742784 // Draw extra characters for tabs or wide runes
743785 for i := 1 ; i < r .width ; i ++ {
744786 if r .r == '\t' {
745- drawrune , drawstyle , bgoverridable = getRuneStyle ('\t' , r .style , false )
787+ drawrune , drawstyle , bgoverridable = getRuneStyle ('\t' , r .style , i , false )
746788 } else {
747- drawrune , drawstyle , bgoverridable = getRuneStyle (' ' , r .style , true )
789+ drawrune , drawstyle , bgoverridable = getRuneStyle (' ' , r .style , i , true )
748790 }
749791 draw (drawrune , nil , drawstyle , true , false , bgoverridable )
750792 }
@@ -791,7 +833,7 @@ func (w *BufWindow) displayBuffer() {
791833
792834 if vloc .X != maxWidth {
793835 // Display newline within a selection
794- drawrune , drawstyle , bgoverridable := getRuneStyle (' ' , config .DefStyle , true )
836+ drawrune , drawstyle , bgoverridable := getRuneStyle (' ' , config .DefStyle , 0 , true )
795837 draw (drawrune , nil , drawstyle , true , true , bgoverridable )
796838 }
797839
0 commit comments