diff --git a/README.md b/README.md index f9f31f2..f0795d4 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ A simple Vim plugin that lets you insert single characters without leaving norma - Stay in normal mode for efficient editing - Minimal workflow interruption - Works with Vim 9+ +- **Supports [`vim-repeat`](https://github.com/tpope/vim-repeat) for `.` repeat functionality** ## Installation @@ -26,6 +27,16 @@ cp -r vim-singlechar ~/.vim/pack/plugins/start/ 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 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: - `3i,` will insert three commas at the cursor position - `5a.` 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 You can customize the plugin by setting these variables in your vimrc: diff --git a/autoload/singlechar.vim b/autoload/singlechar.vim new file mode 100644 index 0000000..f14370e --- /dev/null +++ b/autoload/singlechar.vim @@ -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 ==# "\" + 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 .. "\" + #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("\(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 diff --git a/doc/singlechar.txt b/doc/singlechar.txt index ca88bb4..17b0258 100644 --- a/doc/singlechar.txt +++ b/doc/singlechar.txt @@ -34,6 +34,7 @@ REQUIREMENTS *singlechar-requiremen - Vim 9.0 or newer - Vim compiled with `+eval` feature +- [vim-repeat](https://github.com/tpope/vim-repeat/) (optional, for dot-repeat support) =============================================================================== INSTALLATION *singlechar-installation* @@ -43,6 +44,13 @@ Manual installation: > mkdir -p ~/.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* @@ -60,6 +68,12 @@ You can use a count before the mapping to insert the character multiple times: > 5i- " Insert 5 hyphens at cursor position 3a. " 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* @@ -110,10 +124,15 @@ Adding multiple periods: > Action: Position cursor at the end, press 3a. After: Some text... < +Dot-repeat: > + Action: Press i? to insert a question mark, then press . to repeat the insertion at the next location. +< + =============================================================================== TIPS & TRICKS *singlechar-tips* - 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* diff --git a/plugin/singlechar.vim b/plugin/singlechar.vim index 32e7dcf..465158c 100644 --- a/plugin/singlechar.vim +++ b/plugin/singlechar.vim @@ -1,4 +1,5 @@ vim9script noclear +import autoload 'singlechar.vim' # ------------------------------------------------------------------------------ # # singlechar.vim - Insert single characters without entering insert mode # Author: lohhiiccc @@ -17,8 +18,8 @@ if exists('g:loaded_singlechar') || &cp || v:version < 900 endif g:loaded_singlechar = 1 # ------------------------------------------------------------------------------ # - # Configuration options + # Mapping to insert a character at cursor position (before cursor) if !exists('g:singlechar_map_insert_at') g:singlechar_map_insert_at = 'i' @@ -35,37 +36,18 @@ if !exists('g:singlechar_prompt') endif # ------------------------------------------------------------------------------ # -# Core functionality - -# 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 -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 ==# "\" - 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 .. "\" -enddef - +# +g:last_singlechar_key = '' +g:last_singlechar_mode = '' +g:last_singlechar_count = 1 +# # ------------------------------------------------------------------------------ # -# Commands and mappings +# Mappings +nnoremap (singlechar-repeat) :call g:RepeatSingleChar() # Direct command implementations -command! -count=1 -nargs=0 InsertCharAt InsertChar('at', ) -command! -count=1 -nargs=0 InsertCharAfter InsertChar('after', ) +command! -count=1 -nargs=0 InsertCharAt singlechar.InsertChar('at', ) +command! -count=1 -nargs=0 InsertCharAfter singlechar.InsertChar('after', ) # Create default mappings unless disabled if !exists('g:singlechar_no_mappings') @@ -73,7 +55,6 @@ if !exists('g:singlechar_no_mappings') execute 'nnoremap ' .. g:singlechar_map_insert_after .. ' ":InsertCharAfter " .. v:count1 .. ""' endif - # Usage: # i - Insert character at cursor position # a - Insert character after cursor position