public override bool Handle(AutoCompleteEventArgs e, AutoCompleteSettings settings, out CodeString result) { result = null; if (!settings.SelfClosingPairs.IsEnabled || !_scpInputLookup.TryGetValue(e.Character, out var pair) && e.Character != '\b') { // not an interesting keypress. return(false); } var original = CodePaneHandler.GetCurrentLogicalLine(e.Module); if (original == null || original.Lines.Length == MaximumLines) { // selection spans more than a single logical line, or // logical line somehow spans more than the maximum number of physical lines in a logical line of code (25). return(false); } if (!original.CaretPosition.IsSingleCharacter) { // here would be an opportunity to "wrap selection" with a SCP. // todo: WrapSelectionWith(pair)? result = null; return(false); } if (pair != null) { // found a SCP for the input key; see if we should handle it: if (!HandleInternal(e, original, pair, out result)) { return(false); } } else if (e.Character == '\b') { // backspace - see if SCP logic needs to intervene: foreach (var scp in _selfClosingPairs) { if (HandleInternal(e, original, scp, out result)) { break; } } } if (result == null) { // no meaningful output; let the input be handled by another handler, maybe. return(false); } // 1-based selection span in the code pane starts at column 1 but really encompasses the entire line. var snippetPosition = new Selection(result.SnippetPosition.StartLine, 1, result.SnippetPosition.EndLine, 1); result = new CodeString(result.Code, result.CaretPosition, snippetPosition); _scpService.ShowQuickInfo(); e.Handled = true; return(true); }
public override bool Execute(AutoCompleteEventArgs e, AutoCompleteSettings settings) { var result = base.Execute(e, settings); var module = e.CodeModule; using (var pane = module.CodePane) { var original = module.GetLines(e.CurrentSelection); var hasAsToken = Regex.IsMatch(original, $@"{Tokens.Property} {Tokens.Get}\s+\(.*\)\s+{Tokens.As}\s?", RegexOptions.IgnoreCase); var hasAsType = Regex.IsMatch(original, $@"{Tokens.Property} {Tokens.Get}\s+\w+\(.*\)\s+{Tokens.As}\s+(?<Identifier>\w+)", RegexOptions.IgnoreCase); var asTypeClause = hasAsToken && hasAsType ? string.Empty : hasAsToken ? $" {Tokens.Variant}" : $" {Tokens.As} {Tokens.Variant}"; if (result && Regex.IsMatch(original, $"{Tokens.Property} {Tokens.Get}")) { var code = original + asTypeClause; module.ReplaceLine(e.CurrentSelection.StartLine, code); var newCode = module.GetLines(e.CurrentSelection); if (code == newCode) { pane.Selection = new Selection(e.CurrentSelection.StartLine, code.Length - Tokens.Variant.Length + 1, e.CurrentSelection.StartLine, code.Length + 1); } } } return(result); }
public static AutoCompleteSettingsElastic ToAutoCompleteSettingsElastic(this AutoCompleteSettings autoComplete, AutoCompleteSettingsElastic original = null) { var model = new AutoCompleteSettingsElastic { Confidence = autoComplete.Confidence.HasValue ? autoComplete.Confidence.Value : (double)original?.Confidence, Count = autoComplete.Count.HasValue ? autoComplete.Count.Value : (int)original?.Count, MaximumErrors = autoComplete.MaximumErrors.HasValue ? autoComplete.MaximumErrors.Value : (double)original?.MaximumErrors, }; return(model); }
public static AutoCompleteSettings ToAutoCompleteSettingsModel(this AutoCompleteSettingsElastic autoComplete) { var model = new AutoCompleteSettings { Confidence = autoComplete.Confidence, Count = autoComplete.Count, MaximumErrors = autoComplete.MaximumErrors, }; return(model); }
public virtual bool Execute(AutoCompleteEventArgs e, AutoCompleteSettings settings) { var input = e.Character.ToString(); if (!IsMatch(input)) { return(false); } var module = e.CodeModule; using (var pane = module.CodePane) { var pSelection = pane.Selection; var zSelection = pSelection.ToZeroBased(); var original = module.GetLines(pSelection); var nextChar = zSelection.StartColumn == original.Length ? string.Empty : original.Substring(zSelection.StartColumn, 1); if (input == InputToken && (input != OutputToken || nextChar != OutputToken)) { string code; if (!StripExplicitCallStatement(ref original, ref pSelection)) { code = original.Insert(Math.Max(0, zSelection.StartColumn), InputToken + OutputToken); } else { code = original; } module.ReplaceLine(pSelection.StartLine, code); var newCode = module.GetLines(pSelection); if (newCode.Equals(code, StringComparison.OrdinalIgnoreCase)) { pane.Selection = new Selection(pSelection.StartLine, pSelection.StartColumn + 1); } else { // VBE added a space; need to compensate: pane.Selection = new Selection(pSelection.StartLine, GetPrettifiedCaretPosition(pSelection, code, newCode)); } e.Handled = true; return(true); } else if (input == OutputToken && nextChar == OutputToken) { // just move caret one character to the right & suppress the keypress pane.Selection = new Selection(pSelection.StartLine, GetPrettifiedCaretPosition(pSelection, original, original) + 1); e.Handled = true; return(true); } return(false); } }
public override bool Handle(AutoCompleteEventArgs e, AutoCompleteSettings settings, out CodeString result) { result = null; if (e.Character != '\r' || (!settings?.SmartConcat.IsEnabled ?? true)) { return(false); } var currentContent = CodePaneHandler.GetCurrentLogicalLine(e.Module); if ((!currentContent?.IsInsideStringLiteral ?? true) || currentContent.Lines.Length >= settings.SmartConcat.ConcatMaxLines) { // selection spans more than a single logical line, or spans too many lines to be legal; // too many line continuations throws COMException if we attempt to modify. return(false); } var lastIndexLeftOfCaret = currentContent.CaretLine.Length > 2 ? currentContent.CaretLine.Substring(0, currentContent.CaretPosition.StartColumn).LastIndexOf('"') : 0; if (lastIndexLeftOfCaret > 0) { var indent = currentContent.CaretLine.NthIndexOf('"', 1); var whitespace = new string(' ', indent); // todo: handle shift modifier? var concatVbNewLine = settings.SmartConcat.ConcatVbNewLineModifier.HasFlag(ModifierKeySetting.CtrlKey) && e.IsControlKeyDown; var autoCode = $"\" {(concatVbNewLine ? "& vbNewLine " : string.Empty)}& _\r\n{whitespace}\""; var left = currentContent.CaretLine.Substring(0, currentContent.CaretPosition.StartColumn); var right = currentContent.CaretLine.Substring(currentContent.CaretPosition.StartColumn); var caretLine = $"{left}{autoCode}{right}"; var lines = currentContent.Lines; lines[currentContent.CaretPosition.StartLine] = caretLine; var code = string.Join("\r\n", lines); var newContent = new CodeString(code, currentContent.CaretPosition, currentContent.SnippetPosition); var newPosition = new Selection(newContent.CaretPosition.StartLine + 1, indent + 1); e.Handled = true; result = new CodeString(newContent.Code, newPosition, new Selection(newContent.SnippetPosition.StartLine, 1, newContent.SnippetPosition.EndLine, 1)); CodePaneHandler.SubstituteCode(e.Module, result); var finalSelection = new Selection(result.SnippetPosition.StartLine, 1).Offset(result.CaretPosition); CodePaneHandler.SetSelection(e.Module, finalSelection); return(true); } return(false); }
public void ApplyAutoCompleteSettings(Configuration config) { _settings = config.UserSettings.AutoCompleteSettings; if (_settings.IsEnabled) { Enable(); } else { Disable(); } _initialized = true; }
public override bool Execute(AutoCompleteEventArgs e, AutoCompleteSettings settings) { var ignoreTab = e.Character == '\t' && !settings.CompleteBlockOnTab; var ignoreEnter = e.Character == '\r' && !settings.CompleteBlockOnEnter; if (IsInlineCharCompletion || e.IsDelete || ignoreTab || ignoreEnter) { return(false); } var module = e.CodeModule; using (var pane = module.CodePane) { var selection = pane.Selection; var originalCode = module.GetLines(selection); var code = originalCode.Trim().StripStringLiterals(); var hasComment = code.HasComment(out int commentStart); var isDeclareStatement = Regex.IsMatch(code, $"\\b{Tokens.Declare}\\b", RegexOptions.IgnoreCase); var isExitStatement = Regex.IsMatch(code, $"\\b{Tokens.Exit}\\b", RegexOptions.IgnoreCase); var isNamedArg = Regex.IsMatch(code, $"\\b{InputToken}\\:\\=", RegexOptions.IgnoreCase); if ((SkipPreCompilerDirective && code.StartsWith("#")) || isDeclareStatement || isExitStatement || isNamedArg) { return(false); } if (IsMatch(code) && !IsBlockCompleted(module, selection)) { var indent = originalCode.TakeWhile(c => char.IsWhiteSpace(c)).Count(); var newCode = OutputToken.PadLeft(OutputToken.Length + indent, ' '); var stdIndent = IndentBody ? IndenterSettings.Create().IndentSpaces : 0; module.InsertLines(selection.NextLine.StartLine, "\n" + newCode); module.ReplaceLine(selection.NextLine.StartLine, new string(' ', indent + stdIndent)); pane.Selection = new Selection(selection.NextLine.StartLine, indent + stdIndent + 1); e.Handled = true; return(true); } return(false); } }
public override bool Handle(AutoCompleteEventArgs e, AutoCompleteSettings settings, out CodeString result) { result = null; if (!_scpInputLookup.TryGetValue(e.Character, out var pair) && e.Character != '\b') { return(false); } var original = CodePaneHandler.GetCurrentLogicalLine(e.Module); if (original == null || original.Lines.Length == MaximumLines) { // selection spans more than a single logical line, or // logical line somehow spans more than the maximum number of physical lines in a logical line of code (25). return(false); } if (pair != null) { if (!HandleInternal(e, original, pair, out result)) { return(false); } } else if (e.Character == '\b') { foreach (var scp in _selfClosingPairs) { if (HandleInternal(e, original, scp, out result)) { break; } } } if (result == null) { return(false); } var snippetPosition = new Selection(result.SnippetPosition.StartLine, 1, result.SnippetPosition.EndLine, 1); result = new CodeString(result.Code, result.CaretPosition, snippetPosition); e.Handled = true; return(true); }
private SearchSettingsWrapperElastic MergeSettings( SearchSettingsWrapperElastic defaultSettings, AutoCompleteSettings autoCompleteSettings, ClassifierSettings classifierSettings, SearchSettings searchSettings) { var result = new SearchSettingsWrapperElastic(defaultSettings); if (autoCompleteSettings != null) { result.AutoCompleteSettings = defaultSettings.AutoCompleteSettings != null?autoCompleteSettings.ToAutoCompleteSettingsElastic(defaultSettings.AutoCompleteSettings) : null; } if (classifierSettings != null) { result.ClassifierSettings = defaultSettings.ClassifierSettings != null?classifierSettings.ToClassifierSearchSettingsElastic(defaultSettings.ClassifierSettings) : null; } if (searchSettings != null) { result.SearchSettings = defaultSettings.SearchSettings != null?searchSettings.ToSearchSettingsElastic(defaultSettings.SearchSettings, true) : null; } return(result); }
private static SmartConcatenationHandler InitializeSut(TestCodeString original, TestCodeString prettified, out Mock <ICodeModule> module, out Mock <ICodePane> pane, out AutoCompleteSettings settings) { var builder = new MockVbeBuilder(); var project = builder.ProjectBuilder("TestProject1", ProjectProtection.Unprotected) .AddComponent("Module1", ComponentType.StandardModule, ""); var vbe = builder.AddProject(project.Build()).Build(); module = new Mock <ICodeModule>(); pane = new Mock <ICodePane>(); pane.SetupProperty(m => m.Selection); var paneSelection = new Selection(original.SnippetPosition.StartLine + original.CaretPosition.StartLine, original.CaretPosition.StartColumn + 1); pane.Object.Selection = paneSelection; module.Setup(m => m.DeleteLines(original.SnippetPosition.StartLine, original.SnippetPosition.LineCount)); module.Setup(m => m.InsertLines(original.SnippetPosition.StartLine, original.Code)); module.Setup(m => m.CodePane).Returns(pane.Object); for (var i = 0; i < original.SnippetPosition.LineCount; i++) { var index = i; module.Setup(m => m.GetLines(index + 1, 1)).Returns(original.Lines[index]); } module.Setup(m => m.GetLines(original.SnippetPosition)).Returns(prettified.Code); module.Setup(m => m.GetLines(paneSelection.StartLine, paneSelection.LineCount)).Returns(prettified.CaretLine); settings = new AutoCompleteSettings { IsEnabled = true }; settings.SmartConcat.IsEnabled = true; settings.SmartConcat.ConcatVbNewLineModifier = ModifierKeySetting.CtrlKey; settings.SmartConcat.ConcatMaxLines = AutoCompleteSettings.ConcatMaxLinesMaxValue; var handler = new CodePaneSourceCodeHandler(new ProjectsRepository(vbe.Object)); var sut = new SmartConcatenationHandler(handler); return(sut); }
private IActionResult Validate(AutoCompleteSettings autoCompleteSettings) { //nothing to do (the model validate everything) return(null); }
private static SmartConcatenationHandler InitializeSut(TestCodeString code, out Mock <ICodeModule> module, out AutoCompleteSettings settings) { return(InitializeSut(code, code, out module, out _, out settings)); }
public AutoComplete(AutoCompleteSettings settings, ViewContext context, IViewDataContainer viewDataContainer) : base(settings, context, viewDataContainer) { }
public AutoComplete(AutoCompleteSettings settings) : base(settings) { }
/// <summary> /// A method that returns <c>false</c> if the input isn't handled, <c>true</c> if it is. /// </summary> /// <param name="e">The autocompletion event info</param> /// <param name="settings">The current AC settings</param> /// <param name="result">If handled, the resulting <c>CodeString</c></param> /// <returns></returns> public abstract bool Handle(AutoCompleteEventArgs e, AutoCompleteSettings settings, out CodeString result);