Skip to content

Wrap selection in a field into brackets when a bracket is inserted#15442

Merged
calixtus merged 9 commits into
JabRef:mainfrom
InAnYan:feat/bracket-wrap
Apr 5, 2026
Merged

Wrap selection in a field into brackets when a bracket is inserted#15442
calixtus merged 9 commits into
JabRef:mainfrom
InAnYan:feat/bracket-wrap

Conversation

@InAnYan

@InAnYan InAnYan commented Mar 29, 2026

Copy link
Copy Markdown
Member

Related issues and pull requests

Closes https://github.com/JabRef/jabref-issue-melting-pot/issues/1106

PR Description

When user selects a text and types '{' the selection will be wrapped in '{' and '}'. This is a shorthand for "Protect terms" feature, and similar to how code editors do with other types of brackets.

I think this will be useful. It is done by intercepting the key press event.

Right now I have not added a CHANGELOG.md entry. Will add it soon.
UPD: Added. Ready for review.

Steps to test

  1. Open JabRef and some library and go to some entry.
  2. Click on a field and type some text.
  3. Select a word in a text and type '{'.

Result: the selected word is wrapped in '{' and '}'.

2026-03-29.20-07-35.mp4

Checklist

  • I own the copyright of the code submitted and I license it under the MIT license
  • I manually tested my changes in running JabRef (always required)
  • I added JUnit tests for changes (if applicable)
  • I added screenshots in the PR description (if change is visible to the user)
  • I added a screenshot in the PR description showing a library with a single entry with me as author and as title the issue number
  • I described the change in CHANGELOG.md in a way that can be understood by the average user (if change is visible to the user)
  • I checked the user documentation for up to dateness and submitted a pull request to our user documentation repository

@InAnYan InAnYan marked this pull request as ready for review March 29, 2026 18:19
@qodo-free-for-open-source-projects

Copy link
Copy Markdown
Contributor

Review Summary by Qodo

Add bracket wrapping shorthand for protecting field terms

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Add bracket wrapping shorthand for protecting terms in fields
• When user selects text and types '{', selection wraps in brackets
• Implement via KeyEvent filter in FieldEditorFX component
• Include comprehensive unit tests and changelog documentation
Diagram
flowchart LR
  A["User selects text in field"] -- "types '{'" --> B["KeyEvent filter intercepts"]
  B -- "selection exists" --> C["Wrap text in brackets"]
  B -- "no selection" --> D["Insert '{' normally"]
  C --> E["Display wrapped text"]
  D --> E
Loading

Grey Divider

File Changes

1. jabgui/src/main/java/org/jabref/gui/fieldeditors/FieldEditorFX.java ✨ Enhancement +10/-0

Implement bracket wrapping for selected text

• Add KeyEvent filter to intercept '{' character input
• Check if text is selected when '{' is typed
• Wrap selected text with opening and closing braces
• Consume event to prevent default character insertion

jabgui/src/main/java/org/jabref/gui/fieldeditors/FieldEditorFX.java


2. jabgui/src/test/java/org/jabref/gui/fieldeditors/FieldEditorFXTest.java 🧪 Tests +76/-0

Add unit tests for bracket wrapping feature

• Create new test class extending ApplicationTest for GUI testing
• Test wrapping behavior when '{' typed with active selection
• Test normal insertion when '{' typed without selection
• Use TestFX framework for interactive field testing

jabgui/src/test/java/org/jabref/gui/fieldeditors/FieldEditorFXTest.java


3. CHANGELOG.md 📝 Documentation +1/-0

Document bracket wrapping feature in changelog

• Add entry documenting the new bracket wrapping shorthand feature
• Describe functionality as quick way to protect terms in fields
• Reference PR #15442 for tracking

CHANGELOG.md


Grey Divider

Qodo Logo

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Mar 29, 2026

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (1) 📎 Requirement gaps (0) 🎨 UX Issues (0)

Grey Divider


Action required

1. Whitespace not preserved in wrap 🐞 Bug ≡ Correctness
Description
FieldEditorFX.establishBinding wraps the entire selected text including leading/trailing spaces when
'{' is typed, which differs from the existing “Protect selection” action that keeps surrounding
spaces outside the braces. This causes unexpected field-content changes for common selections like "
world " and contradicts the in-code claim of equivalence.
Code

jabgui/src/main/java/org/jabref/gui/fieldeditors/FieldEditorFX.java[R49-57]

