public bool ProcessMessage(string message) { // Note: Post() to UI thread is expensive, and can saturate the message pump when there's a lot of output, // making UI non-responsive. So avoid using it unless we need it - and we only need it for FlushOutput, // and we only need it to handle CR. if (message.Length > 1 && message[0] == '\r' && message[1] != '\n') { _coreShell.MainThread().Post(() => { // Make sure output buffer is up to date _interactiveWindow.FlushOutput(); // If message starts with CR we remember current output buffer // length so we can continue writing lines into the same spot. // See txtProgressBar in R. // Store the message and the initial position. All subsequent // messages that start with CR will be written into the same place. if (_messagePos != null) { ProcessReplacement(); } // Locate last end of line var snapshot = _interactiveWindow.OutputBuffer.CurrentSnapshot; var line = snapshot.GetLineFromPosition(snapshot.Length); var text = message.Substring(1); _messagePos = new MessagePos() { Text = text, Position = line.Start, PlaceholderLength = text.Length + 8 // buffer for, say, '| 100%' }; // It is important that replacement matches original text length // since interactive window creates fixed colorized spans for errors // and replacement of text by a text with a different length // causes odd changes in color - word may appear partially in // black and partially in red. // Replacement placeholder so we can receive 'buffer changed' event // Placeholder is whitespace that is as long as original message plus // few more space to account for example, for 0% - 100% when CR is used // to display ASCII progress. var placeholder = new string(' ', _messagePos.PlaceholderLength); _interactiveWindow.Write(placeholder); _interactiveWindow.FlushOutput(); // Must flush so we do get 'buffer changed' immediately. }); return(true); } return(false); }
internal void WriteFrameworkElement(System.Windows.UIElement control, System.Windows.Size desiredSize) { if (_window == null) { return; } _window.Write(""); _window.FlushOutput(); var caretPos = _window.TextView.Caret.Position.BufferPosition; var manager = InlineReplAdornmentProvider.GetManager(_window.TextView); manager.AddAdornment(new ZoomableInlineAdornment(control, _window.TextView, desiredSize), caretPos); }
private void FlushOutput(IInteractiveWindow window) { // Give interactive window writer time to process message queue UIThreadHelper.Instance.DoEvents(400); window.FlushOutput(); }