From a1596e9f20f9b35c7167ba2efff27e443931a8a1 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Fri, 22 Mar 2024 19:22:28 +0800 Subject: [PATCH] fix(chinese): fix translating function between numerals Co-authored-by: Kun Lin --- autoload/SpaceVim/layers/chinese.vim | 134 ++++++++++++++++++++------- 1 file changed, 103 insertions(+), 31 deletions(-) diff --git a/autoload/SpaceVim/layers/chinese.vim b/autoload/SpaceVim/layers/chinese.vim index cf708d257..4e22930af 100644 --- a/autoload/SpaceVim/layers/chinese.vim +++ b/autoload/SpaceVim/layers/chinese.vim @@ -65,50 +65,122 @@ function! SpaceVim#layers#chinese#health() abort return 1 endfunction -command! -nargs=0 -range ConvertChineseNumberToDigit :,call s:ConvertChineseNumberToDigit() -nnoremap ConvertChineseNumberToDigit :ConvertChineseNumberToDigit -vnoremap ConvertChineseNumberToDigit :ConvertChineseNumberToDigit -function! s:ConvertChineseNumberToDigit() range + +" 定义快捷键映射 +nnoremap ConvertChineseNumberToDigit :call ConvertChineseNumberToDigit('normal') +vnoremap ConvertChineseNumberToDigit :call ConvertChineseNumberToDigit('visual') + +" 函数定义 +function! s:ConvertChineseNumberToDigit(mode) range let save_cursor = getcurpos() - let ChineseNumberPattern = '[〇一二三四五六七八九十百千万亿兆零壹贰叁肆伍陆柒捌玖拾佰仟萬億两点]\+' - if mode() ==? 'n' && a:firstline == a:lastline + let save_register = @k + if a:mode == 'normal' + " 正常模式处理 let cword = expand('') - let cword = substitute(cword, ChineseNumberPattern, '\=Zh2Num#Translator(submatch(0))', "g") - let save_register_k = getreg("k") - call setreg("k", cword) - normal! viw"kp - call setreg("k", save_register_k) + let rst = substitute(cword, Zh2Num#getZhNumPattern(), '\=Zh2Num#Translator(submatch(0))', "g") + if rst != cword + let @k = rst + normal! viw"kp + endif else - silent execute a:firstline . "," . a:lastline . 'substitute/' . ChineseNumberPattern . '/\=Zh2Num#Translator(submatch(0))/g' + " 可视模式处理 + normal! gv + if mode() == "\" + " 块选择模式 + let [line_start, column_start] = getpos("'<")[1:2] + let [line_end, column_end] = getpos("'>")[1:2] + if column_end < column_start + let [column_start, column_end] = [column_end, column_start] + endif + for line_num in range(line_start, line_end) + let line = getline(line_num) + let line_utf8 = iconv(line, &encoding, 'UTF-8') + let selectedText = line_utf8[column_start - 1: column_end - 1] + let translatedText = substitute(selectedText, Zh2Num#getZhNumPattern(), '\=Zh2Num#Translator(submatch(0))', 'g') + let newLine = line[:column_start - 2] . translatedText . line[column_end:] + call setline(line_num, newLine) + endfor + else + " 其他可视模式 + normal! "ky + let selectedText = iconv(@k, &encoding, 'UTF-8') + let translatedText = substitute(selectedText, Zh2Num#getZhNumPattern(), '\=Zh2Num#Translator(submatch(0))', 'g') + if translatedText != selectedText + call setreg('k', translatedText) + normal! gv"kp + endif + endif endif call setpos('.', save_cursor) + let @k = save_register endfunction -command! -nargs=0 -range ConvertDigitToChineseNumberLower :,call s:ConvertDigitToChineseNumber("lower") -nnoremap ConvertDigitToChineseNumberLower :ConvertDigitToChineseNumberLower -vnoremap ConvertDigitToChineseNumberLower :ConvertDigitToChineseNumberLower +nnoremap ConvertDigitToChineseNumberLower :call ConvertDigitToChineseNumber('normal', "lower") +vnoremap ConvertDigitToChineseNumberLower :call ConvertDigitToChineseNumber('visual', "lower") -command! -nargs=0 -range ConvertDigitToChineseNumberUpper :,call s:ConvertDigitToChineseNumber("upper") -nnoremap ConvertDigitToChineseNumberUpper :ConvertDigitToChineseNumberUpper -vnoremap ConvertDigitToChineseNumberUpper :ConvertDigitToChineseNumberUpper +nnoremap ConvertDigitToChineseNumberUpper :call ConvertDigitToChineseNumber('normal', "upper") +vnoremap ConvertDigitToChineseNumberUpper :call ConvertDigitToChineseNumber('visual', "upper") -function! s:ConvertDigitToChineseNumber(style) range +function! s:ConvertDigitToChineseNumber(mode, caseType) abort let save_cursor = getcurpos() - let NumberPattern = '\v\d+(\.\d+)?' - if mode() ==? 'n' && a:firstline == a:lastline - let cword = expand('') - " 在这里使用双引号和 . 连接符来正确地引用 a:style - let cword = substitute(cword, NumberPattern, '\=Num2Zh#Translator(submatch(0), "'.a:style.'")', "g") - let save_register_k = getreg("k") - call setreg("k", cword) - normal! viw"kp - call setreg("k", save_register_k) - else - " 在执行替换的字符串中正确使用 a:style 参数 - silent execute a:firstline . "," . a:lastline . 'substitute/' . NumberPattern . '/\=Num2Zh#Translator(submatch(0), "'.a:style.'")/g' + let save_register = @k + let cword = expand('') + if a:mode == 'normal' + if !empty(cword) + let rst = substitute(cword, Num2Zh#getNumberPattern(), '\=Num2Zh#Translator(submatch(0), "'. a:caseType .'")', "g") + if rst != cword + let @k = rst + normal! viw"kp + endif + endif + " 如果是block模式,则特别处理 + elseif a:mode == 'visual' + normal! gv + if mode() == "\" + let [line_start, column_start] = getpos("'<")[1:2] + let [line_end, column_end] = getpos("'>")[1:2] + if column_end < column_start + let [column_start, column_end] = [column_end, column_start] + endif + for line_num in range(line_start, line_end) + let line = getline(line_num) + " 将行文本转换为UTF-8编码 + let line_utf8 = iconv(line, &encoding, 'UTF-8') + let selectedText = line_utf8[column_start - 1: column_end - 1] + let translatedText = substitute(selectedText, Num2Zh#getNumberPattern(), '\=Num2Zh#Translator(submatch(0), "' . a:caseType . '")', 'g') + let newLine = line[:column_start - 2] . translatedText . line[column_end:] + call setline(line_num, newLine) + endfor + else + " 对其他模式的处理 + if mode() == 'line' + normal! '[V'] + elseif mode() == 'char' + normal! `[v`] + elseif mode() ==? 'v' + normal! gv + else + normal! '[v'] + endif + + " 获取选择的文本,将其保存在寄存器t中 + normal! "ky + let selectedText = iconv(@k, &encoding, 'UTF-8') + + " 转换文本 + let translatedText = substitute(selectedText, Num2Zh#getNumberPattern(), '\=Num2Zh#Translator(submatch(0), "' . a:caseType . '")', 'g') + + if translatedText != selectedText + " 替换原文本 + call setreg('k', translatedText) + normal! gv"kp + endif + endif endif call setpos('.', save_cursor) + let @k = save_register endfunction + " function() wrapper if v:version > 703 || v:version == 703 && has('patch1170') function! s:_function(fstr) abort