zoukankan      html  css  js  c++  java
  • Vim一键修改光标所在单词为相反或关联的词

    写代码或文字时,经常会需要修改当前词(或选中区域)为相反相关的词,比如

    A B
    up down
    left right
    show hide
    from to
    encode decode
    get set
    yes no
    on off
    down up
    left right
    top bottom
    this base
    read write
    row column
    rows columns
    RowHeight ColumnWidth
    focus blur
    var const
    lower upper
    odd even
    before after
    max min
    prev next
    true false
    enable disable
    enabled disabled
    permit deny
    smtp imap
    width height
    horizontal vertical
    user pwd
    username password
    SendMessage PostMessage
    水平 垂直
    成功 失败
    显示 隐藏
    github.com github.com.cnpmjs.org

    于是就有了以下 map 和相关函数
    切换后仍会保留原大小写格式
    核心见hy_string#modify#toggleWord函数

    NOTE:比如设置了getset的转化后,那么以下情况也会自动有效

    getValue setValue
    get_value set_value

    原理getValue如果未匹配,则会分别判断getValue是否被定义

    补充:在函数一开始还额外定义了.prop["prop"] 的转化(不需要删除即可)

    nnoremap <silent> <M-t> ciw<C-r>=hy_string#modify#toggleWord(@")<cr><esc>
    xnoremap <silent> <M-t> s<C-r>=hy_string#modify#toggleWord(@")<cr><esc>
    
    "true/false, up/down切换
    "NOTE lis大小写或首字母大写,全用小写,其他情况保留原大小写
    function! hy_string#modify#toggleWord(word)
        " .prop ⇄ ["prop"]
        if (a:word =~ '^v.w+$') | return '["' .strpart(a:word,1). '"]' | endif
        if (a:word =~ '^v["w+"]$') | return '.' .strpart(a:word,2,len(a:word)-4) | endif
        let lis = [
                     ['!', '!'],
                     [',', ','],
                     ['.', '。'],
                     ['<^', 'LCtrl & '],
                     ['>^', 'RCtrl & '],
                     ['<+', 'LShift & '],
                     ['>+', 'RShift & '],
                     ['<!', 'LAlt & '],
                     ['>!', 'RAlt & '],
                     ['FireShot', 'mcbpblocgmgfnpjjppndjkmgjaogfceg'],
                     ['Surfingkeys', 'gfbliohnnapiefjpjlpjnehglfpaknnc'],
                     ['SwitchyOmega', 'padekgcemlokbadohgkifijomclgjgif'],
                     ['Tampermonkey', 'dhdgffkkebhmkfjojejmpbldmpobfkfo'],
                     ['show', 'hide'],
                     ['from', 'to'],
                     ['encode', 'decode'],
                     ['get', 'set'],
                     ['yes', 'no'],
                     ['on', 'off'],
                     ['down', 'up'],
                     ['left', 'right'],
                     ['top', 'bottom'],
                     ['this', 'base'],
                     ['read', 'write'],
                     ['row', 'column'],
                     ['rows', 'columns'],
                     ['RowHeight', "ColumnWidth"],
                     ['focus', 'blur'],
                     ['lower', 'upper'],
                     ['odd', 'even'],
                     ['before', 'after'],
                     ['max', 'min'],
                     ['prev', 'next'],
                     ['true', 'false'],
                     ['enable', 'disable'],
                     ['enabled', 'disabled'],
                     ['permit', 'deny'],
                     ['user', 'pwd'],
                     ['username', 'password'],
                     ['smtp', 'imap'],
                     ['width', 'height'],
                     ['horizontal', 'vertical'],
                     ['var', 'const'],
                     ['absolute', 'relative'],
                     ['hkcr', 'HKEY_CLASSES_ROOT'],
                     ['hkcu', 'HKEY_CURRENT_USER'],
                     ['hklm', 'HKEY_LOCAL_MACHINE'],
                     ['hku', 'HKEY_USERS'],
                     ['hkcc', 'HKEY_CURRENT_CONFIG'],
                     ['ActiveCell', 'selection'],
                     ['WinActive', 'WinActivate'],
                     ['SendMessage', 'PostMessage'],
                     ['setTimeout', 'setInterval'],
                     ['screen', 'window'],
                     ['左', '右'],
                     ['上', '下'],
                     ['水平', '垂直'],
                     ['成功', '失败'],
                     ['显示', '隐藏'],
                     ['jshint', 'eslint'],
                     ['scanf', 'printf'],
                     ['WinGetClientPos', 'WinGetPos'],
                     ['cells', 'range'],
                     ['MergeArea', 'MergeCells'],
                     ['ComObjActive', 'ComObject'],
                     ['chr', 'ord'],
                     ['FindFirst', 'FindAll'],
                     ['FileMove', 'FileCopy'],
                     ['FileDelete', 'FileRecycle'],
                     ['font', 'interior'],
                     ['querySelector', 'querySelectorAll'],
                     ['innerHTML', 'innerText'],
                     ['LCtrl', 'RCtrl'],
                     ['LShift', 'RShift'],
                     ['LAlt', 'RAlt'],
                     ['run', 'RunWait'],
                     ['msgbox', 'tooltip'],
                     ['PgDn', 'PgUp'],
                     ['RegExReplace', 'RegExMatch'],
                     ['access', 'trunk'],
                     ['waitForPackage', 'waitForActivity'],
                     ['textStartsWith', 'textMatches'],
                     ['clickByWindow', 'clickStayByWindow'],
                     ['toastLog', 'toastInfo'],
                     ['0x111', 'WM_COMMAND:=0x111'],
                     ['WM_COMMAND', 'WM_COMMAND:=0x111'],
                     ['0x112', 'WM_SYSCOMMAND:=0x112'],
                     ['WM_SYSCOMMAND', 'WM_SYSCOMMAND:=0x112'],
                     ['currentPackage', 'currentActivity'],
                     ['github.com', 'github.com.cnpmjs.org'],
                     ]
        let word = a:word
        "获取 word 前后内容(用来 setline)
        let sLine = getline('.')
        let idx0 = stridx(sLine, word, col('.')-strlen(word))
        let strBefore = strpart(sLine, 0, idx0)
        let strAfter = strpart(sLine, idx0+strlen(word))
        "echom strBefore .'--'. strAfter .'--'. word
        "lPair 转成 dic(相互为key,方便判断)
        let dic = {}
        for lPair in lis
            let dic[lPair[0]] = lPair[1]
            let dic[lPair[1]] = lPair[0]
        endfor
        "NOTE dic 额外增加单向的内容
        let dic['int'] = 'integer'
        let dic['integer'] = '^d+$'
        "处理单词大小写
        let upCase = hy_string#get#upperCase(word)
        let wordFixed = upCase > 0 ? tolower(word) : word "wordFixed 用来调整大小写
        "echom word .' '. wordFixed
        if !has_key(dic,wordFixed) "不在定义列表内
            "echom 'not in dic'
            "aUp → aDown
            if word =~# '[A-Z]'
                let char = ''
                let l = hy_string#split#byUpper(word)
            else
                let char = matchstr(word, 'c[^a-z]')
                let l = split(word, 'c[^a-z]')
            endif
            for i in range(len(l))
                let upCase = hy_string#get#upperCase(l[i])
                let wordFixed = upCase > 0 ? tolower(l[i]) : word "wordFixed 用来调整大小写
                if has_key(dic, wordFixed) "找到匹配
                    let res = dic[wordFixed]
                    "恢复大小写
                    if upCase == 1
                        let res = tolower(res)
                    elseif upCase == 2
                        let res = toupper(res)
                    elseif upCase == 3
                        let res = substitute(res, '.*', 'Lu&', '')
                    endif
                    "修改 l
                    let l[i] = res
                    return join(l, char)
                endif
            endfor
            return word
        else
            let res = dic[wordFixed]
            if upCase == 1
                let res = tolower(res)
            elseif upCase == 2
                let res = toupper(res)
            elseif upCase == 3
                let res = substitute(res, '.*', 'Lu&', '')
            endif
        endif
        return res
        "    execute "normal! ciw" . res
        "call setline(line('.'), strBefore . res . strAfter)
    endfunction
    
    "获取字符串的大小写情况
    "1为小写
    "2为大写
    "3为首字母大写
    "0为其他情况(strUpper)
    function! hy_string#get#upperCase(str) abort
        if a:str !~ 'a' "没字母
            return 0
        elseif a:str ==# tolower(a:str)
            return 1
        elseif a:str ==# toupper(a:str)
            return 2
        elseif a:str =~# 'v^ul*$'
            return 3
        else
            return 0
        endif
    endfunction
    
    "abcUp转成 ['abc', 'Up']
    function! hy_string#split#byUpper(str) abort
        let char = '!'
        let s = substitute(a:str, 'A', char.'&', 'g') "转换非字母
        let s = substitute(s, 'vC[A-ZW]', char.'&', 'g') "大写字母前增加符号用来 split
        if strcharpart(s, 0, 1) == char | let s = strcharpart(s, 1) | endif
        return split(s, char)
    endfunction
    
  • 相关阅读:
    NodeJS 难点(网络,文件)的 核心 stream 二:stream是什么
    NodeJS 难点(网络,文件)的 核心 stream 一:Buffer
    了解了这些才能开始发挥jQuery的威力
    一般公司的大体要求
    js 的垃圾回收器 原理 坑 优化-- 待续
    iframe 问题集合
    图片预加载 js css预加载
    各种插件
    Django REST framework快速入门指南
    Vue.js devtool插件安装后无法使用的解决办法
  • 原文地址:https://www.cnblogs.com/hyaray/p/15200130.html
Copyright © 2011-2022 走看看