/// <summary>
            /// Appends given text to the last input span (standard input or active code input).
            /// </summary>
            private void AppendInput(string text)
            {
                var inputSpan = _window._projectionSpans[_window._projectionSpans.Count - 1];

                Debug.Assert(inputSpan.Kind == ReplSpanKind.Language || inputSpan.Kind == ReplSpanKind.StandardInput);
                Debug.Assert(inputSpan.TrackingSpan.TrackingMode == SpanTrackingMode.Custom);

                var buffer = inputSpan.TrackingSpan.TextBuffer;
                var span   = inputSpan.TrackingSpan.GetSpan(buffer.CurrentSnapshot);

                using (var edit = buffer.CreateEdit())
                {
                    edit.Insert(edit.Snapshot.Length, text);
                    edit.Apply();
                }

                var replSpan = new ReplSpan(
                    new CustomTrackingSpan(
                        buffer.CurrentSnapshot,
                        new Span(span.Start, span.Length + text.Length),
                        PointTrackingMode.Negative,
                        PointTrackingMode.Positive),
                    inputSpan.Kind);

                ReplaceProjectionSpan(_window._projectionSpans.Count - 1, replSpan);

                _window.Caret.EnsureVisible();
            }
            private int AppendProjectionSpan(ReplSpan span)
            {
                int index = _window._projectionSpans.Count;

                InsertProjectionSpan(index, span);
                return(index);
            }
Exemple #3
0
 public void ReplaceProjectionSpan(int spanToReplace, ReplSpan newSpan)
 {
     Debug.Assert(_window._projectionSpans[spanToReplace].LineNumber == newSpan.LineNumber);
     _window._projectionSpans[spanToReplace] = newSpan;
     _window._projectionBuffer.ReplaceSpans(spanToReplace, 1, new[] { newSpan.Span }, EditOptions.None, editTag: s_suppressPromptInjectionTag);
     _window.CheckProjectionSpanLineNumbers();
 }
