Skip to content

Commit 8748a8c

Browse files
committed
search locals in completion logic
1 parent 23e0ca1 commit 8748a8c

File tree

1 file changed

+39
-17
lines changed

1 file changed

+39
-17
lines changed

src/Lib/Starscript.Completions.cs

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
using Starscript.Internal;
2+
// ReSharper disable MemberCanBePrivate.Global
3+
// ReSharper disable UnusedMember.Global
24

35
namespace Starscript;
46

57
public partial class StarscriptHypervisor
6-
{
8+
{
79
/// <summary>
810
/// Calls the provided callback for every completion that can be resolved from global variables, and returns the parsed <paramref name="source"/>.
911
/// </summary>
1012
/// <param name="source">Starscript input.</param>
1113
/// <param name="position">The position of the caret.</param>
1214
/// <param name="callback">What to do with each completion suggestion.</param>
1315
/// <param name="cancellationToken">A cancellation token you can use to short-circuit return from completion logic on a best-effort basis.</param>
14-
public ParserResult ParseAndGetCompletions(string source, int position, CompletionCallback callback, CancellationToken cancellationToken = default)
16+
public ParserResult ParseAndGetCompletions(string source, int position, CompletionCallback callback,
17+
CancellationToken cancellationToken = default)
1518
{
1619
var parserResult = Parser.Parse(source);
1720

@@ -28,35 +31,46 @@ public ParserResult ParseAndGetCompletions(string source, int position, Completi
2831

2932
return parserResult;
3033
}
31-
34+
3235
/// <summary>
3336
/// Calls the provided callback for every completion that can be resolved from global variables.
3437
/// </summary>
3538
/// <param name="source">Starscript input.</param>
3639
/// <param name="position">The position of the caret.</param>
3740
/// <param name="callback">What to do with each completion suggestion.</param>
3841
/// <param name="cancellationToken">A cancellation token you can use to short-circuit return from completion logic on a best-effort basis.</param>
39-
public void GetCompletions(string source, int position, CompletionCallback callback, CancellationToken cancellationToken = default)
42+
public void GetCompletions(string source, int position, CompletionCallback callback,
43+
CancellationToken cancellationToken = default)
4044
=> _ = ParseAndGetCompletions(source, position, callback, cancellationToken);
4145

42-
private void CompletionsExpr(string source, int pos, Expr expr, CompletionCallback callback, CancellationToken cancellationToken)
46+
private void CompletionsExpr(string source, int pos, Expr expr, CompletionCallback callback,
47+
CancellationToken cancellationToken)
4348
{
44-
if (pos < expr.Start || (pos > expr.End && pos != source.Length))
49+
if (cancellationToken.IsCancellationRequested)
4550
return;
4651

47-
if (cancellationToken.IsCancellationRequested)
52+
if (pos < expr.Start || (pos > expr.End && pos != source.Length))
4853
return;
4954

5055
if (expr is Expr.Variable variableExpr)
5156
{
5257
var start = source[variableExpr.Start..pos];
5358

59+
if (Locals != null)
60+
{
61+
foreach (var (key, value) in Locals)
62+
{
63+
if (!key.StartsWith('_') && key.StartsWith(start))
64+
callback(key, value().IsFunction);
65+
}
66+
}
67+
5468
foreach (var (key, value) in Globals)
5569
{
5670
if (!key.StartsWith('_') && key.StartsWith(start))
5771
callback(key, value().IsFunction);
5872
}
59-
}
73+
}
6074
else if (expr is Expr.Get getExpr)
6175
{
6276
if (pos >= getExpr.End - getExpr.Name.Length)
@@ -66,23 +80,31 @@ private void CompletionsExpr(string source, int pos, Expr expr, CompletionCallba
6680
if (value is not null && value.IsMap)
6781
{
6882
var start = source[(getExpr.Object.End + 1)..pos];
69-
83+
7084
foreach (var (subKey, subValue) in value.GetMap())
7185
{
7286
if (!subKey.StartsWith('_') && subKey.StartsWith(start))
7387
callback(subKey, subValue().IsFunction);
7488
}
7589
}
76-
7790
}
7891
else
79-
foreach (var child in expr.Children)
92+
foreach (var child in expr.Children)
8093
CompletionsExpr(source, pos, child, callback, cancellationToken);
8194
}
8295
else if (expr is Expr.Block blockExpr)
8396
{
8497
if (blockExpr.Expr is null)
8598
{
99+
if (Locals != null)
100+
{
101+
foreach (var (key, value) in Locals)
102+
{
103+
if (!key.StartsWith('_'))
104+
callback(key, value().IsFunction);
105+
}
106+
}
107+
86108
foreach (var (key, value) in Globals)
87109
{
88110
if (!key.StartsWith('_'))
@@ -91,30 +113,30 @@ private void CompletionsExpr(string source, int pos, Expr expr, CompletionCallba
91113
}
92114
else
93115
{
94-
foreach (var child in expr.Children)
116+
foreach (var child in expr.Children)
95117
CompletionsExpr(source, pos, child, callback, cancellationToken);
96118
}
97119
}
98120
else
99121
{
100-
foreach (var child in expr.Children)
122+
foreach (var child in expr.Children)
101123
CompletionsExpr(source, pos, child, callback, cancellationToken);
102124
}
103125
}
104-
126+
105127
private Value? Resolve(Expr expr)
106128
{
107129
if (expr is Expr.Variable variableExpr)
108130
{
109131
return (Locals?.GetRaw(variableExpr.Name) ?? Globals.GetRaw(variableExpr.Name))?.Invoke();
110-
}
111-
132+
}
133+
112134
if (expr is Expr.Get getExpr)
113135
{
114136
var value = Resolve(getExpr.Object);
115137
if (value is null || !value.IsMap)
116138
return null;
117-
139+
118140
return value.GetMap().GetRaw(getExpr.Name)?.Invoke();
119141
}
120142

0 commit comments

Comments
 (0)