3

I think noticing a slow redrawing and slow cursor movement on a fastest PC, is one of the popular frustrations with Vim. Here I am as a yet another instance.

I have a fresh installation of VIM, with the $MYVIMRC at the bottom.

My problem is basically a painful slowdown of cursor movements and screen redraws, which are seen often after a while when

  • lot many buffers parallelly open
  • a longer sessions with multiple buffers used but not immediately after I start vim. They may not be the only cases though.

This is frustrating because, the problem is not easily reproducible. I cannot debug by line by line in $VIMRC, because I don't know how long should I wait to see slow down. All that I could do over the time is to observe the two above cases.

Can some of the vim-monks quickly see where the problem is in the vimrc below? (I copied all except a heap of :nnoremap commands that I often use)

:set nocompatible
:set regexpengine=1     "The new engine replaced with old (suggested on vi.SE)
:set foldmethod=marker   "fold based on default-markers 
:set foldnestmax=10      "deepest fold is 10 levels
:set nofoldenable        "dont fold by default
:set noswapfile     "Realized that swap troubles much more than it helps 
:set number
:set wildmenu
:set guifont=Monospace\ 12
:colorscheme industry

"Make search more user-friendly
:set incsearch  "Search as you go
:set hlsearch   "Highlight matches
:set ignorecase "Case-insensitive searches

:set showmatch  "Quickly jump to matching bracket/brace etc

 %for highlighting in red all exceedingly longer lines
:au BufWinEnter * let w:m2=matchadd('ErrorMsg', '\%>85v.\+', -1)
                      "==> This seems to be the potential culprit..

:filetype plugin on
:runtime macros/matchit.vim

:set formatoptions=tcroqlj

:au VimLeave * :mapclear 
:au VimLeave * :mksession! ~/.hari_vim_session
:au VimLeave * :%normal g_lD


set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()
Plugin 'VundleVim/Vundle.vim'
Plugin 'tpope/vim-surround'
Plugin 'tpope/vim-repeat'
Plugin 'vim-scripts/tComment'   " Toggle Comments -- comment/uncomment
Plugin 'scrooloose/nerdtree'
Plugin 'vim-airline/vim-airline'        
Plugin 'vim-airline/vim-airline-themes'
Plugin 'bling/vim-bufferline'
                 "Is this bufferline the culprit? Thought it was nice!!
Plugin 'vim-scripts/vis'    "Vertically selection to filters
call vundle#end()

:set lazyredraw   "Don't redraw unnecessarily too many times
:set ttyfast 

BTW, following How do I debug my vimrc file? when I started vim in no-plugin no-vimrc mode, I see no slow down, but the default interface is not usable to me. I need some modifications as I did in above $MYVIMRC. Hope you don't ask me to withdraw the whole $MYVIMRC.

9
  • Try disabling vim-bufferline plugin. I see some performance issues on it's Github tracker.
    – grodzik
    Dec 16, 2016 at 8:19
  • 2
    Maybe the line highlighting the 85+ columns is the culprit (See this question). Also to expand grodzik comment: maybe a plugin or a combination of plugins causes the slowdown. Try to comment all of your plugins and use Vim for some time, if the slow down stops, reenabled them ones by ones and you'll eventually find which plugin is causing the problem. Edit you use regexpengine=1 I didn't see that, so matchadd should not be a reason of the slow down... I would still try to comment it, just to be sure.
    – statox
    Dec 16, 2016 at 9:01
  • 'nocompatible' affects a lot of of other settings and should be at the top of your vimrc file. See :help 'compatible. That may not help your slowdown, but it may affect the way other settings affect the slowdown.
    – garyjohn
    Dec 16, 2016 at 14:14
  • Also, what do you mean by the comment, "swap troubles more than it helps"? I don't notice any difference in performance when swap files are enabled unless the swap files are on a slow file system such as on a remote file system with a slow network connection. Trouble with your swap files could be indicative of an underlying problem that is contributing to other slowness.
    – garyjohn
    Dec 16, 2016 at 15:10
  • 1
    @statox,grodzik Indeed, matchadd seems to make some significant difference as I open more and more buffers, even under regexpengine=1. But I also have bufferline plugin disabled. Bufferline-disabling didn't show much improvement so I disabled matchadd on top. Dec 17, 2016 at 0:23

2 Answers 2

3

I have no idea if any of the following will help, but here are a few things you could try.

You have the following autocmd:

:au BufWinEnter * let w:m2=matchadd('ErrorMsg', '\%>85v.\+', -1)

I can't read your whole vimrc file, so maybe you already did it in the missing part, but in case you didn't, you should probably wrap this autocmd (and the other ones) inside an augroup.

augroup long_lines
    au!
    au BufWinEnter * let w:m2=matchadd('ErrorMsg', '\%>85v.\+', -1)
augroup END

The line au! makes sure to delete all the autocmds inside the current augroup every time you source your vimrc.

