" Script Name: mark.vim " Description: Highlight several words in different colors simultaneously. " " Copyright: (C) 2008-2018 Ingo Karkat " (C) 2005-2008 Yuheng Xie " The VIM LICENSE applies to this script; see ':help copyright'. " " Maintainer: Ingo Karkat " Orig Author: Yuheng Xie " Contributors:Luc Hermitte, Ingo Karkat " " Dependencies: " - Requires Vim 7.1 with "matchadd()", or Vim 7.2 or higher. " - mark.vim autoload script " - mark/palettes.vim autoload script for additional palettes " - mark/cascade.vim autoload script for cascading search " - ingo/err.vim autoload script " - ingo/msg.vim autoload script " " Version: 3.0.0 " Avoid installing twice or when in unsupported Vim version. if exists('g:loaded_mark') || (v:version == 701 && ! exists('*matchadd')) || (v:version < 701) finish endif let g:loaded_mark = 1 let s:save_cpo = &cpo set cpo&vim "- configuration -------------------------------------------------------------- if ! exists('g:mwHistAdd') let g:mwHistAdd = '/@' endif if ! exists('g:mwAutoLoadMarks') let g:mwAutoLoadMarks = 0 endif if ! exists('g:mwAutoSaveMarks') let g:mwAutoSaveMarks = 1 endif if ! exists('g:mwDefaultHighlightingNum') let g:mwDefaultHighlightingNum = -1 endif if ! exists('g:mwDefaultHighlightingPalette') let g:mwDefaultHighlightingPalette = 'original' endif if ! exists('g:mwPalettes') let g:mwPalettes = { \ 'original': [ \ { 'ctermbg':'Cyan', 'ctermfg':'Black', 'guibg':'#8CCBEA', 'guifg':'Black' }, \ { 'ctermbg':'Green', 'ctermfg':'Black', 'guibg':'#A4E57E', 'guifg':'Black' }, \ { 'ctermbg':'Yellow', 'ctermfg':'Black', 'guibg':'#FFDB72', 'guifg':'Black' }, \ { 'ctermbg':'Red', 'ctermfg':'Black', 'guibg':'#FF7272', 'guifg':'Black' }, \ { 'ctermbg':'Magenta', 'ctermfg':'Black', 'guibg':'#FFB3FF', 'guifg':'Black' }, \ { 'ctermbg':'Blue', 'ctermfg':'Black', 'guibg':'#9999FF', 'guifg':'Black' }, \], \ 'extended': function('mark#palettes#Extended'), \ 'maximum': function('mark#palettes#Maximum') \} endif if ! exists('g:mwDirectGroupJumpMappingNum') let g:mwDirectGroupJumpMappingNum = 9 endif if ! exists('g:mwExclusionPredicates') let g:mwExclusionPredicates = [function('mark#DefaultExclusionPredicate')] endif if ! exists('g:mwMaxMatchPriority') " Default the highest match priority to -10, so that we do not override the " 'hlsearch' of 0, and still allow other custom highlightings to sneak in " between. let g:mwMaxMatchPriority = -10 endif "- default highlightings ------------------------------------------------------ function! s:GetPalette() let l:palette = [] if type(g:mwDefaultHighlightingPalette) == type([]) " There are custom color definitions, not a named built-in palette. return g:mwDefaultHighlightingPalette endif if ! has_key(g:mwPalettes, g:mwDefaultHighlightingPalette) if ! empty(g:mwDefaultHighlightingPalette) call ingo#msg#WarningMsg('Mark: Unknown value for g:mwDefaultHighlightingPalette: ' . g:mwDefaultHighlightingPalette) endif return [] endif if type(g:mwPalettes[g:mwDefaultHighlightingPalette]) == type([]) return g:mwPalettes[g:mwDefaultHighlightingPalette] elseif type(g:mwPalettes[g:mwDefaultHighlightingPalette]) == type(function('tr')) return call(g:mwPalettes[g:mwDefaultHighlightingPalette], []) else call ingo#msg#ErrorMsg(printf('Mark: Invalid value type for g:mwPalettes[%s]', g:mwDefaultHighlightingPalette)) return [] endif endfunction function! s:DefineHighlightings( palette, isOverride ) let l:command = (a:isOverride ? 'highlight' : 'highlight def') let l:highlightingNum = (g:mwDefaultHighlightingNum == -1 ? len(a:palette) : g:mwDefaultHighlightingNum) for i in range(1, l:highlightingNum) execute l:command 'MarkWord' . i join(map(items(a:palette[i - 1]), 'join(v:val, "=")')) endfor return l:highlightingNum endfunction call s:DefineHighlightings(s:GetPalette(), 0) autocmd ColorScheme * call DefineHighlightings(GetPalette(), 0) " Default highlighting for the special search type. " You can override this by defining / linking the 'SearchSpecialSearchType' " highlight group before this script is sourced. highlight def link SearchSpecialSearchType MoreMsg "- mappings ------------------------------------------------------------------- nnoremap MarkSet :if ! mark#MarkCurrentWord(v:count)execute "normal! \C-\>\C-n>\Esc>"endif vnoremap MarkSet :if ! mark#DoMark(v:count, mark#GetVisualSelectionAsLiteralPattern())[0]execute "normal! \C-\>\C-n>\Esc>"endif vnoremap MarkIWhiteSet :if ! mark#DoMark(v:count, mark#GetVisualSelectionAsLiteralWhitespaceIndifferentPattern())[0]execute "normal! \C-\>\C-n>\Esc>"endif nnoremap MarkRegex :if ! mark#MarkRegex(v:count, '')execute "normal! \C-\>\C-n>\Esc>"echoerr ingo#err#Get()endif vnoremap MarkRegex :if ! mark#MarkRegex(v:count, mark#GetVisualSelectionAsRegexp())execute "normal! \C-\>\C-n>\Esc>"echoerr ingo#err#Get()endif nnoremap MarkClear :if ! mark#Clear(v:count)execute "normal! \C-\>\C-n>\Esc>"echoerr ingo#err#Get()endif nnoremap MarkAllClear :call mark#ClearAll() nnoremap MarkConfirmAllClear :if confirm('Really delete all marks? This cannot be undone.', "&Yes\n&No") == 1call mark#ClearAll()endif nnoremap MarkToggle :call mark#Toggle() nnoremap MarkSearchCurrentNext :if ! mark#SearchCurrentMark(0)echoerr ingo#err#Get()endif nnoremap MarkSearchCurrentPrev :if ! mark#SearchCurrentMark(1)echoerr ingo#err#Get()endif nnoremap MarkSearchAnyNext :if ! mark#SearchAnyMark(0)echoerr ingo#err#Get()endif nnoremap MarkSearchAnyPrev :if ! mark#SearchAnyMark(1)echoerr ingo#err#Get()endif " When typed, [*#nN] open the fold at the search result, but inside a mapping or " :normal this must be done explicitly via 'zv'. nnoremap MarkSearchNext :if ! mark#SearchNext(0)execute 'normal! *zv'endif nnoremap MarkSearchPrev :if ! mark#SearchNext(1)execute 'normal! #zv'endif nnoremap MarkSearchOrCurNext :if ! mark#SearchNext(0,'mark#SearchCurrentMark')execute 'normal! *zv'endif nnoremap MarkSearchOrCurPrev :if ! mark#SearchNext(1,'mark#SearchCurrentMark')execute 'normal! #zv'endif nnoremap MarkSearchOrAnyNext :if ! mark#SearchNext(0,'mark#SearchAnyMark')execute 'normal! *zv'endif nnoremap MarkSearchOrAnyPrev :if ! mark#SearchNext(1,'mark#SearchAnyMark')execute 'normal! #zv'endif nnoremap MarkSearchGroupNext :if ! mark#SearchGroupMark(v:count, 1, 0, 1)execute "normal! \C-\>\C-n>\Esc>"echoerr ingo#err#Get()endif nnoremap MarkSearchGroupPrev :if ! mark#SearchGroupMark(v:count, 1, 1, 1)execute "normal! \C-\>\C-n>\Esc>"echoerr ingo#err#Get()endif nnoremap MarkSearchUsedGroupNext :if ! mark#SearchNextGroup(v:count1, 0)execute "normal! \C-\>\C-n>\Esc>"echoerr ingo#err#Get()endif nnoremap MarkSearchUsedGroupPrev :if ! mark#SearchNextGroup(v:count1, 1)execute "normal! \C-\>\C-n>\Esc>"echoerr ingo#err#Get()endif nnoremap MarkSearchCascadeStartWithStop :if ! mark#cascade#Start(v:count, 1)execute "normal! \C-\>\C-n>\Esc>" echoerr ingo#err#Get()endif nnoremap MarkSearchCascadeNextWithStop :if ! mark#cascade#Next(v:count1, 1, 0)execute "normal! \C-\>\C-n>\Esc>"echoerr ingo#err#Get()endif nnoremap MarkSearchCascadePrevWithStop :if ! mark#cascade#Next(v:count1, 1, 1)execute "normal! \C-\>\C-n>\Esc>"echoerr ingo#err#Get()endif nnoremap MarkSearchCascadeStartNoStop :if ! mark#cascade#Start(v:count, 0)execute "normal! \C-\>\C-n>\Esc>" echoerr ingo#err#Get()endif nnoremap MarkSearchCascadeNextNoStop :if ! mark#cascade#Next(v:count1, 0, 0)execute "normal! \C-\>\C-n>\Esc>"echoerr ingo#err#Get()endif nnoremap MarkSearchCascadePrevNoStop :if ! mark#cascade#Next(v:count1, 0, 1)execute "normal! \C-\>\C-n>\Esc>"echoerr ingo#err#Get()endif if !hasmapto('MarkSet', 'n') nmap l MarkSet endif if !hasmapto('MarkSet', 'x') xmap l MarkSet endif " No default mapping for MarkIWhiteSet. if !hasmapto('MarkRegex', 'n') nmap r MarkRegex endif if !hasmapto('MarkRegex', 'x') xmap r MarkRegex endif if !hasmapto('MarkClear', 'n') nmap k MarkClear endif " No default mapping for MarkAllClear. " No default mapping for MarkConfirmAllClear. " No default mapping for MarkToggle. "if !hasmapto('MarkSearchCurrentNext', 'n') " nmap * MarkSearchCurrentNext "endif if !hasmapto('MarkSearchCurrentPrev', 'n') nmap # MarkSearchCurrentPrev endif if !hasmapto('MarkSearchAnyNext', 'n') nmap / MarkSearchAnyNext endif if !hasmapto('MarkSearchAnyPrev', 'n') nmap ? MarkSearchAnyPrev endif if !hasmapto('MarkSearchNext', 'n') nmap * MarkSearchNext endif if !hasmapto('MarkSearchPrev', 'n') nmap # MarkSearchPrev endif " No default mapping for MarkSearchOrCurNext " No default mapping for MarkSearchOrCurPrev " No default mapping for MarkSearchOrAnyNext " No default mapping for MarkSearchOrAnyPrev " No default mapping for MarkSearchGroupNext " No default mapping for MarkSearchGroupPrev " No default mapping for MarkSearchUsedGroupNext " No default mapping for MarkSearchUsedGroupPrev function! s:MakeDirectGroupMappings() for l:cnt in range(1, g:mwDirectGroupJumpMappingNum) for [l:isBackward, l:direction, l:keyModifier] in [[0, 'Next', ''], [1, 'Prev', 'C-']] let l:plugMappingName = printf('MarkSearchGroup%d%s', l:cnt, l:direction) execute printf('nnoremap %s :if ! mark#SearchGroupMark(%d, v:count1, %d, 1)execute "normal! \C-\>\C-n>\Esc>"echoerr ingo#err#Get()endif', l:plugMappingName, l:cnt, l:isBackward) if ! hasmapto(l:plugMappingName, 'n') execute printf('nmap <%sk%d> %s', l:keyModifier, l:cnt, l:plugMappingName) endif endfor endfor endfunction call s:MakeDirectGroupMappings() delfunction s:MakeDirectGroupMappings "- commands ------------------------------------------------------------------- command! -bang -range=0 -nargs=? -complete=customlist,mark#Complete Mark if 0 | silent call mark#DoMark(, '') | endif | if ! mark#SetMark(, )[0] | echoerr ingo#err#Get() | endif command! -bar MarkClear call mark#ClearAll() command! -bar Marks call mark#List() command! -bar -nargs=? -complete=customlist,mark#MarksVariablesComplete MarkLoad if ! mark#LoadCommand(1, ) | echoerr ingo#err#Get() | endif command! -bar -nargs=? -complete=customlist,mark#MarksVariablesComplete MarkSave if ! mark#SaveCommand() | echoerr ingo#err#Get() | endif command! -bar -register MarkYankDefinitions if ! mark#YankDefinitions(0, ) | echoerr ingo#err#Get()| endif command! -bar -register MarkYankDefinitionsOneLiner if ! mark#YankDefinitions(1, ) | echoerr ingo#err#Get()| endif function! s:SetPalette( paletteName ) if type(g:mwDefaultHighlightingPalette) == type([]) " Convert the directly defined list to a palette named "default". let g:mwPalettes['default'] = g:mwDefaultHighlightingPalette unlet! g:mwDefaultHighlightingPalette " Avoid E706. endif let g:mwDefaultHighlightingPalette = a:paletteName let l:palette = s:GetPalette() if empty(l:palette) return endif call mark#ReInit(s:DefineHighlightings(l:palette, 1)) call mark#UpdateScope() endfunction function! s:MarkPaletteComplete( ArgLead, CmdLine, CursorPos ) return sort(filter(keys(g:mwPalettes), 'v:val =~ ''\V\^'' . escape(a:ArgLead, "\\")')) endfunction command! -bar -nargs=1 -complete=customlist,MarkPaletteComplete MarkPalette call SetPalette() command! -bar -bang -range=0 -nargs=? MarkName if ! mark#SetName(0, , ) | echoerr ingo#err#Get() | endif "- marks persistence ---------------------------------------------------------- if g:mwAutoLoadMarks " As the viminfo is only processed after sourcing of the runtime files, the " persistent global variables are not yet available here. Defer this until Vim " startup has completed. function! s:AutoLoadMarks() if g:mwAutoLoadMarks && exists('g:MARK_MARKS') && g:MARK_MARKS !=# '[]' if ! exists('g:MARK_ENABLED') || g:MARK_ENABLED " There are persistent marks and they haven't been disabled; we need to " show them right now. call mark#LoadCommand(0) else " Though there are persistent marks, they have been disabled. We avoid " sourcing the autoload script and its invasive autocmds right now; " maybe the marks are never turned on. We just inform the autoload " script that it should do this once it is sourced on-demand by a " mark mapping or command. let g:mwDoDeferredLoad = 1 endif endif endfunction augroup MarkInitialization autocmd! " Note: Avoid triggering the autoload unless there actually are persistent " marks. For that, we need to check that g:MARK_MARKS doesn't contain the " empty list representation, and also :execute the :call. autocmd VimEnter * call AutoLoadMarks() augroup END endif let &cpo = s:save_cpo unlet s:save_cpo " vim: ts=4 sts=0 sw=4 noet