The command() handler now receives startLine and endLine (0-based)
from the resolved ex-command range. Previously the range was received
by the internal CommandAliasHandler but discarded before reaching the
plugin lambda.
Also fix using editor.projectId instead of the VimApiImpl's own
projectId, so the handler resolves the correct editor context.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Per VIM-4144 coroutine audit: methods inside non-locking scopes
(OptionScope, DigraphScope, OutputPanelScope) should be suspend
for RemDev future-proofing. Updated interfaces, implementations,
and extension functions.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Per VIM-4144 coroutine audit: handler lambdas should be suspend
for RemDev future-proofing. Implementation uses runBlocking bridge.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Per VIM-4144 coroutine audit: handler lambdas should be suspend
for RemDev future-proofing. Implementation uses runBlocking bridge.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Per VIM-4144 coroutine audit: handler lambdas should be suspend
for RemDev future-proofing. Also exposes command() at init time.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Per VIM-4144 coroutine audit: handler lambdas should be suspend
for RemDev future-proofing. Implementation uses runBlocking bridge.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove enterInsertMode(), enterNormalMode(), enterVisualMode() from VimApi.
Mode changes should use normal() — e.g., normal("<Esc>"), normal("i"),
normal("v") — matching how real Vim plugins handle mode transitions.
Neither Vim nor Neovim has a direct "set mode" API. All mode changes in
real plugins (surround, exchange, commentary, ReplaceWithRegister) use
normal!, feedkeys(), or :stopinsert. The removed methods used incomplete
internal delegation (changeMode Level 2) that skipped proper entry/exit
setup (marks, strokes, dot-repeat, document listeners).
Also removes the now-unused changeMode() function from Modes.kt.
See VIM-4143 for future proper mode-changing API design.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
After setAsCurrentWindow(), getSelectedTextEditor() returns stale data
because the platform propagates the change asynchronously via
flatMapLatest + stateIn, and there is no way to observe when
propagation completes.
Comment out window APIs in VimApi, VimApiImpl, CaretRead, CaretReadImpl.
Add limitation comment to VimWindowGroup. Update EditorContextTest to
call injector.window directly. Track re-enablement in VIM-4138.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Introduce VimInitApi as a restricted wrapper around VimApi that exposes
only init-safe methods (getVariable, mappings, textObjects,
exportOperatorFunction). During plugin init() there is no editor context,
so editor operations should not be callable. VimInitApi enforces this at
the type level via delegation rather than inheritance.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use FileEditorManager's selected editor (internal model) instead of
focus-based detection. Falls back to injector.fallbackWindow when
projectId is null (init phase, project loading).
- Add getSelectedEditor(projectId) to VimEditorGroup interface
- Implement in EditorGroup.java using FileEditorManager
- Convert all thinapi scope impls from objects to classes accepting projectId
- Fix exportOperatorFunction to use execution-time editor.projectId
instead of init-time captured null
- Update all thinapi mock tests to mock fallbackWindow and restore
injector before tearDown
- Update CaretTransactionTest to use real projectId
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add projectId to VimApiImpl and propagate through scope implementations.
This is a pre-refactoring step before switching from getFocusedEditor()
to getSelectedEditor() API.
- VimApiImpl: Add projectId parameter (nullable), with KDoc explaining
that it's null during init and falls back to fallback editor
- Scope implementations: Pass projectId through construction chain
- MappingScopeImpl, TextObjectScopeImpl: Get projectId from editor
at execution time via editor.projectId
- Tests: Pass null for projectId (no editor context in setup)
- Remove VimApi.kt extension function (no longer needed)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The caret can legitimately be at position chars.length (end-of-file), which is valid in IntelliJ but not a valid character index. findBlock and getQuoteRangeNoPSI assumed the caret was always on a character, causing a crash when text objects like a) were used at EOF.
Return null early when pos is out of character index range, since there is no block or quote to match at that position.
Formatting was broken in split mode and also in monolith mode cursor position restoring didn't match vim actual behaviour. refactored it to work in same way as commenting works
Add focusNew parameter to splitWindow to allow NERDTree preview
mappings (gs, gi, ga) to keep focus on the tree.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Use this.javaClass.classLoader instead of object {}.javaClass.classLoader
- Alphabetize imports in VimInjector.kt
- Remove outdated TODO in VimMotionGroupBase.kt
- Fix missing trailing newline in VimPsiService.kt
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The field was used to break out of the mapping replay loop when max
recursion depth was hit. This is unnecessary since handleKey already
returns early on max depth, stopping further processing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>