+        // When '{' is typed with an active selection, wrap the selected text in '{…}' instead of replacing it.
+        // This is equivalent to the "Protect terms" option in the context menu.
+        textInputControl.addEventFilter(KeyEvent.KEY_TYPED, e -> {
+            if ("{".equals(e.getCharacter()) && textInputControl.getSelection().getLength() > 0) {
+                String selectedText = textInputControl.getSelectedText();
+                textInputControl.replaceSelection("{" + selectedText + "}");
+                e.consume();
+            }
+        });
Evidence
The new key-typed handler always does "{" + selectedText + "}", so any leading/trailing whitespace
becomes protected inside braces. The existing UI command “Protect selection” has explicit logic to
move leading/trailing spaces outside braces and to strip the wrapped term, showing that whitespace
handling is intended/important and that the new handler is not equivalent.

jabgui/src/main/java/org/jabref/gui/fieldeditors/FieldEditorFX.java[49-57]
jabgui/src/main/java/org/jabref/gui/fieldeditors/contextmenu/ProtectedTermsMenu.java[60-79]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Typing `{` with an active selection currently wraps the *entire* selection, including leading/trailing spaces. This differs from the existing **Protect selection** behavior, which keeps surrounding spaces outside the braces and wraps the stripped term.
### Issue Context
`FieldEditorFX.establishBinding` claims the behavior is equivalent to the context menu “Protect terms”, but `ProtectedTermsMenu.ProtectSelectionAction` has special whitespace handling.
### Fix Focus Areas
- jabgui/src/main/java/org/jabref/gui/fieldeditors/FieldEditorFX.java[49-57]
- jabgui/src/main/java/org/jabref/gui/fieldeditors/contextmenu/ProtectedTermsMenu.java[60-79]
### Implementation notes
Replicate the `ProtectSelectionAction` logic in the key handler:
- compute `firstStr`/`lastStr` based on `selectedText.startsWith(" ")` and `selectedText.endsWith(" ")`
- wrap `selectedText.strip()`
- (optionally) adjust the comment to state the precise equivalence

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Comments restate brace wrapping 📘 Rule violation ⚙ Maintainability
Description
The newly added comments primarily describe what the code does rather than explaining
rationale/intent, making them trivial and adding noise. This violates the requirement that comments
should explain 'why' instead of restating obvious behavior.
Code

jabgui/src/main/java/org/jabref/gui/fieldeditors/FieldEditorFX.java[R49-50]

+        // When '{' is typed with an active selection, wrap the selected text in '{…}' instead of replacing it.
+        // This is equivalent to the "Protect terms" option in the context menu.
Evidence
PR Compliance ID 17 forbids trivial comments that merely describe code behavior; the added `// When
'{' is typed...` comment restates the immediately following event-filter logic instead of providing
rationale.

AGENTS.md
jabgui/src/main/java/org/jabref/gui/fieldeditors/FieldEditorFX.java[49-55]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
New comments describe what the code does (wrapping selection on `{` key typed) instead of explaining the rationale/intent, which is discouraged by the project's comment guidelines.
## Issue Context
The behavior is already clear from the event filter code; comments should focus on why this interception is needed (e.g., UX parity with "Protect terms", preventing replacement of selection), not restate the obvious.
## Fix Focus Areas
- jabgui/src/main/java/org/jabref/gui/fieldeditors/FieldEditorFX.java[49-55]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Missing whitespace wrap tests🐞 Bug ⚙ Maintainability
Description
FieldEditorFXTest only tests wrapping a selection without surrounding spaces, despite whitespace
being a documented special case in the existing “Protect selection” implementation. This leaves the
most likely behavior mismatch untested and allows regressions after fixing the whitespace behavior.
Code

jabgui/src/test/java/org/jabref/gui/fieldeditors/FieldEditorFXTest.java[R50-74]

+    @Test
+    void openingBraceWrapsSelectedText() {
+        interact(() -> {
+            textField.setText("hello world");
+            textField.selectRange(6, 11);
+            textField.fireEvent(new KeyEvent(
+                    textField, textField, KeyEvent.KEY_TYPED, "{", "{", KeyCode.UNDEFINED,
+                    false, false, false, false));
+        });
+
+        assertEquals("hello {world}", textField.getText());
+    }
+
+    @Test
+    void openingBraceWithoutSelectionInsertsNormally() {
+        interact(() -> {
+            textField.setText("hello");
+            textField.positionCaret(5);
+            textField.fireEvent(new KeyEvent(
+                    textField, textField, KeyEvent.KEY_TYPED, "{", "{", KeyCode.UNDEFINED,
+                    false, false, false, false));
+        });
+
+        assertEquals("hello{", textField.getText());
+    }
Evidence
The test covers only selecting "world" and typing '{'. The existing ProtectSelectionAction
explicitly handles leading/trailing spaces, implying this edge case should be verified for the new
shortcut too.

