private bool WillHandle(AutoCompleteEventArgs e)
        {
            Debug.Assert(_settings != null);

            if (!_enabled)
            {
                Logger.Warn("KeyDown controller is executing, but auto-completion service is disabled.");
                return(false);
            }

            if (_popupShown || e.Character == default && e.IsDeleteKey)
            {
                return(false);
            }

            var module = e.Module;

            using (var pane = module.CodePane)
            {
                if (pane.Selection.LineCount > 1)
                {
                    return(false);
                }
            }

            return(true);
        }
        private void ShowAutoComplete()
        {
            args = new AutoCompleteEventArgs {
                Cancel = false, AutoCompleteList = myAutoCompleteList
            };
            // With...
            if ((listBox.SelectedIndex == -1))
            {
                args.SelectedIndex = 0;
                System.Diagnostics.Debug.WriteLine("Always {0}", args.SelectedIndex);
            }
            else
            {
                args.SelectedIndex = listBox.SelectedIndex;
                System.Diagnostics.Debug.WriteLine("Not always {0}", args.SelectedIndex);
            }

            if (BeforeDisplayingAutoComplete != null)
            {
                BeforeDisplayingAutoComplete(this, args);
            }
            myAutoCompleteList = args.AutoCompleteList;

            if ((!args.Cancel && (args.AutoCompleteList != null) && args.AutoCompleteList.Count > 0))
            {
                DoShowAuto();
            }
            else
            {
                DoHideAuto();
            }
        }
示例#3
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);
        }
        public SelfClosingPairTestInfo(
            Mock <SelfClosingPairCompletionService> service,
            CodeString original,
            CodeString prettified,
            char input,
            CodeString rePrettified,
            bool isControlKeyDown = false,
            bool isDeleteKey      = false)
        {
            Original     = original;
            Prettified   = prettified;
            Input        = input;
            RePrettified = rePrettified;
            Settings     = AutoCompleteSettings.AllEnabled;

            Service = service;
            Module  = new Mock <ICodeModule>();
            Handler = new Mock <ICodePaneHandler>();
            Handler.Setup(e => e.GetCurrentLogicalLine(Module.Object)).Returns(original);
            Handler.SetupSequence(e => e.Prettify(Module.Object, It.IsAny <CodeString>()))
            .Returns(prettified)
            .Returns(rePrettified);

            Args = new AutoCompleteEventArgs(Module.Object, input, isControlKeyDown, isDeleteKey);
        }
        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);
        }
示例#6
0
        private void HandleTab()
        {
            var args = new AutoCompleteEventArgs(this.currentInput.ToString());

            this.AutoCompleteRequired?.Invoke(this, args);

            if (args.Suggestions.Count == 0)
            {
                return;
            }

            var enumerator = args.Suggestions.GetEnumerator();

            enumerator.MoveNext();

            if (args.Suggestions.Count == 1)
            {
                this.currentInput.Clear().Append(enumerator.Current);
                this.Refresh();
            }
            else
            {
                Console.WriteLine();

                Console.Write(enumerator.Current);

                while (enumerator.MoveNext())
                {
                    Console.Write(", {0}", enumerator.Current);
                }

                this.Refresh();
            }
        }
        private void HandleKeyDown(object sender, AutoCompleteEventArgs e)
        {
            if (e.Character == default && !e.IsDelete)
            {
                return;
            }

            var module             = e.CodeModule;
            var qualifiedSelection = module.GetQualifiedSelection();

            Debug.Assert(qualifiedSelection != null, nameof(qualifiedSelection) + " != null");
            var pSelection = qualifiedSelection.Value.Selection;

            if (_popupShown || pSelection.LineCount > 1 || e.IsDelete)
            {
                return;
            }

            var currentContent = module.GetLines(pSelection);

            if (HandleSmartConcat(e, pSelection, currentContent, module))
            {
                return;
            }

            HandleSelfClosingPairs(e, module, pSelection);
        }
        /// <summary>
        /// Adds a line continuation when {ENTER} is pressed inside a string literal; returns false otherwise.
        /// </summary>
        private bool HandleSmartConcat(AutoCompleteEventArgs e, Selection pSelection, string currentContent, ICodeModule module)
        {
            var shouldHandle = _settings.EnableSmartConcat &&
                               e.Character == '\r' &&
                               IsInsideStringLiteral(pSelection, ref currentContent);

            var lastIndexLeftOfCaret = currentContent.Length > 2 ? currentContent.Substring(0, pSelection.StartColumn - 1).LastIndexOf('"') : 0;

            if (shouldHandle && lastIndexLeftOfCaret > 0)
            {
                var indent     = currentContent.NthIndexOf('"', 1);
                var whitespace = new string(' ', indent);
                var code       = $"{currentContent.Substring(0, pSelection.StartColumn - 1)}\" & _\r\n{whitespace}\"{currentContent.Substring(pSelection.StartColumn - 1)}";

                if (e.ControlDown)
                {
                    code = $"{currentContent.Substring(0, pSelection.StartColumn - 1)}\" & vbNewLine & _\r\n{whitespace}\"{currentContent.Substring(pSelection.StartColumn - 1)}";
                }

                module.ReplaceLine(pSelection.StartLine, code);
                using (var pane = module.CodePane)
                {
                    pane.Selection = new Selection(pSelection.StartLine + 1, indent + currentContent.Substring(pSelection.StartColumn - 2).Length);
                    e.Handled      = true;
                    return(true);
                }
            }

            return(false);
        }
        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);
            }
        }
