- Updated `integrationsTest` script to accept project directory as an argument.
- Modified `build.gradle.kts` to pass project root directory to the `integrationsTest` task.
- Improved flexibility and reusability by allowing dynamic project directory input.
- Removed all YouTrack-related helper functions from `build.gradle.kts`.
- Simplified the build script by eliminating unused code and redundant tasks.
- Improved maintainability by reducing script complexity.
- Moved `integrationsTest` logic from `build.gradle.kts` to `scripts/integrationsTest.kt`.
- Registered `integrationsTest` as a `JavaExec` task in `scripts/build.gradle.kts`.
- Improved modularity by isolating test logic into a dedicated script.
- Simplified task structure and maintained existing functionality.
- Extracted `releaseActions` logic from `build.gradle.kts` into `scripts/releaseActions.kt`.
- Registered `releaseActions` as a `JavaExec` task in `scripts/build.gradle.kts`.
- Added helper functions for YouTrack version management (`addReleaseToYoutrack`, `getVersionIdByName`, `setYoutrackFixVersion`, etc.).
- Simplified coroutine usage and modularized task logic for maintainability.
- Extracted `updateChangelog` functionality from `build.gradle.kts` into `scripts/updateChangelog.kt`.
- Registered `updateChangelog` as a `JavaExec` task in `scripts/build.gradle.kts`.
- Improved modularity and reusability by isolating changelog update logic.
- Consolidated shared changelog utilities in `scripts/changelogUtils.kt`.
- Extracted `updateMergedPr` logic from `build.gradle.kts` into `scripts/updateMergedPr.kt`.
- Registered `updateMergedPr` as a `JavaExec` task in `scripts/build.gradle.kts`.
- Improved modularity and reusability by moving update logic to a dedicated script.
- Updated task to accept arguments for `prId` and project directory.
- Extracted `updateAuthors` logic from `build.gradle.kts` into `scripts/updateAuthors.kt`.
- Registered `updateAuthors` as a `JavaExec` task in `scripts/build.gradle.kts`.
- Updated dependencies to include required libraries (`github-api` and `markdown`).
- Improved modularity and reusability of the `updateAuthors` implementation.
- Moved `slackNotification` logic from `build.gradle.kts` to `scripts/slackNotification.kt`.
- Refactored notification handling for better modularity and reusability.
- Added task registration in `scripts/build.gradle.kts` to execute the standalone script.
- Updated dependencies to include `mark-down-to-slack` for Slack message formatting.
- Replaced `updateYoutrackOnCommit` function in build script with a dedicated Kotlin `main()` entry point.
- Simplified task registration with `JavaExec` in `scripts/build.gradle.kts`.
- Integrated argument support for specifying project directory.
- Removed duplicate and redundant code for Change processing.
- Adjusted GitHub workflow to use the new task structure.
The skill was too passive and didn't guide me to find documentation issues
proactively. Updated based on the MappingScope documentation sync experience.
Key improvements:
- Add "Phase 0: Pre-Analysis Search" to find red flags before deep reading
- Establish "ground truth" from working implementations first
- Change mindset from "be conservative" to "be aggressive finding issues"
- Add explicit checklist for verifying each code example
- Emphasize checking what was REMOVED (deletions matter more than additions)
- Add step-by-step workflow with git history checks
- Include "Key Lessons Learned" section with critical insights
The skill now prioritizes finding working code as ground truth and assumes
documentation is outdated after code changes, rather than assuming it's
correct until proven otherwise.
The documentation was showing incorrect function signatures with non-existent
parameters (keys, label, isRepeatable) and not following the 2-step <Plug>
mapping pattern established in d288a52ef.
Changes:
- Remove non-existent parameters from all mapping examples
- Update all examples to use the correct 2-step pattern:
1. nnoremap("<Plug>...") for non-recursive <Plug> → action mappings
2. nmap("key", "<Plug>...") for recursive key → <Plug> mappings
- Add explanation of the 2-step pattern and its benefits in the tutorial
- Remove non-existent shortPath parameter from @VimPlugin annotation
This ensures documentation matches the actual MappingScope API and teaches
users the best practice pattern for creating mappings that can be overridden
in .ideavimrc.
Create a new agent skill that keeps IdeaVim documentation in sync with code
changes. The skill can work bidirectionally:
- Mode A: Verify documentation matches current code
- Mode B: Update documentation after code changes
Features:
- Checks doc/, README.md, and CONTRIBUTING.md
- Conservative updates (only when truly needed)
- Identifies API changes, renamed functions, behavior changes
- Provides structured reports of findings and updates
The skill follows proper formatting with YAML frontmatter and is located
in .claude/skills/doc-sync/SKILL.md as per Claude Code conventions.
Implement mode-specific hasmapto functions following the MappingScope style:
- hasmapto() - checks nvo modes
- nhasmapto() - checks normal mode
- vhasmapto() - checks visual mode
- xhasmapto() - checks visual exclusive mode
- shasmapto() - checks select mode
- ohasmapto() - checks operator pending mode
- ihasmapto() - checks insert mode
- chasmapto() - checks command line mode
These functions check if any mapping exists that maps TO the given string,
which is essential for plugins to detect if users have already mapped to
their <Plug> mappings. This enables the common pattern: "only create default
key mapping if user hasn't already mapped to the <Plug> mapping".
Implementation delegates to VimKeyGroup.hasmapto().
The map/noremap/unmap functions should only affect Normal, Visual, Select,
and Operator-pending modes (nvo), not all modes including Insert and
Command-line. This matches Vim's behavior where :map affects nvo modes only.
Changed from MappingMode.ALL to MappingMode.NVO.
Group mapping functions by mode instead of by operation type for better
organization and readability. Each mode group now contains:
- Recursive mapping (map variants)
- Non-recursive mapping (noremap variants)
- Unmap function
Order: map, nmap, vmap, xmap, smap, omap, imap, cmap
This makes the API more discoverable and easier to navigate.
The 3-argument mapping functions (e.g., nmap(keys, actionName, action)) had
incorrect implementation that used recursive mappings for both sub-mappings.
Also, this approach makes it impossible to implement other mapping features
such as skipping mapping registration if the mapping is already defined in
.ideavimrc.
A different solution for convenient mapping patterns will be implemented later.
Changes:
- Remove 16 three-argument function declarations from MappingScope interface
- Remove 16 three-argument function implementations from MappingScopeImpl
- Update ReplaceWithRegister plugins to use correct 2-step pattern:
1. nnoremap("<Plug>...") for non-recursive <Plug> → action
2. nmap("key", "<Plug>...") for recursive key → <Plug>
Total: 374 lines deleted, 18 lines added
The project switching and version control menus in the top-left corner remain unavailable due to accessibility issues (failure to implement the Accessible interface, specifically) with the ToolbarComboButton component in the IntelliJ platform.
Fixes wrong recorded inputs when code completion introduces an import.
Fixes wrong recorded inputs when completing a static member with a partial type name. Example: `WiE.A` -> `WindowEvent.ACTION_EVENT_MASK`
Co-authored-by: Alex Plãte <aleksei.plate@jetbrains.com>
Replace unsafe non-null assertions (!!) with explicit null checks that provide
meaningful error messages when fold regions are not found. This makes test
failures easier to debug by clearly indicating what was expected.
Changes:
- ChangeActionJavaTest: Fixed 4 instances in testInsertAfterToggleFold and testInsertBeforeFold
- VisualInsertActionJavaTest: Fixed 1 instance in test block insert after folds
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Remove duplicate empty dictionary test (already covered at line 28)
- Rename 'test len with zero' to 'test len with zero number' for clarity
- Rename 'test len with negative number' to 'test len with negative numbers' (plural)
Co-authored-by: Alex Plãte <AlexPl292@users.noreply.github.com>
What was inspected:
- LenFunctionTest.kt and its corresponding implementation LenFunctionHandler.kt
Issues found:
- Test coverage was limited to basic happy path scenarios
- Missing tests for important edge cases: empty strings, zero, negative numbers,
large numbers, empty collections, and special character handling
- No tests distinguishing between single-quoted and double-quoted string behavior
in Vimscript
Changes made:
- Added 9 new test methods covering:
* Empty strings (both single and double quoted)
* Empty lists and dictionaries
* Zero and negative numbers
* Large numbers
* Multi-element collections
* Strings with escape sequences (documenting Vim's single vs double quote behavior)
Why this improves the code:
- Ensures len() function handles all data type edge cases correctly
- Documents expected behavior for Vimscript string quoting conventions
- Provides regression protection against future changes
- Aligns with testing best practices by covering boundary conditions
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Adds a test to verify that when using 'idearefactormode=visual' with
inclusive selection (default), the caret is correctly positioned at the
inclusive end of the selection (on the last character) rather than the
exclusive end (after the last character).
This test covers the caret adjustment logic in IdeaSpecifics.kt that
moves the caret from IntelliJ's exclusive end position to Vim's
inclusive end position for Visual mode when 'selection' doesn't contain
"exclusive".
Adds length validation before accessing string indices and replaces unsafe
!! operator with proper null handling to prevent crashes on invalid mapleader values.
The 'idearefactormode' default of Select would leave an inline rename in Insert mode, and hitting Escape to return to Normal frequently cancelled the rename.
Also fixes various edge cases when moving between template variables. Often, this works due to a change in selection, but if there's an empty template variable and no current selection, there's no change in selection, and the mode isn't updated.
In clearStatusBarMessage(), the mutable 'message' property was being
accessed multiple times without capturing it in a local variable. This
could theoretically cause issues if the property changed between the
null check and the usage. Additionally, calling toString() on a String
is redundant and creates an unnecessary allocation.
Fixed by capturing the message in a local variable at the start of the
method, which allows Kotlin's smart cast to work properly and removes
the need for the redundant toString() call.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added bounds checking to EndOfLineMatcher and StartOfLineMatcher to
prevent potential IndexOutOfBoundsException when index is outside the
valid text range. This follows the defensive programming pattern used
in other matchers like CharacterMatcher, DotMatcher, StartOfWordMatcher,
and EndOfWordMatcher.
Changes:
- EndOfLineMatcher: Added check for index > length before array access
- StartOfLineMatcher: Added check for index < 0 or index > length
While the NFA engine should prevent invalid indices, these defensive
checks improve code safety and consistency across all matcher
implementations.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added a new bullet point under the Testing section that instructs
maintainers to write regression tests when fixing bugs. These tests
should:
- Fail with the buggy implementation
- Pass with the fix
- Document what bug they're testing
- Test the specific boundary condition that exposed the bug
This ensures bugs don't resurface during future refactorings and
provides clear documentation of the expected behavior.
Co-authored-by: Alex Plãte <AlexPl292@users.noreply.github.com>
This test validates the off-by-one error fix in IndexedExpression.kt:56.
When accessing a string at index equal to its length, the code should
return an empty string rather than throwing IndexOutOfBoundsException.
The old condition (idx > text.length) would allow idx == text.length to
pass through, causing an exception. The new condition (idx >= text.length)
correctly treats this as out of bounds.
Test case: 'hello'[5] should return '' since 'hello'.length == 5
Co-authored-by: Alex Plãte <AlexPl292@users.noreply.github.com>