Without this augroup and the au! line, each time you source your vimrc, a new identical autocmd is added, and you should be able to reproduce some slowdown by sourcing your vimrc:

:so $MYVIMRC

... then repeating this command enough time.
For example, to repeat it 40 times, you could type, in normal mode, 40@:.
@: will reexecute the last Ex command, the number of times you asked (here 40).

See here and here for more info.


Currently, the autocmd adds a new identical match every time a buffer is displayed in a window, which is probably unnecessary.

If you reload your current buffer, by typing :e, you should see that a new identical match has been created. You can see it with the getmatches() function, by typing:

:echo getmatches()
" info about the current matches

:echo len(getmatches())
" number of matches

If you reload your buffer enough times, by typing for example 40@: (to reexecute the last Ex command, which here is :e, fourty times), you should see a big list of identical matches.

From there, if you load one of your usual files, you should probably experience some slowdown.

The previous augroup and the au! command won't protect you from these duplications. You need a second protection on top of the augroup.

For example, you could ask Vim to check whether you already created a match with the exists() function:

if !exists('w:m2')
    " create your match and store its identifier inside the variable `w:m2`
endif

The exclamation mark before exists() is there to invert the test. You don't want to create the match when one already exists. You want to create a match when one does NOT already exist.

So, all in all, you could try this autocmd:

augroup long_lines
    au!
    au BufWinEnter * if !exists('w:m2') | let w:m2=matchadd('ErrorMsg', '\%>85v.\+', -1) | endif
augroup END

You don't need to disable the 'compatible' option, because it should be done automatically by Vim if it finds a vimrc. From :h 'cp:

When a |vimrc| or |gvimrc| file is found while Vim is starting up,
this option is switched off, and all options that have not been
modified will be set to the Vim defaults.

It's not linked to your issue, but you don't need to prefix your commands with a colon :, because when Vim sources your vimrc it interprets the lines as Ex commands (and not normal commands).

You don't need to prefix your autocmds with a colon either. Because an autocmd executes Ex commands by default. It doesn't execute normal commands, like dd (you would have to write normal! dd, but normal is still an Ex command).

So, as an example, you could rewrite this part:

:au VimLeave * :mapclear 
:au VimLeave * :mksession! ~/.hari_vim_session
:au VimLeave * :%normal g_lD

Like this:

augroup my_augroup
    au!
    au VimLeave * mapclear 
    au VimLeave * mksession! ~/.hari_vim_session
    au VimLeave * %normal g_lD
augroup END

You could also try to avoid writing comments right after an Ex command.
Try to write your comments on their own dedicated lines.
In particular avoid adding a comment right after a mapping.


If Vim is still slow, and you suspect something in your vimrc is the cause, you could write the line finish somewhere in the middle of it. But don't write finish between the lines:

call vundle#begin()

and

call vundle#end()

Anything after finish won't be executed by Vim. If the problem persists, it means the cause is somewhere before finish, otherwise after.

Then, you repeat the process.
If you know that the cause is in the first half of your vimrc, you move finish in the middle of it (that is after 1/4 of the file), otherwise in the middle of the second half (that is after 3/4 of the file).

So, in the first step, you write finish after half of the file.
In the second step, you write it after 1/4 or 3/4 of the file (depending on the result of the previous step).
In the third step, you write it after 1/8, 3/8, 5/8 or 7/8 of the file.
...

After each step, you should be able to eliminate half of the remaining lines as possible suspects.

To move your cursor right after the first half of your file, from normal mode, you can type 50%.
To move it after 1/4 of the file, you can type 25%.
After 1/8, 12% or 13%, etc.

4
  • +1 accepted. Thanks a lot! Wish someone like you taught me all this in the first place. Let me guess. Do you have any tutorials by yourself? Dec 17, 2016 at 6:28
  • @LovesProbability No sorry I don't have any tutorial, but there are good resources out there, in the sidebar on the vim's subreddit, a book from Drew Neil called Practical Vim, a tutorial on github (github.com/mhinz/vim-galore)... Dec 17, 2016 at 12:30
  • @LovesProbability I've edited the answer, because I think the previous autocmd could still cause some slowdown. You should probably check whether an identical match already exists before trying to create a new one. I've tried to explain it in the edited answer. Dec 17, 2016 at 12:32
  • @LovesProbability Basically you should probably replace let w:m2=matchadd('ErrorMsg', '\%>85v.\+', -1) with if !exists('w:m2') | let w:m2=matchadd('ErrorMsg', '\%>85v.\+', -1) | endif. Dec 17, 2016 at 15:58
0

Lots of matchadd slow down my nvim:

set conceallevel=2 concealcursor=n
set lazyredraw
set synmaxcol=90
" set synmaxcol=140
"
" helper
    nno <Leader>o  <cmd>TSHighlightCapturesUnderCursor<cr>
    nno <Leader>oo <cmd>call Syn_stack_herE()<cr>
        func! Syn_stack_herE()
            let out_in = 1
            for id in synstack(line("."),  col("."))
                echo out_in synIDattr(id,  "name")
                let out_in += 1
            endfor
        endf


