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 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 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); }