Exemple #4
0
            /// <summary>
            /// Returns the language or command text buffer that the specified point belongs to.
            /// If the point lays in a prompt returns the buffer corresponding to the prompt.
            /// </summary>
            /// <returns>The language or command buffer or null if the point doesn't belong to any.</returns>
            private ITextBuffer GetLanguageBuffer(SnapshotPoint point)
            {
                int promptIndex = _window.GetPromptIndexForPoint(point);

                if (promptIndex < 0)
                {
                    return(null);
                }

                // Grab the span following the prompt (either language or standard input).
                ReplSpan projectionSpan = _window._projectionSpans[promptIndex + 1];

                if (projectionSpan.Kind != ReplSpanKind.Language)
                {
                    Debug.Assert(projectionSpan.Kind == ReplSpanKind.StandardInput);
                    return(null);
                }

                var inputBuffer   = projectionSpan.TrackingSpan.TextBuffer;
                var inputSnapshot = inputBuffer.CurrentSnapshot;

                var projectedSnapshot = _window._textView.BufferGraph.MapUpToBuffer(
                    new SnapshotSpan(inputSnapshot, 0, inputSnapshot.Length),
                    SpanTrackingMode.EdgePositive,
                    _window._projectionBuffer);

                Debug.Assert(projectedSnapshot.Count > 0);
                var projectedSnapshotStart = projectedSnapshot.First().Start;
                var projectedSnapshotEnd   = projectedSnapshot.Last().End;

                if (point < projectedSnapshotStart.GetContainingLine().Start)
                {
                    return(null);
                }

                // If the buffer is the current buffer, the cursor might be in a virtual space behind the buffer
                // but logically it belongs to the current submission. Since the current language buffer is the last buffer in the
                // projection we don't need to check for its end.
                if (inputBuffer == _window._currentLanguageBuffer)
                {
                    return(inputBuffer);
                }

                // if the point is at the end of the buffer it might be on the next line that doesn't logically belong to the input region:
                if (point > projectedSnapshotEnd || (point == projectedSnapshotEnd && projectedSnapshotEnd.GetContainingLine().LineBreakLength != 0))
                {
                    return(null);
                }

                return(inputBuffer);
            }
            /// <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
                ReplSpan promptSpan   = _window.CreatePrimaryPrompt();
                ReplSpan languageSpan = new ReplSpan(_window.CreateLanguageTrackingSpan(new Span(0, 0)), ReplSpanKind.Language);

                // projection buffer update must be the last operation as it might trigger event that accesses prompt line mapping:
                _window.AppendProjectionSpans(promptSpan, languageSpan);
            }
            /// <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
                ReplSpan promptSpan = _window.CreatePrimaryPrompt();
                ReplSpan languageSpan = new ReplSpan(_window.CreateLanguageTrackingSpan(new Span(0, 0)), ReplSpanKind.Language, promptSpan.LineNumber);

                // projection buffer update must be the last operation as it might trigger event that accesses prompt line mapping:
                _window.AppendProjectionSpans(promptSpan, languageSpan);
            }
 public void ReplaceProjectionSpan(int spanToReplace, ReplSpan newSpan)
 {
     Debug.Assert(_window._projectionSpans[spanToReplace].LineNumber == newSpan.LineNumber);
     _window._projectionSpans[spanToReplace] = newSpan;
     _window._projectionBuffer.ReplaceSpans(spanToReplace, 1, new[] { newSpan.Span }, EditOptions.None, editTag: s_suppressPromptInjectionTag);
     _window.CheckProjectionSpanLineNumbers();
 }
 private void InsertProjectionSpan(int index, ReplSpan span)
 {
     _window._projectionSpans.Insert(index, span);
     _window._projectionBuffer.ReplaceSpans(index, 0, new[] { span.Span }, EditOptions.None, editTag: s_suppressPromptInjectionTag);
     _window.CheckProjectionSpanLineNumbers();
 }
 private int AppendProjectionSpan(ReplSpan span)
 {
     int index = _window._projectionSpans.Count;
     InsertProjectionSpan(index, span);
     return index;
 }
            /// <summary>
            /// Appends given text to the last input span (standard input or active code input).
            /// </summary>
            private void AppendInput(string text)
            {
                var inputSpan = _window._projectionSpans[_window._projectionSpans.Count - 1];
                Debug.Assert(inputSpan.Kind == ReplSpanKind.Language || inputSpan.Kind == ReplSpanKind.StandardInput);
                Debug.Assert(inputSpan.TrackingSpan.TrackingMode == SpanTrackingMode.Custom);

                var buffer = inputSpan.TrackingSpan.TextBuffer;
                var span = inputSpan.TrackingSpan.GetSpan(buffer.CurrentSnapshot);
                using (var edit = buffer.CreateEdit())
                {
                    edit.Insert(edit.Snapshot.Length, text);
                    edit.Apply();
                }

                var replSpan = new ReplSpan(
                    new CustomTrackingSpan(
                        buffer.CurrentSnapshot,
                        new Span(span.Start, span.Length + text.Length),
                        PointTrackingMode.Negative,
                        PointTrackingMode.Positive),
                    inputSpan.Kind,
                    inputSpan.LineNumber);

                ReplaceProjectionSpan(_window._projectionSpans.Count - 1, replSpan);

                _window.Caret.EnsureVisible();
            }
 public void ReplaceProjectionSpan(int spanToReplace, ReplSpan newSpan)
 {
     _window._projectionSpans[spanToReplace] = newSpan;
     _window._projectionBuffer.ReplaceSpans(spanToReplace, 1, new[] { newSpan.Span }, EditOptions.None, editTag: s_suppressPromptInjectionTag);
 }
 private void InsertProjectionSpan(int index, ReplSpan span)
 {
     _window._projectionSpans.Insert(index, span);
     _window._projectionBuffer.ReplaceSpans(index, 0, new[] { span.Span }, EditOptions.None, editTag: s_suppressPromptInjectionTag);
 }
        public InteractiveWindow(
            IInteractiveWindowEditorFactoryService host,
            IContentTypeRegistryService contentTypeRegistry,
            ITextBufferFactoryService bufferFactory,
            IProjectionBufferFactoryService projectionBufferFactory,
            IEditorOperationsFactoryService editorOperationsFactory,
            ITextEditorFactoryService editorFactory,
            IIntellisenseSessionStackMapService intellisenseSessionStackMap,
            ISmartIndentationService smartIndenterService,
            IInteractiveEvaluator evaluator)
        {
            if (evaluator == null)
            {
                throw new ArgumentNullException(nameof(evaluator));
            }

            _dangerous_uiOnly = new UIThreadOnly(this, host);

            this.Properties = new PropertyCollection();
            _history        = new History();

            _intellisenseSessionStackMap = intellisenseSessionStackMap;
            _smartIndenterService        = smartIndenterService;

            var textContentType       = contentTypeRegistry.GetContentType("text");
            var replContentType       = contentTypeRegistry.GetContentType(PredefinedInteractiveContentTypes.InteractiveContentTypeName);
            var replOutputContentType = contentTypeRegistry.GetContentType(PredefinedInteractiveContentTypes.InteractiveOutputContentTypeName);

            _outputBuffer        = bufferFactory.CreateTextBuffer(replOutputContentType);
            _standardInputBuffer = bufferFactory.CreateTextBuffer();

            var projBuffer = projectionBufferFactory.CreateProjectionBuffer(
                new EditResolver(this),
                Array.Empty <object>(),
                ProjectionBufferOptions.None,
                replContentType);

            // we need to set IReplPromptProvider property before TextViewHost is instantiated so that ReplPromptTaggerProvider can bind to it
            projBuffer.Properties.AddProperty(typeof(InteractiveWindow), this);

            _projectionBuffer = projBuffer;
            _dangerous_uiOnly.AppendNewOutputProjectionBuffer(); // Constructor runs on UI thread.
            projBuffer.Changed += new EventHandler <TextContentChangedEventArgs>(ProjectionBufferChanged);

            var roleSet = editorFactory.CreateTextViewRoleSet(
                PredefinedTextViewRoles.Analyzable,
                PredefinedTextViewRoles.Editable,
                PredefinedTextViewRoles.Interactive,
                PredefinedTextViewRoles.Zoomable,
                PredefinedInteractiveTextViewRoles.InteractiveTextViewRole);

            _textView = host.CreateTextView(this, projBuffer, roleSet);

            _textView.Caret.PositionChanged += CaretPositionChanged;

            _textView.Options.SetOptionValue(DefaultTextViewHostOptions.HorizontalScrollBarId, false);
            _textView.Options.SetOptionValue(DefaultTextViewHostOptions.LineNumberMarginId, false);
            _textView.Options.SetOptionValue(DefaultTextViewHostOptions.OutliningMarginId, false);
            _textView.Options.SetOptionValue(DefaultTextViewHostOptions.GlyphMarginId, false);
            _textView.Options.SetOptionValue(DefaultTextViewOptions.WordWrapStyleId, WordWrapStyles.WordWrap);

            string lineBreak = _textView.Options.GetNewLineCharacter();

            _lineBreakOutputSpan = new ReplSpan(lineBreak, ReplSpanKind.Output);
            _dangerous_uiOnly.EditorOperations = editorOperationsFactory.GetEditorOperations(_textView); // Constructor runs on UI thread.

            _buffer       = new OutputBuffer(this);
            _outputWriter = new InteractiveWindowWriter(this, spans: null);

            SortedSpans errorSpans = new SortedSpans();

            _errorOutputWriter = new InteractiveWindowWriter(this, errorSpans);
            OutputClassifierProvider.AttachToBuffer(_outputBuffer, errorSpans);

            RequiresUIThread();
            evaluator.CurrentWindow = this;
            _evaluator = evaluator;
        }
 public void ReplaceProjectionSpan(int spanToReplace, ReplSpan newSpan)
 {
     _window._projectionSpans[spanToReplace] = newSpan;
     _window._projectionBuffer.ReplaceSpans(spanToReplace, 1, new[] { newSpan.Span }, EditOptions.None, editTag: s_suppressPromptInjectionTag);
 }
        public InteractiveWindow(
            IInteractiveWindowEditorFactoryService host,
            IContentTypeRegistryService contentTypeRegistry,
            ITextBufferFactoryService bufferFactory,
            IProjectionBufferFactoryService projectionBufferFactory,
            IEditorOperationsFactoryService editorOperationsFactory,
            ITextEditorFactoryService editorFactory,
            IIntellisenseSessionStackMapService intellisenseSessionStackMap,
            ISmartIndentationService smartIndenterService,
            IInteractiveEvaluator evaluator)
        {
            if (evaluator == null)
            {
                throw new ArgumentNullException(nameof(evaluator));
            }

            _dangerous_uiOnly = new UIThreadOnly(this, host);

            this.Properties = new PropertyCollection();
            _history = new History();

            _intellisenseSessionStackMap = intellisenseSessionStackMap;
            _smartIndenterService = smartIndenterService;

            var textContentType = contentTypeRegistry.GetContentType("text");
            var replContentType = contentTypeRegistry.GetContentType(PredefinedInteractiveContentTypes.InteractiveContentTypeName);
            var replOutputContentType = contentTypeRegistry.GetContentType(PredefinedInteractiveContentTypes.InteractiveOutputContentTypeName);

            _outputBuffer = bufferFactory.CreateTextBuffer(replOutputContentType);
            _standardInputBuffer = bufferFactory.CreateTextBuffer();

            var projBuffer = projectionBufferFactory.CreateProjectionBuffer(
                new EditResolver(this),
                Array.Empty<object>(),
                ProjectionBufferOptions.None,
                replContentType);

            // we need to set IReplPromptProvider property before TextViewHost is instantiated so that ReplPromptTaggerProvider can bind to it 
            projBuffer.Properties.AddProperty(typeof(InteractiveWindow), this);

            _projectionBuffer = projBuffer;
            _dangerous_uiOnly.AppendNewOutputProjectionBuffer(); // Constructor runs on UI thread.
            projBuffer.Changed += new EventHandler<TextContentChangedEventArgs>(ProjectionBufferChanged);

            var roleSet = editorFactory.CreateTextViewRoleSet(
                PredefinedTextViewRoles.Analyzable,
                PredefinedTextViewRoles.Editable,
                PredefinedTextViewRoles.Interactive,
                PredefinedTextViewRoles.Zoomable,
                PredefinedInteractiveTextViewRoles.InteractiveTextViewRole);

            _textView = host.CreateTextView(this, projBuffer, roleSet);

            _textView.Caret.PositionChanged += CaretPositionChanged;

            _textView.Options.SetOptionValue(DefaultTextViewHostOptions.HorizontalScrollBarId, false);
            _textView.Options.SetOptionValue(DefaultTextViewHostOptions.LineNumberMarginId, false);
            _textView.Options.SetOptionValue(DefaultTextViewHostOptions.OutliningMarginId, false);
            _textView.Options.SetOptionValue(DefaultTextViewHostOptions.GlyphMarginId, false);
            _textView.Options.SetOptionValue(DefaultTextViewOptions.WordWrapStyleId, WordWrapStyles.WordWrap);

            string lineBreak = _textView.Options.GetNewLineCharacter();
            _lineBreakOutputSpan = new ReplSpan(lineBreak, ReplSpanKind.Output);
            _dangerous_uiOnly.EditorOperations = editorOperationsFactory.GetEditorOperations(_textView); // Constructor runs on UI thread.

            _buffer = new OutputBuffer(this);
            _outputWriter = new InteractiveWindowWriter(this, spans: null);

            SortedSpans errorSpans = new SortedSpans();
            _errorOutputWriter = new InteractiveWindowWriter(this, errorSpans);
            OutputClassifierProvider.AttachToBuffer(_outputBuffer, errorSpans);

            RequiresUIThread();
            evaluator.CurrentWindow = this;
            _evaluator = evaluator;
        }