From 50a55a0d5258654212376808d4b1965c12a67d18 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Fri, 21 May 2021 12:16:24 +0200 Subject: [PATCH] Autoformat keeps cursor position after Undo --- .../formatter/clangformat/ClangFormat.java | 18 ++++++++++++++---- .../AutoformatProducesOneUndoActionTest.java | 3 ++- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/app/src/cc/arduino/packages/formatter/clangformat/ClangFormat.java b/app/src/cc/arduino/packages/formatter/clangformat/ClangFormat.java index 85cd940566e..d4a69b6480b 100644 --- a/app/src/cc/arduino/packages/formatter/clangformat/ClangFormat.java +++ b/app/src/cc/arduino/packages/formatter/clangformat/ClangFormat.java @@ -46,7 +46,7 @@ import processing.app.Base; import processing.app.BaseNoGui; import processing.app.Editor; -import processing.app.EditorTab; +import processing.app.syntax.SketchTextArea; public class ClangFormat implements Runnable { @@ -60,17 +60,27 @@ public ClangFormat(Editor editor) { @Override public void run() { - EditorTab tab = editor.getCurrentTab(); + SketchTextArea tab = editor.getCurrentTab().getTextArea(); String originalText = tab.getText(); - int cursorOffset = tab.getTextArea().getCaretPosition(); + int cursorOffset = tab.getCaretPosition(); try { FormatResult result = runClangFormatOn(originalText, cursorOffset); if (result.FormattedText.equals(originalText)) { editor.statusNotice(tr("No changes necessary for Auto Format.")); return; } + + // To keep cursor position after UNDO we produce a bogus edit (insertion + // and removal of a " " at cursor position) and we compound this change + // with the full auto-format update. + tab.beginAtomicEdit(); + tab.insert(" ", cursorOffset); + tab.replaceRange("", cursorOffset, cursorOffset + 1); tab.setText(result.FormattedText); - tab.getTextArea().setCaretPosition(result.Cursor); + tab.endAtomicEdit(); + + tab.setCaretPosition(result.Cursor); + editor.statusNotice(tr("Auto Format finished.")); } catch (IOException | InterruptedException e) { editor.statusError("Auto format error: " + e.getMessage()); diff --git a/app/test/processing/app/AutoformatProducesOneUndoActionTest.java b/app/test/processing/app/AutoformatProducesOneUndoActionTest.java index 3d23e068de1..f24ec92eaff 100644 --- a/app/test/processing/app/AutoformatProducesOneUndoActionTest.java +++ b/app/test/processing/app/AutoformatProducesOneUndoActionTest.java @@ -72,7 +72,8 @@ public void shouldSaveCaretPositionAfterAutoformat() { String formattedText = editor.getText(); assertEquals(SOURCE_AFTER, formattedText); - assertEquals(29, editor.getCaretPosition()); + // Autoformat with clang-format keeps cursor relative to source code + assertEquals(17, editor.getCaretPosition()); menuEditUndo.requireEnabled(); menuEditUndo.click();