mirror of
https://github.com/haven1433/HexManiacAdvance.git
synced 2026-09-14 11:58:02 -05:00
draft of auto-complete for script tool
This commit is contained in:
@@ -386,21 +386,65 @@ namespace HavenSoft.HexManiac.Core.Models.Code {
|
||||
return new LabelLibrary(model, labels);
|
||||
}
|
||||
|
||||
public string GetHelp(string currentLine) {
|
||||
public string GetHelp(IDataModel model, HelpContext context) {
|
||||
var currentLine = context.Line;
|
||||
if (string.IsNullOrWhiteSpace(currentLine)) return null;
|
||||
var tokens = ScriptLine.Tokenize(currentLine.Trim());
|
||||
var candidates = engine.Where(line => line.LineCommand.Contains(tokens[0])).ToList();
|
||||
|
||||
var isAfterToken = context.Index > 0 &&
|
||||
(context.Line.Length == context.Index || context.Line[context.Index] == ' ') &&
|
||||
char.IsLetterOrDigit(context.Line[context.Index - 1]);
|
||||
if (isAfterToken) {
|
||||
tokens = ScriptLine.Tokenize(currentLine.Substring(0, context.Index).Trim());
|
||||
// try to auto-complete whatever token is left of the cursor
|
||||
|
||||
// need autocomplete for command?
|
||||
if (tokens.Length == 1) {
|
||||
candidates.Where(line => line.LineCommand.StartsWith(tokens[0])).ToList();
|
||||
return Environment.NewLine.Join(candidates.Take(10).Select(line => line.Usage));
|
||||
}
|
||||
|
||||
// filter down to just perfect matches. There could be several (trainerbattle)
|
||||
candidates = candidates.Where(line => line.LineCommand == tokens[0]).ToList();
|
||||
var checkToken = 1;
|
||||
while (candidates.Count > 1 && checkToken < tokens.Length) {
|
||||
if (!tokens[checkToken].TryParseHex(out var codeValue)) break;
|
||||
candidates = candidates.Where(line => line.LineCode[checkToken] == codeValue).ToList();
|
||||
}
|
||||
var syntax = candidates.FirstOrDefault();
|
||||
if (syntax != null) {
|
||||
var args = syntax.Args.Where(arg => arg is ScriptArg).ToList();
|
||||
if (args.Count + 1 > tokens.Length) {
|
||||
var arg = args[tokens.Length - 2];
|
||||
if (!string.IsNullOrEmpty(arg.EnumTableName)) {
|
||||
var options = model.GetOptions(arg.EnumTableName).Where(option => option.MatchesPartial(tokens[tokens.Length - 1])).ToList();
|
||||
if (options.Count > 10) {
|
||||
while (options.Count > 9) options.RemoveAt(options.Count - 1);
|
||||
options.Add("...");
|
||||
}
|
||||
return Environment.NewLine.Join(options);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (candidates.Count > 10) return null;
|
||||
if (candidates.Count == 0) return null;
|
||||
if (candidates.Count == 1) {
|
||||
if (candidates[0].Args.Count == tokens.Length - 1) return null;
|
||||
if (candidates[0].CountShowArgs() == tokens.Length - 1) return null;
|
||||
return candidates[0].Usage + Environment.NewLine + string.Join(Environment.NewLine, candidates[0].Documentation);
|
||||
}
|
||||
var perfectMatch = candidates.FirstOrDefault(candidate => (currentLine + " ").StartsWith(candidate.LineCommand + " "));
|
||||
if (perfectMatch != null) {
|
||||
if (perfectMatch.Args.Count == tokens.Length - 1) return null;
|
||||
if (perfectMatch.CountShowArgs() == tokens.Length - 1) return null;
|
||||
return perfectMatch.Usage + Environment.NewLine + string.Join(Environment.NewLine, perfectMatch.Documentation);
|
||||
}
|
||||
var bestMatch = candidates.FirstOrDefault(candidate => tokens[0].Contains(candidate.LineCommand));
|
||||
if (bestMatch != null) {
|
||||
if (bestMatch.CountShowArgs() == tokens.Length - 1) return null;
|
||||
return bestMatch.Usage + Environment.NewLine + Environment.NewLine.Join(bestMatch.Documentation);
|
||||
}
|
||||
return string.Join(Environment.NewLine, candidates.Select(line => line.Usage));
|
||||
}
|
||||
|
||||
@@ -450,6 +494,14 @@ namespace HavenSoft.HexManiac.Core.Models.Code {
|
||||
string Compile(IDataModel model, int start, string scriptLine, LabelLibrary labels, out byte[] result);
|
||||
|
||||
void AddDocumentation(string content);
|
||||
|
||||
public int CountShowArgs() {
|
||||
return Args.Sum(arg => {
|
||||
if (arg is ScriptArg) return 1;
|
||||
return 0;
|
||||
// something with array args?
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public class MacroScriptLine : IScriptLine {
|
||||
|
||||
@@ -300,13 +300,13 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Tools {
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateScriptHelpFromLine(object sender, string line) {
|
||||
private void UpdateScriptHelpFromLine(object sender, HelpContext context) {
|
||||
var codeBody = (CodeBody)sender;
|
||||
string help = null;
|
||||
if (mode == CodeMode.Script) help = ScriptParser.GetHelp(line);
|
||||
else if (mode == CodeMode.BattleScript) BattleScriptParser.GetHelp(line);
|
||||
else if (mode == CodeMode.AnimationScript) AnimationScriptParser.GetHelp(line);
|
||||
else if (mode == CodeMode.TrainerAiScript) BattleAIScriptParser.GetHelp(line);
|
||||
string help;
|
||||
if (mode == CodeMode.Script) help = ScriptParser.GetHelp(model, context);
|
||||
else if (mode == CodeMode.BattleScript) help = BattleScriptParser.GetHelp(model, context);
|
||||
else if (mode == CodeMode.AnimationScript) help = AnimationScriptParser.GetHelp(model, context);
|
||||
else if (mode == CodeMode.TrainerAiScript) help = BattleAIScriptParser.GetHelp(model, context);
|
||||
else throw new NotImplementedException();
|
||||
codeBody.HelpContent = help;
|
||||
}
|
||||
@@ -505,7 +505,7 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Tools {
|
||||
public class CodeBody : ViewModelCore {
|
||||
public event EventHandler ContentChanged;
|
||||
|
||||
public event EventHandler<string> HelpSourceChanged;
|
||||
public event EventHandler<HelpContext> HelpSourceChanged;
|
||||
|
||||
private string label;
|
||||
public string Label {
|
||||
@@ -541,7 +541,7 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Tools {
|
||||
|
||||
// only show help if we're not within content curlies.
|
||||
if (contentBoundaryCount != 0) HelpContent = string.Empty;
|
||||
else HelpSourceChanged?.Invoke(this, lines[0]);
|
||||
else HelpSourceChanged?.Invoke(this, new(lines[0], caretPosition));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -568,4 +568,6 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Tools {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public record HelpContext(string Line, int Index);
|
||||
}
|
||||
|
||||
@@ -200,7 +200,7 @@ end
|
||||
|
||||
[Fact]
|
||||
public void LoadPointerCommand_StartsWithWhitespace_StillGetHelp() {
|
||||
Assert.NotEmpty(ViewPort.Tools.CodeTool.ScriptParser.GetHelp(" loadpointer"));
|
||||
Assert.NotEmpty(ViewPort.Tools.CodeTool.ScriptParser.GetHelp(Model, new(" loadpointer", 13)));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
Reference in New Issue
Block a user