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] 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')