Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1547176
  • 博文数量: 596
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 173
  • 用 户 组: 普通用户
  • 注册时间: 2016-07-06 15:50
个人简介

在线笔记

文章分类

全部博文(596)

文章存档

2016年(1)

2015年(104)

2014年(228)

2013年(226)

2012年(26)

2011年(11)

分类: Android平台

2015-04-30 10:31:37


  1. " Script Name: mark.vim
  2. " Description: Highlight several words in different colors simultaneously.
  3. "
  4. " Copyright: (C) 2005-2008 by Yuheng Xie
  5. " (C) 2008-2011 by Ingo Karkat
  6. " The VIM LICENSE applies to this script; see ':help copyright'.
  7. "
  8. " Maintainer: Ingo Karkat <ingo@karkat.de>
  9. " modify by yangrz, base 2.51 version
  10. "
  11. " Avoid installing twice or when in unsupported Vim version.
  12. if exists('g:loaded_mark') || (v:version == 701 && ! exists('*matchadd')) || (v:version < 702)
  13.     finish
  14. endif
  15. let g:loaded_mark = 1

  16. "- functions ------------------------------------------------------------------
  17.  s:EscapeText( text )
  18.     return substitute( escape(a:text, '\' . '^$.*[~'), "\n", '\\n', 'ge' )
  19. endfunction

  20. " Mark the current word, like the built-in star command.
  21. " If the cursor is on an existing mark, remove it.
  22.  mark#MarkCurrentWord()
  23.     let l:regexp = mark#CurrentMark()[0]
  24.     if empty(l:regexp)
  25.         let l:cword = expand('<cword>')
  26.         if ! empty(l:cword)
  27.             let l:regexp = s:EscapeText(l:cword)
  28.             " The star command only creates a \ search pattern if the
  29.             " <cword> actually only consists of keyword characters.
  30.             if l:cword =~# '^\k\+$'
  31.                 let l:regexp = '\<' . l:regexp . '\>'
  32.             endif
  33.         endif
  34.     endif

  35.     if ! empty(l:regexp)
  36.         let @/ = l:regexp
  37.         call mark#DoMark(l:regexp)
  38.     endif
  39. endfunction

  40.  s:Cycle( ... )
  41.     let l:currentCycle = s:cycle
  42.     let l:newCycle = (a:0 ? a:1 : s:cycle) + 1
  43.     let s:cycle = (l:newCycle < s:markNum ? l:newCycle : 0)
  44.     return l:currentCycle
  45. endfunction

  46. " Set match / clear matches in the current window.
  47. function! s:MarkMatch( indices, expr )
  48.     if ! exists('w:mwMatch') || len(w:mwMatch) == 0
  49.         let w:mwMatch = repeat([0], s:markNum)
  50.     endif

  51.     for l:index in a:indices
  52.         if w:mwMatch[l:index] > 0
  53.             silent! call matchdelete(w:mwMatch[l:index])
  54.             let w:mwMatch[l:index] = 0
  55.         endif
  56.     endfor

  57.     if ! empty(a:expr)
  58.         let l:index = a:indices[0]    " Can only set one index for now.

  59.         " Info: matchadd() does not consider the 'magic' (it's always on),
  60.         " 'ignorecase' and 'smartcase' settings.
  61.         " Make the match according to the 'ignorecase' setting, like the star command.
  62.         " (But honor an explicit case-sensitive regexp via the /\C/ atom.)
  63.         let l:expr = ((&ignorecase && a:expr !~# '\\\@<!\\C') ? '\c' . a:expr : a:expr)

  64.         " To avoid an arbitrary ordering of highlightings, we assign a different
  65.         " priority based on the highlighting group, and ensure that the highest
  66.         " priority is -10, so that we do not override the 'hlsearch' of 0, and still
  67.         " allow other custom highlightings to sneak in between.
  68.         let l:priority = -10 - s:markNum + 1 + l:index

  69.         let w:mwMatch[l:index] = matchadd('MarkWord' . (l:index + 1), l:expr, l:priority)
  70.     endif
  71. endfunction

  72. " Initialize mark colors in a (new) window.
  73. function! mark#UpdateMark()
  74.     let i = 0
  75.     while i < s:markNum
  76.         if ! s:enabled || empty(s:pattern[i])
  77.             call s:MarkMatch([i], '')
  78.         else
  79.             call s:MarkMatch([i], s:pattern[i])
  80.         endif
  81.         let i += 1
  82.     endwhile
  83. endfunction

  84. " Set / clear matches in all windows.
  85.  s:MarkScope( indices, expr )
  86.     let l:currentWinNr = winnr()

  87.     " By entering a window, its height is potentially increased from 0 to 1 (the
  88.     " minimum for the current window). To avoid any modification, save the window
  89.     " sizes and restore them after visiting all windows.
  90.     let l:originalWindowLayout = winrestcmd()

  91.     noautocmd windo call s:MarkMatch(a:indices, a:expr)
  92.     execute l:currentWinNr . 'wincmd w'
  93.     silent! execute l:originalWindowLayout
  94. endfunction

  95. " Update matches in all windows.
  96.  mark#UpdateScope()
  97.     let l:currentWinNr = winnr()

  98.     " By entering a window, its height is potentially increased from 0 to 1 (the
  99.     " minimum for the current window). To avoid any modification, save the window
  100.     " sizes and restore them after visiting all windows.
  101.     let l:originalWindowLayout = winrestcmd()

  102.     noautocmd windo call mark#UpdateMark()
  103.     execute l:currentWinNr . 'wincmd w'
  104.     silent! execute l:originalWindowLayout
  105. endfunction

  106. function! s:MarkEnable( enable, ...)
  107.     if s:enabled != a:enable
  108.         " En-/disable marks and perform a full refresh in all windows, unless
  109.         " explicitly suppressed by passing in 0.
  110.         let s:enabled = a:enable
  111.         
  112.         if ! a:0 || ! a:1
  113.             call mark#UpdateScope()
  114.         endif
  115.     endif
  116. endfunction

  117. function! s:EnableAndMarkScope( indices, expr )
  118.     if s:enabled
  119.         " Marks are already enabled, we just need to push the changes to all
  120.         " windows.
  121.         call s:MarkScope(a:indices, a:expr)
  122.     else
  123.         call s:MarkEnable(1)
  124.     endif
  125. endfunction

  126. " Toggle visibility of marks, like :nohlsearch does for the regular search
  127. " highlighting.
  128. function! mark#Toggle()
  129.     if s:enabled
  130.         call s:MarkEnable(0)
  131.         echo 'Disabled marks'
  132.     else
  133.         call s:MarkEnable(1)

  134.         let l:markCnt = len(filter(copy(s:pattern), '! empty(v:val)'))
  135.         echo 'Enabled' (l:markCnt > 0 ? l:markCnt . ' ' : '') . 'marks'
  136.     endif
  137. endfunction


  138. " Mark or unmark a regular expression.
  139.  s:SetPattern( index, pattern )
  140.     let s:pattern[a:index] = a:pattern
  141. endfunction

  142.  mark#ClearAll()
  143.     let i = 0
  144.     let indices = []
  145.     while i < s:markNum
  146.         if ! empty(s:pattern[i])
  147.             call s:SetPattern(i, '')
  148.             call add(indices, i)
  149.         endif
  150.         let i += 1
  151.     endwhile
  152.     let s:lastSearch = ''

  153. " Re-enable marks; not strictly necessary, since all marks have just been
  154. " cleared, and marks will be re-enabled, anyway, when the first mark is added.
  155. " It's just more consistent for mark persistence. But save the full refresh, as
  156. " we do the update ourselves.
  157.     call s:MarkEnable(0, 0)

  158.     call s:MarkScope(l:indices, '')

  159.     if len(indices) > 0
  160.         echo 'Cleared all' len(indices) 'marks'
  161.     else
  162.         echo 'All marks cleared'
  163.     endif
  164. endfunction

  165.  mark#DoMark(...) " DoMark(regexp)
  166.     let regexp = (a:0 ? a:1 : '')

  167.     " Disable marks if regexp is empty. Otherwise, we will be either removing a
  168.     " mark or adding one, so marks will be re-enabled.
  169.     if empty(regexp)
  170.         call mark#Toggle()
  171.         return
  172.     endif

  173.     " clear the mark if it has been marked
  174.     let i = 0
  175.     while i < s:markNum
  176.         if regexp ==# s:pattern[i]
  177.             if s:lastSearch ==# s:pattern[i]
  178.                 let s:lastSearch = ''
  179.             endif
  180.             call s:SetPattern(i, '')
  181.             call s:EnableAndMarkScope([i], '')
  182.             return
  183.         endif
  184.         let i += 1
  185.     endwhile

  186.     if s:markNum <= 0
  187.         " Uh, somehow no mark highlightings were defined. Try to detect them again.
  188.         call mark#Init()
  189.         if s:markNum <= 0
  190.             " Still no mark highlightings; complain.
  191.             let v:errmsg = 'No mark highlightings defined'
  192.             echohl ErrorMsg
  193.             echomsg v:errmsg
  194.             echohl None
  195.             return
  196.         endif
  197.     endif

  198.     " add to history
  199.     if stridx(g:mwHistAdd, '/') >= 0
  200.         call histadd('/', regexp)
  201.     endif
  202.     if stridx(g:mwHistAdd, '@') >= 0
  203.         call histadd('@', regexp)
  204.     endif

  205.     " choose an unused mark group
  206.     let i = 0
  207.     while i < s:markNum
  208.         if empty(s:pattern[i])
  209.             call s:SetPattern(i, regexp)
  210.             call s:Cycle(i)
  211.             call s:EnableAndMarkScope([i], regexp)
  212.             return
  213.         endif
  214.         let i += 1
  215.     endwhile

  216.     " choose a mark group by cycle
  217.     let i = s:Cycle()
  218.     if s:lastSearch ==# s:pattern[i]
  219.         let s:lastSearch = ''
  220.     endif
  221.     call s:SetPattern(i, regexp)
  222.     call s:EnableAndMarkScope([i], regexp)
  223. endfunction

  224. " Return [mark text, mark start position] of the mark under the cursor (or
  225. " ['', []] if there is no mark).
  226. " The mark can include the trailing newline character that concludes the line,
  227. " but marks that span multiple lines are not supported.
  228. function! mark#CurrentMark()
  229.     let line = getline('.') . "\n"

  230.     " Highlighting groups with higher numbers take precedence over lower numbers,
  231.     " and therefore its marks appear "above" other marks. To retrieve the visible
  232.     " mark in case of overlapping marks, we need to check from highest to lowest
  233.     " highlighting group.
  234.     let i = s:markNum - 1
  235.     while i >= 0
  236.         if ! empty(s:pattern[i])
  237.             " Note: col() is 1-based, all other indexes zero-
  238.             let start = 0
  239.             while start >= 0 && start < strlen(line) && start < col('.')
  240.                 let b = match(line, s:pattern[i], start)
  241.                 let e = matchend(line, s:pattern[i], start)
  242.                 if b < col('.') && col('.') <= e
  243.                     return [s:pattern[i], [line('.'), (b + 1)]]
  244.                 endif
  245.                 if b == e
  246.                     break
  247.                 endif
  248.                 let start = e
  249.             endwhile
  250.         endif
  251.         let i -= 1
  252.     endwhile
  253.     return ['', []]
  254. endfunction

  255. "- initializations ------------------------------------------------------------
  256. augroup Mark
  257.     autocmd!
  258.     autocmd WinEnter * if ! exists('w:mwMatch') | call mark#UpdateMark() | endif
  259.     autocmd TabEnter * call mark#UpdateScope()
  260. augroup END

  261. " Define global variables and initialize current scope.
  262.  mark#Init()
  263.     let s:markNum = 0
  264.     while hlexists('MarkWord' . (s:markNum + 1))
  265.         let s:markNum += 1
  266.     endwhile
  267.     let s:pattern = repeat([''], s:markNum)
  268.     let s:cycle = 0
  269.     let s:lastSearch = ''
  270.     let s:enabled = 1
  271. endfunction

  272. "- configuration --------------------------------------------------------------
  273. if ! exists('g:mwHistAdd')
  274.     let g:mwHistAdd = '/@'
  275. endif

  276. call mark#Init()
  277. call mark#UpdateScope()

  278. "- default highlightings ------------------------------------------------------
  279.  s:DefaultHighlightings()
  280.     " You may define your own colors in your vimrc file, in the form as below:
  281.     highlight def MarkWord1 ctermbg=Red ctermfg=White guibg=Red guifg=White
  282.     highlight def MarkWord2 ctermbg=Yellow ctermfg=Black guibg=Yellow guifg=Black
  283.     highlight def MarkWord3 ctermbg=Blue ctermfg=Black guibg=Blue guifg=Black
  284.     highlight def MarkWord4 ctermbg=Green ctermfg=Black guibg=Green guifg=Black
  285.     highlight def MarkWord5 ctermbg=Magenta ctermfg=White guibg=Magenta guifg=White
  286.     highlight def MarkWord6 ctermbg=Cyan ctermfg=Black guibg=Cyan guifg=Black
  287.     highlight def MarkWord7 ctermbg=Gray ctermfg=Black guibg=Gray guifg=Black
  288.     highlight def MarkWord8 ctermbg=Brown ctermfg=Black guibg=Brown guifg=Black
  289. endfunction

  290. call s:DefaultHighlightings()
  291. autocmd ColorScheme * call DefaultHighlightings()

  292. "- mappings -------------------------------------------------------------------
  293. nnoremap <silent> <Plug>MarkSet :<C-u>call mark#MarkCurrentWord()<CR>:noh<CR>
  294. nnoremap <silent> <Plug>MarkAllClear :<C-u>call mark#ClearAll()<CR>:noh<CR>

  295. if !hasmapto('<Plug>MarkSet', 'n')
  296.   nmap <unique> <silent> mm <Plug>MarkSet
  297.   nmap <unique> <silent> mc <Plug>MarkAllClear
  298. endif

  299.  -nargs=? Mark call mark#DoMark(<f-args>)
  300.  -bar MarkClear call mark#ClearAll()


阅读(1160) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~