/// <summary> /// Pends the next input line to the current input buffer, optionally executing it /// if it forms a complete statement. /// </summary> private async Task ProcessQueuedInputAsync() { var textView = _window.TextView; var eval = _window.GetPythonEvaluator(); bool supportsMultipleStatements = false; if (eval != null) { supportsMultipleStatements = await eval.GetSupportsMultipleStatementsAsync(); } // Process all of our pending inputs until we get a complete statement while (_pendingInputs.First != null) { string current = _pendingInputs.First.Value; _pendingInputs.RemoveFirst(); MoveCaretToEndOfCurrentInput(); var statements = RecombineInput( current, _window.CurrentLanguageBuffer?.CurrentSnapshot.GetText(), supportsMultipleStatements, await textView.GetLanguageVersionAsync(_serviceProvider), textView.Options.GetNewLineCharacter() ); if (statements.Count > 0) { // If there was more than one statement then save those for execution later... var input = statements[0]; for (int i = statements.Count - 1; i > 0; i--) { _pendingInputs.AddFirst(statements[i]); } _window.InsertCode(input); string fullCode = _window.CurrentLanguageBuffer.CurrentSnapshot.GetText(); if (_window.Evaluator.CanExecuteCode(fullCode)) { // the code is complete, execute it now _window.Operations.ExecuteInput(); return; } _window.InsertCode(textView.Options.GetNewLineCharacter()); if (_submitAtEnd && _pendingInputs.First == null) { _window.Operations.ExecuteInput(); } } } }
public static async Task <bool> GetSupportsMultipleStatements(this IInteractiveWindow window) { var pie = window.GetPythonEvaluator(); if (pie == null) { return(false); } return(await pie.GetSupportsMultipleStatementsAsync()); }
public Task<ExecutionResult> Execute(IInteractiveWindow window, string arguments) { var finder = new FileFinder(arguments); var eval = window.GetPythonEvaluator(); if (eval != null) { finder.Search(eval.Configuration.WorkingDirectory); foreach (var p in eval.Configuration.SearchPaths) { finder.Search(p); } } finder.ThrowIfNotFound(); string commandPrefix = "$"; string lineBreak = window.TextView.Options.GetNewLineCharacter(); IEnumerable<string> lines = File.ReadLines(finder.Filename); IEnumerable<string> submissions; if (eval != null) { submissions = ReplEditFilter.JoinToCompleteStatements(lines, eval.LanguageVersion).Where(CommentPrefixPredicate); } else { // v1 behavior, will probably never be hit, but if someone was developing their own IReplEvaluator // and using this class it would be hit. var submissionList = new List<string>(); var currentSubmission = new List<string>(); foreach (var line in lines) { if (line.StartsWith(_commentPrefix)) { continue; } if (line.StartsWith(commandPrefix)) { AddSubmission(submissionList, currentSubmission, lineBreak); submissionList.Add(line); currentSubmission.Clear(); } else { currentSubmission.Add(line); } } AddSubmission(submissionList, currentSubmission, lineBreak); submissions = submissionList; } window.SubmitAsync(submissions); return ExecutionResult.Succeeded; }
public Task <ExecutionResult> Execute(IInteractiveWindow window, string arguments) { var finder = new FileFinder(arguments); var eval = window.GetPythonEvaluator(); if (eval != null) { finder.Search(eval.Configuration.WorkingDirectory); foreach (var p in eval.Configuration.SearchPaths) { finder.Search(p); } } finder.ThrowIfNotFound(); string commandPrefix = "$"; string lineBreak = window.TextView.Options.GetNewLineCharacter(); IEnumerable <string> lines = File.ReadLines(finder.Filename); IEnumerable <string> submissions; if (eval != null) { submissions = ReplEditFilter.JoinToCompleteStatements(lines, eval.LanguageVersion).Where(CommentPrefixPredicate); } else { // v1 behavior, will probably never be hit, but if someone was developing their own IReplEvaluator // and using this class it would be hit. var submissionList = new List <string>(); var currentSubmission = new List <string>(); foreach (var line in lines) { if (line.StartsWith(_commentPrefix)) { continue; } if (line.StartsWith(commandPrefix)) { AddSubmission(submissionList, currentSubmission, lineBreak); submissionList.Add(line); currentSubmission.Clear(); } else { currentSubmission.Add(line); } } AddSubmission(submissionList, currentSubmission, lineBreak); submissions = submissionList; } window.SubmitAsync(submissions); return(ExecutionResult.Succeeded); }
private static async Task PasteReplCode( IInteractiveWindow window, string pasting, PythonLanguageVersion version ) { // there's some text in the buffer... var view = window.TextView; var caret = view.Caret; if (view.Selection.IsActive && !view.Selection.IsEmpty) { foreach (var span in view.Selection.SelectedSpans) { foreach (var normalizedSpan in view.BufferGraph.MapDownToBuffer(span, SpanTrackingMode.EdgeInclusive, window.CurrentLanguageBuffer)) { normalizedSpan.Snapshot.TextBuffer.Delete(normalizedSpan); } } } var curBuffer = window.CurrentLanguageBuffer; var inputPoint = view.BufferGraph.MapDownToBuffer( caret.Position.BufferPosition, PointTrackingMode.Positive, curBuffer, PositionAffinity.Successor ); // if we didn't find a location then see if we're in a prompt, and if so, then we want // to insert after the prompt. if (caret.Position.BufferPosition != window.TextView.TextBuffer.CurrentSnapshot.Length) { for (int i = caret.Position.BufferPosition + 1; inputPoint == null && i <= window.TextView.TextBuffer.CurrentSnapshot.Length; i++) { inputPoint = view.BufferGraph.MapDownToBuffer( new SnapshotPoint(window.TextView.TextBuffer.CurrentSnapshot, i), PointTrackingMode.Positive, curBuffer, PositionAffinity.Successor ); } } if (inputPoint == null) { // we didn't find a point to insert, insert at the beginning. inputPoint = new SnapshotPoint(curBuffer.CurrentSnapshot, 0); } // we want to insert the pasted code at the caret, but we also want to // respect the stepping. So first grab the code before and after the caret. string startText = curBuffer.CurrentSnapshot.GetText(0, inputPoint.Value); string endText = curBuffer.CurrentSnapshot.GetText( inputPoint.Value, curBuffer.CurrentSnapshot.Length - inputPoint.Value); var splitCode = JoinToCompleteStatements(SplitAndDedent(startText + pasting + endText), version).ToList(); curBuffer.Delete(new Span(0, curBuffer.CurrentSnapshot.Length)); bool supportMultiple = window.GetPythonEvaluator()?.SupportsMultipleStatements ?? false; if (supportMultiple) { await window.SubmitAsync(new[] { string.Join(Environment.NewLine, splitCode) }); } else if (splitCode.Count == 1) { curBuffer.Insert(0, splitCode[0]); var viewPoint = view.BufferGraph.MapUpToBuffer( new SnapshotPoint(curBuffer.CurrentSnapshot, Math.Min(inputPoint.Value.Position + pasting.Length, curBuffer.CurrentSnapshot.Length)), PointTrackingMode.Positive, PositionAffinity.Successor, view.TextBuffer ); if (viewPoint != null) { view.Caret.MoveTo(viewPoint.Value); } } else if (splitCode.Count != 0) { var lastCode = splitCode[splitCode.Count - 1]; splitCode.RemoveAt(splitCode.Count - 1); while (splitCode.Any()) { var code = splitCode[0]; splitCode.RemoveAt(0); await window.SubmitAsync(new[] { code }); supportMultiple = window.GetPythonEvaluator()?.SupportsMultipleStatements ?? false; if (supportMultiple) { // Might have changed while we were executing break; } } if (supportMultiple) { // Submit all remaning lines of code await window.SubmitAsync(new[] { string.Join(Environment.NewLine, splitCode) }); } else { window.CurrentLanguageBuffer.Insert(0, lastCode); } } else { window.CurrentLanguageBuffer.Insert(0, startText + pasting + endText); } }