Skip to content

Commit 1e5bcdb

Browse files
Merge branch 'MoreCharOptions' into dev
2 parents 58f3b7f + 71d5c09 commit 1e5bcdb

File tree

3 files changed

+67
-47
lines changed

3 files changed

+67
-47
lines changed

internal/config/settings.go

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,7 @@ var defaultCommonSettings = map[string]interface{}{
7070
"hltrailingws": false,
7171
"ignorecase": true,
7272
"incsearch": true,
73-
"indenttabchar": " ",
74-
"indentspacechar": " ",
75-
"spacechar": " ",
73+
"indentchar": " ", // Deprecated
7674
"keepautoindent": false,
7775
"matchbrace": true,
7876
"matchbraceleft": true,
@@ -90,6 +88,7 @@ var defaultCommonSettings = map[string]interface{}{
9088
"scrollbar": false,
9189
"scrollmargin": float64(3),
9290
"scrollspeed": float64(2),
91+
"showchars": "",
9392
"smartpaste": true,
9493
"softwrap": false,
9594
"splitbottom": true,
@@ -215,12 +214,6 @@ func validateParsedSettings() error {
215214
continue
216215
}
217216

218-
if k == "indentchar" {
219-
// migrate to "indenttabchar" from "indentchar"
220-
parsedSettings["indenttabchar"] = v
221-
err = errors.New("indentchar has been deprecated, use indenttabchar instead")
222-
}
223-
224217
if _, ok := defaults[k]; ok {
225218
if e := verifySetting(k, v, defaults[k]); e != nil {
226219
err = e

internal/display/bufwindow.go

Lines changed: 50 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package display
22

33
import (
44
"strconv"
5+
"strings"
56

67
runewidth "github.com/mattn/go-runewidth"
78
"github.com/micro-editor/tcell/v2"
@@ -451,6 +452,32 @@ func (w *BufWindow) displayBuffer() {
451452
cursors := b.GetCursors()
452453

453454
curStyle := config.DefStyle
455+
456+
// Parse showchars which is in the format of option1=val1,option2=val2,...
457+
spacechars := " "
458+
tabchars := b.Settings["indentchar"].(string)
459+
indentspacechars := " "
460+
indenttabchars := b.Settings["indentchar"].(string)
461+
462+
charsentries := strings.Split(b.Settings["showchars"].(string), ",")
463+
for _, entry := range charsentries {
464+
if !strings.Contains(entry, "=") {
465+
continue
466+
}
467+
entrykey := strings.Split(entry, "=")[0]
468+
entryval := strings.Split(entry, "=")[1]
469+
switch entrykey {
470+
case "space":
471+
spacechars = entryval
472+
case "tab":
473+
tabchars = entryval
474+
case "ispace":
475+
indentspacechars = entryval
476+
case "itab":
477+
indenttabchars = entryval
478+
}
479+
}
480+
454481
for ; vloc.Y < w.bufHeight; vloc.Y++ {
455482
vloc.X = 0
456483

@@ -495,7 +522,7 @@ func (w *BufWindow) displayBuffer() {
495522
}
496523
bloc.X = bslice
497524

498-
draw := func(r rune, combc []rune, validrune bool, style tcell.Style, highlight bool, showcursor bool) {
525+
draw := func(r rune, showoffset int, combc []rune, isplaceholder bool, style tcell.Style, highlight bool, showcursor bool) {
499526
if nColsBeforeStart <= 0 && vloc.Y >= 0 {
500527
if highlight {
501528
if w.Buf.HighlightSearch && w.Buf.SearchMatch(bloc) {
@@ -572,25 +599,30 @@ func (w *BufWindow) displayBuffer() {
572599
}
573600
}
574601

575-
if r == '\t' || (r == ' ' && bloc.X < blineLen && validrune) {
602+
if (r == '\t' || r == ' ') && !isplaceholder {
576603
var indentrunes []rune
577604
switch r {
578605
case '\t':
579-
indentrunes = []rune(b.Settings["indenttabchar"].(string))
606+
if bloc.X < leadingwsEnd && !b.Settings["tabstospaces"].(bool) {
607+
indentrunes = []rune(indenttabchars)
608+
} else {
609+
indentrunes = []rune(tabchars)
610+
}
580611
case ' ':
581-
if bloc.X%tabsize == 0 && bloc.X < leadingwsEnd {
582-
indentrunes = []rune(b.Settings["indentspacechar"].(string))
612+
if bloc.X%tabsize == 0 && bloc.X < leadingwsEnd && b.Settings["tabstospaces"].(bool) {
613+
indentrunes = []rune(indentspacechars)
583614
} else {
584-
indentrunes = []rune(b.Settings["spacechar"].(string))
615+
indentrunes = []rune(spacechars)
585616
}
586617
}
587618

588-
// if no override for current character, use space
589-
if len(indentrunes) == 0 {
590-
indentrunes = []rune{' '}
619+
if showoffset < len(indentrunes) {
620+
r = indentrunes[showoffset]
621+
} else {
622+
// use space if no showchars or after we showed showchars
623+
r = ' '
591624
}
592625

593-
r = indentrunes[0]
594626
if s, ok := config.Colorscheme["indent-char"]; ok && r != ' ' {
595627
fg, _, _ := s.Decompose()
596628
style = style.Foreground(fg)
@@ -704,7 +736,7 @@ func (w *BufWindow) displayBuffer() {
704736
// If a word (or just a wide rune) does not fit in the window
705737
if vloc.X+wordwidth > maxWidth && vloc.X > w.gutterOffset {
706738
for vloc.X < maxWidth {
707-
draw(' ', nil, false, config.DefStyle, false, false)
739+
draw(' ', 0, nil, true, config.DefStyle, false, false)
708740
}
709741

710742
// We either stop or we wrap to draw the word in the next line
@@ -728,17 +760,14 @@ func (w *BufWindow) displayBuffer() {
728760
}
729761

730762
for _, r := range word {
731-
draw(r.r, r.combc, true, r.style, true, true)
763+
draw(r.r, 0, r.combc, false, r.style, true, true)
732764

733-
// Draw any extra characters either spaces for tabs or @ for incomplete wide runes
734-
if r.width > 1 {
735-
char := ' '
765+
// Draw any extra characters for tabs
766+
for i := 1; i < r.width; i++ {
736767
if r.r != '\t' {
737-
char = '@'
738-
}
739-
740-
for i := 1; i < r.width; i++ {
741-
draw(char, nil, false, r.style, true, false)
768+
draw(' ', i, nil, true, r.style, true, false)
769+
} else {
770+
draw('\t', i, nil, false, r.style, true, false)
742771
}
743772
}
744773
bloc.X++
@@ -792,7 +821,7 @@ func (w *BufWindow) displayBuffer() {
792821

793822
if vloc.X != maxWidth {
794823
// Display newline within a selection
795-
draw(' ', nil, false, config.DefStyle, true, true)
824+
draw(' ', 0, nil, true, config.DefStyle, true, true)
796825
}
797826

798827
bloc.X = w.StartCol

runtime/help/options.md

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -203,24 +203,21 @@ Here are the available options:
203203

204204
default value: `true`
205205

206-
* `indenttabchar`: sets the indentation character for tabs. This will not be
207-
inserted into files; it is only a visual indicator that whitespace is present.
208-
If set to a printing character, it functions as a subset of the
209-
"show invisibles" setting available in many other text editors. The color of
210-
this character is determined by the `indent-char` field in the current theme
211-
rather than the default text color.
206+
* `showchars`: sets what characters to be shown for various inivisible characters
207+
in the file. This is similar to `listchars` in vim and the characters shown
208+
will not be inserted into files. This option supersedes the `indentchar`
209+
option.
210+
The color of the shown character is determined by the `indent-char`
211+
field in the current theme rather than the default text color.
212+
This field is specified in the form of `option1=value1,option2=value2,...`.
213+
Here are the list of options:
214+
- `ispace`: indent space characters (space before first visible character)
215+
- `itab`: indent tab characters (tab before first visible character)
216+
- `space`: space characters (space after first visible character)
217+
- `tab`: tab characters (tab after first visible character)
218+
An example of this option could be `tab=>,space=.,itab=|>,ispace=|`
212219

213-
default value: ` ` (space)
214-
215-
* `indentspacechar`: same as `indenttabchar` except for spaces that are at
216-
locations that are divisible by `tabsize`.
217-
218-
default value: ` ` (space)
219-
220-
* `spacechar`: same as `indenttabchar` but for all spaces. `indentspacechar`
221-
takes precedence over this option.
222-
223-
default value: ` ` (space)
220+
default value: ``
224221

225222
* `infobar`: enables the line at the bottom of the editor where messages are
226223
printed. This option is `global only`.
@@ -599,6 +596,7 @@ so that you can see what the formatting should look like.
599596
"scrollbarchar": "|",
600597
"scrollmargin": 3,
601598
"scrollspeed": 2,
599+
"showchars": " ",
602600
"smartpaste": true,
603601
"softwrap": false,
604602
"splitbottom": true,

0 commit comments

Comments
 (0)