From 404446bcf0069660a00e37ca6b95c2a25dabed20 Mon Sep 17 00:00:00 2001 From: dzmipt Date: Wed, 24 Jan 2024 20:24:47 +0100 Subject: [PATCH] Remove insert paired char ' and ` into RSTA. Option to disable other paired chars --- notes.md | 1 + src/studio/kdb/Config.java | 1 + src/studio/ui/SettingsDialog.java | 8 ++- src/studio/ui/StudioWindow.java | 2 + .../ui/rstextarea/RSTextAreaFactory.java | 43 +++++++++++++- .../studio/ui/RSTAEditorTest.java | 58 +++++++++++++++++++ .../studio/ui/RSTextAreaFrameForTest.java | 37 ------------ .../studio/ui/RSTextAreaTest.java | 32 ---------- 8 files changed, 111 insertions(+), 71 deletions(-) create mode 100644 test-integration/studio/ui/RSTAEditorTest.java delete mode 100644 test-integration/studio/ui/RSTextAreaFrameForTest.java delete mode 100644 test-integration/studio/ui/RSTextAreaTest.java diff --git a/notes.md b/notes.md index 4643f9a5..c2a0e25e 100644 --- a/notes.md +++ b/notes.md @@ -1,3 +1,4 @@ +* New setting to disable insert of paired character into the editor * Implement continuous search * Fixed the bug with sequential replace action in the editor diff --git a/src/studio/kdb/Config.java b/src/studio/kdb/Config.java index d6cb2dcb..741d624d 100755 --- a/src/studio/kdb/Config.java +++ b/src/studio/kdb/Config.java @@ -42,6 +42,7 @@ public class Config extends AbstractConfig { public static final String RSTA_ANIMATE_BRACKET_MATCHING = configDefault("rstaAnimateBracketMatching", ConfigType.BOOLEAN, true); public static final String RSTA_HIGHLIGHT_CURRENT_LINE = configDefault("rstaHighlightCurrentLine", ConfigType.BOOLEAN, true); public static final String RSTA_WORD_WRAP = configDefault("rstaWordWrap", ConfigType.BOOLEAN, false); + public static final String RSTA_INSERT_PAIRED_CHAR = configDefault("rstaInsertPairedChar", ConfigType.BOOLEAN, true); public static final String DEFAULT_LINE_ENDING = configDefault("defaultLineEnding", ConfigType.ENUM, LineEnding.Unix); diff --git a/src/studio/ui/SettingsDialog.java b/src/studio/ui/SettingsDialog.java index a0152c16..363290fb 100644 --- a/src/studio/ui/SettingsDialog.java +++ b/src/studio/ui/SettingsDialog.java @@ -33,6 +33,7 @@ public class SettingsDialog extends EscapeDialog { private JCheckBox chBoxRTSAAnimateBracketMatching; private JCheckBox chBoxRTSAHighlightCurrentLine; private JCheckBox chBoxRTSAWordWrap; + private JCheckBox chBoxRTSAInsertPairedChar; private JComboBox comboBoxLookAndFeel; private JFormattedTextField txtTabsCount; private JFormattedTextField txtMaxCharsInResult; @@ -169,6 +170,9 @@ private void initComponents() { chBoxRTSAWordWrap = new JCheckBox("Word wrap"); chBoxRTSAWordWrap.setSelected(CONFIG.getBoolean(Config.RSTA_WORD_WRAP)); + chBoxRTSAInsertPairedChar = new JCheckBox("Insert paired () {} [] \"\" on selection"); + chBoxRTSAInsertPairedChar.setSelected(CONFIG.getBoolean(Config.RSTA_INSERT_PAIRED_CHAR)); + NumberFormatter formatter = new NumberFormatter(); formatter.setMinimum(1); @@ -284,7 +288,8 @@ private void initComponents() { layout = new GroupLayoutSimple(pnlEditor); layout.setStacks( new GroupLayoutSimple.Stack() - .addLineAndGlue(chBoxRTSAAnimateBracketMatching, chBoxRTSAHighlightCurrentLine, chBoxRTSAWordWrap) + .addLineAndGlue(chBoxRTSAAnimateBracketMatching, chBoxRTSAHighlightCurrentLine, + chBoxRTSAWordWrap, chBoxRTSAInsertPairedChar) .addLineAndGlue(chBoxEmulateTab, txtEmulatedTabSize, chBoxReplaceTabOnOpen) .addLineAndGlue(lblDefaultLineEnding, comboBoxLineEnding) .addLineAndGlue(lblExecAll, comboBoxExecAll) @@ -359,6 +364,7 @@ public void saveSettings() { boolean changedEditor = CONFIG.setBoolean(Config.RSTA_ANIMATE_BRACKET_MATCHING, isAnimateBracketMatching()); changedEditor |= CONFIG.setBoolean(Config.RSTA_HIGHLIGHT_CURRENT_LINE, isHighlightCurrentLine()); changedEditor |= CONFIG.setBoolean(Config.RSTA_WORD_WRAP, isWordWrap()); + changedEditor |= CONFIG.setBoolean(Config.RSTA_INSERT_PAIRED_CHAR, chBoxRTSAInsertPairedChar.isSelected()); changedEditor |= editorFontSelection.saveSettings(); changedEditor |= CONFIG.setBoolean(Config.EDITOR_TAB_EMULATED, chBoxEmulateTab.isSelected()); changedEditor |= CONFIG.setInt(Config.EDITOR_TAB_SIZE, (Integer)txtEmulatedTabSize.getValue()); diff --git a/src/studio/ui/StudioWindow.java b/src/studio/ui/StudioWindow.java index 68736698..924c4b7f 100755 --- a/src/studio/ui/StudioWindow.java +++ b/src/studio/ui/StudioWindow.java @@ -766,6 +766,8 @@ public static void refreshEditorsSettings() { editor.setTabSize(CONFIG.getInt(Config.EDITOR_TAB_SIZE)); editor.setTabsEmulated(CONFIG.getBoolean(Config.EDITOR_TAB_EMULATED)); + + editor.setInsertPairedCharacters(CONFIG.getBoolean(Config.RSTA_INSERT_PAIRED_CHAR)); return true; }); } diff --git a/src/studio/ui/rstextarea/RSTextAreaFactory.java b/src/studio/ui/rstextarea/RSTextAreaFactory.java index fed456a4..d3caa4c0 100644 --- a/src/studio/ui/rstextarea/RSTextAreaFactory.java +++ b/src/studio/ui/rstextarea/RSTextAreaFactory.java @@ -21,6 +21,11 @@ import java.awt.event.KeyEvent; import java.util.ArrayList; import java.util.Arrays; +import java.util.List; +import java.util.ListIterator; +import java.util.stream.Collectors; + +import static org.fife.ui.rsyntaxtextarea.RSyntaxTextAreaEditorKit.*; public class RSTextAreaFactory { @@ -29,9 +34,36 @@ public class RSTextAreaFactory { private static final ActionMap actionMap; + static { java.util.List actions = new ArrayList<>(); actions.addAll(Arrays.asList(new RSyntaxTextAreaEditorKit().getActions())); + + List wrongInsPairCharActionName = new ArrayList<>(); + for (ListIterator iterator = actions.listIterator(); iterator.hasNext(); ) { + Action action = iterator.next(); + if (action instanceof InsertPairedCharacterAction) { + wrongInsPairCharActionName.add(((InsertPairedCharacterAction) action).getName()); + iterator.remove(); + } + } + + List insertPairedActions = Arrays.asList( + new InsertPairedCharacterAction(rstaOpenParenAction, '(', ')'), + new InsertPairedCharacterAction(rstaOpenSquareBracketAction, '[', ']'), + new InsertPairedCharacterAction(rstaOpenCurlyAction, '{', '}'), + new InsertQuoteAction(rstaDoubleQuoteAction, InsertQuoteAction.QuoteType.DOUBLE_QUOTE) +// We should not wrap ` and ' +// new InsertQuoteAction(rstaSingleQuoteAction, RSyntaxTextAreaEditorKit.InsertQuoteAction.QuoteType.SINGLE_QUOTE), +// new InsertQuoteAction(rstaBacktickAction, RSyntaxTextAreaEditorKit.InsertQuoteAction.QuoteType.BACKTICK) + ); + + wrongInsPairCharActionName.removeAll( + insertPairedActions.stream().map(RecordableTextAction::getName).collect(Collectors.toList()) + ); + + actions.addAll(insertPairedActions); + actions.add(new CopyCutAsStyledTextAction(false)); actions.add(new CopyCutAsStyledTextAction(true)); @@ -73,6 +105,14 @@ public class RSTextAreaFactory { inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_R, defaultModifier), FindReplaceAction.replaceAction); inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), HideSearchPanelAction.action); + + for (KeyStroke ks: inputMap.allKeys() ) { + Object action = inputMap.get(ks); + if (wrongInsPairCharActionName.contains(action)) { + inputMap.remove(ks); + } + } + UIManager.put("RSyntaxTextAreaUI.inputMap", inputMap); FoldParserManager.get().addFoldParserMapping(RSTokenMaker.CONTENT_TYPE, new CurlyFoldParser()); @@ -106,6 +146,7 @@ public static StudioRSyntaxTextArea newTextArea(boolean editable) { textArea.setTabsEmulated(Config.getInstance().getBoolean(Config.EDITOR_TAB_EMULATED)); textArea.setTabSize(Config.getInstance().getInt(Config.EDITOR_TAB_SIZE)); + textArea.setInsertPairedCharacters(Config.getInstance().getBoolean(Config.RSTA_INSERT_PAIRED_CHAR)); return textArea; } @@ -158,7 +199,7 @@ public void actionPerformedImpl(ActionEvent e, RTextArea textArea) { try { textArea.getDocument().remove(selStart, selEnd - selStart); } catch (BadLocationException ex) { - System.err.println("Ups... That's not expected: " + ex); + System.err.println("Oops... That's not expected: " + ex); ex.printStackTrace(); } } diff --git a/test-integration/studio/ui/RSTAEditorTest.java b/test-integration/studio/ui/RSTAEditorTest.java new file mode 100644 index 00000000..8ab4c34f --- /dev/null +++ b/test-integration/studio/ui/RSTAEditorTest.java @@ -0,0 +1,58 @@ +package studio.ui; + +import org.assertj.swing.fixture.JTextComponentFixture; +import org.junit.Test; + +public class RSTAEditorTest extends StudioTest { + + @Test + public void testPairedChars() { + JTextComponentFixture editor = frameFixture.textBox("editor1"); + editor.enterText("`'()[]{}\""); + editor.requireText("`'()[]{}\""); + } + + @Test + public void testNotWrappedSpecChars() { + JTextComponentFixture editor = frameFixture.textBox("editor1"); + editor.enterText("select"); + editor.selectAll(); + editor.enterText("`"); + editor.requireText("`"); + + editor.deleteText(); + editor.enterText("select"); + editor.selectAll(); + editor.enterText("'"); + editor.requireText("'"); + } + + + @Test + public void testWrappedChars() { + JTextComponentFixture editor = frameFixture.textBox("editor1"); + editor.enterText("select"); + editor.selectAll(); + editor.enterText("("); + editor.requireText("(select)"); + + editor.deleteText(); + editor.enterText("select"); + editor.selectAll(); + editor.enterText("["); + editor.requireText("[select]"); + + editor.deleteText(); + editor.enterText("select"); + editor.selectAll(); + editor.enterText("{"); + editor.requireText("{select}"); + + editor.deleteText(); + editor.enterText("select"); + editor.selectAll(); + editor.enterText("\""); + editor.requireText("\"select\""); + } + +} diff --git a/test-integration/studio/ui/RSTextAreaFrameForTest.java b/test-integration/studio/ui/RSTextAreaFrameForTest.java deleted file mode 100644 index a2de98d2..00000000 --- a/test-integration/studio/ui/RSTextAreaFrameForTest.java +++ /dev/null @@ -1,37 +0,0 @@ -package studio.ui; - -import org.fife.ui.rtextarea.RTextScrollPane; -import studio.ui.rstextarea.RSTextAreaFactory; -import studio.ui.rstextarea.StudioRSyntaxTextArea; - -import javax.swing.*; -import java.awt.*; - -public class RSTextAreaFrameForTest extends JFrame { - - public RSTextAreaFrameForTest() { - super("Frame"); - setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - JPanel panel = new JPanel(new BorderLayout()); - - JTextField textField = new JTextField(50); - textField.setName("textField"); - - StudioRSyntaxTextArea textArea = RSTextAreaFactory.newTextArea(true); - textArea.setName("textArea"); - - RTextScrollPane scrollPane = new RTextScrollPane(textArea); - textArea.setGutter(scrollPane.getGutter()); - - panel.add(textField, BorderLayout.NORTH); - panel.add(scrollPane, BorderLayout.CENTER); - - setContentPane(panel); - setSize(600,400); - show(); - } - - public static void main(String[] args) throws Exception { - SwingUtilities.invokeAndWait(()->new RSTextAreaFrameForTest()); - } -} diff --git a/test-integration/studio/ui/RSTextAreaTest.java b/test-integration/studio/ui/RSTextAreaTest.java deleted file mode 100644 index 5ddef4c7..00000000 --- a/test-integration/studio/ui/RSTextAreaTest.java +++ /dev/null @@ -1,32 +0,0 @@ -package studio.ui; - -import org.assertj.swing.edt.GuiActionRunner; -import org.assertj.swing.fixture.FrameFixture; -import org.assertj.swing.fixture.JTextComponentFixture; -import org.assertj.swing.junit.testcase.AssertJSwingJUnitTestCase; -import org.junit.Test; - -public class RSTextAreaTest extends AssertJSwingJUnitTestCase { - - private FrameFixture frameFixture; - - @Override - protected void onSetUp() throws Exception { - RSTextAreaFrameForTest frame = GuiActionRunner.execute(() -> new RSTextAreaFrameForTest()); - - frameFixture = new FrameFixture(robot(), frame); - } - - @Test - public void test() { - JTextComponentFixture textField = frameFixture.textBox("textField"); - textField.requireText(""); - textField.enterText("test"); - textField.requireText("test"); - - JTextComponentFixture textArea = frameFixture.textBox("textArea"); - textArea.requireText(""); - textArea.enterText("something"); - textArea.requireText("something"); - } -}