示例#10
0
        private static TestCodeString Run(TestCodeString original, char input, bool isCtrlDown = false, bool isDeleteKey = false)
        {
            var sut  = InitializeSut(original, out var module, out var settings);
            var args = new AutoCompleteEventArgs(module.Object, input, isCtrlDown, isDeleteKey);

            if (sut.Handle(args, settings, out var result))
            {
                return(new TestCodeString(result));
            }

            return(null);
        }
        private bool HandleInternal(AutoCompleteEventArgs e, CodeString original, SelfClosingPair pair, out CodeString result)
        {
            if (!original.CaretPosition.IsSingleCharacter)
            {
                // todo: WrapSelection?
                result = null;
                return(false);
            }

            var isPresent = original.CaretLine.EndsWith($"{pair.OpeningChar}{pair.ClosingChar}");

            if (!_scpService.Execute(pair, original, e.Character, out result))
            {
                return(false);
            }

            var prettified = CodePaneHandler.Prettify(e.Module, original);

            if (!isPresent && original.CaretLine.Length + 2 == prettified.CaretLine.Length &&
                prettified.CaretLine.EndsWith($"{pair.OpeningChar}{pair.ClosingChar}"))
            {
                // prettifier just added the pair for us; likely a Sub or Function statement.
                prettified = original; // pretend this didn't happen. note: probably breaks if original has extra whitespace.
            }

            if (!_scpService.Execute(pair, prettified, e.Character, out result))
            {
                return(false);
            }

            result = CodePaneHandler.Prettify(e.Module, result);

            var currentLine = result.Lines[result.CaretPosition.StartLine];

            if (!string.IsNullOrWhiteSpace(currentLine) &&
                currentLine.EndsWith(" ") &&
                result.CaretPosition.StartColumn == currentLine.Length)
            {
                result = result.ReplaceLine(result.CaretPosition.StartLine, currentLine.TrimEnd());
            }

            if (pair.OpeningChar == '(' &&
                e.Character == pair.OpeningChar &&
                !result.CaretLine.EndsWith($"{pair.OpeningChar}{pair.ClosingChar}"))
            {
                // VBE eats it. bail out but still swallow the keypress, since we've already re-prettified.
                e.Handled = true;
                result    = null;
                return(false);
            }

            return(true);
        }
示例#12
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 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);
            }
        }
        private void HandleKeyDown(object sender, AutoCompleteEventArgs e)
        {
            if (!WillHandle(e))
            {
                return;
            }

            foreach (var handler in _handlers)
            {
                if (TryHandle(e, handler))
                {
                    return;
                }
            }
        }
示例#15
0
        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);
        }
