/// <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));
            }
示例#4
0
            // 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;
            }
示例#8
0
 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);
            }
示例#11
0
 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();
            }
示例#13
0
        // 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);
            }
        }
示例#14
0
 public ReplSpan(CustomTrackingSpan span, ReplSpanKind kind, int lineNumber)
     : this((object)span, kind, lineNumber)
 {
     Debug.Assert(!kind.IsPrompt());
 }
            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);
            }
            // 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));
            }
示例#21
0
 public ReplSpan(CustomTrackingSpan span, ReplSpanKind kind)
 {
     Debug.Assert(!kind.IsPrompt());
     this.Span = span;
     this.Kind = kind;
 }