Skip to content

Commit 34412cd

Browse files
committed
Various improvements
1 parent 0b27192 commit 34412cd

File tree

12 files changed

+173
-67
lines changed

12 files changed

+173
-67
lines changed

v2/cmenu.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ func (e *Editor) CommandMenu(c *vt.Canvas, tty *vt.TTY, status *StatusBar, undo
395395
useMenuIndex = len(menuChoices) - 1 // The "No colors" menu choice is always last
396396
}
397397
changedTheme = true
398-
selectedItemIndex, _ := e.Menu(status, tty, "Select color theme", menuChoices, e.Background, e.MenuTitleColor, e.MenuArrowColor, e.MenuTextColor, e.MenuHighlightColor, e.MenuSelectedColor, useMenuIndex, extraDashes)
398+
selectedItemIndex, _ := e.Menu(status, tty, "Select color theme", menuChoices, e.MenuBackgroundColor, e.MenuTitleColor, e.MenuArrowColor, e.MenuTextColor, e.MenuHighlightColor, e.MenuSelectedColor, e.MenuSelectedBackgroundColor, useMenuIndex, extraDashes)
399399
// Extract the O_THEME value (or "nocolor") from the selected menu entry for string matching
400400
var selectedTheme string
401401
if selectedItemIndex >= 0 && selectedItemIndex < len(menuChoices) {
@@ -619,7 +619,7 @@ func (e *Editor) CommandMenu(c *vt.Canvas, tty *vt.TTY, status *StatusBar, undo
619619
// Launch a generic menu
620620
useMenuIndex := max(lastMenuIndex, 0)
621621

622-
selected, spacePressed := e.Menu(status, tty, menuTitle, menuChoices, e.Background, e.MenuTitleColor, e.MenuArrowColor, e.MenuTextColor, e.MenuHighlightColor, e.MenuSelectedColor, useMenuIndex, extraDashes)
622+
selected, spacePressed := e.Menu(status, tty, menuTitle, menuChoices, e.MenuBackgroundColor, e.MenuTitleColor, e.MenuArrowColor, e.MenuTextColor, e.MenuHighlightColor, e.MenuSelectedColor, e.MenuSelectedBackgroundColor, useMenuIndex, extraDashes)
623623
if spacePressed {
624624
return selected, spacePressed
625625
}

v2/highlight.go

Lines changed: 59 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -259,15 +259,67 @@ func Print(s *scanner.Scanner, w io.Writer, p Printer, m mode.Mode) error {
259259
}
260260
}
261261
inComment := false
262+
isCFamily := m == mode.C || m == mode.Cpp || m == mode.ObjC || m == mode.Arduino
263+
inPreproc := false // true after # in C-family, until the directive word
264+
inInclude := false // true after #include, expecting <...>
265+
inAngle := false // true inside <...> of an #include path
266+
if isCFamily {
267+
s.Mode &^= scanner.ScanChars
268+
}
262269
for tok := s.Scan(); tok != scanner.EOF; tok = s.Scan() {
263270
tokText := s.TokenText()
264-
if err := p.Print(w, tokenKind(tok, tokText, &inComment, m), tokText); err != nil {
271+
kind := tokenKind(tok, tokText, &inComment, m)
272+
if isCFamily {
273+
switch {
274+
case tok == '\n':
275+
inPreproc = false
276+
inInclude = false
277+
inAngle = false
278+
case tok == '#' && !inComment:
279+
inPreproc = true
280+
kind = Literal
281+
case inPreproc && tok == scanner.Ident:
282+
kind = Literal
283+
inPreproc = false
284+
if tokText == "include" {
285+
inInclude = true
286+
}
287+
case inInclude && unicode.IsSpace(tok):
288+
// skip whitespace after #include, but keep inInclude true
289+
case inInclude && tok == '<':
290+
inAngle = true
291+
kind = AngleBracket
292+
case inInclude:
293+
// Some other token after #include, reset inInclude
294+
inInclude = false
295+
case inAngle:
296+
if tok == '>' {
297+
inAngle = false
298+
inInclude = false
299+
}
300+
kind = AngleBracket
301+
}
302+
}
303+
if err := p.Print(w, kind, tokText); err != nil {
265304
return err
266305
}
267306
}
268307
return nil
269308
}
270309

310+
// AsText returns src highlighted for mode m, using the editor's theme.
311+
func (e *Editor) AsText(src []byte, m mode.Mode, options ...Option) ([]byte, error) {
312+
cfg := *e.Theme.TextConfig()
313+
for _, opt := range options {
314+
opt(&cfg)
315+
}
316+
var buf bytes.Buffer
317+
if err := Print(NewScanner(src), &buf, TextPrinter(cfg), m); err != nil {
318+
return nil, err
319+
}
320+
return buf.Bytes(), nil
321+
}
322+
271323
// AsText returns src highlighted for mode m, applying options to TextConfig.
272324
func AsText(src []byte, m mode.Mode, options ...Option) ([]byte, error) {
273325
cfg := DefaultTextConfig
@@ -488,7 +540,7 @@ func (e *Editor) WriteLines(c *vt.Canvas, fromline, toline LineIndex, cx, cy uin
488540
if e.syntaxHighlight && !envNoColor {
489541
// Output a syntax highlighted line. Escape any tags in the input line.
490542
// textWithTags must be unescaped if there is not an error.
491-
if textWithTags, err = AsText([]byte(escapeFunction(line)), e.mode); err != nil {
543+
if textWithTags, err = e.AsText([]byte(escapeFunction(line)), e.mode); err != nil {
492544
// Only output the line up to the width of the canvas
493545
screenLine = e.ChopLine(line, int(cw))
494546
// TODO: Check if just "fmt.Print" works here, for several terminal emulators
@@ -582,7 +634,7 @@ func (e *Editor) WriteLines(c *vt.Canvas, fromline, toline LineIndex, cx, cy uin
582634
// Inline Lua comment, e.g. "local x = 42 -- set x to 42"
583635
parts := strings.SplitN(line, "--", 2)
584636
// Highlight the code portion before the comment
585-
if newTextWithTags, err = AsText([]byte(escapeFunction(parts[0])), e.mode); err != nil {
637+
if newTextWithTags, err = e.AsText([]byte(escapeFunction(parts[0])), e.mode); err != nil {
586638
coloredString = unEscapeFunction(tout.DarkTags(string(textWithTags)))
587639
} else {
588640
// Append the comment portion highlighted as a comment
@@ -637,14 +689,14 @@ func (e *Editor) WriteLines(c *vt.Canvas, fromline, toline LineIndex, cx, cy uin
637689
coloredString = unEscapeFunction(e.MultiLineComment.Start(line))
638690
} else if doubleSemiCount == 1 {
639691
parts = strings.SplitN(line, ";;", 2)
640-
if newTextWithTags, err = AsText([]byte(escapeFunction(parts[0])), e.mode); err != nil {
692+
if newTextWithTags, err = e.AsText([]byte(escapeFunction(parts[0])), e.mode); err != nil {
641693
coloredString = unEscapeFunction(tout.DarkTags(string(textWithTags)))
642694
} else {
643695
coloredString = unEscapeFunction(tout.DarkTags(string(newTextWithTags)) + e.MultiLineComment.Get(";;"+parts[1]))
644696
}
645697
} else if strings.Count(trimmedLine, ";") == 1 {
646698
parts = strings.SplitN(line, ";", 2)
647-
if newTextWithTags, err = AsText([]byte(escapeFunction(parts[0])), e.mode); err != nil {
699+
if newTextWithTags, err = e.AsText([]byte(escapeFunction(parts[0])), e.mode); err != nil {
648700
coloredString = unEscapeFunction(tout.DarkTags(string(textWithTags)))
649701
} else {
650702
coloredString = unEscapeFunction(tout.DarkTags(string(newTextWithTags)) + e.MultiLineComment.Start(";"+parts[1]))
@@ -663,7 +715,7 @@ func (e *Editor) WriteLines(c *vt.Canvas, fromline, toline LineIndex, cx, cy uin
663715
coloredString = unEscapeFunction(e.MultiLineComment.Start(line))
664716
} else {
665717
parts = strings.SplitN(line, "\"", 2)
666-
if newTextWithTags, err = AsText([]byte(escapeFunction(parts[0])), e.mode); err != nil {
718+
if newTextWithTags, err = e.AsText([]byte(escapeFunction(parts[0])), e.mode); err != nil {
667719
coloredString = unEscapeFunction(tout.DarkTags(string(textWithTags)))
668720
} else {
669721
coloredString = unEscapeFunction(tout.DarkTags(string(newTextWithTags)) + e.MultiLineComment.Start("\""+parts[1]))
@@ -745,7 +797,7 @@ func (e *Editor) WriteLines(c *vt.Canvas, fromline, toline LineIndex, cx, cy uin
745797
parts = strings.SplitN(line, otherCommentMarker, 2)
746798
commentMarkerString = tout.DarkTags(parts[0] + "<" + e.Dollar + ">" + otherCommentMarker + "<off>")
747799
theRestString = tout.DarkTags(parts[1])
748-
if theRestWithTags, err = AsText([]byte(escapeFunction(parts[1])), e.mode); err == nil {
800+
if theRestWithTags, err = e.AsText([]byte(escapeFunction(parts[1])), e.mode); err == nil {
749801
theRestString = tout.DarkTags(string(theRestWithTags))
750802
}
751803
coloredString = unEscapeFunction(commentMarkerString + theRestString)

v2/lsp.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1680,7 +1680,7 @@ func (e *Editor) handleLSPCompletion(c *vt.Canvas, status *StatusBar, tty *vt.TT
16801680
stopSpinner()
16811681

16821682
currentWord := e.CurrentWord()
1683-
choice, _ := e.Menu(status, tty, "Completions", choices, e.Background, e.MenuTitleColor, e.MenuArrowColor, e.MenuTextColor, e.MenuHighlightColor, e.MenuSelectedColor, 0, false)
1683+
choice, _ := e.Menu(status, tty, "Completions", choices, e.MenuBackgroundColor, e.MenuTitleColor, e.MenuArrowColor, e.MenuTextColor, e.MenuHighlightColor, e.MenuSelectedColor, e.MenuSelectedBackgroundColor, 0, false)
16841684
if choice < 0 || choice >= len(items) {
16851685
return false
16861686
}

v2/menu.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ func ctrlkey2letter(key string) (string, bool) {
131131
// -1 is "no choice", 0 and up is which choice were selected.
132132
// initialMenuIndex is the choice that should be highlighted when displaying the choices.
133133
// returns -1, true if space was pressed
134-
func (e *Editor) Menu(status *StatusBar, tty *vt.TTY, title string, choices []string, bgColor, titleColor, arrowColor, textColor, highlightColor, selectedColor vt.AttributeColor, initialMenuIndex int, extraDashes bool) (int, bool) {
134+
func (e *Editor) Menu(status *StatusBar, tty *vt.TTY, title string, choices []string, bgColor, titleColor, arrowColor, textColor, highlightColor, selectedColor, highlightBgColor vt.AttributeColor, initialMenuIndex int, extraDashes bool) (int, bool) {
135135
notRegularEditingRightNow.Store(true)
136136
defer func() {
137137
notRegularEditingRightNow.Store(false)
@@ -144,7 +144,7 @@ func (e *Editor) Menu(status *StatusBar, tty *vt.TTY, title string, choices []st
144144
selectionLetterMap = selectionLettersForChoices(choices)
145145
selectedDelay = 100 * time.Millisecond
146146
c = vt.NewCanvas()
147-
menu = NewMenuWidget(title, choices, titleColor, arrowColor, textColor, highlightColor, selectedColor, c.W(), c.H(), extraDashes, selectionLetterMap)
147+
menu = NewMenuWidget(title, choices, titleColor, arrowColor, textColor, highlightColor, selectedColor, bgColor, highlightBgColor, c.W(), c.H(), extraDashes, selectionLetterMap)
148148
sigChan = make(chan os.Signal, 1)
149149
running = true
150150
changed = true

v2/menuwidget.go

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,14 @@ type MenuWidget struct {
2222
arrowColor vt.AttributeColor // arrow color (before each menu choice)
2323
textColor vt.AttributeColor // text color (the choices that are not highlighted)
2424
highlightColor vt.AttributeColor // highlight color (the choice that will be selected if return is pressed)
25+
highlightBgColor vt.AttributeColor // highlight background color
2526
selectedColor vt.AttributeColor // selected color (the choice that has been selected after return has been pressed)
27+
backgroundColor vt.AttributeColor // menu background color
2628
extraDashes bool // add "---" after each menu item?
2729
}
2830

2931
// NewMenuWidget creates a new MenuWidget
30-
func NewMenuWidget(title string, choices []string, titleColor, arrowColor, textColor, highlightColor, selectedColor vt.AttributeColor, canvasWidth, canvasHeight uint, extraDashes bool, selectionLetterMap map[string]*RuneAndPosition) *MenuWidget {
32+
func NewMenuWidget(title string, choices []string, titleColor, arrowColor, textColor, highlightColor, selectedColor, backgroundColor, highlightBgColor vt.AttributeColor, canvasWidth, canvasHeight uint, extraDashes bool, selectionLetterMap map[string]*RuneAndPosition) *MenuWidget {
3133
maxlen := uint(0)
3234
for _, choice := range choices {
3335
if ulen(choice) > uint(maxlen) {
@@ -59,7 +61,9 @@ func NewMenuWidget(title string, choices []string, titleColor, arrowColor, textC
5961
arrowColor: arrowColor,
6062
textColor: textColor,
6163
highlightColor: highlightColor,
64+
highlightBgColor: highlightBgColor,
6265
selectedColor: selectedColor,
66+
backgroundColor: backgroundColor,
6367
selectionLetterMap: selectionLetterMap,
6468
}
6569
}
@@ -74,7 +78,7 @@ func (m *MenuWidget) Draw(c *vt.Canvas) {
7478
// Draw the title
7579
titleHeight := 2
7680
for x, r := range m.title {
77-
c.PlotColor(uint(m.marginLeft+x), uint(m.marginTop), m.titleColor, r)
81+
c.WriteRune(uint(m.marginLeft+x), uint(m.marginTop), m.titleColor, m.backgroundColor, r)
7882
}
7983
// Draw the menu entries, with various colors
8084
ulenChoices := ulen(m.choices)
@@ -110,18 +114,18 @@ func (m *MenuWidget) Draw(c *vt.Canvas) {
110114
beforeRightBracket = false
111115
}
112116
if x < 2 {
113-
c.PlotColor(uint(m.marginLeft+int(x)), uint(m.marginTop+int(y)+titleHeight), m.arrowColor, r)
117+
c.WriteRune(uint(m.marginLeft+int(x)), uint(m.marginTop+int(y)+titleHeight), m.arrowColor, m.backgroundColor, r)
114118
} else if y < 10 && afterLeftBracket && beforeRightBracket {
115119
// color the 0-9 number differrently (in the title color)
116-
c.PlotColor(uint(m.marginLeft+int(x)), uint(m.marginTop+int(y)+titleHeight), m.titleColor, r)
120+
c.WriteRune(uint(m.marginLeft+int(x)), uint(m.marginTop+int(y)+titleHeight), m.titleColor, m.backgroundColor, r)
117121
} else if y == m.y {
118-
c.PlotColor(uint(m.marginLeft+int(x)), uint(m.marginTop+int(y)+titleHeight), m.highlightColor, r)
122+
c.WriteRune(uint(m.marginLeft+int(x)), uint(m.marginTop+int(y)+titleHeight), m.highlightColor, m.highlightBgColor, r)
119123
} else if !highlightedAccelerator && unicode.ToLower(r) == selectionLetter {
120124
// color the accelerator letter differently (in the arrow color)
121-
c.PlotColor(uint(m.marginLeft+int(x)), uint(m.marginTop+int(y)+titleHeight), m.arrowColor, r)
125+
c.WriteRune(uint(m.marginLeft+int(x)), uint(m.marginTop+int(y)+titleHeight), m.arrowColor, m.backgroundColor, r)
122126
highlightedAccelerator = true
123127
} else {
124-
c.PlotColor(uint(m.marginLeft+int(x)), uint(m.marginTop+int(y)+titleHeight), m.textColor, r)
128+
c.WriteRune(uint(m.marginLeft+int(x)), uint(m.marginTop+int(y)+titleHeight), m.textColor, m.backgroundColor, r)
125129
}
126130
if r == '[' {
127131
afterLeftBracket = true

v2/symbolmenu.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ func (e *Editor) SymbolMenu(tty *vt.TTY, status *StatusBar, title string, choice
1919

2020
var (
2121
c = vt.NewCanvas()
22-
symbolMenu = NewSymbolWidget(title, choices, titleColor, textColor, highlightColor, e.Background, int(c.W()), int(c.H()))
22+
symbolMenu = NewSymbolWidget(title, choices, titleColor, textColor, highlightColor, e.MenuBackgroundColor, e.MenuSelectedBackgroundColor, int(c.W()), int(c.H()))
2323
sigChan = make(chan os.Signal, 1)
2424
running = true
2525
changed = true

v2/symbolwidget.go

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,25 @@ import (
77

88
// SymbolWidget represents a TUI widget for presenting a menu with choices for the user
99
type SymbolWidget struct {
10-
title string // title
11-
choices [][]string // a slice of a slice of menu items
12-
bgColor vt.AttributeColor // background color
13-
highlightColor vt.AttributeColor // selected color (the choice that has been selected after return has been pressed)
14-
textColor vt.AttributeColor // text color (the choices that are not highlighted)
15-
titleColor vt.AttributeColor // title color (above the choices)
16-
x int // current position
17-
marginLeft int // margin, may be negative?
18-
marginTop int // margin, may be negative?
19-
oldy int // previous position
20-
y int // current position
21-
oldx int // previous position
22-
h int // height (number of menu items)
23-
cellWidth int // width of a cell
10+
title string // title
11+
choices [][]string // a slice of a slice of menu items
12+
bgColor vt.AttributeColor // background color
13+
highlightColor vt.AttributeColor // selected color (the choice that has been selected after return has been pressed)
14+
highlightBgColor vt.AttributeColor // selected background color
15+
textColor vt.AttributeColor // text color (the choices that are not highlighted)
16+
titleColor vt.AttributeColor // title color (above the choices)
17+
x int // current position
18+
marginLeft int // margin, may be negative?
19+
marginTop int // margin, may be negative?
20+
oldy int // previous position
21+
y int // current position
22+
oldx int // previous position
23+
h int // height (number of menu items)
24+
cellWidth int // width of a cell
2425
}
2526

2627
// NewSymbolWidget creates a new SymbolWidget
27-
func NewSymbolWidget(title string, choices [][]string, titleColor, textColor, highlightColor, bgColor vt.AttributeColor, canvasWidth, canvasHeight int) *SymbolWidget {
28+
func NewSymbolWidget(title string, choices [][]string, titleColor, textColor, highlightColor, bgColor, highlightBgColor vt.AttributeColor, canvasWidth, canvasHeight int) *SymbolWidget {
2829
maxCols := 0
2930
maxCellWidth := 1
3031
for _, choice := range choices {
@@ -49,20 +50,21 @@ func NewSymbolWidget(title string, choices [][]string, titleColor, textColor, hi
4950
marginTop = 0
5051
}
5152
return &SymbolWidget{
52-
title: title,
53-
h: len(choices),
54-
cellWidth: maxCellWidth,
55-
x: 0,
56-
oldx: 0,
57-
y: 0,
58-
oldy: 0,
59-
marginLeft: marginLeft,
60-
marginTop: marginTop,
61-
choices: choices,
62-
titleColor: titleColor,
63-
textColor: textColor,
64-
highlightColor: highlightColor,
65-
bgColor: bgColor,
53+
title: title,
54+
h: len(choices),
55+
cellWidth: maxCellWidth,
56+
x: 0,
57+
oldx: 0,
58+
y: 0,
59+
oldy: 0,
60+
marginLeft: marginLeft,
61+
marginTop: marginTop,
62+
choices: choices,
63+
titleColor: titleColor,
64+
textColor: textColor,
65+
highlightColor: highlightColor,
66+
highlightBgColor: highlightBgColor,
67+
bgColor: bgColor,
6668
}
6769
}
6870

@@ -86,7 +88,7 @@ func (sw *SymbolWidget) Draw(c *vt.Canvas) {
8688
symbol := sw.choices[y][x]
8789
// SetXY(0, uint(sw.marginTop+y+titleHeight))
8890
if y == int(sw.y) && x == int(sw.x) {
89-
c.Write(uint(sw.marginLeft+x*cellStep), uint(sw.marginTop+y+titleHeight), sw.highlightColor, sw.bgColor, symbol)
91+
c.Write(uint(sw.marginLeft+x*cellStep), uint(sw.marginTop+y+titleHeight), sw.highlightColor, sw.highlightBgColor, symbol)
9092
} else {
9193
c.Write(uint(sw.marginLeft+x*cellStep), uint(sw.marginTop+y+titleHeight), sw.textColor, sw.bgColor, symbol)
9294
}

0 commit comments

Comments
 (0)