Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New feature: Highlighting whitespace errors #1897

Merged
merged 8 commits into from
Mar 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ You can also check out the website for Micro at https://micro-editor.github.io.
- Small and simple.
- Easily configurable.
- Macros.
- Smart highlighting of trailing whitespace and tab vs space errors.
- Common editor features such as undo/redo, line numbers, Unicode support, soft wrapping, …

## Installation
Expand Down
8 changes: 8 additions & 0 deletions internal/action/bufpane.go
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,14 @@ func (h *BufPane) HandleEvent(event tcell.Event) {
InfoBar.ClearGutter()
}
}

cursors := h.Buf.GetCursors()
for _, c := range cursors {
if c.NewTrailingWsY != c.Y && (!c.HasSelection() ||
(c.NewTrailingWsY != c.CurSelection[0].Y && c.NewTrailingWsY != c.CurSelection[1].Y)) {
c.NewTrailingWsY = -1
}
}
}

// Bindings returns the current bindings tree for this buffer.
Expand Down
7 changes: 7 additions & 0 deletions internal/buffer/cursor.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ type Cursor struct {
// to know what the original selection was
OrigSelection [2]Loc

// The line number where a new trailing whitespace has been added
// or -1 if there is no new trailing whitespace at this cursor.
// This is used for checking if a trailing whitespace should be highlighted
NewTrailingWsY int

// Which cursor index is this (for multiple cursors)
Num int
}
Expand All @@ -38,6 +43,8 @@ func NewCursor(b *Buffer, l Loc) *Cursor {
c := &Cursor{
buf: b,
Loc: l,

NewTrailingWsY: -1,
}
c.StoreVisualX()
return c
Expand Down
61 changes: 61 additions & 0 deletions internal/buffer/eventhandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ func (eh *EventHandler) DoTextEvent(t *TextEvent, useUndo bool) {
c.Relocate()
c.LastVisualX = c.GetVisualX()
}

if useUndo {
eh.updateTrailingWs(t)
}
}

