Skip to content

Commit dd22b38

Browse files
committed
Improve syntax highlighting
1 parent 8a3b4cd commit dd22b38

11 files changed

+53
-40
lines changed

buffer.nim

+1-3
Original file line numberDiff line numberDiff line change
@@ -158,9 +158,7 @@ proc delete_tokens*(buffer: Buffer, start: int) =
158158
while buffer.tokens.len > 0 and
159159
buffer.tokens[buffer.tokens.len - 1].stop >= start:
160160
tok = buffer.tokens.pop()
161-
while not tok.can_stop and
162-
tok.state.requires_stop_token() and
163-
buffer.tokens.len > 0:
161+
while not tok.can_stop and buffer.tokens.len > 0:
164162
tok = buffer.tokens.pop()
165163
buffer.tokens_done = false
166164

editor.nim

+1-1
Original file line numberDiff line numberDiff line change
@@ -1488,7 +1488,7 @@ method render(editor: Editor, box: Box, ren: var TermRenderer) =
14881488

14891489
method close*(editor: Editor) =
14901490
editor.buffer.unregister_hook(editor.cursor_hook_id)
1491-
1491+
14921492
proc make_editor*(app: App, buffer: Buffer): Editor =
14931493
result = Editor(
14941494
buffer: buffer,

highlight/cpp.nim

+5-2
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ method next(state: State, text: seq[Rune]): Token =
7676
case chr:
7777
of '\n':
7878
let state = State(it: start + 1)
79-
return Token(kind: TokenUnknown, start: start, stop: start + 1, state: state)
79+
return Token(kind: TokenUnknown, start: start, stop: start + 1, state: state, can_stop: true)
8080
of '\"':
8181
let
8282
it = text.skip_string_like(start + 1, end_char='\"')
@@ -111,12 +111,15 @@ method next(state: State, text: seq[Rune]): Token =
111111
of ModeNone:
112112
let start = text.skip_whitespace(state.it)
113113
if start >= text.len:
114-
return Token(kind: TokenNone)
114+
return Token(kind: TokenNone)
115115
let chr = text[start]
116116
template skip_chr() =
117117
let state = State(it: start + 1)
118118
return Token(kind: TokenUnknown, start: start, stop: start + 1, state: state)
119119
case chr:
120+
of '\n':
121+
let state = State(it: start + 1)
122+
return Token(kind: TokenUnknown, start: start, stop: start + 1, state: state, can_stop: true)
120123
of '\"', '\'':
121124
let
122125
it = text.skip_string_like(start + 1, end_char=chr)

highlight/css.nim

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ method next(state: State, text: seq[Rune]): Token =
7171

7272
template char_token(new_state) =
7373
return Token(kind: TokenUnknown,
74-
start: start, stop: start + 1, state: new_state
74+
start: start, stop: start + 1, state: new_state, can_stop: true
7575
)
7676

7777
template skip_token() =

highlight/highlight.nim

+1-2
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,12 @@ type
4545
can_stop*: bool
4646

4747
method next*(state: HighlightState, text: seq[Rune]): Token {.base.} = quit "Abstract"
48-
method requires_stop_token*(state: HighlightState): bool {.base.} = false
4948

5049
proc is_inside*(token: Token, index: int): bool =
5150
index >= token.start and index < token.stop
5251

5352
proc is_whitespace*(rune: Rune): bool =
54-
rune == ' ' or rune == '\t' or rune == '\r' or rune == '\n'
53+
rune == ' ' or rune == '\t' or rune == '\r'
5554

5655
proc skip_whitespace*(text: seq[Rune], pos: int): int =
5756
result = pos

highlight/html.nim

+3
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ method next*(state: State, text: seq[Rune]): Token =
3434
return Token(kind: TokenNone)
3535
let chr = text[start]
3636
case chr:
37+
of '\n':
38+
let state = State(it: start + 1, is_tag: state.is_tag, is_close: state.is_close)
39+
return Token(kind: TokenUnknown, start: start, stop: start + 1, state: state, can_stop: true)
3740
of '\"':
3841
let
3942
it = text.skip_string_like(start + 1)

highlight/json.nim

+2-2
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,9 @@ method next(state: State, text: seq[Rune]): Token =
4545
stop = text.skip_string_like(start + 1, end_char = chr)
4646
state = State(it: stop + 1)
4747
return Token(kind: TokenString, start: start, stop: stop + 1, state: state)
48-
of ':', ',', '[', ']', '{', '}':
48+
of ':', ',', '[', ']', '{', '}', '\n':
4949
let state = State(it: start + 1)
50-
return Token(kind: TokenUnknown, start: start, stop: start + 1, state: state)
50+
return Token(kind: TokenUnknown, start: start, stop: start + 1, state: state, can_stop: true)
5151
else:
5252
var
5353
name: seq[Rune] = @[]

highlight/lisp.nim

+5-2
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,18 @@ proc token_kind(name: seq[Rune], is_call: bool, is_quote: bool): TokenKind =
5757
method next*(state: State, text: seq[Rune]): Token =
5858
var start = text.skip_whitespace(state.it)
5959
if start >= text.len:
60-
return Token(kind: TokenNone)
60+
return Token(kind: TokenNone)
6161
let chr = text[start]
6262
case chr:
63+
of '\n':
64+
let new_state = State(it: start + 1, depth: state.depth, quote_depths: state.quote_depths)
65+
return Token(kind: TokenUnknown, start: start, stop: start + 1, state: new_state, can_stop: true)
6366
of ';':
6467
var it = start + 1
6568
while it < text.len and text[it] != '\n':
6669
it += 1
6770
let new_state = State(it: it + 1, depth: state.depth, quote_depths: state.quote_depths)
68-
return Token(kind: TokenComment, start: start, stop: it + 1, state: new_state)
71+
return Token(kind: TokenComment, start: start, stop: it + 1, state: new_state, can_stop: true)
6972
of '\"':
7073
let
7174
it = text.skip_string_like(start + 1)

highlight/lua.nim

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ method next*(state: State, text: seq[Rune]): Token =
7474
name.add(chr)
7575
it += 1
7676
if name.len == 0:
77-
return Token(kind: TokenUnknown, start: start, stop: it + 1, state: State(it: it + 1))
77+
return Token(kind: TokenUnknown, start: start, stop: it + 1, state: State(it: it + 1), can_stop: true)
7878
return Token(kind: name.token_kind, start: start, stop: it, state: State(it: it + 1))
7979

8080
proc new_lua_highlighter*(): HighlightState = State()

highlight/markdown.nim

+1-3
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,8 @@ proc token_kind(state: State): TokenKind =
3838
return TokenItalic
3939
return TokenUnknown
4040

41-
method requires_stop_token(state: State): bool = true
42-
4341
method next(state: State, text: seq[Rune]): Token =
44-
let start = text.skip(state.it, {' ', '\r', '\t'})
42+
let start = text.skip_whitespace(state.it)
4543
if start >= text.len:
4644
return Token(kind: TokenNone)
4745
let chr = text[start]

highlight/nim.nim

+32-23
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import highlight, ../utils
2626
type
2727
State = ref object of HighlightState
2828
it: int
29-
is_float: bool
3029

3130
const
3231
NIM_KEYWORDS = [
@@ -53,7 +52,8 @@ const
5352
"bool", "char", "auto", "pointer",
5453
"cint", "cshort", "cstring", "clong",
5554
"cuint", "culong", "cushort",
56-
"openArray", "Table", "Deque", "HashSet", "range"
55+
"openArray", "Table", "Deque", "HashSet", "range",
56+
"untyped", "typed", "varargs"
5757
]
5858

5959

@@ -64,7 +64,9 @@ proc token_kind(str: seq[Rune]): TokenKind =
6464
return TokenKeyword
6565
elif $str in NIM_TYPES:
6666
return TokenType
67-
elif str.is_int(allow_underscore=true) or str.is_float(allow_underscore=true):
67+
elif str.is_int(allow_underscore=true) or
68+
str.is_float(allow_underscore=true) or
69+
('\'' in str and str.split('\'')[0].is_float(true)):
6870
return TokenLiteral
6971

7072
return TokenName
@@ -80,11 +82,16 @@ method next*(state: State, text: seq[Rune]): Token =
8082
it = text.skip_string_like(start + 1)
8183
state = State(it: it + 1)
8284
return Token(kind: TokenString, start: start, stop: it + 1, state: state)
83-
of '\'':
85+
of '\'':
8486
let
8587
it = text.skip_string_like(start + 1, end_char='\'')
8688
state = State(it: it + 1)
8789
return Token(kind: TokenChar, start: start, stop: it + 1, state: state)
90+
of '`':
91+
let
92+
it = text.skip_string_like(start + 1, end_char='`')
93+
state = State(it: it + 1)
94+
return Token(kind: TokenName, start: start, stop: it + 1, state: state)
8895
of '#':
8996
if start + 1 < text.len and text[start + 1] == '[':
9097
var
@@ -106,37 +113,39 @@ method next*(state: State, text: seq[Rune]): Token =
106113
it += 1
107114
let state = State(it: it + 1)
108115
return Token(kind: TokenComment, start: start, stop: it, state: state)
109-
of ':', '<', '>', '[', ']', '(', ')', '{', '}', ',', ';', '=', '`':
116+
of ':', '.', '[', ']', '(', ')', '{', '}', ',', ';':
110117
let state = State(it: start + 1)
111118
return Token(kind: TokenUnknown, start: start, stop: start + 1, state: state)
112-
of '.':
113-
var
114-
kind = TokenUnknown
115-
offset = 1
116-
if state.is_float and
117-
start + 1 < text.len and
118-
is_digit(text[start + 1]):
119-
kind = TokenLiteral
120-
offset = 2
119+
of '\n':
121120
let state = State(it: start + 1)
122-
return Token(kind: kind, start: start, stop: start + offset, state: state)
121+
return Token(kind: TokenUnknown, start: start, stop: start + 1, state: state, can_stop: true)
123122
else:
123+
type NameKind = enum NameNone, NameOperator, NameText
124+
124125
var
125126
name: seq[Rune] = @[]
127+
kind = NameNone
126128
it = start
127129
while it < text.len:
128130
let chr = text[it]
129131
case chr:
130-
of ' ', '\t', '\n', '\r', ':', '<', '>',
132+
of ' ', '\t', '\n', '\r', ':',
131133
'[', ']', '(', ')', '{', '}', ',', ';',
132-
'=', '`', '\"', '#', '\'', '.':
133-
break
134+
'`', '\"', '#', '\'', '.':
135+
if not (name.is_float(true) and chr == '\''):
136+
break
137+
of '+', '-', '*', '/', '=', '<', '>', '!', '$', '%', '&', '|', '?':
138+
if kind == NameText:
139+
break
140+
kind = NameOperator
134141
else:
135-
name.add(chr)
142+
if kind == NameOperator and
143+
not (name.is_int(true) and chr == '.'):
144+
break
145+
kind = NameText
146+
name.add(chr)
136147
it += 1
137-
let
138-
kind = name.token_kind()
139-
state = State(it: it, is_float: name.is_float(allow_underscore=true))
140-
return Token(kind: kind, start: start, stop: it, state: state)
148+
let state = State(it: it)
149+
return Token(kind: name.token_kind(), start: start, stop: it, state: state)
141150

142151
proc new_nim_highlighter*(): HighlightState = State()

0 commit comments

Comments
 (0)