Add writability check in initInsert() to prevent insert mode entry for read-only files. Shows dialog for temporarily read-only files(e.g., ~/ideavimrc) or blocks entry for non-writable files
Signed-off-by: NaMinhyeok <nmh9097@gmail.com>
This breaks a specific construct: `echo(42)(999)`. The `echo` command can parse multiple expressions without separating whitespace. IdeaVim now treats this example as a function call of the resul of the `(42)` expression, which is, of course, invalid. Vim evaluates expressions as it is parsing and declines to apply the `(999)` subscript because it knows the first expression is not a funcref/partial.
IdeaVim does not have this context, so cannot know that this is two expressions and not a function call.
I think it is better to support the `expr10(expr1, ...)` syntax and break this (what feels like niche) functionality than not have function calls through expression results at all.
The only change to the rules themselves is to add unary plus/minus to IntExpression and FloatExpression. This matches Vim's precedence, where the unary operator applies to numeric constants at a higher precedence than to other expressions. E.g. `-4->abs()` invokes `abs` on `-4`, while `-a->abs()` is the negative value of `abs(a)`.
The companion function `modeToMappingMode` was not used anywhere in the codebase.
The extension function `toMappingMode()` serves the same purpose and is used throughout.
Also removed unused import and extra blank line for cleaner code formatting.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
VimEditorGroupBase has been unused since its creation in April 2022. Unlike other
*Base classes in the api package (VimApplicationBase, VimMessagesBase, etc.),
VimEditorGroupBase is never extended. The actual EditorGroup implementation
directly implements the VimEditorGroup interface instead of extending this base class.
This removal cleans up dead code and reduces maintenance overhead.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
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
Adds length validation before accessing string indices and replaces unsafe
!! operator with proper null handling to prevent crashes on invalid mapleader values.
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>
Fixed three issues in IndexedExpression.kt:
1. Off-by-one error: Changed condition from `idx > text.length` to `idx >= text.length` to properly handle boundary cases when indexing strings
2. Redundant evaluation: Reused `indexValue` instead of re-evaluating `index.evaluate()` in the string indexing path
3. Variable shadowing: Renamed local variable from `index` to `indexNum` in `assignToListItem` to avoid shadowing the property
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add bounds checking to clamp line numbers to the last line of the document,
preventing potential exceptions when accessing line text with out-of-bounds
ranges like `:$+100=`. This matches the behavior of other commands like
GoToLineCommand.
Also add tests to verify the edge case behavior with and without flags.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Update copyright year to 2025 and add test coverage for edge case when
caret is at the beginning of the command line.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The SortCommand was incorrectly using editor.getSelectionModel() which
returns the editor's global selection model. This is problematic in
multi-caret scenarios where each caret has its own independent selection.
Changed to use caret.hasSelection(), caret.selectionStart, and
caret.selectionEnd directly, which correctly handles per-caret selections.
This also removes the only meaningful usage of VimEditor.getSelectionModel()
in vim-engine, making that interface a candidate for removal in future
cleanup.
Implements five new vimscript list functions:
- count(): counts occurrences of a value in a list/dict
- index(): finds first index of a value in a list
- min()/max(): finds minimum/maximum value in a list/dict
- range(): generates a list of numbers with optional stride
Includes error handling for edge cases like zero stride and invalid ranges.
Implement five commonly used vimscript functions:
- repeat(expr, count): Repeats strings or lists multiple times
- char2nr(char): Converts character to Unicode code point
- nr2char(number): Converts code point to character
- trim(text, [mask], [dir]): Trims whitespace or custom characters
- reverse(object): Reverses lists in-place or returns reversed string
All functions include comprehensive test coverage and follow vim's
official behavior including edge cases.