Skip to content

Add inline find bar as an alternative to the floating find/replace panel#1643

Open
valsong wants to merge 3 commits into
macvim-dev:masterfrom
valsong:master
Open

Add inline find bar as an alternative to the floating find/replace panel#1643
valsong wants to merge 3 commits into
macvim-dev:masterfrom
valsong:master

Conversation

@valsong
Copy link
Copy Markdown

@valsong valsong commented Apr 17, 2026

Previously, Cmd+F always opened a floating NSPanel (MMFindReplaceController). This commit introduces an optional inline find bar (MMFindBarView) that appears as a draggable overlay anchored to the top-right corner of the text area, similar to the find bar found in VS Code and other modern editors.

The inline mode is opt-in, controlled by a new "Find bar: Inline" toggle in the General preferences pane (off by default, preserving existing behaviour).

Key changes:

  • Add MMFindBarView: a programmatic NSView with find/replace fields, Ignore Case / Match Whole Word Only checkboxes, and Replace / Replace All / Previous / Next action buttons with an MMHoverButton close button styled to match the tab close button.
  • The bar is freely draggable within the text-editing area. It snaps to the top-right corner only on first show; subsequent Cmd+F presses preserve the user's last position.
  • Window resize and tab-bar visibility changes keep the bar in bounds via a delta-based repositioning algorithm in -frameSizeMayHaveChanged:.
  • Add MMFindBarInlineKey user default and register it (default NO).
  • Add "Find bar" toggle to the General preferences pane (MMPreferenceController + Preferences.xib).
  • Route ShowFindReplaceDialogMsgID to the inline bar or the floating panel based on the preference (MMVimController).
  • Consolidate find/replace dispatch into the existing -findAndReplace: IBAction in MMWindowController, selecting the data source (MMFindBarView or MMFindReplaceController) at call time; no new public methods required.
  • Add unit tests for MMFindBarView flag encoding (MacVimTests).

Default mode
3
4

Inline mode
1
2

valsong and others added 3 commits April 17, 2026 18:56
Previously, Cmd+F always opened a floating NSPanel (MMFindReplaceController).
This commit introduces an optional inline find bar (MMFindBarView) that appears
as a draggable overlay anchored to the top-right corner of the text area,
similar to the find bar found in VS Code and other modern editors.

The inline mode is opt-in, controlled by a new "Find bar: Inline" toggle in
the General preferences pane (off by default, preserving existing behaviour).

Key changes:

- Add MMFindBarView: a programmatic NSView with find/replace fields,
  Ignore Case / Match Whole Word Only checkboxes, and Replace / Replace All /
  Previous / Next action buttons with an MMHoverButton close button styled to
  match the tab close button.
- The bar is freely draggable within the text-editing area. It snaps to the
  top-right corner only on first show; subsequent Cmd+F presses preserve the
  user's last position.
- Window resize and tab-bar visibility changes keep the bar in bounds via
  a delta-based repositioning algorithm in -frameSizeMayHaveChanged:.
- Add MMFindBarInlineKey user default and register it (default NO).
- Add "Find bar" toggle to the General preferences pane
  (MMPreferenceController + Preferences.xib).
- Route ShowFindReplaceDialogMsgID to the inline bar or the floating panel
  based on the preference (MMVimController).
- Consolidate find/replace dispatch into the existing -findAndReplace: IBAction
  in MMWindowController, selecting the data source (MMFindBarView or
  MMFindReplaceController) at call time; no new public methods required.
- Add unit tests for MMFindBarView flag encoding (MacVimTests).
Previously, pressing Escape only closed the find bar when a text field
inside it had keyboard focus (handled via NSControlTextEditingDelegate).
If focus had moved back to the editor, Escape had no effect on the bar.

Install a local NSEvent monitor (NSEventMaskKeyDown) when the bar is
shown, and remove it when the bar closes or is deallocated. The monitor
intercepts keyCode 53 (Escape) app-wide and closes the bar regardless
of which view holds focus. The existing focused-field path is unchanged;
the hidden-guard in the monitor block prevents a double-close if both
paths fire for the same event.
Using `__unsafe_unretained` in an MRR block does not retain the captured
object, leaving `unsafeSelf` as a dangling pointer after `MMFindBarView`
is deallocated. When the NSEvent local monitor fires after dealloc, any
message send to `unsafeSelf` causes a SIGSEGV (access at offset 0x10).

Remove `__unsafe_unretained` and capture `self` directly. In MRR, a block
implicitly retains captured Objective-C objects, keeping `self` alive for
the lifetime of the monitor. The temporary retain cycle
(monitor block → self → _escMonitor → block) is safely broken by
`_removeEscapeMonitor` called in both `-_close:` and `-dealloc`.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@gouch
Copy link
Copy Markdown

gouch commented May 21, 2026

Cool on rethinking the Find window. But this proposal trades other project goals for a not clear improvement.

The current popup window does feel clunky. But it’s also Mac-like (the goal of MacVim). I’d say Mac has two styles of dynamic Find window: The oldish floating window used in MacVim and the iWork apps and the sleeker one used in e.g. Safari, Terminal, TextEdit where a thin banner slides down at document top.

find-banners

To me, if a Find redesign is done, then the Mac-like thin banner should be the target appearance.

Also, redesigns should be good enough to fully replace old implementations: That’s less code to maintain and less decisions to pass on to users.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants