diff options
author | alaviss <alaviss@users.noreply.github.com> | 2019-02-07 23:08:15 +0700 |
---|---|---|
committer | Miran <narimiran@disroot.org> | 2019-02-07 17:08:15 +0100 |
commit | 2fdf816332d48f55719c5709477756e872daab0d (patch) | |
tree | e5ec3c53d529f72d807e79fde98bd55a7fe2a03c /compiler/suggest.nim | |
parent | 29fbf111a878db0ff095f8046a4de9e0f851d466 (diff) | |
download | Nim-2fdf816332d48f55719c5709477756e872daab0d.tar.gz |
compiler/[msgs, suggest]: improve highlighter accuracy (#10496)
Previously the compiler would generate suggestions based on the symbol identifier length, but that might not reflect the actual representation of it within the actual source code. This commit implements a simple source scanner for the suggest module to address the problem outlined above. Fixes nim-lang/nimsuggest#24
Diffstat (limited to 'compiler/suggest.nim')
-rw-r--r-- | compiler/suggest.nim | 39 |
1 files changed, 37 insertions, 2 deletions
diff --git a/compiler/suggest.nim b/compiler/suggest.nim index 09eacbbed..70a085bdf 100644 --- a/compiler/suggest.nim +++ b/compiler/suggest.nim @@ -32,7 +32,7 @@ # included from sigmatch.nim -import algorithm, prefixmatches, lineinfos, pathutils +import algorithm, prefixmatches, lineinfos, pathutils, parseutils from wordrecg import wDeprecated, wError, wAddr, wYield, specialWords when defined(nimsuggest): @@ -81,6 +81,38 @@ proc cmpSuggestions(a, b: Suggest): int = # independent of hashing order: result = cmp(a.name[], b.name[]) +proc getTokenLenFromSource(conf: ConfigRef; ident: string; info: TLineInfo): int = + let + line = sourceLine(conf, info) + column = toColumn(info) + + proc isOpeningBacktick(col: int): bool = + if col >= 0 and col < line.len: + if line[col] == '`': + not isOpeningBacktick(col - 1) + else: + isOpeningBacktick(col - 1) + else: + false + + if column > line.len: + result = 0 + elif column > 0 and line[column - 1] == '`' and isOpeningBacktick(column - 1): + result = skipUntil(line, '`', column) + if cmpIgnoreStyle(line[column..column + result - 1], ident) != 0: + result = 0 + elif ident[0] in linter.Letters and ident[^1] != '=': + result = identLen(line, column) + if cmpIgnoreStyle(line[column..column + result - 1], ident) != 0: + result = 0 + else: + result = skipWhile(line, OpChars + {'[', '(', '{', ']', ')', '}'}, column) + if ident[^1] == '=' and ident[0] in linter.Letters: + if line[column..column + result - 1] != "=": + result = 0 + elif line[column..column + result - 1] != ident: + result = 0 + proc symToSuggest(conf: ConfigRef; s: PSym, isLocal: bool, section: IdeCmd, info: TLineInfo; quality: range[0..100]; prefix: PrefixMatch; inTypeContext: bool; scope: int): Suggest = @@ -88,7 +120,6 @@ proc symToSuggest(conf: ConfigRef; s: PSym, isLocal: bool, section: IdeCmd, info result.section = section result.quality = quality result.isGlobal = sfGlobal in s.flags - result.tokenLen = s.name.s.len result.prefix = prefix result.contextFits = inTypeContext == (s.kind in {skType, skGenericParam}) result.scope = scope @@ -126,6 +157,10 @@ proc symToSuggest(conf: ConfigRef; s: PSym, isLocal: bool, section: IdeCmd, info result.line = toLinenumber(infox) result.column = toColumn(infox) result.version = conf.suggestVersion + result.tokenLen = if section != ideHighlight: + s.name.s.len + else: + getTokenLenFromSource(conf, s.name.s, infox) proc `$`*(suggest: Suggest): string = result = $suggest.section |