示例#16
0
        private void HandleKeyDown(object sender, AutoCompleteEventArgs e)
        {
            if (!WillHandle(e))
            {
                return;
            }

            foreach (var handler in _handlers)
            {
                if (!handler.Handle(e, _settings, out _))
                {
                    continue;
                }

                e.Handled = true;
                return;
            }
        }
示例#17
0
        private bool TryHandle(AutoCompleteEventArgs e, AutoCompleteHandlerBase handler)
        {
            try
            {
                if (!handler.Handle(e, _settings, out _))
                {
                    return(false);
                }

                e.Handled = true;
                return(true);
            }
            catch (Exception exception)
            {
                Logger.Error(exception);
                return(false);
            }
        }
        private bool TryHandle(AutoCompleteEventArgs e, AutoCompleteHandlerBase handler)
        {
            try
            {
                if (!handler.Handle(e, _settings, out _))
                {
                    return(false);
                }

                Logger.Debug($"Keypress was handled by {handler.GetType().Name}.");
                e.Handled = true;
                return(true);
            }
            catch (Exception exception)
            {
                Logger.Error(exception);
                return(false);
            }
        }
        private void HandleSelfClosingPairs(AutoCompleteEventArgs e, ICodeModule module, Selection pSelection)
        {
            if (!pSelection.IsSingleCharacter)
            {
                return;
            }

            var currentCode      = e.CurrentLine;
            var currentSelection = e.CurrentSelection;
            //var surroundingCode = GetSurroundingCode(module, currentSelection); // todo: find a way to parse the current instruction

            var original = new CodeString(currentCode, new Selection(0, currentSelection.EndColumn - 1), new Selection(pSelection.StartLine, 1));

            var prettifier = new CodeStringPrettifier(module);

            foreach (var selfClosingPair in _selfClosingPairs)
            {
                CodeString result;
                if (e.Character == '\b' && pSelection.StartColumn > 1)
                {
                    result = _selfClosingPairCompletion.Execute(selfClosingPair, original, '\b');
                }
                else
                {
                    result = _selfClosingPairCompletion.Execute(selfClosingPair, original, e.Character, prettifier);
                }

                if (result != default)
                {
                    using (var pane = module.CodePane)
                    {
                        module.DeleteLines(result.SnippetPosition);
                        module.InsertLines(result.SnippetPosition.StartLine, result.Code);
                        pane.Selection = result.SnippetPosition.Offset(result.CaretPosition);
                        e.Handled      = true;
                        return;
                    }
                }
            }
        }
		protected void text_AutoComplete(object sender, AutoCompleteEventArgs e)
		{			
			//just return 10 strings starting with the given one
			e.Results = Enumerable.Range(0, 10).Select(x => e.Parameter + x.ToString());
		}
 /// <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);
        private bool HandleInternal(AutoCompleteEventArgs e, CodeString original, SelfClosingPair pair, out CodeString result)
        {
            // if executing the SCP against the original code yields no result, we need to bail out.
            if (!_scpService.Execute(pair, original, e.Character, out result))
            {
                return(false);
            }

            // let the VBE alter the original code if it wants to, then work with the prettified code.
            var prettified = CodePaneHandler.Prettify(e.Module, original);

            var isPresent = original.CaretLine.EndsWith($"{pair.OpeningChar}{pair.ClosingChar}");

            if (!isPresent && original.CaretLine.Length + 2 == prettified.CaretLine.Length &&
                prettified.CaretLine.EndsWith($"{pair.OpeningChar}{pair.ClosingChar}"))
            {
                // prettifier just added the pair for us; likely a Sub or Function statement.
                prettified = original; // pretend this didn't happen; we need to work out the caret position anyway.
            }

            if (prettified.CaretLine.Length == 0)
            {
                // prettifier destroyed the indent. need to reinstate it now.
                prettified = prettified.ReplaceLine(
                    index: prettified.CaretPosition.StartLine,
                    content: new string(' ', original.CaretLine.TakeWhile(c => c == ' ').Count())
                    );
            }

            if (original.CaretLine.EndsWith(" ") &&
                string.Equals(original.CaretLine, prettified.CaretLine + " ", StringComparison.InvariantCultureIgnoreCase))
            {
                prettified = original;
            }

            // if executing the SCP against the prettified code yields no result, we need to bail out.
            if (!_scpService.Execute(pair, prettified, e.Character, out result))
            {
                return(false);
            }

            var reprettified = CodePaneHandler.Prettify(e.Module, result);

            if (pair.OpeningChar == '(' && e.Character == pair.OpeningChar)
            {
                if (string.Equals(reprettified.Code, result.Code, StringComparison.InvariantCultureIgnoreCase))
                {
                    e.Handled = true;
                    result    = reprettified;
                    return(true);
                }

                // VBE eats it. bail out but don't swallow the keypress.
                e.Handled = false;
                result    = null;
                return(false);
            }

            var currentLine = reprettified.Lines[reprettified.CaretPosition.StartLine];

            if (!string.IsNullOrWhiteSpace(currentLine) &&
                currentLine.EndsWith(" ") &&
                reprettified.CaretPosition.StartColumn == currentLine.Length)
            {
                result = reprettified.ReplaceLine(reprettified.CaretPosition.StartLine, currentLine.TrimEnd());
            }

            if (pair.OpeningChar == '(' &&
                e.Character == pair.OpeningChar &&
                !result.CaretLine.EndsWith($"{pair.OpeningChar}{pair.ClosingChar}"))
            {
                // VBE eats it. bail out but still swallow the keypress; we already prettified the opening character into the editor.
                e.Handled = true;
                result    = null;
                return(false);
            }

            return(true);
        }
        private void ShowAutoComplete()
        {
            args = new AutoCompleteEventArgs {Cancel = false, AutoCompleteList = myAutoCompleteList};
            // With...
            if ((listBox.SelectedIndex == -1))
            {
                args.SelectedIndex = 0;
                System.Diagnostics.Debug.WriteLine("Always {0}", args.SelectedIndex);
            }
            else
            {
                args.SelectedIndex = listBox.SelectedIndex;
                System.Diagnostics.Debug.WriteLine("Not always {0}", args.SelectedIndex);
            }

            if (BeforeDisplayingAutoComplete != null) BeforeDisplayingAutoComplete(this, args);
            myAutoCompleteList = args.AutoCompleteList;

            if ((!args.Cancel && (args.AutoCompleteList != null) && args.AutoCompleteList.Count > 0))
            {
                DoShowAuto();
            }
            else
            {
                DoHideAuto();
            }
        }