" hide
    au AG Syntax * hi HidE      guifg=#fdf6e3   guibg=none gui=none
    nno  ,h "hyiw<esc>:let a_id = matchadd('HidE', @h, 99, -1)<cr>
    vno  ,h "hy<esc>:  let a_id = matchadd('HidE', @h, 99, -1)<cr>
                                                        " 非Conceal这个group, 无法显示cchar

" c: conceal
    nno  ,c "cyiw<esc>:let a_id = matchadd('Conceal', @c, 100, -1, {'conceal':'☾'})<cr>
    vno  ,c  <Cmd>call Concel_thiS()<cr>
        fun! Concel_thiS()
            normal "cy
            let @c = @c ->substitute(   '\.',
                                     \ '\\.',
                                     \ '',
                                     \ )
            echom  @c
            let a_id = matchadd('Conceal', @c, 100, -1, {'conceal':'•'})
        endf
    " vno  ,c "cy<esc>:let a_id = matchadd('Conceal', @c, 100, -1, {'conceal':'☾'})<cr>



fun! Match_byE(lan, v_regex, cchar) abort
    exe "au AG Syntax"  a:lan
        \ "call  matchadd('Conceal', '\\v"..a:v_regex.."', 999, -1, {'conceal': '"..a:cchar.."'})"
                                    " pattern要用单引号包裹,
                                    " ¿\\¿escape后是¿\¿
endf


au AG Syntax * call Bye_alL()
        fun! Bye_alL()
            let all_byE = {
                \ 'between (<\w\w{-}> )+\zsand\ze \w':'⇔'  ,
                \ '(^| )\zsreturn\ze( |$)'           :'↵'  ,
                \}
            for [r,c] in items(all_byE)
                call Match_byE('*', r, c)
            endfor
        endf

" 导致进入terminal 会弹出echo窗口
    " au AG Syntax *
    "     \ | if &syntax != 'vim'
    "     \ |   call Bye_all_not_viM()
    "     \ | endif

au AG Syntax python,zsh    call Bye_all_not_viM()
    fun! Bye_all_not_viM()
            let all_not_vim_byE = {
                \  '\s+\zs\\$'                    :'↙️' ,
                \}
            for [r,c] in items(all_not_vim_byE)
                call Match_byE('*', r, c)
            endfor
    endf



