From e3b5bdd39215e5422ea796d4b95c2ad0cf41e814 Mon Sep 17 00:00:00 2001 From: lohhiiccc <96543753+lohhiiccc@users.noreply.github.com> Date: Tue, 19 Aug 2025 16:34:43 +0200 Subject: [PATCH 1/3] feat: improve InsertChar handling for Unicode and input validation - Use strcharpart for Unicode character support - Add warning message if more than one character is entered - Refactor InsertChar to clarify variable names and flow - Make user input handling robust against accidental multi-char input - Add global config for warning message - Update commands and mappings for flexible argument handling --- autoload/singlechar.vim | 46 +++++++++++++++++++++-------------------- plugin/singlechar.vim | 14 ++++++++++--- 2 files changed, 35 insertions(+), 25 deletions(-) diff --git a/autoload/singlechar.vim b/autoload/singlechar.vim index f14370e..bd8cefc 100644 --- a/autoload/singlechar.vim +++ b/autoload/singlechar.vim @@ -1,39 +1,41 @@ 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 == '' +export def InsertChar(mode: string, count: number, input_char: string = ''): void + var warning_message = '' + var first_char = strcharpart(input_char, 0, 1) # strcharpart for Unicode support + + if input_char == '' echo g:singlechar_prompt redraw # Get character from user var char = getchar() - key = nr2char(char) + first_char = nr2char(char) + elseif g:singlechar_keylen_warning == 1 && strchars(input_char) > 1 + warning_message = substitute(g:singlechar_warning_message, '{char}', first_char, '') endif - if key ==# "\" + + if first_char ==# "\" 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 + # Determine whether to insert before (i) or after (a) cursor + var insert_command = (mode ==# 'at') ? 'i' : 'a' + var insert_text = repeat(first_char, (count == 0) ? 1 : count) + + execute 'normal! ' .. insert_command .. insert_text .. "\" + + # Save last used values + g:last_singlechar_key = first_char 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 + legacy silent! call repeat#set("\(singlechar-repeat)") + + if warning_message != '' + redraw! + echomsg warning_message + endif enddef def g:RepeatSingleChar(): void diff --git a/plugin/singlechar.vim b/plugin/singlechar.vim index 465158c..abd3890 100644 --- a/plugin/singlechar.vim +++ b/plugin/singlechar.vim @@ -32,7 +32,15 @@ endif # Prompt message shown when waiting for character input if !exists('g:singlechar_prompt') - g:singlechar_prompt = 'Press the character to insert - Press Esc to cancel...' + g:singlechar_prompt = 'Press the character to insert - Press Esc to cancel...' +endif + +if !exists('g:singlechar_keylen_warning') + g:singlechar_keylen_warning = 1 +endif + +if !exists('g:singlechar_warning_message') + g:singlechar_warning_message = 'Only the first character will be taken: {char}' endif # ------------------------------------------------------------------------------ # @@ -46,8 +54,8 @@ g:last_singlechar_count = 1 nnoremap (singlechar-repeat) :call g:RepeatSingleChar() # Direct command implementations -command! -count=1 -nargs=0 InsertCharAt singlechar.InsertChar('at', ) -command! -count=1 -nargs=0 InsertCharAfter singlechar.InsertChar('after', ) +command! -count=1 -nargs=? InsertCharAt call singlechar.InsertChar('at', , ) +command! -count=1 -nargs=? InsertCharAfter singlechar.InsertChar('after', , ) # Create default mappings unless disabled if !exists('g:singlechar_no_mappings') -- 2.47.3 From 2970edd2ab14845bad4a24306bab01985ef68ba2 Mon Sep 17 00:00:00 2001 From: lohhiiccc <96543753+lohhiiccc@users.noreply.github.com> Date: Tue, 19 Aug 2025 16:45:17 +0200 Subject: [PATCH 2/3] doc: update docs --- README.md | 12 ++++++++++-- doc/singlechar.txt | 8 +++++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f0795d4..e1ac198 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # vim-singlechar -A simple Vim plugin that lets you insert single characters without leaving normal mode. +A simple Vim plugin that lets you insert single characters (including Unicode) without leaving normal mode. ## Overview @@ -8,8 +8,9 @@ A simple Vim plugin that lets you insert single characters without leaving norma ## Features -- Insert characters at or after the cursor position +- Insert characters (supports Unicode) at or after the cursor position - Support for counts to insert a character multiple times +- Input validation: warns if more than one character is entered - Stay in normal mode for efficient editing - Minimal workflow interruption - Works with Vim 9+ @@ -71,6 +72,13 @@ let g:singlechar_prompt = 'Press the character to insert - Press Esc to cancel.. " Disable default mappings (if you want to create your own) let g:singlechar_no_mappings = 1 + +" Show warning if more than one character is entered (default: enabled) +let g:singlechar_keylen_warning = 1 + +" Customize the warning message (default: 'Only the first character will be taken: {char}') +let g:singlechar_warning_message = 'Only the first character will be taken: {char}' + ``` ## Commands diff --git a/doc/singlechar.txt b/doc/singlechar.txt index 17b0258..ab2e7eb 100644 --- a/doc/singlechar.txt +++ b/doc/singlechar.txt @@ -27,7 +27,7 @@ INTRODUCTION *singlechar-introducti vim-singlechar is a minimalist Vim plugin designed to optimize the workflow of inserting single characters during editing. It eliminates the need to enter insert mode for simple edits like adding punctuation, which helps maintain the flow of -normal mode operations. +normal mode operations. Now supports Unicode. =============================================================================== REQUIREMENTS *singlechar-requirements* @@ -111,6 +111,12 @@ Disabling default mappings: > Changing the prompt message: > let g:singlechar_prompt = 'Character to insert (Esc to cancel): ' < +Show warning if more than one character is entered (default: enabled): > + let g:singlechar_keylen_warning = 1 +< +Customize the warning message (default: 'Only the first character will be taken: {char}'): > + let g:singlechar_warning_message = 'Only the first character will be taken: {char}' +< =============================================================================== EXAMPLES *singlechar-examples* -- 2.47.3 From 9a44a23fc9fe762055fd2f195a6dd53373db1e54 Mon Sep 17 00:00:00 2001 From: lohhiiccc <96543753+lohhiiccc@users.noreply.github.com> Date: Tue, 19 Aug 2025 16:52:07 +0200 Subject: [PATCH 3/3] typo: strange and unnecessary "call" and fake news in README --- README.md | 1 - plugin/singlechar.vim | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index e1ac198..46b3a0e 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,6 @@ A simple Vim plugin that lets you insert single characters (including Unicode) w - Insert characters (supports Unicode) at or after the cursor position - Support for counts to insert a character multiple times -- Input validation: warns if more than one character is entered - Stay in normal mode for efficient editing - Minimal workflow interruption - Works with Vim 9+ diff --git a/plugin/singlechar.vim b/plugin/singlechar.vim index abd3890..e4ddf80 100644 --- a/plugin/singlechar.vim +++ b/plugin/singlechar.vim @@ -54,7 +54,7 @@ g:last_singlechar_count = 1 nnoremap (singlechar-repeat) :call g:RepeatSingleChar() # Direct command implementations -command! -count=1 -nargs=? InsertCharAt call singlechar.InsertChar('at', , ) +command! -count=1 -nargs=? InsertCharAt singlechar.InsertChar('at', , ) command! -count=1 -nargs=? InsertCharAfter singlechar.InsertChar('after', , ) # Create default mappings unless disabled -- 2.47.3