示例#24
0
        /// <summary>
        /// Handles and auto-complete request according to the result of the
        /// <see cref="AutoCompleteEvent"/> (also, see
        /// <see cref="CompletionList"/>)
        /// </summary>
        private void CmdAutoComplete()
        {
            if (AutoCompleteEvent == null)
            {
                InsertChar('\t');
                return;
            }

            AutoCompleteEventArgs eventArgs = new AutoCompleteEventArgs(
                text.ToString().Substring(0, textPosition));

            AutoCompleteEvent(this, eventArgs);

            string[] completions = eventArgs.Completions.
                                   SelectMany(c => c.Completions).
                                   Distinct().
                                   OrderBy(s => s).
                                   ToArray();

            int noOfCompletions = completions.Length;

            if (noOfCompletions == 0)
            {
                return;
            }

            if (completions.Length == 1)
            {
                InsertTextAtCursor(completions[0]);
            }
            else
            {
                string commonPrefix = eventArgs.Completions.
                                      Select(c => c.CommonPrefix).
                                      ElementAtMin(s => s.Length);

                int last = -1;

                for (int p = 0; p < completions[0].Length; p++)
                {
                    char c = completions[0][p];

                    for (int i = 1; i < noOfCompletions; i++)
                    {
                        if (completions[i].Length < p)
                        {
                            goto mismatch;
                        }

                        if (completions[i][p] != c)
                        {
                            goto mismatch;
                        }
                    }
                    last = p;
                }

mismatch:
                if (last != -1)
                {
                    InsertTextAtCursor(completions[0].Substring(0, last + 1));
                }
                Console.WriteLine();
                foreach (string s in completions)
                {
                    Console.Write(commonPrefix);
                    Console.Write(s);
                    Console.WriteLine();
                }
                Console.WriteLine();
                Render();
                MoveCursor(textPosition);
            }
        }