" language specific

    au AG Syntax tex call Bye_teX()
        call matchadd('Conceal', "\\v\\~\\\\ref\\{.{-}}", 100, -1, {'conceal':' '})
                " au AG Syntax tex call matchadd('Conceal', '\v\~\\ref\{.{-}}', 100, -1, {'conceal':' '})
                                                       " 单引号vs双引号:
                                                       " 这个不行
        fun! Bye_teX()
            let tex_byE = {    '\{equation}'  :'_'  ,
                        \  '\{aligned}'       :''  ,
                        \  '\\vspace\{-?.{-}}':'_'  ,
                        \
                        \  '^\% {1,3}!TeX'    :'𐌼'  ,
                        "\ \  '\\\a+\{\p{-}}' :''  ,
                        "\ 封印所有命令, more readable
                                                "\ m: magic各种语言的magic command/comment统一用它
                        \  '\%$'                :''  ,
                        \  'state-of-the-art'   :'👍'  ,
                        \  '\times'             :'X' ,
                        \  '\\footnote'         :'𝔫',
                        \  '\~\\etal'             :'',
                        \  '\~\\cite'             :'',
                        "\  '\\~\\\\ref\\{.{-}}':''  ,
                    \}
            " can not conceal paremeter in ¿{}¿
                let g:vimtex_syntax_custom_cmds = [
                          \ #{name: 'lbrack'  , conceal: 1, concealchar:''},
                          "\ \ #{name: 'lbrack '  , conceal: 1, concealchar:'['},
                          "\ 多了这个空格不行
                          \ #{name: 'rbrack'   , conceal: 1, concealchar:']'},
                          \ #{name: 'noindent'   , conceal: 1, concealchar:'_'},
                      \]

                    " 加了下面的导致无法conceal:
                          " \ #{name: 'Prob'     , mathmode: 1, concealchar: 'ℙ'},
                          " \ #{name: 'Expect'   , mathmode: 1, concealchar: '𝔼'},
                          " \ #{name: 'Var'      , mathmode: 1, concealchar: '𝕍'},
                          " \ #{name: 'pdf'      , mathmode: 1, concealchar: '𝕡'},
                          " \ #{name: 'qdf'      , mathmode: 1, concealchar: '𝕢'},
                          " \ #{name: 'NormDist' , mathmode: 1, concealchar: '𝒩'},
                          " \ #{name: 'Reals'    , mathmode: 1, concealchar: 'ℝ'},
                          " \ #{name: 'Imags'    , mathmode: 1, concealchar: '𝕀'},
                          " \ #{name: 'Naturals' , mathmode: 1, concealchar: 'ℕ'},
                          " \ #{name: 'Integers' , mathmode: 1, concealchar: 'ℤ'},
                          " \ #{name: 'ones'     , mathmode: 1, concealchar: '𝟙'},
                          " \ #{name: 'bigO'     , mathmode: 1, concealchar: '𝒪'},
                          " \]

                  " 尝试:
                      " "\ \ {'name': 'vect', 'mathmode': 1, 'argstyle': 'bold', 'conceal': 1},
                      " "\ \ {'name': 'mat' , 'mathmode': 1, 'argstyle': 'bold', 'conceal': 1},
                      " "\ \ {'name': 'bm'  , 'mathmode': 1, 'argstyle': 'bold', 'conceal': 1},
                      " "\ \ {'name': 'pmb' , 'mathmode': 1, 'argstyle': 'bold', 'conceal': 1},
                      " \]


            for [r,c] in items(tex_byE)
                call Match_byE('tex', r, c)
            endfor

            " todo: 动态conceal
                " 不知道为啥不行
                " let g:tex_bye_dict2 = { '\\\a+\{\p{-}}':'',
                "                 \  '\{aligned}'    :''  ,
                "                 \ 'usepackage'     :'_',
                "                 \}
                "
                "     au AG Syntax tex nno <buffer> <Leader>cl   <Cmd>call Conceal_lateX()<cr>
                "                                                             " 封印所有命令, more readable
                "         function! g:Conceal_lateX() abort
                "             for [r,c] in items(g:tex_bye_dict2)
                "                 call Match_byE('tex', r, c)
                "                 echom 'regex is: ' r
                "
                "             endfor
                "         endfunction
                "     au AG Syntax tex nno <buffer> <Leader>cn    <Cmd>call matchdelete(cl_id)<cr>
                "                                           "conceal not

        endf

    au AG Syntax vim call Bye_viM()
    fun! Bye_viM()
        " let vim_byE = {'call'               :  '𝔠'   ,  有些会导致屏幕很脏
        let vim_byE = {
                    \  '^\s*\zsif>'                      :'▸'  ,
                    \  '^\s*\zselseif>'                  :'▹'  ,
                    \  '^\s*\zsel%[se]>'                 :'▪'  ,
                    \  '^\s*\zsendif>'                   :'◀'  ,
                    \  '\s*\zsendif$'                    :'◀'  ,
                    \  '^\s*\zsen>'                      :'◀'  ,
                    \
                    \  '^\s*\zsfor>'                     :'∀'  ,
                    \  '^\s*\zsendfor>'                  :'↥'  ,
                    \
                    \  '^\s*\zsfunction! \ze\w\p+\(.{-}\)':''  ,
                    \      '^\s*\zsfunc! \ze\w\p+\(.{-}\)':''  ,
                    \       '^\s*\zsfun! \ze\w\p+\(.{-}\)':''  ,
                    \        '^\s*\zsfu! \ze\w\p+\(.{-}\)':''  ,
                    \
                    \  '^\s*\zsendf>'                    :'❰'  ,
                    \  '^\s*\zsendfunction>'             :'❰'  ,
                    \
                    \  '^\s*\zs\\'                       :'↗' ,
                    \
                    \  '<let\s+\ze\p{-}\='               :''   ,
                    \  '<let>.{-} \zs\=\ze '             :'←'  ,
                    "\ \  '<let>.{-} \zs\.\=\ze ':'↙️'  ,
                    "\ 会出现2个cchar
                    \
                    \  '() \zsabort'        :  ''  ,
                    \  '(\p\+) \zsabort'    :  ''  ,
                  \}

        for [r,c] in items(vim_byE)
            call Match_byE('vim', r, c)
        endfor
    endf

     " help
        au AG Syntax help call matchadd('Conceal', '\v^\s*\zsif>'         , 99, -1, {'conceal':'▸'})

    " python
    au AG Syntax python call Bye_pythoN()
        fun! Bye_pythoN()
            let py_byE = {
                        \  '^\s*\zsif>'     :'▸'  ,
                        \  '^\s*\zselif:'   :'▹'  ,
                        \  '^\s*\zselse'    :'▪'  ,
                        "\ \  '<os\.path\.join'    :'𝔍' ,
                        "\ \  '^\s*\zselse:':'▪'  ,
                        "\ \  'else'        :'▪'  ,
                        \
                        \  '^\s*\zsfor>'               :'∀'  ,
                        \  '^\s*\zsdef \ze {-}\w+\(.{-}\)':''  ,
                        \
                      \}

            for [r,c] in items(py_byE)
                call Match_byE('python', r, c)
            endfor
        endf

    " zsh
    " au AG Syntax zsh call Bye_zsH()
        fun! Bye_zsH()
            let zsh_byE = {
                        \  '^\s*\zsif>'  :'▸'  ,
                        \  '^\s*\zselif>':'▹'  ,
                        \  '^\s*\zselse>':'▪'  ,
                        \  '^\s*\zsfi>'  :'◀'  ,
                        \
                        \  '^\s*\zsfor>' :'∀'  ,
                        \  '^\s*\zsdone>':'↥'  ,
                        \
                        "\ \  '[^ ]\zs\=\ze[^ ]'  :'←'  ,
                        "\ \  '[^ ]\zs\=\ze[^ ]'  :'📓'  ,  \ ⩶
                        "\  '[^ ]\zs\=\ze[^ ]'  :'🕮'  ,
                        "\ \  '[^ ]\zs\=\ze[^ ]'  :'一'  ,
                        \  '[^ ]\zs\=\ze[^ ]'  :'←'  ,
                        \  '\zsnn \ze\w\w{-}[^ ]\=[^ ]'  :''  ,
                        "\ \  'nn \w{-}\zs\=\ze[^ ]'  :''  ,
                      \}

            au AG Syntax zsh call matchadd('Conceal', '\v^\s*\zsif>'         , 99, -1, {'conceal':'▸'})
            for [r,c] in items(zsh_byE)
                call Match_byE('zsh', r, c)
            endfor
        endf



