/// <summary> /// Creates and adds a new language buffer to the projection buffer. /// </summary> private void AddLanguageBuffer() { ITextBuffer buffer = _host.CreateAndActivateBuffer(_window); buffer.Properties.AddProperty(typeof(IInteractiveEvaluator), _window._evaluator); buffer.Properties.AddProperty(typeof(InteractiveWindow), _window); _window._currentLanguageBuffer = buffer; var bufferAdded = _window.SubmissionBufferAdded; if (bufferAdded != null) { bufferAdded(_window, new SubmissionBufferAddedEventArgs(buffer)); } // add the whole buffer to the projection buffer and set it up to expand to the right as text is appended var promptSpan = _window.CreatePrimaryPrompt(); var languageSpan = new CustomTrackingSpan( _window._currentLanguageBuffer.CurrentSnapshot, new Span(0, 0), PointTrackingMode.Negative, PointTrackingMode.Positive); // projection buffer update must be the last operation as it might trigger event that accesses prompt line mapping: _window.AppendProjectionSpans(promptSpan, languageSpan); }
/// <summary> /// Appends given text to the last input span (standard input or active code input). /// </summary> private void AppendInput(string text) { var snapshot = _window._projectionBuffer.CurrentSnapshot; var spanCount = snapshot.SpanCount; var inputSpan = snapshot.GetSourceSpan(spanCount - 1); var kind = _window.GetSpanKind(inputSpan.Snapshot); Debug.Assert(kind == ReplSpanKind.Language || kind == ReplSpanKind.StandardInput); var buffer = inputSpan.Snapshot.TextBuffer; var span = inputSpan.Span; using (var edit = buffer.CreateEdit()) { edit.Insert(edit.Snapshot.Length, text); edit.Apply(); } var replSpan = new CustomTrackingSpan( buffer.CurrentSnapshot, new Span(span.Start, span.Length + text.Length), PointTrackingMode.Negative, PointTrackingMode.Positive); ReplaceProjectionSpan(spanCount - 1, replSpan); _window.Caret.EnsureVisible(); }
// WARNING: When updating projection spans we need to update _projectionSpans list first and // then projection buffer, since the projection buffer update might trigger events that might // access the projection spans. public void AppendNewOutputProjectionBuffer() { var trackingSpan = new CustomTrackingSpan( _window._outputBuffer.CurrentSnapshot, new Span(_window._outputBuffer.CurrentSnapshot.Length, 0), PointTrackingMode.Negative, PointTrackingMode.Positive); _currentOutputProjectionSpan = AppendProjectionSpan(new ReplSpan(trackingSpan, ReplSpanKind.Output)); }
// WARNING: When updating projection spans we need to update _projectionSpans list first and // then projection buffer, since the projection buffer update might trigger events that might // access the projection spans. public void AppendNewOutputProjectionBuffer() { var currentSnapshot = _window._outputBuffer.CurrentSnapshot; var trackingSpan = new CustomTrackingSpan( currentSnapshot, new Span(currentSnapshot.Length, 0), PointTrackingMode.Negative, PointTrackingMode.Positive); var lastLineNumber = _window._textView == null ? 0 : _window.LastLineNumber; _currentOutputProjectionSpan = AppendProjectionSpan(new ReplSpan(trackingSpan, ReplSpanKind.Output, lastLineNumber)); }
public void NewOutputBuffer() { // Stop growing the current output projection span. var sourceSpan = _window._projectionBuffer.CurrentSnapshot.GetSourceSpan(_currentOutputProjectionSpan); Debug.Assert(_window.GetSpanKind(sourceSpan) == ReplSpanKind.Output); var nonGrowingSpan = new CustomTrackingSpan( sourceSpan.Snapshot, sourceSpan.Span, PointTrackingMode.Negative, PointTrackingMode.Negative); ReplaceProjectionSpan(_currentOutputProjectionSpan, nonGrowingSpan); AppendNewOutputProjectionBuffer(); _outputTrackingCaretPosition = _window._textView.Caret.Position.BufferPosition; }
/// <summary> /// Creates and adds a new language buffer to the projection buffer. /// </summary> private void AddLanguageBuffer() { ITextBuffer buffer = _factory.CreateAndActivateBuffer(_window); buffer.Properties.AddProperty(typeof(IInteractiveEvaluator), Evaluator); buffer.Properties.AddProperty(typeof(InteractiveWindow), _window); CurrentLanguageBuffer = buffer; var bufferAdded = _window.SubmissionBufferAdded; if (bufferAdded != null) { bufferAdded(_window, new SubmissionBufferAddedEventArgs(buffer)); } _window.LanguageBufferCounter++; // add the whole buffer to the projection buffer and set it up to expand to the right as text is appended var promptSpan = CreatePrimaryPrompt(); var languageSpan = new CustomTrackingSpan( CurrentLanguageBuffer.CurrentSnapshot, new Span(0, 0), canAppend: true); // projection buffer update must be the last operation as it might trigger event that accesses prompt line mapping: AppendProjectionSpans(promptSpan, languageSpan); }
public void NewOutputBuffer() { // Stop growing the current output projection span. var sourceSpan = _window._projectionBuffer.CurrentSnapshot.GetSourceSpan(_currentOutputProjectionSpan); var sourceSnapshot = sourceSpan.Snapshot; Debug.Assert(_window.GetSpanKind(sourceSnapshot) == ReplSpanKind.Output); var nonGrowingSpan = new CustomTrackingSpan( sourceSnapshot, sourceSpan.Span, PointTrackingMode.Negative, PointTrackingMode.Negative); ReplaceProjectionSpan(_currentOutputProjectionSpan, nonGrowingSpan); AppendNewOutputProjectionBuffer(); _outputTrackingCaretPosition = _window._textView.Caret.Position.BufferPosition; }
public ReplSpan(CustomTrackingSpan span, ReplSpanKind kind) { Debug.Assert(!kind.IsPrompt()); this.Span = span; this.Kind = kind; }
private void NewOutputBuffer() { // Stop growing the current output projection span. var sourceSpan = _projectionBuffer.CurrentSnapshot.GetSourceSpan(_currentOutputProjectionSpan); Debug.Assert(GetSpanKind(sourceSpan) == ReplSpanKind.Output); var nonGrowingSpan = new CustomTrackingSpan( sourceSpan.Snapshot, sourceSpan.Span); ReplaceProjectionSpan(_currentOutputProjectionSpan, nonGrowingSpan); AppendNewOutputProjectionBuffer(); _outputTrackingCaretPosition = TextView.Caret.Position.BufferPosition; }
private void AppendNewOutputProjectionBuffer() { var currentSnapshot = OutputBuffer.CurrentSnapshot; var trackingSpan = new CustomTrackingSpan( currentSnapshot, new Span(currentSnapshot.Length, 0), canAppend: true); _currentOutputProjectionSpan = AppendProjectionSpan(trackingSpan); }
public ReplSpan(CustomTrackingSpan span, ReplSpanKind kind, int lineNumber) : this((object)span, kind, lineNumber) { Debug.Assert(!kind.IsPrompt()); }
/// <summary> /// Appends given text to the last input span (standard input or active code input). /// </summary> private void AppendInput(string text) { var snapshot = _projectionBuffer.CurrentSnapshot; var spanCount = snapshot.SpanCount; var inputSpan = snapshot.GetSourceSpan(spanCount - 1); Debug.Assert(GetSpanKind(inputSpan) == ReplSpanKind.Input || GetSpanKind(inputSpan) == ReplSpanKind.StandardInput); var buffer = inputSpan.Snapshot.TextBuffer; var span = inputSpan.Span; using (var edit = buffer.CreateEdit()) { edit.Insert(edit.Snapshot.Length, text); edit.Apply(); } var replSpan = new CustomTrackingSpan( buffer.CurrentSnapshot, new Span(span.Start, span.Length + text.Length), canAppend: true); ReplaceProjectionSpan(spanCount - 1, replSpan); TextView.Caret.EnsureVisible(); }
// TODO: What happens if multiple non-UI threads call this method? (https://github.com/dotnet/roslyn/issues/3984) TextReader IInteractiveWindow.ReadStandardInput() { // shouldn't be called on the UI thread because we'll hang RequiresNonUIThread(); State previousState = default(State); // Compiler doesn't know these lambdas run sequentially. UIThread(uiOnly => { previousState = uiOnly.State; uiOnly.State = State.ReadingStandardInput; _buffer.Flush(); if (previousState == State.WaitingForInput) { var snapshot = _projectionBuffer.CurrentSnapshot; var spanCount = snapshot.SpanCount; if (spanCount > 0 && GetSpanKind(snapshot.GetSourceSpan(spanCount - 1)) == ReplSpanKind.Language) { // we need to remove our input prompt. uiOnly.RemoveLastInputPrompt(); } } uiOnly.AddStandardInputSpan(); Caret.EnsureVisible(); uiOnly.ResetCursor(); uiOnly.UncommittedInput = null; _stdInputStart = _standardInputBuffer.CurrentSnapshot.Length; }); _inputEvent.WaitOne(); _stdInputStart = null; UIThread(uiOnly => { var sourceSpans = _projectionBuffer.CurrentSnapshot.GetSourceSpans(); // if the user cleared the screen we cancelled the input, so we won't have our span here. // We can also have an interleaving output span, so we'll search back for the last input span. int i = uiOnly.IndexOfLastStandardInputSpan(sourceSpans); if (i != -1) { uiOnly.RemoveProtection(_standardInputBuffer, uiOnly.StandardInputProtection); // replace previous span w/ a span that won't grow... var oldSpan = sourceSpans[i]; var newSpan = new CustomTrackingSpan(oldSpan.Snapshot, oldSpan.Span, PointTrackingMode.Negative, PointTrackingMode.Negative); uiOnly.ReplaceProjectionSpan(i, newSpan); uiOnly.ApplyProtection(_standardInputBuffer, uiOnly.StandardInputProtection, allowAppend: true); uiOnly.NewOutputBuffer(); // TODO: Do we need to restore the state if reading is cancelled? (https://github.com/dotnet/roslyn/issues/3984) if (previousState == State.WaitingForInput) { uiOnly.PrepareForInput(); // Will update _uiOnly.State. } else { uiOnly.State = previousState; } } }); // input has been cancelled: if (_inputValue.HasValue) { var value = _inputValue.GetValueOrDefault(); UIThread(uiOnly => uiOnly.History.Add(value)); return(new StringReader(value.GetText())); } else { return(null); } }
public void AppendNewOutputProjectionBuffer() { var currentSnapshot = _window._outputBuffer.CurrentSnapshot; var trackingSpan = new CustomTrackingSpan( currentSnapshot, new Span(currentSnapshot.Length, 0), PointTrackingMode.Negative, PointTrackingMode.Positive); _currentOutputProjectionSpan = AppendProjectionSpan(trackingSpan); }
/// <summary> /// Appends given text to the last input span (standard input or active code input). /// </summary> private void AppendInput(string text) { var snapshot = _window._projectionBuffer.CurrentSnapshot; var spanCount = snapshot.SpanCount; var inputSpan = snapshot.GetSourceSpan(spanCount - 1); Debug.Assert(_window.GetSpanKind(inputSpan) == ReplSpanKind.Language || _window.GetSpanKind(inputSpan) == ReplSpanKind.StandardInput); var buffer = inputSpan.Snapshot.TextBuffer; var span = inputSpan.Span; using (var edit = buffer.CreateEdit()) { edit.Insert(edit.Snapshot.Length, text); edit.Apply(); } var replSpan = new CustomTrackingSpan( buffer.CurrentSnapshot, new Span(span.Start, span.Length + text.Length), PointTrackingMode.Negative, PointTrackingMode.Positive); ReplaceProjectionSpan(spanCount - 1, replSpan); _window.Caret.EnsureVisible(); }
/// <summary> /// Add a zero-width tracking span at the end of the projection buffer mapping to the end of the standard input buffer. /// </summary> public void AddStandardInputSpan() { var promptSpan = _window.CreateStandardInputPrompt(); var currentSnapshot = _window._standardInputBuffer.CurrentSnapshot; var inputSpan = new CustomTrackingSpan( currentSnapshot, new Span(currentSnapshot.Length, 0), PointTrackingMode.Negative, PointTrackingMode.Positive); AppendProjectionSpans(promptSpan, inputSpan); }
/// <summary> /// Add a zero-width tracking span at the end of the projection buffer mapping to the end of the standard input buffer. /// </summary> private void AddStandardInputSpan() { var promptSpan = CreateStandardInputPrompt(); var currentSnapshot = StandardInputBuffer.CurrentSnapshot; var inputSpan = new CustomTrackingSpan( currentSnapshot, new Span(currentSnapshot.Length, 0), canAppend: true); AppendProjectionSpans(promptSpan, inputSpan); }
private void MakeStandardInputReadonly() { AppendLineNoPromptInjection(StandardInputBuffer); // We can also have an interleaving output span, so we'll search back for the last input span. var sourceSpans = _projectionBuffer.CurrentSnapshot.GetSourceSpans(); int index = IndexOfLastStandardInputSpan(sourceSpans); Debug.Assert(index >= 0); RemoveProtection(StandardInputBuffer, _standardInputProtection); // replace previous span w/ a span that won't grow... var oldSpan = sourceSpans[index]; var newSpan = new CustomTrackingSpan(oldSpan.Snapshot, oldSpan.Span); ReplaceProjectionSpan(index, newSpan); ApplyProtection(StandardInputBuffer, _standardInputProtection, allowAppend: true); }