forked from Araq/nimedit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
overviews.nim
93 lines (84 loc) · 3.29 KB
/
overviews.nim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
## Currently only supports Nim.
import buffertype, buffer
import
parseutils, strutils, intsets,
compiler/ast, compiler/idents, compiler/parser,
compiler/llstream,
compiler/msgs,
compiler/astalgo, compiler/renderer, compiler/lookups
proc errorHandler(info: TLineInfo; msg: TMsgKind; arg: string) =
discard "ignore errors for the minimap generation"
proc allDeclarations(n: PNode; minimap: Buffer; useActiveLines: bool) =
proc addDecl(n: PNode; minimap: Buffer; useActiveLines: bool) =
if n.info.line >= 0:
if useActiveLines:
minimap.activeLines.incl n.info.line-1
var nn = n
if nn.kind == nkPragmaExpr: nn = nn[0]
if nn.kind == nkPostfix: nn = nn[1]
let ident = considerQuotedIdent(nn)
let s = newSym(skUnknown, ident, nil, n.info)
minimap.symtab.strTableAdd(s)
else:
let line = $n.info.line
minimap.insert(line & repeat(' ', 6 - line.len) &
renderTree(n, {renderNoBody, renderNoComments, renderDocComments,
renderNoPragmas}).replace("\L"))
minimap.insert("\L")
case n.kind
of nkProcDef, nkMethodDef, nkIteratorDef, nkConverterDef,
nkTemplateDef, nkMacroDef:
addDecl(n[namePos], minimap, useActiveLines)
of nkConstDef, nkTypeDef:
addDecl(n[0], minimap, useActiveLines)
of nkIdentDefs:
for i in 0..n.len-3:
addDecl(n[i], minimap, useActiveLines)
of nkStmtList, nkStmtListExpr, nkConstSection, nkLetSection,
nkVarSection, nkTypeSection, nkWhenStmt:
for i in 0..<n.len:
allDeclarations(n[i], minimap, useActiveLines)
else: discard
proc onEnter*(minimap: Buffer): int =
## returns the line it should be jumped to. -1 if nothing was selected.
result = -1
discard parseInt(minimap.getCurrentLine, result, 0)
proc filterMinimap*(b: Buffer) =
if b.minimapVersion != b.version:
b.minimapVersion = b.version
b.activeLines = initIntSet()
let ast = parser.parseString(b.fullText, b.filename, 0,
errorHandler)
allDeclarations(ast, b, true)
proc containsIgnoreStyle(a, b: string): bool =
# YYY optimize and make part of stdlib
a.normalize.contains(b.normalize)
proc gotoNextDeclaration*(b: Buffer; ident: string): int =
var it: TIdentIter
var s = initIdentIter(it, b.symtab, getIdent(ident))
if s == nil:
# there is no such declared identifier, so search for something similar:
var it: TTabIter
s = initTabIter(it, b.symtab)
while s != nil:
if s.name.s.containsIgnoreStyle(ident) and b.currentLine+1 != s.info.line:
return s.info.line
s = nextIter(it, b.symtab)
else:
while s != nil:
if b.currentLine+1 != s.info.line:
return s.info.line
s = nextIdentIter(it, b.symtab)
proc populateMinimap*(minimap, buffer: Buffer) =
# be smart and don't do unnecessary work:
if minimap.version != buffer.version or minimap.filename != buffer.filename:
minimap.version = buffer.version
minimap.filename = buffer.filename
minimap.lang = buffer.lang
# XXX make the buffer implement the streams interface
let ast = parser.parseString(buffer.fullText, buffer.filename, 0,
errorHandler)
minimap.clear()
allDeclarations(ast, minimap, false)
if minimap.numberOfLines >= 1:
minimap.gotoLine(1, -1)