" 之前的蠢方法
    " nno  ,c "cy<esc>:syn match ConCeaL "<c-r><c-w>" conceal
    "                     \ containedin=vimLineComment,vimComment
    "                     \<left><left><left><left><left><left><left><left><left><left>

" 隐藏后 老是想按u, 所以:
    nno  ,u :call matchdelete(a_id)<cr>
    nno  ,U :call clearmatches()<cr>
" 隐藏后 老是想按ctrl r, 所以:
    nno  ,r :call matchdelete(a_id)<cr>
    nno  ,R :call clearmatches()<cr>



func! g:Hi_paiR()
    syn cluster In_fancY     contains=In_VictoR,In_AcutE,In_Underline,In_BackticK
      "   cluster不能用这个argument:   containedin=pythonRawString


    hi In_VictoR guibg=#d0e0da
        syn match In_VictoR   "\v¿[^¿]+¿"hs=s+1,he=e-1  contains=VictoR containedin=mdCode
                                                                        " containedin=all  "  导致包裹区域被conceal
        syn match VictoR     "¿"  contained  conceal


    au AG BufRead * if expand('%:p')  !=  '/home/wf/dotF/cfg/nvim/conceal.vim'
                    \ | setl modifiable
                    \ | % sub  #✌#¿#ge
                    \ | call histdel('search',-2,)
                    \ | endif
                        " coc设置时 会报错,  它在搞鬼:
                        " 忽略即可
                                    " coc_nvim  BufEnter
                                    "     *         call s:Autocmd('BufEnter', +expand('<abuf>'))
                                    "     Last set from ~/.local/share/nvim/PL/coc/plugin/coc.vim line 338




    hi In_AcutE guibg=#d0e0da
        syn match In_AcutE     contains=AcutE      "\v´[^´]+´"hs=s+1,he=e-1
        syn match In_AcutE     contains=AcutE     "\v(^|[^a-z\"[])\zs´[^´]+´"hs=s+1,he=e-1
        syn match In_AcutE     contains=AcutE      "\(^\|[^a-z"[]\)\zs´[^´]\+´\ze\([^a-z\t."']\|$\)"hs=s+1,he=e-1

        syn match AcutE     "´" contained  conceal
            " echom 'acute______________'  能echom, 但为啥不生效?

        " call matchadd('leoHight', '`[^` \t]\+', 1, -1, {"conceal":1} )
        " 用作method为啥不行?
        "  leoHight->matchadd('`[^` \t]\+')
        " 没加let吧?
        "

    hi In_Underline guifg=none gui=underline
        syn match In_Underline   contains=Exclam_up_down    "\v \zs¡[-_a-zA-Z0-9'"*+/:%#=[\]<>.,]+¡"
                                                             " ¡包裹的
        syn match Exclam_up_down   '¡' contained conceal

    " hi  In_StrikE  ✗gui=italic,inverse✗ guifg=gray  guibg=none
    hi  In_StrikE  gui=italic guifg=#e0e0e0  guibg=#fdf6e3
        syn match In_StrikE        contains=StrikE  "\v✗[^✗]+✗"
        syn match StrikE    '✗'  contained "  conceal
                            " ctrl-k Y-

    syn match Double_quotE   '"' contained conceal cchar=  " space
        hi In_Double_quotE guifg=#303a7a gui=none
        syn match In_Double_quotE   contains=Double_quotE          '\v \zs"[^"]{1,80}"'
        " hi In_Double_quotE_short guifg=#903a9a gui=none
        "     " 太短 所以颜色要明显一些 不然看不出来  "     算了 长的也明显些吧
        "     syn match In_Double_quotE_short   contains=Double_quotE    '\v^\s*[^:]{-}\zs"[^"]{1,6}"'
                                                              " not end with star

    " syn match Single_quotE   "'" contained conceal containedin=String  " 没有String这个syntax group, 它只是highlight group
    " syn match Single_quotE   "'" contained conceal containedin=PyStr  " 不行
    syn match Single_quotE   "'" contained conceal cchar=  " cchar用space, 避免影响缩进
        hi In_Single_quotE guifg=#508a9a gui=none
            " syn match In_Single_quotE   contains=Single_quotE    %\v \zs'[^']{3,80}'%
            syn match In_Single_quotE   contains=Single_quotE    %\v\W\zs'[^']{3,80}'%

        hi link Short_optioN In_Single_quotE
            syn match Short_optioN      contains=Single_quotE    %'-\a'%  " python的命令行的-a -h等选项
        hi link RHS_of_equatioN In_Single_quotE
            syn match RHS_of_equatioN   contains=Single_quotE    %\v\= ?\zs'\k+'%  " python的命令行的-a -h等选项

        hi Single_quote_shorT guifg=#508a9a gui=none guibg=#e0e6e3
            syn match Single_quote_shorT    contains=Single_quotE    %\v \zs'[^']{1,2}'%


    " hi In_BackticK guifg=#00000 guibg=#fdf0e3 gui=none
    hi In_BackticK guifg=#00000 guibg=#e0e0df gui=none
        syn match In_BackticK     contains=BackTicK,In_VictoR  "`[^` \t]\+`"hs=s+1,he=e-1
                                                                " 不高亮两头的backtick
        syn match In_BackticK     contains=BackTicK,In_VictoR  "\v \zs(^|[^a-z\"[])\zs`[^`]+`"hs=s+1,he=e-1
        syn match In_BackticK     contains=BackTicK,In_VictoR  "\(^\|[^a-z"[]\)\zs`[^`]\+`\ze\([^a-z\t."']\|$\)"hs=s+1,he=e-1
            " 貌似不能用 /变量/hs....
                " let str_HI = "\v(^|[^a-z\"[])\zs" .. "`[^`]+`"
                " let str_HI = "\v(^|[^a-z\"[])\zs" .. "`[^`]+`" .. "\ze([^a-z\t\"']|$)"
                " syn match In_BackticK     contains=BackTicK  /str_HI/hs=s+1,he=e-1
                "
        " hi  BackTicK guifg=#fdf6e3  gui=none guibg=none
        syn match BackTicK   "`"   contained conceal


endf

fun! g:Hi_pair_markuP()
    " 如果要用, 再加这行, (别在python里conceal square bracket, it does not mean optional):
        " syn cluster Markup_fancY   contains=In_VictoR,In_AcutE,In_Underline,In_SquarE,Short_hand

         " syntax match vimLineComment   /^[ \t:]*".*$/  contains=@vimCommentGroup,vimCommentString,vimCommentTitle
         " 这样comment就和正文混一起了.. .

    " 让regex里的\v藏起来
    " 没生效?
        syn keyword VeryMagiC   \\v contained conceal
        hi link VeryMagiC DebuG
        syn match Has_VeryMagiC   contains=Single_quotE    '\v "\zs\\v\ze.{1,80}"'
        hi link Has_VeryMagiC Statement


    hi man_QuotE  guifg=#903a9a gui=none
        syn match man_QuotE contains=BackTicK,Single_quotE "\v zs``?.[^`']{1,80}'?'"
                                                              "   ``''
                                                              "   或
                                                              "   `'




    " todo: 生效没?
        " au AG Syntax   md,markdown
        "     \   syn match VictoR    "¿"  contained  conceal  containedin=mdNonListItemBlock
        "     \ | syn match Md_beautifY contains=VictoR      "\v¿[^¿]+¿"hs=s+1,he=e-1
        "                                 \ contained  conceal containedin=mdNonListItemBlock

    syn match BaR    "|"  contained conceal
        hi  In_BaR  guifg=#206043                         " 能匹配好多东西
            syn match In_BaR        contains=BaR  "\v\\@<!\|[!#-)+-~]+\|"
                                                      " ! 双引号是34  # $ % & ' (  )  42是星号   +  ~
                                                      " 33           35            41           43 126
        hi  Toc_lnum guifg=#808080
            syn match Toc_lnum        contains=BaR  "\v\\@<!\|\s{,4}\d{1,5}\|"
                                                          " toc的行号
        "
        " 这使得竖线不是被隐藏, 而是和背景一样的颜色, 看不见,(但还占着位置,不会少一个字符位置)
            " 代替了:
            " syn match BaR    "|"  contained  conceal    |  hi def  BaR gui=underline
                                                               " conceal后, hi def BaR 被覆盖
                                    " contained让竖\1线不会被单独匹配
                                                  " conceal作为一个flag, 让竖线(bar)在被匹配时, 会被conceal
            " hi def  BaR  guibg=#ff0000
            " 1.  有hi def link
            "   但hi def 某个颜色 很少见, 如果用了,
            "   得先hi clear再hi def不生效
            "
            " 2. hi  BaR guifg=bg_wf
            "    在leo_light.vim里 guifg=bg_wf 明明可以, 这里却不生效(但不报错)

                " 这是为了排除掉包含bar的这几种情况?
                    syn match helpNormal                "|.*====*|"
                    syn match helpNormal                "|||"
                    syn match helpNormal                ":|vim:|"       " for :help modeline

        hi In_SquarE guifg=#b0b0b0
            syn match In_SquarE     contains=left_squarE,righ_squarE  "\v\s\[[-a-zA-Z0-9_]+]"
                syn match left_squarE        "\["  contained conceal
                syn match righ_squarE         "]"  contained conceal
                " help.vim里有可以匹配[count]等的这个:
                "   syn match helpSpecial         "\v\s\[[-a-z^A-Z0-9_]{2,}]"ms=s+1
                "   所以In_SquarE被helpSpecial覆盖了?

          " 处理缩写,比如 b[uffer]
          hi Short_hand guifg=#b0b0b0
              syn match Short_hand    contains=left_squarE,righ_squarE "\v\w\zs\[(\w+|!)\]"
                  " g[lobal]里面的中括号, 表示缩写,不表示option,
                  " 不在helpOptional这个组里
                  " 我用正则 可以匹配g[lobal]

    " {大括号包裹} In_BracE
    hi In_CurlY guifg=#446655 gui=bold
                      " 若有似无的暗绿色
        syn match In_CurlY   contains=CurlY_1,CurlY_2      "\v[^{]\zs\{[-_a-zA-Z0-9'"*+/:%#=[\]<>.,]+}"
                                                                     " 长这样:   {至少一个[]里的字符}
                                                          " vim的help里的regex, markdown等不一定适用
        syn match CurlY_1   '{' contained conceal  cchar=♭
        syn match CurlY_2   '}' contained conceal


    " au AG Syntax * echom 'afile:'  expand('<afile>:p') | echom ' '
    " au AG Syntax * echom 'amatch:' expand('<amatch>:p') | echom ' '
    "                                      " amatch显示~/dotF/cfg/nvim下的文件(扔掉.vim)

    " :help syntax-loading
        "   Any other user installed FileType or Syntax autocommands are triggered.
        "   This can be used to change the highlighting for a specific syntax.
endf

au AG BufEnter *                        filetype detect

au AG Syntax   *                        call Hi_paiR()
au AG Syntax   help,man,nroff,w3m,tex   call Hi_pair_markuP()
" 好像不行:
" au AG FileType *

au AG Syntax   * call Few_wordS()
    fun! g:Few_wordS() abort
        syn match FeW  "\vless\s+than"    conceal cchar=≺
        syn match FeW  "\vmore\s+than"    conceal cchar=≻
        syn match FeW  "\vgreater\s+than" conceal cchar=≻

    endf

au AG Syntax   help                     call Hi_helP()
    fun! Hi_helP()
        " markdown和zsh里别用:
        syn match StaR   "\*"  contained conceal

            hi  In_StaR  guibg=#f0f6e3 gui=none
            " " hi  In_StaR    guifg=#a05058 gui=none
                syn match In_StaR        "\v\*[#-)!+-~]+\*$"         contains=StaR
                syn match In_StaR        "\v\*[#-)!+-~]+\*\s"he=e-1  contains=StaR
            "                                                  " 加了这个 避免空格被高亮:
            "                                                  "    he   offset for where the Highlight End
            "                                                  "    e   end of the matched pattern

            " 让行末的help tag的fg和bg_wf一样, 藏起来
            hi  In_StaR_EOL guifg=#fdf6e3
            syn match In_StaR_EOL    "\v([[:graph:]] {2,}|^ {9,})\zs\*[#-)* +-~]+\*$"
                                           " [[:graph:]] 如何用\p等代替?
                                                " 别用conceal
                                                " (有些help_tag 被我拿来当小标题了)
                                                " \p\s+: 排除掉位于行首(作为小标题)的情况
                                                " \S\s+遇到中括号 或大括号结束时, 不能匹配
                                                " 为啥有的内容 能被这个regex 匹配, 但还是In_StaR的高亮?

    endf

au AG Syntax vim                call Hi_viM()
    fun! Hi_viM()
        hi  link Vim_com_delI Ignore
            syn match Vim_com_delI #\v^\s*\zs"%( |$)#
                \ contained  containedin=vimLineComment conceal
                               " 官方定义了vimLineComment
                               " syn match vimLineComment  /^[ \t:]*".*$/  contains=@vimCommentGroup,vimCommentString,vimCommentTitle
    endf

        au AG Syntax   zsh     syn match Zsh_com_delI '\v%(^|\s+)\zs#%( |$)'
              \ contained conceal containedin=zshComment
              \ | hi link Zsh_com_delI Vim_com_delI


        au AG Syntax   autohotkey     syn match Ahk_com_delI  '\v%(^|\s+)\zs;%( |$)'
              \ contained conceal containedin=ahkComment
              \ | hi link Ahk_com_delI   Vim_com_delI

    " hi link Fold_marK HidE
        au AG Syntax   *   syn match Fold_marK  #"\s*{{{\d\?$# conceal containedin=vimLineComment,vimComment
        au AG Syntax   *   syn match Fold_marK  #"\s*}}}\d\?$# conceal containedin=vimLineComment,vimComment


" 花哨的digraph:
            "
        " Db ◆  9670 Dw ◇  9671 LZ ◊  9674 0m ○  9675 0o ◎  9678 0M ●  9679 0L ◐  9680 0R ◑  9681 Sn ◘  9688 Ic ◙  9689
        " Fd ◢  9698 Bd ◣  9699 *2 ★  9733 *1 ☆  9734 <H ☜  9756 >H ☞  9758 0u ☺  9786 0U ☻  9787 SU ☼  9788 Fm ♀  9792
        " Ml ♂  9794 cS ♠  9824 cH ♡  9825 cD ♢  9826 cC ♣  9827 Md ♩  9833 M8 ♪  9834 M2 ♫  9835 Mb ♭  9837 Mx ♮  9838
        " MX ♯  9839 OK ✓  10003XX ✗  10007-X ✠  10016IS   12288 ,_ 、 12289 ._ 。 12290 +" 〃 12291 +_ 〄 12292 *_ 々 12293

" ref:
    " if !has('conceal')
    "     finish
    " endif
    "
    " syntax clear cppOperator
    "
    " syntax match cppOperator "<=" conceal cchar=≤
    " syntax match cppOperator ">=" conceal cchar=≥
    "
    " syntax match cppOperator "=\@<!===\@!" conceal cchar=≡
    " syntax match cppOperator "!=" conceal cchar=≢
    "
    " syntax match cppOperator "\<or\>" conceal cchar=∨
    " syntax match cppOperator "\<and\>" conceal cchar=∧
    " syntax match cppOperator "\<not\>" conceal cchar=¬
    "
    " syntax match cppOperator "::" conceal cchar=∷
    " syntax match cppOperator "++" conceal cchar=⧺
    "
    " syntax match cppOperator "\<pi\>" conceal cchar=π
    " syntax match cppOperator "\<sqrt\>" conceal cchar=√
    "
    " syntax match cppOperator ">>" conceal cchar=»
    " syntax match cppOperator "<<" conceal cchar=«
    "
    " syntax keyword cppOperator NULL conceal cchar=⊥
    " syntax keyword cppOperator nullptr conceal cchar=⊥
    "
    " syntax keyword cppOperator bool conceal cchar=𝔹
    " syntax keyword cppOperator int conceal cchar=ℤ
    " syntax keyword cppOperator float conceal cchar=ℜ
    "
    " syntax match cppOperator "\<length\>" conceal cchar=ₗ
    " syntax match cppOperator "\<size\>" conceal cchar=ₛ
    "
    " syntax match cppOperator "\<array\>" conceal cchar=𝒜
    " syntax match cppOperator "\<list\>" conceal cchar=ℒ
    "
    " syntax keyword cppOperator void conceal cchar=⊥
    "
    " syntax keyword cppOperator false conceal cchar=𝐅
    "
    " syntax keyword cppOperator true conceal cchar=𝐓
    "
    "
    "
    " syntax keyword cppOperator function conceal cchar=λ
    " syntax keyword cppOperator return conceal cchar=↵
    "
    " hi link cppOperator Operator
    " hi! link Conceal Operator
    "
    " setl     conceallevel=1
    "
    "
    "
    "
" ref:
    " setl     conceallevel=1
    " syntax clear cppOperator
    "
        " syntax match cppOperator "++" conceal cchar=⧺
        "
        " syntax match cppOperator "=\@<!===\@!" conceal cchar=≖
        " syntax match cppOperator "!=" conceal cchar=≠
        " syntax match cppOperator "<=" conceal cchar=≤
        " syntax match cppOperator ">=" conceal cchar=≥
        "
        " syntax match cppOperator "<<" conceal cchar=«
        " syntax match cppOperator ">>" conceal cchar=»
        "
        " syntax match cppOperator "::" conceal cchar=∷
        " syntax match cppOperator "->" conceal cchar=→
        "
        " syntax match cppOperator "||" conceal cchar=∥
    "
1
  • This answer contains a lot of code and practically no explanation. An edit to trim down the code to representative examples and add explanations would improve this answer.
    – D. Ben Knoble
    Jun 10, 2022 at 14:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.