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.
Surprisingly Float is converted to String, and then concatenated. But this is only supported for the binary concatenation operator, not the compound assignment concatenation operator. This lead to improved validation and behaviour closer to Vim.