From 87671ee0cdad8e7225632a3e08bf996d52a9a067 Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Thu, 16 Mar 2017 10:03:48 +0100 Subject: [PATCH] During compilation, scroll the console to the first error While adding messages to the console, this keeps track of the position of the first bit of stderr output. Then, whenever `EditorConsole.scrollDown()` is called, the scroll position is changed so that the line above the first error line is the first one in the console. If no errors are printed yet, the console scrolls down as before. To know what messages are coming from stderr, the ConsoleOutputStream that generated the message is passed to `EditorConsole.insertString()`, though this might not be the best solution for this. --- app/src/cc/arduino/ConsoleOutputStream.java | 2 +- app/src/processing/app/EditorConsole.java | 28 ++++++++++++++++++--- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/app/src/cc/arduino/ConsoleOutputStream.java b/app/src/cc/arduino/ConsoleOutputStream.java index 452c190b414..ea93b31a508 100644 --- a/app/src/cc/arduino/ConsoleOutputStream.java +++ b/app/src/cc/arduino/ConsoleOutputStream.java @@ -95,7 +95,7 @@ private void printInConsole(String text) { if (editorConsole != null) { SwingUtilities.invokeLater(() -> { try { - editorConsole.insertString(text, attributes); + editorConsole.insertString(this, text, attributes); } catch (BadLocationException ble) { //ignore } diff --git a/app/src/processing/app/EditorConsole.java b/app/src/processing/app/EditorConsole.java index 851f46e8af3..29381aea927 100644 --- a/app/src/processing/app/EditorConsole.java +++ b/app/src/processing/app/EditorConsole.java @@ -57,6 +57,7 @@ public static void setCurrentEditorConsole(EditorConsole console) { private final DefaultStyledDocument document; private final JTextPane consoleTextPane; + private int firstErrorOffset = -1; public EditorConsole() { document = new DefaultStyledDocument(); @@ -117,21 +118,42 @@ public void clear() { // ignore the error otherwise this will cause an infinite loop // maybe not a good idea in the long run? } + firstErrorOffset = -1; } public void scrollDown() { - getHorizontalScrollBar().setValue(0); - getVerticalScrollBar().setValue(getVerticalScrollBar().getMaximum()); + if (firstErrorOffset >= 0) { + try { + // Scroll to the first error, making sure that the line above the error + // is the first one shown. + int offset = Utilities.getPositionAbove(consoleTextPane, + firstErrorOffset, 0); + if (offset < 0) + offset = firstErrorOffset; + Rectangle rect = consoleTextPane.modelToView(offset); + this.getViewport().setViewPosition(new Point(0, rect.y)); + } catch (BadLocationException e) { + // Ignore + } + } else { + getHorizontalScrollBar().setValue(0); + getVerticalScrollBar().setValue(getVerticalScrollBar().getMaximum()); + } } public boolean isEmpty() { return document.getLength() == 0; } - public void insertString(String line, SimpleAttributeSet attributes) throws BadLocationException { + public void insertString(ConsoleOutputStream from, String line, + SimpleAttributeSet attributes) + throws BadLocationException { line = line.replace("\r\n", "\n").replace("\r", "\n"); int offset = document.getLength(); document.insertString(offset, line, attributes); + if (from == err && firstErrorOffset < 0) { + firstErrorOffset = offset; + } } public String getText() {