jabgui/src/test/java/org/jabref/gui/fieldeditors/FieldEditorFXTest.java[50-74]
jabgui/src/main/java/org/jabref/gui/fieldeditors/contextmenu/ProtectedTermsMenu.java[67-78]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new tests don’t cover selections with leading and/or trailing spaces, which is a known special case for brace-protection behavior.
### Issue Context
`ProtectedTermsMenu.ProtectSelectionAction` adjusts braces/spacing when selection starts/ends with spaces.
### Fix Focus Areas
- jabgui/src/test/java/org/jabref/gui/fieldeditors/FieldEditorFXTest.java[50-74]
### Test cases to add
Add 2–3 tests such as:
- selection includes leading space: "hello world" select " world" -> expect "hello {world}" or "hello {world}" with space preserved outside depending on intended behavior
- selection includes trailing space: "hello world" select "world " -> expect "hello {world} "
- selection includes both: select " world " -> expect "hello {world} "
(Align expected strings with the corrected implementation that matches ProtectSelectionAction.)

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

@testlens-app

testlens-app Bot commented Mar 29, 2026

Copy link
Copy Markdown

✅ All tests passed ✅

🏷️ Commit: 390a5d4
▶️ Tests: 10212 executed
⚪️ Checks: 96/96 completed


Learn more about TestLens at testlens.app.

@koppor koppor added status: ready-for-review Pull Requests that are ready to be reviewed by the maintainers and removed status: no-bot-comments labels Mar 29, 2026
subhramit
subhramit previously approved these changes Mar 30, 2026

@subhramit subhramit left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🏄🏻

@Siedlerchr Siedlerchr self-requested a review March 30, 2026 07:52
@Siedlerchr

Copy link
Copy Markdown
Member

Will chekc this later on mac

calixtus
calixtus previously approved these changes Mar 31, 2026

@calixtus calixtus left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@calixtus

Copy link
Copy Markdown
Member

Will chekc this later on mac

So, did it work?

@calixtus

calixtus commented Apr 3, 2026

Copy link
Copy Markdown
Member

As @Siedlerchr is not complaining, I guess it is good now. If not, can always be reverted and reopened.
But just to keep on moving forward here, ill put this on merge queue.

@calixtus calixtus added this pull request to the merge queue Apr 3, 2026
@github-actions github-actions Bot added the status: to-be-merged PRs which are accepted and should go into the merge-queue. label Apr 3, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Apr 3, 2026
@calixtus calixtus removed the request for review from Siedlerchr April 3, 2026 20:18
@calixtus calixtus enabled auto-merge April 3, 2026 20:22
@github-actions github-actions Bot added status: changes-required Pull requests that are not yet complete and removed status: ready-for-review Pull Requests that are ready to be reviewed by the maintainers labels Apr 3, 2026
@InAnYan

InAnYan commented Apr 4, 2026

Copy link
Copy Markdown
Member Author

I'll look into the failing check

@calixtus

calixtus commented Apr 4, 2026

Copy link
Copy Markdown
Member

This looks like an interesting challenge: Inbalanced brackets in user can now select a text and type a '{' to quickly wrap the selection in brackets.

Quickfix: Just write "opening curly braces" or something insted of {.
Perfect solution: Alter linter logic

Maybe just settle for quickfix, dont believe its worth to put more time into this.

@github-actions

github-actions Bot commented Apr 5, 2026

Copy link
Copy Markdown
Contributor

Your pull request conflicts with the target branch.

Please merge with your code. For a step-by-step guide to resolve merge conflicts, see https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/addressing-merge-conflicts/resolving-a-merge-conflict-using-the-command-line.

@github-actions github-actions Bot added status: no-bot-comments and removed status: changes-required Pull requests that are not yet complete labels Apr 5, 2026
@InAnYan InAnYan self-assigned this Apr 5, 2026
@calixtus calixtus added this pull request to the merge queue Apr 5, 2026
Merged via the queue into JabRef:main with commit 5f3b65e Apr 5, 2026
53 checks passed
@InAnYan InAnYan deleted the feat/bracket-wrap branch April 15, 2026 14:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status: no-bot-comments status: to-be-merged PRs which are accepted and should go into the merge-queue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants