Adding showchars option

This commit is contained in:
Neko Box Coder
2025-07-13 20:05:39 +01:00
parent 532c315f79
commit 1ef6459846
3 changed files with 81 additions and 23 deletions

View File

@@ -70,7 +70,7 @@ var defaultCommonSettings = map[string]interface{}{
"hltrailingws": false,
"ignorecase": true,
"incsearch": true,
"indentchar": " ",
"indentchar": " ", // Deprecated
"keepautoindent": false,
"matchbrace": true,
"matchbraceleft": true,
@@ -88,6 +88,7 @@ var defaultCommonSettings = map[string]interface{}{
"scrollbar": false,
"scrollmargin": float64(3),
"scrollspeed": float64(2),
"showchars": "",
"smartpaste": true,
"softwrap": false,
"splitbottom": true,
@@ -210,6 +211,7 @@ func validateParsedSettings() error {
}
continue
}
if _, ok := defaults[k]; ok {
if e := verifySetting(k, v, defaults[k]); e != nil {
err = e

View File

@@ -2,6 +2,7 @@ package display
import (
"strconv"
"strings"
runewidth "github.com/mattn/go-runewidth"
"github.com/micro-editor/tcell/v2"
@@ -450,6 +451,30 @@ func (w *BufWindow) displayBuffer() {
cursors := b.GetCursors()
curStyle := config.DefStyle
// Parse showchars which is in the format of key1=val1,key2=val2,...
spacechars := " "
tabchars := b.Settings["indentchar"].(string)
var indentspacechars string
var indenttabchars string
for _, entry := range strings.Split(b.Settings["showchars"].(string), ",") {
split := strings.SplitN(entry, "=", 2)
if len(split) < 2 {
continue
}
key, val := split[0], split[1]
switch key {
case "space":
spacechars = val
case "tab":
tabchars = val
case "ispace":
indentspacechars = val
case "itab":
indenttabchars = val
}
}
for ; vloc.Y < w.bufHeight; vloc.Y++ {
vloc.X = 0
@@ -495,7 +520,7 @@ func (w *BufWindow) displayBuffer() {
bloc.X = bslice
// returns the rune to be drawn, style of it and if the bg should be preserved
getRuneStyle := func(r rune, style tcell.Style, isplaceholder bool) (rune, tcell.Style, bool) {
getRuneStyle := func(r rune, style tcell.Style, showoffset int, linex int, isplaceholder bool) (rune, tcell.Style, bool) {
if nColsBeforeStart > 0 || vloc.Y < 0 || isplaceholder {
return r, style, false
}
@@ -518,19 +543,33 @@ func (w *BufWindow) displayBuffer() {
return r, style, false
}
var drawrune rune
if r == '\t' {
indentrunes := []rune(b.Settings["indentchar"].(string))
// if empty indentchar settings, use space
if len(indentrunes) == 0 {
indentrunes = []rune{' '}
var indentrunes []rune
switch r {
case '\t':
if bloc.X < leadingwsEnd && indenttabchars != "" {
indentrunes = []rune(indenttabchars)
} else {
indentrunes = []rune(tabchars)
}
case ' ':
if linex%tabsize == 0 && bloc.X < leadingwsEnd && indentspacechars != "" {
indentrunes = []rune(indentspacechars)
} else {
indentrunes = []rune(spacechars)
}
}
drawrune = indentrunes[0]
if s, ok := config.Colorscheme["indent-char"]; ok {
fg, _, _ := s.Decompose()
style = style.Foreground(fg)
}
var drawrune rune
if showoffset < len(indentrunes) {
drawrune = indentrunes[showoffset]
} else {
// use space if no showchars or after we showed showchars
drawrune = ' '
}
if s, ok := config.Colorscheme["indent-char"]; ok {
fg, _, _ := s.Decompose()
style = style.Foreground(fg)
}
preservebg := false
@@ -692,6 +731,7 @@ func (w *BufWindow) displayBuffer() {
width := 0
linex := totalwidth
switch r {
case '\t':
ts := tabsize - (totalwidth % tabsize)
@@ -732,15 +772,15 @@ func (w *BufWindow) displayBuffer() {
}
for _, r := range word {
drawrune, drawstyle, preservebg := getRuneStyle(r.r, r.style, false)
drawrune, drawstyle, preservebg := getRuneStyle(r.r, r.style, 0, linex, false)
draw(drawrune, r.combc, drawstyle, true, true, preservebg)
// Draw extra characters for tabs or wide runes
for i := 1; i < r.width; i++ {
if r.r == '\t' {
drawrune, drawstyle, preservebg = getRuneStyle('\t', r.style, false)
drawrune, drawstyle, preservebg = getRuneStyle('\t', r.style, i, linex+i, false)
} else {
drawrune, drawstyle, preservebg = getRuneStyle(' ', r.style, true)
drawrune, drawstyle, preservebg = getRuneStyle(' ', r.style, i, linex+i, true)
}
draw(drawrune, nil, drawstyle, true, false, preservebg)
}
@@ -787,7 +827,7 @@ func (w *BufWindow) displayBuffer() {
if vloc.X != maxWidth {
// Display newline within a selection
drawrune, drawstyle, preservebg := getRuneStyle(' ', config.DefStyle, true)
drawrune, drawstyle, preservebg := getRuneStyle(' ', config.DefStyle, 0, totalwidth, true)
draw(drawrune, nil, drawstyle, true, true, preservebg)
}

View File

@@ -203,12 +203,8 @@ Here are the available options:
default value: `true`
* `indentchar`: sets the indentation character. This will not be inserted into
files; it is only a visual indicator that whitespace is present. If set to a
printing character, it functions as a subset of the "show invisibles"
setting available in many other text editors. The color of this character is
determined by the `indent-char` field in the current theme rather than the
default text color.
* `indentchar`: sets the character to be shown to display tab characters.
This option is **deprecated**, use the `tab` key in `showchars` option instead.
default value: ` ` (space)
@@ -386,6 +382,25 @@ Here are the available options:
default value: `2`
* `showchars`: sets what characters to be shown to display various invisible
characters in the file. The characters shown will not be inserted into files.
This option is specified in the form of `key1=value1,key2=value2,...`.
Here are the list of keys:
- `space`: space characters
- `tab`: tab characters. If set, overrides the `indentchar` option.
- `ispace`: space characters at indent position before the first visible
character in a line. If this is not set, `space` will be shown
instead.
- `itab`: tab characters before the first visible character in a line.
If this is not set, `tab` will be shown instead.
An example of this option value could be `tab=>,space=.,itab=|>,ispace=|`
The color of the shown character is determined by the `indent-char`
field in the current theme rather than the default text color.
default value: ``
* `smartpaste`: add leading whitespace when pasting multiple lines.
This will attempt to preserve the current indentation level when pasting an
unindented block.
@@ -577,6 +592,7 @@ so that you can see what the formatting should look like.
"scrollbarchar": "|",
"scrollmargin": 3,
"scrollspeed": 2,
"showchars": "",
"smartpaste": true,
"softwrap": false,
"splitbottom": true,