// ExecuteTextEvent runs a text event
Expand Down Expand Up @@ -290,6 +294,7 @@ func (eh *EventHandler) UndoOneEvent() {
if teCursor.Num >= 0 && teCursor.Num < len(eh.cursors) {
t.C = *eh.cursors[teCursor.Num]
eh.cursors[teCursor.Num].Goto(teCursor)
eh.cursors[teCursor.Num].NewTrailingWsY = teCursor.NewTrailingWsY
} else {
teCursor.Num = -1
}
Expand Down Expand Up @@ -333,6 +338,7 @@ func (eh *EventHandler) RedoOneEvent() {
if teCursor.Num >= 0 && teCursor.Num < len(eh.cursors) {
t.C = *eh.cursors[teCursor.Num]
eh.cursors[teCursor.Num].Goto(teCursor)
eh.cursors[teCursor.Num].NewTrailingWsY = teCursor.NewTrailingWsY
} else {
teCursor.Num = -1
}
Expand All @@ -342,3 +348,58 @@ func (eh *EventHandler) RedoOneEvent() {

eh.UndoStack.Push(t)
}

// updateTrailingWs updates the cursor's trailing whitespace status after a text event
func (eh *EventHandler) updateTrailingWs(t *TextEvent) {
if len(t.Deltas) != 1 {
return
}
text := t.Deltas[0].Text
start := t.Deltas[0].Start
end := t.Deltas[0].End

c := eh.cursors[eh.active]
isEol := func(loc Loc) bool {
return loc.X == util.CharacterCount(eh.buf.LineBytes(loc.Y))
}
if t.EventType == TextEventInsert && c.Loc == end && isEol(end) {
var addedTrailingWs bool
addedAfterWs := false
addedWsOnly := false
if start.Y == end.Y {
addedTrailingWs = util.HasTrailingWhitespace(text)
addedWsOnly = util.IsBytesWhitespace(text)
addedAfterWs = start.X > 0 && util.IsWhitespace(c.buf.RuneAt(Loc{start.X - 1, start.Y}))
} else {
lastnl := bytes.LastIndex(text, []byte{'\n'})
addedTrailingWs = util.HasTrailingWhitespace(text[lastnl+1:])
}

if addedTrailingWs && !(addedAfterWs && addedWsOnly) {
c.NewTrailingWsY = c.Y
} else if !addedTrailingWs {
c.NewTrailingWsY = -1
}
} else if t.EventType == TextEventRemove && c.Loc == start && isEol(start) {
removedAfterWs := util.HasTrailingWhitespace(eh.buf.LineBytes(start.Y))
var removedWsOnly bool
if start.Y == end.Y {
removedWsOnly = util.IsBytesWhitespace(text)
} else {
firstnl := bytes.Index(text, []byte{'\n'})
removedWsOnly = util.IsBytesWhitespace(text[:firstnl])
}

if removedAfterWs && !removedWsOnly {
c.NewTrailingWsY = c.Y
} else if !removedAfterWs {
c.NewTrailingWsY = -1
}
} else if c.NewTrailingWsY != -1 && start.Y != end.Y && c.Loc.GreaterThan(start) &&
((t.EventType == TextEventInsert && c.Y == c.NewTrailingWsY+(end.Y-start.Y)) ||
(t.EventType == TextEventRemove && c.Y == c.NewTrailingWsY-(end.Y-start.Y))) {
// The cursor still has its new trailingws
// but its line number was shifted by insert or remove of lines above
c.NewTrailingWsY = c.Y
}
}
2 changes: 2 additions & 0 deletions internal/config/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,8 @@ var defaultCommonSettings = map[string]interface{}{
"fileformat": defaultFileFormat(),
"filetype": "unknown",
"hlsearch": false,
"hltaberrors": false,
"hltrailingws": false,
"incsearch": true,
"ignorecase": true,
"indentchar": " ",
Expand Down
37 changes: 37 additions & 0 deletions internal/display/bufwindow.go
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,12 @@ func (w *BufWindow) displayBuffer() {
vloc.X = w.gutterOffset
}

bline := b.LineBytes(bloc.Y)
blineLen := util.CharacterCount(bline)

leadingwsEnd := len(util.GetLeadingWhitespace(bline))
trailingwsStart := blineLen - util.CharacterCount(util.GetTrailingWhitespace(bline))

line, nColsBeforeStart, bslice, startStyle := w.getStartInfo(w.StartCol, bloc.Y)
if startStyle != nil {
curStyle = *startStyle
Expand All @@ -518,6 +524,37 @@ func (w *BufWindow) displayBuffer() {
// over cursor-line and color-column
dontOverrideBackground := origBg != defBg

if b.Settings["hltaberrors"].(bool) {
if s, ok := config.Colorscheme["tab-error"]; ok {
isTab := (r == '\t') || (r == ' ' && !showcursor)
if (b.Settings["tabstospaces"].(bool) && isTab) ||
(!b.Settings["tabstospaces"].(bool) && bloc.X < leadingwsEnd && r == ' ' && !isTab) {
fg, _, _ := s.Decompose()
style = style.Background(fg)
dontOverrideBackground = true
}
}
}

if b.Settings["hltrailingws"].(bool) {
if s, ok := config.Colorscheme["trailingws"]; ok {
if bloc.X >= trailingwsStart && bloc.X < blineLen {
hl := true
for _, c := range cursors {
if c.NewTrailingWsY == bloc.Y {
hl = false
break
}
}
if hl {
fg, _, _ := s.Decompose()
style = style.Background(fg)
dontOverrideBackground = true
}
}
}
}

for _, c := range cursors {
if c.HasSelection() &&
(bloc.GreaterEqual(c.CurSelection[0]) && bloc.LessThan(c.CurSelection[1]) ||
Expand Down
23 changes: 23 additions & 0 deletions internal/util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"strings"
"time"
"unicode"
"unicode/utf8"

"github.com/blang/semver"
runewidth "github.com/mattn/go-runewidth"
Expand Down Expand Up @@ -363,6 +364,28 @@ func GetLeadingWhitespace(b []byte) []byte {
return ws
}

// GetTrailingWhitespace returns the trailing whitespace of the given byte array
func GetTrailingWhitespace(b []byte) []byte {
ws := []byte{}
for len(b) > 0 {
r, size := utf8.DecodeLastRune(b)
if IsWhitespace(r) {
ws = append([]byte(string(r)), ws...)
} else {
break
}

b = b[:len(b)-size]
}
return ws
}

// HasTrailingWhitespace returns true if the given byte array ends with a whitespace
func HasTrailingWhitespace(b []byte) bool {
r, _ := utf8.DecodeLastRune(b)
return IsWhitespace(r)
}

// IntOpt turns a float64 setting to an int
func IntOpt(opt interface{}) int {
return int(opt.(float64))
Expand Down
2 changes: 2 additions & 0 deletions runtime/colorschemes/atom-dark.micro
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,5 @@ color-link color-column "#2D2F31"
#color-link type.extended "default"
#Plain brackets
color-link match-brace "#1D1F21,#62B1FE"
color-link tab-error "#D75F5F"
color-link trailingws "#D75F5F"
2 changes: 2 additions & 0 deletions runtime/colorschemes/bubblegum.micro
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,5 @@ color-link color-column "254"
color-link type.extended "241,231"
color-link symbol.brackets "241,231"
color-link match-brace "231,28"
color-link tab-error "210"
color-link trailingws "210"
2 changes: 2 additions & 0 deletions runtime/colorschemes/cmc-16.micro
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,5 @@ color-link color-column "cyan"
color-link underlined.url "underline blue, white"
color-link divider "blue"
color-link match-brace "black,cyan"
color-link tab-error "brightred"
color-link trailingws "brightred"
2 changes: 2 additions & 0 deletions runtime/colorschemes/cmc-tc.micro
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,5 @@ color-link constant.bool "bold #55ffff"
color-link constant.bool.true "bold #85ff85"
color-link constant.bool.false "bold #ff8585"
color-link match-brace "#1e2124,#55ffff"
color-link tab-error "#d75f5f"
color-link trailingws "#d75f5f"
2 changes: 2 additions & 0 deletions runtime/colorschemes/darcula.micro
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,5 @@ color-link type.extended "default"
#color-link symbol.brackets "default"
color-link symbol.tag "#AE81FF,#242424"
color-link match-brace "#242424,#7A9EC2"
color-link tab-error "#D75F5F"
color-link trailingws "#D75F5F"
2 changes: 2 additions & 0 deletions runtime/colorschemes/default.micro
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,5 @@ color-link type.extended "default"
#color-link symbol.brackets "default"
color-link symbol.tag "#AE81FF,#282828"
color-link match-brace "#282828,#AE81FF"
color-link tab-error "#D75F5F"
color-link trailingws "#D75F5F"
3 changes: 3 additions & 0 deletions runtime/colorschemes/dracula-tc.micro
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,6 @@ color-link color-column "#44475A"
color-link type.extended "default"

color-link match-brace "#282A36,#FF79C6"

color-link tab-error "#D75F5F"
color-link trailingws "#D75F5F"
2 changes: 2 additions & 0 deletions runtime/colorschemes/dukedark-tc.micro
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,5 @@ color-link type.keyword "bold #5aaae6,#001e28"
color-link type.extended "#ffffff,#001e28"
color-link underlined "#608b4e,#001e28"
color-link match-brace "#001e28,#5aaae6"
color-link tab-error "#d75f5f"
color-link trailingws "#d75f5f"
2 changes: 2 additions & 0 deletions runtime/colorschemes/dukelight-tc.micro
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,5 @@ color-link type.keyword "bold #780050,#f0f0f0"
color-link type.extended "#000000,#f0f0f0"
color-link underlined "#3f7f5f,#f0f0f0"
color-link match-brace "#f0f0f0,#780050"
color-link tab-error "#ff8787"
color-link trailingws "#ff8787"
2 changes: 2 additions & 0 deletions runtime/colorschemes/dukeubuntu-tc.micro
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,5 @@ color-link type.keyword "bold #5aaae6,#2d0023"
color-link type.extended "#ffffff,#2d0023"
color-link underlined "#886484,#2d0023"
color-link match-brace "#2d0023,#5aaae6"
color-link tab-error "#d75f5f"
color-link trailingws "#d75f5f"
2 changes: 2 additions & 0 deletions runtime/colorschemes/geany.micro
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,5 @@ color-link diff-deleted "red"
color-link gutter-error ",red"
color-link gutter-warning "red"
color-link match-brace "black,cyan"
color-link tab-error "brightred"
color-link trailingws "brightred"
2 changes: 2 additions & 0 deletions runtime/colorschemes/gotham.micro
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,5 @@ color-link cursor-line "#091F2E"
color-link color-column "#11151C"
color-link symbol "#99D1CE,#0C1014"
color-link match-brace "#0C1014,#D26937"
color-link tab-error "#D75F5F"
color-link trailingws "#D75F5F"
2 changes: 2 additions & 0 deletions runtime/colorschemes/gruvbox-tc.micro
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,5 @@ color-link color-column "#79740e"
color-link statusline "#ebdbb2,#665c54"
color-link tabbar "#ebdbb2,#665c54"
color-link match-brace "#282828,#d3869b"
color-link tab-error "#d75f5f"
color-link trailingws "#d75f5f"
2 changes: 2 additions & 0 deletions runtime/colorschemes/gruvbox.micro
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,5 @@ color-link color-column "237"
color-link statusline "223,237"
color-link tabbar "223,237"
color-link match-brace "235,72"
color-link tab-error "167"
color-link trailingws "167"
2 changes: 2 additions & 0 deletions runtime/colorschemes/material-tc.micro
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,5 @@ color-link todo "bold #C792EA,#263238"
color-link type "#FFCB6B,#263238"
color-link underlined "underline #EEFFFF,#263238"
color-link match-brace "#263238,#C792EA"
color-link tab-error "#D75F5F"
color-link trailingws "#D75F5F"
2 changes: 2 additions & 0 deletions runtime/colorschemes/monokai-dark.micro
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,5 @@ color-link gutter-warning "#E6DB74"
color-link cursor-line "#323232"
color-link color-column "#323232"
color-link match-brace "#1D0000,#AE81FF"
color-link tab-error "#D75F5F"
color-link trailingws "#D75F5F"
2 changes: 2 additions & 0 deletions runtime/colorschemes/monokai.micro
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,5 @@ color-link type.extended "default"
#color-link symbol.brackets "default"
color-link symbol.tag "#AE81FF,#282828"
color-link match-brace "#282828,#AE81FF"
color-link tab-error "#D75F5F"
color-link trailingws "#D75F5F"
2 changes: 2 additions & 0 deletions runtime/colorschemes/one-dark.micro
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,5 @@ color-link type "#66D9EF"
color-link type.keyword "#C678DD"
color-link underlined "#8996A8"
color-link match-brace "#21252C,#C678DD"
color-link tab-error "#D75F5F"
color-link trailingws "#D75F5F"
2 changes: 2 additions & 0 deletions runtime/colorschemes/railscast.micro
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ color-link tabbar "bold #b1b1b1,#232323"
color-link cursor-line "#353535"
color-link color-column "#353535"
color-link space "underline #e6e1dc,#2b2b2b"
color-link tab-error "#d75f5f"
color-link trailingws "#d75f5f"

#the Python syntax definition are wrong. This is not how you should do decorators!
color-link brightgreen "#edb753,#2b2b2b"
Expand Down
2 changes: 2 additions & 0 deletions runtime/colorschemes/simple.micro
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,5 @@ color-link symbol.brackets "default"
#Color shebangs the comment color
color-link preproc.shebang "comment"
color-link match-brace ",magenta"
color-link tab-error "brightred"
color-link trailingws "brightred"
2 changes: 2 additions & 0 deletions runtime/colorschemes/solarized-tc.micro
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,5 @@ color-link color-column "#003541"
color-link type.extended "#839496,#002833"
color-link symbol.brackets "#839496,#002833"
color-link match-brace "#002833,#268BD2"
color-link tab-error "#D75F5F"
color-link trailingws "#D75F5F"
2 changes: 2 additions & 0 deletions runtime/colorschemes/solarized.micro
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,5 @@ color-link color-column "black"
color-link type.extended "default"
color-link symbol.brackets "default"
color-link match-brace ",blue"
color-link tab-error "brightred"
color-link trailingws "brightred"
2 changes: 2 additions & 0 deletions runtime/colorschemes/sunny-day.micro
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,5 @@ color-link cursor-line "229"
#color-link color-column "196"
color-link current-line-number "246"
color-line match-brace "230,22"
color-link tab-error "210"
color-link trailingws "210"
2 changes: 2 additions & 0 deletions runtime/colorschemes/twilight.micro
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,5 @@ color-link type "#F9EE98"
color-link type.keyword "#CDA869"
color-link underlined "#8996A8"
color-link match-brace "#141414,#E0C589"
color-link tab-error "#D75F5F"
color-link trailingws "#D75F5F"
2 changes: 2 additions & 0 deletions runtime/colorschemes/zenburn.micro
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,5 @@ color-link cursor-line "238"
color-link color-column "238"
color-link current-line-number "188,237"
color-link match-brace "237,223"
color-link tab-error "167"
color-link trailingws "167"
Loading
Loading