Feature/vim repeat #1

Merged
lohhiiccc merged 6 commits from feature/vim-repeat into main 2025-08-19 09:21:53 +00:00
4 changed files with 88 additions and 30 deletions

View file

@ -13,6 +13,7 @@ A simple Vim plugin that lets you insert single characters without leaving norma
- Stay in normal mode for efficient editing - Stay in normal mode for efficient editing
- Minimal workflow interruption - Minimal workflow interruption
- Works with Vim 9+ - Works with Vim 9+
- **Supports [`vim-repeat`](https://github.com/tpope/vim-repeat) for `.` repeat functionality**
## Installation ## Installation
@ -26,6 +27,16 @@ cp -r vim-singlechar ~/.vim/pack/plugins/start/
cd - cd -
``` ```
### Optional: Install [vim-repeat](https://github.com/tpope/vim-repeat)
For seamless repeat (`.`) support, install [vim-repeat](https://github.com/tpope/vim-repeat):
```bash
mkdir -p ~/.vim/pack/tpope/start
cd ~/.vim/pack/tpope/start
git clone https://tpope.io/vim/repeat.git
```
## Usage ## Usage
By default, the plugin provides two mappings: By default, the plugin provides two mappings:
@ -42,6 +53,10 @@ You can use a count before the mapping to insert the character multiple times:
- `3<Leader>i,` will insert three commas at the cursor position - `3<Leader>i,` will insert three commas at the cursor position
- `5<Leader>a.` will insert five periods after the cursor position - `5<Leader>a.` will insert five periods after the cursor position
### Repeat last insert with `.`
If [vim-repeat](https://github.com/tpope/vim-repeat) is installed, you can repeat the last character insertion with `.` in normal mode.
## Configuration ## Configuration
You can customize the plugin by setting these variables in your vimrc: You can customize the plugin by setting these variables in your vimrc:

43
autoload/singlechar.vim Normal file
View file

@ -0,0 +1,43 @@
vim9script noclear
# Function to handle character insertion
# Parameters:
# mode: 'at' to insert before cursor, 'after' to insert after cursor
# count: number of times to repeat the character
# pkey: character to insert (optional)
export def InsertChar(mode: string, count: number, pkey: string = ''): void
var key = pkey
if pkey == ''
echo g:singlechar_prompt
redraw
# Get character from user
var char = getchar()
key = nr2char(char)
endif
if key ==# "\<Esc>"
return
endif
# Determine whether to insert before (i) or after (a) cursor
var cmd = (mode ==# 'at') ? 'i' : 'a'
var text = repeat(key, count)
execute 'normal! ' .. cmd .. text .. "\<Esc>"
#save
g:last_singlechar_key = key
g:last_singlechar_mode = mode
g:last_singlechar_count = count
#set vim-repeat
#if exists('*repeat#set')
legacy silent! call repeat#set("\<Plug>(singlechar-repeat)")
#endif
enddef
def g:RepeatSingleChar(): void
if g:last_singlechar_key != ''
call InsertChar(g:last_singlechar_mode, g:last_singlechar_count, g:last_singlechar_key)
endif
enddef

View file

@ -34,6 +34,7 @@ REQUIREMENTS *singlechar-requiremen
- Vim 9.0 or newer - Vim 9.0 or newer
- Vim compiled with `+eval` feature - Vim compiled with `+eval` feature
- [vim-repeat](https://github.com/tpope/vim-repeat/) (optional, for dot-repeat support)
=============================================================================== ===============================================================================
INSTALLATION *singlechar-installation* INSTALLATION *singlechar-installation*
@ -43,6 +44,13 @@ Manual installation: >
mkdir -p ~/.vim/pack/plugins/start/ mkdir -p ~/.vim/pack/plugins/start/
cp -r vim-singlechar ~/.vim/pack/plugins/start/ cp -r vim-singlechar ~/.vim/pack/plugins/start/
< <
To enable dot-repeat (`.`) for character insertions, install vim-repeat: >
mkdir -p ~/.vim/pack/tpope/start
cd ~/.vim/pack/tpope/start
git clone https://tpope.io/vim/repeat.git
<
=============================================================================== ===============================================================================
USAGE *singlechar-usage* USAGE *singlechar-usage*
@ -60,6 +68,12 @@ You can use a count before the mapping to insert the character multiple times: >
5<Leader>i- " Insert 5 hyphens at cursor position 5<Leader>i- " Insert 5 hyphens at cursor position
3<Leader>a. " Insert 3 periods after cursor position 3<Leader>a. " Insert 3 periods after cursor position
< <
Dot-repeat support (`.`):
If [vim-repeat](https://github.com/tpope/vim-repeat/) is installed,
you can use the `.` key to repeat the last single character insertion (with count and position).
=============================================================================== ===============================================================================
COMMANDS *singlechar-commands* COMMANDS *singlechar-commands*
@ -110,10 +124,15 @@ Adding multiple periods: >
Action: Position cursor at the end, press 3<Leader>a. Action: Position cursor at the end, press 3<Leader>a.
After: Some text... After: Some text...
< <
Dot-repeat: >
Action: Press <Leader>i? to insert a question mark, then press . to repeat the insertion at the next location.
<
=============================================================================== ===============================================================================
TIPS & TRICKS *singlechar-tips* TIPS & TRICKS *singlechar-tips*
- The plugin works well with Vim's macro recording feature - The plugin works well with Vim's macro recording feature
- For fast repetitive edits, use dot-repeat (`.`) if vim-repeat is installed
=============================================================================== ===============================================================================
LICENSE *singlechar-license* LICENSE *singlechar-license*

View file

@ -1,4 +1,5 @@
vim9script noclear vim9script noclear
import autoload 'singlechar.vim'
# ------------------------------------------------------------------------------ # # ------------------------------------------------------------------------------ #
# singlechar.vim - Insert single characters without entering insert mode # singlechar.vim - Insert single characters without entering insert mode
# Author: lohhiiccc # Author: lohhiiccc
@ -17,8 +18,8 @@ if exists('g:loaded_singlechar') || &cp || v:version < 900
endif endif
g:loaded_singlechar = 1 g:loaded_singlechar = 1
# ------------------------------------------------------------------------------ # # ------------------------------------------------------------------------------ #
# Configuration options # Configuration options
# Mapping to insert a character at cursor position (before cursor) # Mapping to insert a character at cursor position (before cursor)
if !exists('g:singlechar_map_insert_at') if !exists('g:singlechar_map_insert_at')
g:singlechar_map_insert_at = '<Leader>i' g:singlechar_map_insert_at = '<Leader>i'
@ -35,37 +36,18 @@ if !exists('g:singlechar_prompt')
endif endif
# ------------------------------------------------------------------------------ # # ------------------------------------------------------------------------------ #
# Core functionality #
g:last_singlechar_key = ''
# Function to handle character insertion g:last_singlechar_mode = ''
# Parameters: g:last_singlechar_count = 1
# mode: 'at' to insert before cursor, 'after' to insert after cursor #
# count: number of times to repeat the character
def InsertChar(mode: string, count: number): void
echo g:singlechar_prompt
# Get character from user
var char = getchar()
var key = nr2char(char)
redraw
if key ==# "\<Esc>"
return
endif
# Determine whether to insert before (i) or after (a) cursor
var cmd = (mode ==# 'at') ? 'i' : 'a'
var text = repeat(key, count)
execute 'normal! ' .. cmd .. text .. "\<Esc>"
enddef
# ------------------------------------------------------------------------------ # # ------------------------------------------------------------------------------ #
# Commands and mappings # Mappings <Plug>
nnoremap <Plug>(singlechar-repeat) :call g:RepeatSingleChar()<CR>
# Direct command implementations # Direct command implementations
command! -count=1 -nargs=0 InsertCharAt InsertChar('at', <count>) command! -count=1 -nargs=0 InsertCharAt singlechar.InsertChar('at', <count>)
command! -count=1 -nargs=0 InsertCharAfter InsertChar('after', <count>) command! -count=1 -nargs=0 InsertCharAfter singlechar.InsertChar('after', <count>)
# Create default mappings unless disabled # Create default mappings unless disabled
if !exists('g:singlechar_no_mappings') if !exists('g:singlechar_no_mappings')
@ -73,7 +55,6 @@ if !exists('g:singlechar_no_mappings')
execute 'nnoremap <expr> <silent> ' .. g:singlechar_map_insert_after .. ' ":<C-u>InsertCharAfter " .. v:count1 .. "<CR>"' execute 'nnoremap <expr> <silent> ' .. g:singlechar_map_insert_after .. ' ":<C-u>InsertCharAfter " .. v:count1 .. "<CR>"'
endif endif
# Usage: # Usage:
# <Leader>i - Insert character at cursor position # <Leader>i - Insert character at cursor position
# <Leader>a - Insert character after cursor position # <Leader>a - Insert character after cursor position