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);
        }
示例#2
0
        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);
        }
示例#3
0
        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);
        }
示例#4
0
        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);
            }
        }
示例#6
0
        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);
        }
示例#10
0
        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);
        }
示例#11
0
        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);
        }
示例#12
0
 private IActionResult Validate(AutoCompleteSettings autoCompleteSettings)
 {
     //nothing to do (the model validate everything)
     return(null);
 }
示例#13
0
 private static SmartConcatenationHandler InitializeSut(TestCodeString code, out Mock <ICodeModule> module, out AutoCompleteSettings settings)
 {
     return(InitializeSut(code, code, out module, out _, out settings));
 }
示例#14
0
 public AutoComplete(AutoCompleteSettings settings, ViewContext context, IViewDataContainer viewDataContainer)
     : base(settings, context, viewDataContainer)
 {
 }
示例#15
0
 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);