Skip to content
Browse files

update mark to 2.6.1

  • Loading branch information...
1 parent fb0fca8 commit dd63ea9f69e0f49b5cf9e3840cf021b73fe783a3 @lilydjwg committed Mar 24, 2012
Showing with 558 additions and 357 deletions.
  1. +1 −1 .VimballRecord
  2. +318 −201 autoload/mark.vim
  3. +160 −97 doc/mark.txt
  4. +2 −0 doc/tags
  5. +77 −58 plugin/mark.vim
View
2 .VimballRecord
@@ -10,6 +10,6 @@ diff_movement.vba: call delete('/home/lilydjwg/.vim/ftplugin/diff_movement.vim')
mail_movement.vba: call delete('/home/lilydjwg/.vim/ftplugin/mail_movement.vim')
CountJump.vba: call delete('/home/lilydjwg/.vim/autoload/CountJump.vim')|call delete('/home/lilydjwg/.vim/autoload/CountJump/Motion.vim')|call delete('/home/lilydjwg/.vim/autoload/CountJump/Region.vim')|call delete('/home/lilydjwg/.vim/autoload/CountJump/Region/Motion.vim')|call delete('/home/lilydjwg/.vim/autoload/CountJump/Region/TextObject.vim')|call delete('/home/lilydjwg/.vim/autoload/CountJump/TextObject.vim')|call delete('/home/lilydjwg/.vim/doc/CountJump.txt')
autofmt.vmb: call delete('/home/lilydjwg/.vim/doc/autofmt.txt')|call delete('/home/lilydjwg/.vim/autoload/autofmt/japanese.vim')|call delete('/home/lilydjwg/.vim/autoload/autofmt/compat.vim')|call delete('/home/lilydjwg/.vim/autoload/autofmt/uax14.vim')|call delete('/home/lilydjwg/.vim/autoload/unicode.vim')|call delete('/home/lilydjwg/.vim/tools/unicode.vim')
-mark.vba: call delete('/home/lilydjwg/.vim/autoload/mark.vim')|call delete('/home/lilydjwg/.vim/plugin/mark.vim')|call delete('/home/lilydjwg/.vim/doc/mark.txt')
tagbar.vmb: call delete('/home/lilydjwg/.vim/autoload/tagbar.vim')|call delete('/home/lilydjwg/.vim/doc/tagbar.txt')|call delete('/home/lilydjwg/.vim/plugin/tagbar.vim')|call delete('/home/lilydjwg/.vim/syntax/tagbar.vim')
manpageview.vba: call delete('/home/lilydjwg/.vim/plugin/manpageviewPlugin.vim')|call delete('/home/lilydjwg/.vim/autoload/manpageview.vim')|call delete('/home/lilydjwg/.vim/syntax/man.vim')|call delete('/home/lilydjwg/.vim/syntax/mangl.vim')|call delete('/home/lilydjwg/.vim/syntax/mankey.vim')|call delete('/home/lilydjwg/.vim/syntax/info.vim')|call delete('/home/lilydjwg/.vim/syntax/manphp.vim')|call delete('/home/lilydjwg/.vim/doc/manpageview.txt')|call delete('/home/lilydjwg/.vim/plugin/cecutil.vim')
+mark.vba: call delete('/home/lilydjwg/.vim/autoload/mark.vim')|call delete('/home/lilydjwg/.vim/plugin/mark.vim')|call delete('/home/lilydjwg/.vim/doc/mark.txt')
View
519 autoload/mark.vim
@@ -1,122 +1,142 @@
" Script Name: mark.vim
-" Description: Highlight several words in different colors simultaneously.
+" Description: Highlight several words in different colors simultaneously.
"
" Copyright: (C) 2005-2008 by Yuheng Xie
-" (C) 2008-2011 by Ingo Karkat
-" The VIM LICENSE applies to this script; see ':help copyright'.
+" (C) 2008-2012 by Ingo Karkat
+" The VIM LICENSE applies to this script; see ':help copyright'.
"
-" Maintainer: Ingo Karkat <ingo@karkat.de>
+" Maintainer: Ingo Karkat <ingo@karkat.de>
"
" Dependencies:
-" - SearchSpecial.vim autoload script (optional, for improved search messages).
+" - SearchSpecial.vim autoload script (optional, for improved search messages).
"
-" Version: 2.5.2
+" Version: 2.6.1
" Changes:
+" 23-Mar-2012, Ingo Karkat
+" - ENH: Add :Marks command that prints all mark highlight groups and their
+" search patterns, plus information about the current search mark, next mark
+" group, and whether marks are disabled.
+" - ENH: Show which mark group a pattern was set / added / removed / cleared.
+" - Refactoring: Store index into s:pattern instead of pattern itself in
+" s:lastSearch. For that, mark#CurrentMark() now additionally returns the
+" index.
+" - CHG: Show mark group number in same-mark search and rename search types from
+" "any-mark", "same-mark", and "new-mark" to the shorter "mark-*", "mark-N",
+" and "mark-N!", respectively.
+"
+" 22-Mar-2012, Ingo Karkat
+" - ENH: Allow [count] for <Leader>m and :Mark to add / subtract match to / from
+" highlight group [count], and use [count]<Leader>n to clear only highlight
+" group [count]. This was also requested by Philipp Marek.
+" - FIX: :Mark and <Leader>n actually toggled marks back on when they were
+" already off. Now, they stay off on multiple invocations. Use :call
+" mark#Toggle() / <Plug>MarkToggle if you want toggling.
"
" 09-Nov-2011, Ingo Karkat
" - BUG: With a single match and 'wrapscan' set, a search error was issued
" instead of the wrap message. Add check for l:isStuckAtCurrentMark &&
-" l:isWrapped in the no-match part of s:Search().
+" l:isWrapped in the no-match part of s:Search().
" - FIX: In backwards search with single match, the :break short-circuits the
" l:isWrapped logic, resets l:line and therefore also confuses the logic and
" leads to wrong error message instead of wrap message. Don't reset l:line,
-" set l:isWrapped instead.
+" set l:isWrapped instead.
" - FIX: Wrong logic for determining l:isWrapped lets wrap-around go undetected
" when v:count >= number of total matches. [l:startLine, l:startCol] must
-" be updated on every iteration.
+" be updated on every iteration, and should therefore be named [l:prevLine,
+" l:prevCol].
"
" 17-May-2011, Ingo Karkat
" - Make s:GetVisualSelection() public to allow use in suggested
-" <Plug>MarkSpaceIndifferent vmap.
+" <Plug>MarkSpaceIndifferent vmap.
" - FIX: == comparison in s:DoMark() leads to wrong regexp (\A vs. \a) being
-" cleared when 'ignorecase' is set. Use case-sensitive comparison ==# instead.
+" cleared when 'ignorecase' is set. Use case-sensitive comparison ==# instead.
"
" 10-May-2011, Ingo Karkat
" - Refine :MarkLoad messages: Differentiate between nonexistent and empty
-" g:MARK_MARKS; add note when marks are disabled.
+" g:MARK_MARKS; add note when marks are disabled.
"
" 06-May-2011, Ingo Karkat
-" - Also print status message on :MarkClear to be consistent with :MarkToggle.
+" - Also print status message on :MarkClear to be consistent with :MarkToggle.
"
" 21-Apr-2011, Ingo Karkat
" - Implement toggling of mark display (keeping the mark patterns, unlike the
" clearing of marks), determined by s:enable. s:DoMark() now toggles on empty
" regexp, affecting the \n mapping and :Mark. Introduced
" s:EnableAndMarkScope() wrapper to correctly handle the highlighting updates
-" depending on whether marks were previously disabled.
-" - Implement persistence of s:enable via g:MARK_ENABLED.
+" depending on whether marks were previously disabled.
+" - Implement persistence of s:enable via g:MARK_ENABLED.
" - Generalize s:Enable() and combine with intermediate s:Disable() into
-" s:MarkEnable(), which also performs the persistence of s:enabled.
+" s:MarkEnable(), which also performs the persistence of s:enabled.
" - Implement lazy-loading of disabled persistent marks via g:mwDoDeferredLoad
-" flag passed from plugin/mark.vim.
+" flag passed from plugin/mark.vim.
"
" 20-Apr-2011, Ingo Karkat
" - Extract setting of s:pattern into s:SetPattern() and implement the automatic
-" persistence there.
+" persistence there.
"
" 19-Apr-2011, Ingo Karkat
" - ENH: Add enabling functions for mark persistence: mark#Load() and
-" mark#ToPatternList().
+" mark#ToPatternList().
" - Implement :MarkLoad and :MarkSave commands in mark#LoadCommand() and
-" mark#SaveCommand().
+" mark#SaveCommand().
" - Remove superfluous update autocmd on VimEnter: Persistent marks trigger the
" update themselves, same for :Mark commands which could potentially be issued
" e.g. in .vimrc. Otherwise, when no marks are defined after startup, the
" autosource script isn't even loaded yet, so the autocmd on the VimEnter
-" event isn't yet defined.
+" event isn't yet defined.
"
" 18-Apr-2011, Ingo Karkat
" - BUG: Include trailing newline character in check for current mark, so that a
" mark that matches the entire line (e.g. created by V<Leader>m) can be
-" cleared via <Leader>n. Thanks to ping for reporting this.
-" - Minor restructuring of mark#MarkCurrentWord().
+" cleared via <Leader>n. Thanks to ping for reporting this.
+" - Minor restructuring of mark#MarkCurrentWord().
" - FIX: On overlapping marks, mark#CurrentMark() returned the lowest, not the
" highest visible mark. So on overlapping marks, the one that was not visible
" at the cursor position was removed; very confusing! Use reverse iteration
-" order.
+" order.
" - FIX: To avoid an arbitrary ordering of highlightings when the highlighting
" group names roll over, and to avoid order inconsistencies across different
" windows and tabs, we assign a different priority based on the highlighting
-" group.
+" group.
" - Rename s:cycleMax to s:markNum; the previous name was too
-" implementation-focused and off-by-one with regards to the actual value.
+" implementation-focused and off-by-one with regards to the actual value.
"
" 16-Apr-2011, Ingo Karkat
" - Move configuration variable g:mwHistAdd to plugin/mark.vim (as is customary)
" and make the remaining g:mw... variables script-local, as these contain
" internal housekeeping information that does not need to be accessible by the
-" user.
+" user.
" - Add :MarkSave warning if 'viminfo' doesn't enable global variable
-" persistence.
+" persistence.
"
" 15-Apr-2011, Ingo Karkat
" - Robustness: Move initialization of w:mwMatch from mark#UpdateMark() to
" s:MarkMatch(), where the variable is actually used. I had encountered cases
" where it w:mwMatch was undefined when invoked through mark#DoMark() ->
" s:MarkScope() -> s:MarkMatch(). This can be forced by :unlet w:mwMatch
-" followed by :Mark foo.
+" followed by :Mark foo.
" - Robustness: Checking for s:markNum == 0 in mark#DoMark(), trying to
" re-detect the mark highlightings and finally printing an error instead of
-" choking. This can happen when somehow no mark highlightings are defined.
+" choking. This can happen when somehow no mark highlightings are defined.
"
" 14-Jan-2011, Ingo Karkat
" - FIX: Capturing the visual selection could still clobber the blockwise yank
-" mode of the unnamed register.
+" mode of the unnamed register.
"
" 13-Jan-2011, Ingo Karkat
" - FIX: Using a named register for capturing the visual selection on
" {Visual}<Leader>m and {Visual}<Leader>r clobbered the unnamed register. Now
-" using the unnamed register.
+" using the unnamed register.
"
" 13-Jul-2010, Ingo Karkat
" - ENH: The MarkSearch mappings (<Leader>[*#/?]) add the original cursor
" position to the jump list, like the built-in [/?*#nN] commands. This allows
" to use the regular jump commands for mark matches, like with regular search
-" matches.
+" matches.
"
" 19-Feb-2010, Andy Wokula
" - BUG: Clearing of an accidental zero-width match (e.g. via :Mark \zs) results
-" in endless loop. Thanks to Andy Wokula for the patch.
+" in endless loop. Thanks to Andy Wokula for the patch.
"
" 17-Nov-2009, Ingo Karkat + Andy Wokula
" - BUG: Creation of literal pattern via '\V' in {Visual}<Leader>m mapping
@@ -126,61 +146,89 @@
" (overly) generic mark#GetVisualSelectionEscaped() with
" mark#GetVisualSelectionAsRegexp() and
" mark#GetVisualSelectionAsLiteralPattern(). Thanks to Andy Wokula for the
-" patch.
+" patch.
"
" 06-Jul-2009, Ingo Karkat
-" - Re-wrote s:AnyMark() in functional programming style.
+" - Re-wrote s:AnyMark() in functional programming style.
" - Now resetting 'smartcase' before the search, this setting should not be
" considered for *-command-alike searches and cannot be supported because all
-" mark patterns are concatenated into one large regexp, anyway.
+" mark patterns are concatenated into one large regexp, anyway.
"
" 04-Jul-2009, Ingo Karkat
-" - Re-wrote s:Search() to handle v:count:
+" - Re-wrote s:Search() to handle v:count:
" - Obsoleted s:current_mark_position; mark#CurrentMark() now returns both the
-" mark text and start position.
+" mark text and start position.
" - s:Search() now checks for a jump to the current mark during a backward
-" search; this eliminates a lot of logic at its calling sites.
-" - Reverted negative logic at calling sites; using empty() instead of != "".
+" search; this eliminates a lot of logic at its calling sites.
+" - Reverted negative logic at calling sites; using empty() instead of != "".
" - Now passing a:isBackward instead of optional flags into s:Search() and
-" around its callers.
-" - ':normal! zv' moved from callers into s:Search().
+" around its callers.
+" - ':normal! zv' moved from callers into s:Search().
" - Removed delegation to SearchSpecial#ErrorMessage(), because the fallback
" implementation is perfectly fine and the SearchSpecial routine changed its
-" output format into something unsuitable anyway.
+" output format into something unsuitable anyway.
" - Using descriptive text instead of "@" (and appropriate highlighting) when
-" querying for the pattern to mark.
+" querying for the pattern to mark.
"
" 02-Jul-2009, Ingo Karkat
-" - Split off functions into autoload script.
+" - Split off functions into autoload script.
"- functions ------------------------------------------------------------------
+
+silent! call SearchSpecial#DoesNotExist() " Execute a function to force autoload.
+if exists('*SearchSpecial#WrapMessage')
+ function! s:WrapMessage( searchType, searchPattern, isBackward )
+ redraw
+ call SearchSpecial#WrapMessage(a:searchType, a:searchPattern, a:isBackward)
+ endfunction
+ function! s:EchoSearchPattern( searchType, searchPattern, isBackward )
+ call SearchSpecial#EchoSearchPattern(a:searchType, a:searchPattern, a:isBackward)
+ endfunction
+else
+ function! s:Trim( message )
+ " Limit length to avoid "Hit ENTER" prompt.
+ return strpart(a:message, 0, (&columns / 2)) . (len(a:message) > (&columns / 2) ? "..." : "")
+ endfunction
+ function! s:WrapMessage( searchType, searchPattern, isBackward )
+ redraw
+ let v:warningmsg = printf('%s search hit %s, continuing at %s', a:searchType, (a:isBackward ? 'TOP' : 'BOTTOM'), (a:isBackward ? 'BOTTOM' : 'TOP'))
+ echohl WarningMsg
+ echo s:Trim(v:warningmsg)
+ echohl None
+ endfunction
+ function! s:EchoSearchPattern( searchType, searchPattern, isBackward )
+ let l:message = (a:isBackward ? '?' : '/') . a:searchPattern
+ echohl SearchSpecialSearchType
+ echo a:searchType
+ echohl None
+ echon s:Trim(l:message)
+ endfunction
+endif
+
function! s:EscapeText( text )
return substitute( escape(a:text, '\' . '^$.*[~'), "\n", '\\n', 'ge' )
endfunction
-" Mark the current word, like the built-in star command.
-" If the cursor is on an existing mark, remove it.
-function! mark#MarkCurrentWord()
- let l:regexp = mark#CurrentMark()[0]
+" Mark the current word, like the built-in star command.
+" If the cursor is on an existing mark, remove it.
+function! mark#MarkCurrentWord( groupNum )
+ let l:regexp = (a:groupNum == 0 ? mark#CurrentMark()[0] : '')
if empty(l:regexp)
let l:cword = expand('<cword>')
if ! empty(l:cword)
let l:regexp = s:EscapeText(l:cword)
" The star command only creates a \<whole word\> search pattern if the
- " <cword> actually only consists of keyword characters.
+ " <cword> actually only consists of keyword characters.
if l:cword =~# '^\k\+$'
let l:regexp = '\<' . l:regexp . '\>'
endif
endif
endif
-
- if ! empty(l:regexp)
- call mark#DoMark(l:regexp)
- endif
+ return (empty(l:regexp) ? 0 : mark#DoMark(a:groupNum, l:regexp))
endfunction
function! mark#GetVisualSelection()
let save_clipboard = &clipboard
- set clipboard= " Avoid clobbering the selection and clipboard registers.
+ set clipboard= " Avoid clobbering the selection and clipboard registers.
let save_reg = getreg('"')
let save_regmode = getregtype('"')
silent normal! gvy
@@ -196,15 +244,15 @@ function! mark#GetVisualSelectionAsRegexp()
return substitute(mark#GetVisualSelection(), '\n', '', 'g')
endfunction
-" Manually input a regular expression.
+" Manually input a regular expression.
function! mark#MarkRegex( regexpPreset )
call inputsave()
echohl Question
let l:regexp = input('Input pattern to mark: ', a:regexpPreset)
echohl None
call inputrestore()
if ! empty(l:regexp)
- call mark#DoMark(l:regexp)
+ call mark#DoMark(0, l:regexp)
endif
endfunction
@@ -214,8 +262,18 @@ function! s:Cycle( ... )
let s:cycle = (l:newCycle < s:markNum ? l:newCycle : 0)
return l:currentCycle
endfunction
+function! s:FreeGroup()
+ let i = 0
+ while i < s:markNum
+ if empty(s:pattern[i])
+ return i
+ endif
+ let i += 1
+ endwhile
+ return -1
+endfunction
-" Set match / clear matches in the current window.
+" Set match / clear matches in the current window.
function! s:MarkMatch( indices, expr )
if ! exists('w:mwMatch')
let w:mwMatch = repeat([0], s:markNum)
@@ -229,24 +287,24 @@ function! s:MarkMatch( indices, expr )
endfor
if ! empty(a:expr)
- let l:index = a:indices[0] " Can only set one index for now.
+ let l:index = a:indices[0] " Can only set one index for now.
" Info: matchadd() does not consider the 'magic' (it's always on),
- " 'ignorecase' and 'smartcase' settings.
- " Make the match according to the 'ignorecase' setting, like the star command.
- " (But honor an explicit case-sensitive regexp via the /\C/ atom.)
+ " 'ignorecase' and 'smartcase' settings.
+ " Make the match according to the 'ignorecase' setting, like the star command.
+ " (But honor an explicit case-sensitive regexp via the /\C/ atom.)
let l:expr = ((&ignorecase && a:expr !~# '\\\@<!\\C') ? '\c' . a:expr : a:expr)
" To avoid an arbitrary ordering of highlightings, we assign a different
- " priority based on the highlighting group, and ensure that the highest
+ " priority based on the highlight group, and ensure that the highest
" priority is -10, so that we do not override the 'hlsearch' of 0, and still
- " allow other custom highlightings to sneak in between.
+ " allow other custom highlightings to sneak in between.
let l:priority = -10 - s:markNum + 1 + l:index
let w:mwMatch[l:index] = matchadd('MarkWord' . (l:index + 1), l:expr, l:priority)
endif
endfunction
-" Initialize mark colors in a (new) window.
+" Initialize mark colors in a (new) window.
function! mark#UpdateMark()
let i = 0
while i < s:markNum
@@ -258,27 +316,27 @@ function! mark#UpdateMark()
let i += 1
endwhile
endfunction
-" Set / clear matches in all windows.
+" Set / clear matches in all windows.
function! s:MarkScope( indices, expr )
let l:currentWinNr = winnr()
" By entering a window, its height is potentially increased from 0 to 1 (the
" minimum for the current window). To avoid any modification, save the window
- " sizes and restore them after visiting all windows.
- let l:originalWindowLayout = winrestcmd()
+ " sizes and restore them after visiting all windows.
+ let l:originalWindowLayout = winrestcmd()
noautocmd windo call s:MarkMatch(a:indices, a:expr)
execute l:currentWinNr . 'wincmd w'
silent! execute l:originalWindowLayout
endfunction
-" Update matches in all windows.
+" Update matches in all windows.
function! mark#UpdateScope()
let l:currentWinNr = winnr()
" By entering a window, its height is potentially increased from 0 to 1 (the
" minimum for the current window). To avoid any modification, save the window
- " sizes and restore them after visiting all windows.
- let l:originalWindowLayout = winrestcmd()
+ " sizes and restore them after visiting all windows.
+ let l:originalWindowLayout = winrestcmd()
noautocmd windo call mark#UpdateMark()
execute l:currentWinNr . 'wincmd w'
@@ -288,12 +346,12 @@ endfunction
function! s:MarkEnable( enable, ...)
if s:enabled != a:enable
" En-/disable marks and perform a full refresh in all windows, unless
- " explicitly suppressed by passing in 0.
+ " explicitly suppressed by passing in 0.
let s:enabled = a:enable
if g:mwAutoSaveMarks
let g:MARK_ENABLED = s:enabled
endif
-
+
if ! a:0 || ! a:1
call mark#UpdateScope()
endif
@@ -302,15 +360,15 @@ endfunction
function! s:EnableAndMarkScope( indices, expr )
if s:enabled
" Marks are already enabled, we just need to push the changes to all
- " windows.
+ " windows.
call s:MarkScope(a:indices, a:expr)
else
call s:MarkEnable(1)
endif
endfunction
" Toggle visibility of marks, like :nohlsearch does for the regular search
-" highlighting.
+" highlighting.
function! mark#Toggle()
if s:enabled
call s:MarkEnable(0)
@@ -324,7 +382,7 @@ function! mark#Toggle()
endfunction
-" Mark or unmark a regular expression.
+" Mark or unmark a regular expression.
function! s:SetPattern( index, pattern )
let s:pattern[a:index] = a:pattern
@@ -342,12 +400,12 @@ function! mark#ClearAll()
endif
let i += 1
endwhile
- let s:lastSearch = ''
+ let s:lastSearch = -1
" Re-enable marks; not strictly necessary, since all marks have just been
" cleared, and marks will be re-enabled, anyway, when the first mark is added.
" It's just more consistent for mark persistence. But save the full refresh, as
-" we do the update ourselves.
+" we do the update ourselves.
call s:MarkEnable(0, 0)
call s:MarkScope(l:indices, '')
@@ -358,40 +416,93 @@ function! mark#ClearAll()
echo 'All marks cleared'
endif
endfunction
-function! mark#DoMark(...) " DoMark(regexp)
- let regexp = (a:0 ? a:1 : '')
-
- " Disable marks if regexp is empty. Otherwise, we will be either removing a
- " mark or adding one, so marks will be re-enabled.
- if empty(regexp)
- call mark#Toggle()
- return
- endif
-
- " clear the mark if it has been marked
- let i = 0
- while i < s:markNum
- if regexp ==# s:pattern[i]
- if s:lastSearch ==# s:pattern[i]
- let s:lastSearch = ''
- endif
- call s:SetPattern(i, '')
- call s:EnableAndMarkScope([i], '')
- return
+function! s:SetMark( index, regexp, ... )
+ if a:0
+ if s:lastSearch == a:index
+ let s:lastSearch = a:1
endif
- let i += 1
- endwhile
-
+ endif
+ call s:SetPattern(a:index, a:regexp)
+ call s:EnableAndMarkScope([a:index], a:regexp)
+endfunction
+function! s:ClearMark( index )
+ " A last search there is reset.
+ call s:SetMark(a:index, '', -1)
+endfunction
+function! s:EchoMark( groupNum, regexp )
+ call s:EchoSearchPattern('mark-' . a:groupNum, a:regexp, 0)
+endfunction
+function! s:EchoMarkCleared( groupNum )
+ echohl SearchSpecialSearchType
+ echo 'mark-' . a:groupNum
+ echohl None
+ echon ' cleared'
+endfunction
+function! s:EchoMarksDisabled()
+ echo 'All marks disabled'
+endfunction
+function! mark#DoMark( groupNum, ...)
if s:markNum <= 0
- " Uh, somehow no mark highlightings were defined. Try to detect them again.
+ " Uh, somehow no mark highlightings were defined. Try to detect them again.
call mark#Init()
if s:markNum <= 0
- " Still no mark highlightings; complain.
+ " Still no mark highlightings; complain.
let v:errmsg = 'No mark highlightings defined'
echohl ErrorMsg
echomsg v:errmsg
echohl None
- return
+ return 0
+ endif
+ endif
+
+ if a:groupNum > s:markNum
+ " This highlight group does not exist.
+ return 0
+ endif
+
+ let regexp = (a:0 ? a:1 : '')
+ if empty(regexp)
+ if a:groupNum == 0
+ " Disable all marks.
+ call s:MarkEnable(0)
+ call s:EchoMarksDisabled()
+ else
+ " Clear the mark represented by the passed highlight group number.
+ call s:ClearMark(a:groupNum - 1)
+ call s:EchoMarkCleared(a:groupNum)
+ endif
+
+ return 1
+ endif
+
+ if a:groupNum == 0
+ " Clear the mark if it has been marked.
+ let i = 0
+ while i < s:markNum
+ if regexp ==# s:pattern[i]
+ call s:ClearMark(i)
+ call s:EchoMarkCleared(i + 1)
+ return 1
+ endif
+ let i += 1
+ endwhile
+ else
+ " Add / subtract the pattern as an alternative to the mark represented
+ " by the passed highlight group number.
+ let existingPattern = s:pattern[a:groupNum - 1]
+ if ! empty(existingPattern)
+ " Split only on \|, but not on \\|.
+ let alternatives = split(existingPattern, '\%(\%(^\|[^\\]\)\%(\\\\\)*\\\)\@<!\\|')
+ if index(alternatives, regexp) == -1
+ let regexp = existingPattern . '\|' . regexp
+ else
+ let regexp = join(filter(alternatives, 'v:val !=# regexp'), '\|')
+ if empty(regexp)
+ call s:ClearMark(a:groupNum - 1)
+ call s:EchoMarkCleared(a:groupNum)
+ return 1
+ endif
+ endif
endif
endif
@@ -403,48 +514,49 @@ function! mark#DoMark(...) " DoMark(regexp)
call histadd('@', regexp)
endif
- " choose an unused mark group
- let i = 0
- while i < s:markNum
- if empty(s:pattern[i])
- call s:SetPattern(i, regexp)
+ if a:groupNum == 0
+ let i = s:FreeGroup()
+ if i != -1
+ " Choose an unused highlight group. The last search is kept untouched.
call s:Cycle(i)
- call s:EnableAndMarkScope([i], regexp)
- return
+ call s:SetMark(i, regexp)
+ else
+ " Choose a highlight group by cycle. A last search there is reset.
+ let i = s:Cycle()
+ call s:SetMark(i, regexp, -1)
endif
- let i += 1
- endwhile
-
- " choose a mark group by cycle
- let i = s:Cycle()
- if s:lastSearch ==# s:pattern[i]
- let s:lastSearch = ''
+ else
+ let i = a:groupNum - 1
+ " Use and extend the passed highlight group. A last search is updated
+ " and thereby kept active.
+ call s:SetMark(i, regexp, i)
endif
- call s:SetPattern(i, regexp)
- call s:EnableAndMarkScope([i], regexp)
+
+ call s:EchoMark(i + 1, regexp)
+ return 1
endfunction
-" Return [mark text, mark start position] of the mark under the cursor (or
-" ['', []] if there is no mark).
+" Return [mark text, mark start position, mark index] of the mark under the
+" cursor (or ['', [], -1] if there is no mark).
" The mark can include the trailing newline character that concludes the line,
-" but marks that span multiple lines are not supported.
+" but marks that span multiple lines are not supported.
function! mark#CurrentMark()
let line = getline('.') . "\n"
" Highlighting groups with higher numbers take precedence over lower numbers,
" and therefore its marks appear "above" other marks. To retrieve the visible
" mark in case of overlapping marks, we need to check from highest to lowest
- " highlighting group.
+ " highlight group.
let i = s:markNum - 1
while i >= 0
if ! empty(s:pattern[i])
- " Note: col() is 1-based, all other indexes zero-based!
+ " Note: col() is 1-based, all other indexes zero-based!
let start = 0
while start >= 0 && start < strlen(line) && start < col('.')
let b = match(line, s:pattern[i], start)
let e = matchend(line, s:pattern[i], start)
if b < col('.') && col('.') <= e
- return [s:pattern[i], [line('.'), (b + 1)]]
+ return [s:pattern[i], [line('.'), (b + 1)], i]
endif
if b == e
break
@@ -454,54 +566,25 @@ function! mark#CurrentMark()
endif
let i -= 1
endwhile
- return ['', []]
+ return ['', [], -1]
endfunction
-" Search current mark.
+" Search current mark.
function! mark#SearchCurrentMark( isBackward )
- let [l:markText, l:markPosition] = mark#CurrentMark()
+ let [l:markText, l:markPosition, l:markIndex] = mark#CurrentMark()
if empty(l:markText)
- if empty(s:lastSearch)
+ if s:lastSearch == -1
call mark#SearchAnyMark(a:isBackward)
- let s:lastSearch = mark#CurrentMark()[0]
+ let s:lastSearch = mark#CurrentMark()[2]
else
- call s:Search(s:lastSearch, a:isBackward, [], 'same-mark')
+ call s:Search(s:pattern[s:lastSearch], a:isBackward, [], 'mark-' . (s:lastSearch + 1))
endif
else
- call s:Search(l:markText, a:isBackward, l:markPosition, (l:markText ==# s:lastSearch ? 'same-mark' : 'new-mark'))
- let s:lastSearch = l:markText
+ call s:Search(l:markText, a:isBackward, l:markPosition, 'mark-' . (l:markIndex + 1) . (l:markIndex ==# s:lastSearch ? '' : '!'))
+ let s:lastSearch = l:markIndex
endif
endfunction
-silent! call SearchSpecial#DoesNotExist() " Execute a function to force autoload.
-if exists('*SearchSpecial#WrapMessage')
- function! s:WrapMessage( searchType, searchPattern, isBackward )
- redraw
- call SearchSpecial#WrapMessage(a:searchType, a:searchPattern, a:isBackward)
- endfunction
- function! s:EchoSearchPattern( searchType, searchPattern, isBackward )
- call SearchSpecial#EchoSearchPattern(a:searchType, a:searchPattern, a:isBackward)
- endfunction
-else
- function! s:Trim( message )
- " Limit length to avoid "Hit ENTER" prompt.
- return strpart(a:message, 0, (&columns / 2)) . (len(a:message) > (&columns / 2) ? "..." : "")
- endfunction
- function! s:WrapMessage( searchType, searchPattern, isBackward )
- redraw
- let v:warningmsg = printf('%s search hit %s, continuing at %s', a:searchType, (a:isBackward ? 'TOP' : 'BOTTOM'), (a:isBackward ? 'BOTTOM' : 'TOP'))
- echohl WarningMsg
- echo s:Trim(v:warningmsg)
- echohl None
- endfunction
- function! s:EchoSearchPattern( searchType, searchPattern, isBackward )
- let l:message = (a:isBackward ? '?' : '/') . a:searchPattern
- echohl SearchSpecialSearchType
- echo a:searchType
- echohl None
- echon s:Trim(l:message)
- endfunction
-endif
function! s:ErrorMessage( searchType, searchPattern, isBackward )
if &wrapscan
let v:errmsg = a:searchType . ' not found: ' . a:searchPattern
@@ -513,7 +596,7 @@ function! s:ErrorMessage( searchType, searchPattern, isBackward )
echohl None
endfunction
-" Wrapper around search() with additonal search and error messages and "wrapscan" warning.
+" Wrapper around search() with additonal search and error messages and "wrapscan" warning.
function! s:Search( pattern, isBackward, currentMarkPosition, searchType )
let l:save_view = winsaveview()
@@ -522,7 +605,7 @@ function! s:Search( pattern, isBackward, currentMarkPosition, searchType )
" concatenated as branches in one large regexp, and because patterns that
" result from the *-command-alike mappings should not obey 'smartcase' (like
" the * command itself), anyway. If the :Mark command wants to support
- " 'smartcase', it'd have to emulate that into the regular expression.
+ " 'smartcase', it'd have to emulate that into the regular expression.
let l:save_smartcase = &smartcase
set nosmartcase
@@ -531,80 +614,80 @@ function! s:Search( pattern, isBackward, currentMarkPosition, searchType )
let l:isMatch = 0
let l:line = 0
while l:count > 0
- let [l:startLine, l:startCol] = [line('.'), col('.')]
+ let [l:prevLine, l:prevCol] = [line('.'), col('.')]
- " Search for next match, 'wrapscan' applies.
+ " Search for next match, 'wrapscan' applies.
let [l:line, l:col] = searchpos( a:pattern, (a:isBackward ? 'b' : '') )
"****D echomsg '****' a:isBackward string([l:line, l:col]) string(a:currentMarkPosition) l:count
if a:isBackward && l:line > 0 && [l:line, l:col] == a:currentMarkPosition && l:count == v:count1
" On a search in backward direction, the first match is the start of the
" current mark (if the cursor was positioned on the current mark text, and
- " not at the start of the mark text).
+ " not at the start of the mark text).
" In contrast to the normal search, this is not considered the first
" match. The mark text is one entity; if the cursor is positioned anywhere
" inside the mark text, the mark text is considered the current mark. The
" built-in '*' and '#' commands behave in the same way; the entire <cword>
" text is considered the current match, and jumps move outside that text.
" In normal search, the cursor can be positioned anywhere (via offsets)
" around the search, and only that single cursor position is considered
- " the current match.
+ " the current match.
" Thus, the search is retried without a decrease of l:count, but only if
" this was the first match; repeat visits during wrapping around count as
" a regular match. The search also must not be retried when this is the
" first match, but we've been here before (i.e. l:isMatch is set): This
" means that there is only the current mark in the buffer, and we must
" break out of the loop and indicate that search wrapped around and no
- " other mark was found.
+ " other mark was found.
if l:isMatch
let l:isWrapped = 1
break
endif
" The l:isMatch flag is set so if the final mark cannot be reached, the
" original cursor position is restored. This flag also allows us to detect
- " whether we've been here before, which is checked above.
+ " whether we've been here before, which is checked above.
let l:isMatch = 1
elseif l:line > 0
let l:isMatch = 1
let l:count -= 1
" Note: No need to check 'wrapscan'; the wrapping can only occur if
- " 'wrapscan' is actually on.
- if ! a:isBackward && (l:startLine > l:line || l:startLine == l:line && l:startCol >= l:col)
+ " 'wrapscan' is actually on.
+ if ! a:isBackward && (l:prevLine > l:line || l:prevLine == l:line && l:prevCol >= l:col)
let l:isWrapped = 1
- elseif a:isBackward && (l:startLine < l:line || l:startLine == l:line && l:startCol <= l:col)
+ elseif a:isBackward && (l:prevLine < l:line || l:prevLine == l:line && l:prevCol <= l:col)
let l:isWrapped = 1
endif
else
break
endif
endwhile
let &smartcase = l:save_smartcase
-
+
" We're not stuck when the search wrapped around and landed on the current
- " mark; that's why we exclude a possible wrap-around via v:count1 == 1.
+ " mark; that's why we exclude a possible wrap-around via v:count1 == 1.
let l:isStuckAtCurrentMark = ([l:line, l:col] == a:currentMarkPosition && v:count1 == 1)
"****D echomsg '****' l:line l:isStuckAtCurrentMark l:isWrapped l:isMatch string([l:line, l:col]) string(a:currentMarkPosition)
if l:line > 0 && ! l:isStuckAtCurrentMark
let l:matchPosition = getpos('.')
- " Open fold at the search result, like the built-in commands.
+ " Open fold at the search result, like the built-in commands.
normal! zv
" Add the original cursor position to the jump list, like the
- " [/?*#nN] commands.
+ " [/?*#nN] commands.
" Implementation: Memorize the match position, restore the view to the state
" before the search, then jump straight back to the match position. This
" also allows us to set a jump only if a match was found. (:call
- " setpos("''", ...) doesn't work in Vim 7.2)
+ " setpos("''", ...) doesn't work in Vim 7.2)
call winrestview(l:save_view)
normal! m'
call setpos('.', l:matchPosition)
" Enable marks (in case they were disabled) after arriving at the mark (to
" avoid unnecessary screen updates) but before the error message (to avoid
- " it getting lost due to the screen updates).
+ " it getting lost due to the screen updates).
call s:MarkEnable(1)
if l:isWrapped
@@ -617,14 +700,14 @@ function! s:Search( pattern, isBackward, currentMarkPosition, searchType )
if l:isMatch
" The view has been changed by moving through matches until the end /
" start of file, when 'nowrapscan' forced a stop of searching before the
- " l:count'th match was found.
- " Restore the view to the state before the search.
+ " l:count'th match was found.
+ " Restore the view to the state before the search.
call winrestview(l:save_view)
endif
" Enable marks (in case they were disabled) after arriving at the mark (to
" avoid unnecessary screen updates) but before the error message (to avoid
- " it getting lost due to the screen updates).
+ " it getting lost due to the screen updates).
call s:MarkEnable(1)
if l:line > 0 && l:isStuckAtCurrentMark && l:isWrapped
@@ -637,26 +720,26 @@ function! s:Search( pattern, isBackward, currentMarkPosition, searchType )
endif
endfunction
-" Combine all marks into one regexp.
+" Combine all marks into one regexp.
function! s:AnyMark()
return join(filter(copy(s:pattern), '! empty(v:val)'), '\|')
endfunction
-" Search any mark.
+" Search any mark.
function! mark#SearchAnyMark( isBackward )
let l:markPosition = mark#CurrentMark()[1]
let l:markText = s:AnyMark()
- call s:Search(l:markText, a:isBackward, l:markPosition, 'any-mark')
- let s:lastSearch = ""
+ call s:Search(l:markText, a:isBackward, l:markPosition, 'mark-*')
+ let s:lastSearch = -1
endfunction
-" Search last searched mark.
+" Search last searched mark.
function! mark#SearchNext( isBackward )
let l:markText = mark#CurrentMark()[0]
if empty(l:markText)
return 0
else
- if empty(s:lastSearch)
+ if s:lastSearch == -1
call mark#SearchAnyMark(a:isBackward)
else
call mark#SearchCurrentMark(a:isBackward)
@@ -665,30 +748,30 @@ function! mark#SearchNext( isBackward )
endif
endfunction
-" Load mark patterns from list.
+" Load mark patterns from list.
function! mark#Load( pattern, enabled )
if s:markNum > 0 && len(a:pattern) > 0
" Initialize mark patterns with the passed list. Ensure that, regardless of
- " the list length, s:pattern contains exactly s:markNum elements.
+ " the list length, s:pattern contains exactly s:markNum elements.
let s:pattern = a:pattern[0:(s:markNum - 1)]
let s:pattern += repeat([''], (s:markNum - len(s:pattern)))
let s:enabled = a:enabled
call mark#UpdateScope()
- " The list of patterns may be sparse, return only the actual patterns.
+ " The list of patterns may be sparse, return only the actual patterns.
return len(filter(copy(a:pattern), '! empty(v:val)'))
endif
return 0
endfunction
-" Access the list of mark patterns.
+" Access the list of mark patterns.
function! mark#ToPatternList()
" Trim unused patterns from the end of the list, the amount of available marks
" may differ on the next invocation (e.g. due to a different number of
" highlight groups in Vim and GVIM). We want to keep empty patterns in the
- " front and middle to maintain the mapping to highlight groups, though.
+ " front and middle to maintain the mapping to highlight groups, though.
let l:highestNonEmptyIndex = s:markNum -1
while l:highestNonEmptyIndex >= 0 && empty(s:pattern[l:highestNonEmptyIndex])
let l:highestNonEmptyIndex -= 1
@@ -697,12 +780,12 @@ function! mark#ToPatternList()
return (l:highestNonEmptyIndex < 0 ? [] : s:pattern[0:l:highestNonEmptyIndex])
endfunction
-" :MarkLoad command.
+" :MarkLoad command.
function! mark#LoadCommand( isShowMessages )
if exists('g:MARK_MARKS')
try
" Persistent global variables cannot be of type List, so we actually store
- " the string representation, and eval() it back to a List.
+ " the string representation, and eval() it back to a List.
execute 'let l:loadedMarkNum = mark#Load(' . g:MARK_MARKS . ', ' . (exists('g:MARK_ENABLED') ? g:MARK_ENABLED : 1) . ')'
if a:isShowMessages
if l:loadedMarkNum == 0
@@ -728,7 +811,7 @@ function! mark#LoadCommand( isShowMessages )
endif
endfunction
-" :MarkSave command.
+" :MarkSave command.
function! s:SavePattern()
let l:savedMarks = mark#ToPatternList()
let g:MARK_MARKS = string(l:savedMarks)
@@ -752,6 +835,40 @@ function! mark#SaveCommand()
endif
endfunction
+" :Marks command.
+function! mark#List()
+ let l:nextGroupNum = s:FreeGroup()
+ if l:nextGroupNum == -1
+ let l:nextGroupNum = s:cycle
+ endif
+
+ echohl Title
+ echo ' # Pattern'
+ echohl None
+ echon ' (+ next mark group * current search mark)'
+ for i in range(s:markNum)
+ execute 'echohl MarkWord' . (i + 1)
+ let l:marker = ''
+ if s:lastSearch == i
+ let l:marker .= '*'
+ endif
+ if i == l:nextGroupNum
+ let l:marker .= '+'
+ endif
+
+ echo printf('%1s%2d: %s', l:marker, (i + 1), s:pattern[i])
+ echohl None
+ endfor
+
+ if ! s:enabled
+ echo 'Marks are currently disabled.'
+ endif
+endfunction
+
+function! mark#GetGroupNum()
+ return s:markNum
+endfunction
+
"- initializations ------------------------------------------------------------
augroup Mark
@@ -760,15 +877,15 @@ augroup Mark
autocmd TabEnter * call mark#UpdateScope()
augroup END
-" Define global variables and initialize current scope.
+" Define global variables and initialize current scope.
function! mark#Init()
let s:markNum = 0
while hlexists('MarkWord' . (s:markNum + 1))
let s:markNum += 1
endwhile
let s:pattern = repeat([''], s:markNum)
let s:cycle = 0
- let s:lastSearch = ''
+ let s:lastSearch = -1
let s:enabled = 1
endfunction
@@ -780,4 +897,4 @@ else
call mark#UpdateScope()
endif
-" vim: ts=2 sw=2
+" vim: ts=4 sts=0 sw=4 noet
View
257 doc/mark.txt
@@ -1,4 +1,4 @@
-*mark.txt* Highlight several words in different colors simultaneously.
+*mark.txt* Highlight several words in different colors simultaneously.
MARK by Ingo Karkat
(original version by Yuheng Xie)
@@ -26,64 +26,84 @@ doesn't maintain his original version anymore and cannot be reached via the
email address in his profile. This plugin offers the following advantages over
the original:
- Much faster, all colored words can now be highlighted, no more clashes with
- syntax highlighting (due to use of matchadd()).
-- Many bug fixes.
-- Jumps behave like the built-in search, including wrap and error messages.
+ syntax highlighting (due to use of matchadd()).
+- Many bug fixes.
+- Jumps behave like the built-in search, including wrap and error messages.
- Like the built-in commands, jumps take an optional [count] to quickly skip
- over some marks.
+ over some marks.
+- Marks can be persisted, and patterns can be added / subtracted from
+ mark highlight groups.
RELATED WORKS *
- MultipleSearch (vimscript #479) can highlight in a single window and in all
buffers, but still relies on the :syntax highlighting method, which is
- slower and less reliable.
+ slower and less reliable.
- http://vim.wikia.com/wiki/Highlight_multiple_words offers control over the
color used by mapping the 1-9 keys on the numeric keypad, persistence, and
- highlights only a single window.
+ highlights only a single window.
- highlight.vim (vimscript #1599) highlights lines or patterns of interest in
- different colors, using mappings that start with CTRL-H and work on cword.
+ different colors, using mappings that start with CTRL-H and work on cword.
- quickhl.vim (vimscript #3692) can also list the matches with colors and in
addition offers on-the-fly highlighting of the current word (like many IDEs
- do).
+ do).
==============================================================================
USAGE *mark-usage*
HIGHLIGHTING *mark-highlighting*
*<Leader>m* *v_<Leader>m*
<Leader>m Mark the word under the cursor, similar to the |star|
- command. The next free highlight group is used.
+ command. The next free highlight group is used.
If already on a mark: Clear the mark, like
- |<Leader>n|.
-{Visual}<Leader>m Mark or unmark the visual selection.
+ |<Leader>n|.
+{Visual}<Leader>m Mark or unmark the visual selection.
+[N]<Leader>m With [N], mark the word under the cursor with the
+ named highlight group [N]. When that group is not
+ empty, the word is added as an alternative match, so
+ you can highlight multiple words with the same color.
+ When the word is already contained in the list of
+ alternatives, it is removed.
+{Visual}[N]<Leader>m Ditto, based on the visual selection.
+
*<Leader>r* *v_<Leader>r*
-<Leader>r Manually input a regular expression to mark.
-{Visual}<Leader>r Ditto, based on the visual selection.
+<Leader>r Manually input a regular expression to mark.
+{Visual}<Leader>r Ditto, based on the visual selection.
In accordance with the built-in |star| command,
all these mappings use 'ignorecase', but not
- 'smartcase'.
+ 'smartcase'.
*<Leader>n*
<Leader>n Clear the mark under the cursor.
If not on a mark: Disable all marks, similar to
- |:nohlsearch|.
-
+ |:nohlsearch|.
Note: Marks that span multiple lines are not detected,
so the use of <Leader>n on such a mark will
unintentionally remove all marks! Use
{Visual}<Leader>r or :Mark {pattern} to clear
- multi-line marks.
+ multi-line marks (or pass [N] if you happen to know
+ the group number).
+[N]<Leader>n Clear the marks represented by highlight group [N].
+
*:Mark*
-:Mark {pattern} Mark or unmark {pattern}.
+:[N]Mark Clear the marks represented by highlight group [N].
+:[N]Mark {pattern} Mark or unmark {pattern}. Unless [N] is given, the
+ next free highlight group is used.
+ With [N], mark the word under the cursor with the
+ named highlight group [N]. When that group is not
+ empty, the word is added as an alternative match, so
+ you can highlight multiple words with the same color.
+ When the word is already contained in the list of
+ alternatives, it is removed.
For implementation reasons, {pattern} cannot use the
- 'smartcase' setting, only 'ignorecase'.
+ 'smartcase' setting, only 'ignorecase'.
:Mark Disable all marks, similar to |:nohlsearch|. Marks
will automatically re-enable when a mark is added or
- removed, or a search for marks is performed.
+ removed, or a search for marks is performed.
*:MarkClear*
:MarkClear Clear all marks. In contrast to disabling marks, the
actual mark information is cleared, the next mark will
- use the first highlight group. This cannot be undone.
+ use the first highlight group. This cannot be undone.
SEARCHING *mark-searching*
@@ -92,63 +112,79 @@ SEARCHING *mark-searching*
[count]<Leader>* [count]<Leader>#
[count]<Leader>/ [count]<Leader>?
Use these six keys to jump to the [count]'th next /
- previous occurrence of a mark.
+ previous occurrence of a mark.
You could also use Vim's / and ? to search, since the
mark patterns are (optionally, see configuration)
- added to the search history, too.
+ added to the search history, too.
Cursor over mark Cursor not over mark
---------------------------------------------------------------------------
<Leader>* Jump to the next occurrence of Jump to the next occurrence of
- current mark, and remember it "last mark".
- as "last mark".
+ current mark, and remember it "last mark".
+ as "last mark".
- <Leader>/ Jump to the next occurrence of Same as left.
- ANY mark.
+ <Leader>/ Jump to the next occurrence of Same as left.
+ ANY mark.
- * If <Leader>* is the most recently Do Vim's original * command.
+ * If <Leader>* is the most recently Do Vim's original * command.
used, do a <Leader>*; otherwise
(<Leader>/ is the most recently
- used), do a <Leader>/.
+ used), do a <Leader>/.
Note: When the cursor is on a mark, the backwards
search does not jump to the beginning of the current
mark (like the built-in search), but to the previous
- mark. The entire mark text is treated as one entity.
+ mark. The entire mark text is treated as one entity.
You can use Vim's |jumplist| to go back to previous
- mark matches and the position before a mark search.
+ mark matches and the position before a mark search.
MARK PERSISTENCE *mark-persistence*
The marks can be kept and restored across Vim sessions, using the |viminfo|
file. For this to work, the "!" flag must be part of the 'viminfo' setting: >
- set viminfo+=! " Save and restore global variables.
+ set viminfo+=! " Save and restore global variables.
< *:MarkLoad*
:MarkLoad Restore the marks from the previous Vim session. All
- current marks are discarded.
+ current marks are discarded.
*:MarkSave*
:MarkSave Save the currently defined marks (or clear the
persisted marks if no marks are currently defined) for
- use in a future Vim session.
+ use in a future Vim session.
By default, automatic persistence is enabled (so you don't need to explicitly
|:MarkSave|), but you have to explicitly load the persisted marks in a new Vim
session via |:MarkLoad|, to avoid that you accidentally drag along outdated
highlightings from Vim session to session, and be surprised by the arbitrary
highlight groups and occasional appearance of forgotten marks. If you want
-just that though and automatically restore any marks, set |g:mwAutoLoadMarks|.
+just that though and automatically restore any marks, set |g:mwAutoLoadMarks|.
-You can also initialize the marks to static values, e.g. by including this in
-|vimrc|: >
+You can also initialize some marks (even using particular highlight groups) to
+static values, e.g. by including this in |vimrc|: >
runtime plugin/mark.vim
silent MarkClear
- Mark foo
- Mark bar
+ 5Mark foo
+ 6Mark bar
Or you can define custom commands that preset certain marks: >
- command -bar MyMarks silent MarkClear | execute 'Mark foo' | execute 'Mark bar'
+ command -bar MyMarks silent MarkClear | execute '5Mark foo' | execute '6Mark bar'
Or a command that adds to the existing marks and then toggles them: >
command -bar ToggleFooBarMarks execute 'Mark foo' | execute 'Mark bar'
+<
+MARK INFORMATION *mark-information*
+
+Both |mark-highlighting| and |mark-searching| commands print information about
+the mark and search pattern, e.g.
+ mark-1/\<pattern\> ~
+This is especially useful when you want to add or subtract patterns to a mark
+highlight group via [N].
+
+ *:Marks*
+:Marks List all mark highlight groups and the search patterns
+ defined for them.
+ The group that will be used for the next |:Mark| or
+ |<Leader>m| command (with [N]) is shown with a "+".
+ The last mark used for a search (via |<Leader>*|) is
+ shown with a "*".
==============================================================================
INSTALLATION *mark-installation*
@@ -159,23 +195,26 @@ the archive first, e.g. using WinZip. Inside Vim, install by sourcing the
vimball or via the |:UseVimball| command. >
vim mark.vba.gz
:so %
-To uninstall, use the |:RmVimball| command.
+To uninstall, use the |:RmVimball| command.
DEPENDENCIES *mark-dependencies*
-- Requires Vim 7.1 with "matchadd()", or Vim 7.2 or higher.
+- Requires Vim 7.1 with "matchadd()", or Vim 7.2 or higher.
==============================================================================
CONFIGURATION *mark-configuration*
-For a permanent configuration, put the following commands into your |vimrc|.
+For a permanent configuration, put the following commands into your |vimrc|.
*mark-highlight-colors*
You may define your own colors or more than the default 6 highlightings in
your vimrc file (or anywhere before this plugin is sourced), in the following
form (where N = 1..): >
highlight MarkWordN ctermbg=Cyan ctermfg=Black guibg=#8CCBEA guifg=Black
-Higher numbers always take precedence and are displayed above lower ones.
+Higher numbers always take precedence and are displayed above lower ones.
+If you want to avoid losing the highlightings on |:colorscheme| commands, you
+need to re-apply your highlights on the |ColorScheme| event, similar to how
+this plugin does.
The search type highlighting (in the search message) can be changed via: >
highlight link SearchSpecialSearchType MoreMsg
@@ -191,11 +230,11 @@ To enable the automatic restore of marks from a previous Vim session: >
< *g:mwAutoSaveMarks*
To turn off the automatic persistence of marks across Vim sessions: >
let g:mwAutoSaveMarks = 0
-You can still explicitly save marks via |:MarkSave|.
+You can still explicitly save marks via |:MarkSave|.
*mark-mappings*
You can use different mappings by mapping to the <Plug>Mark... mappings (use
-":map <Plug>Mark" to list them all) before this plugin is sourced.
+":map <Plug>Mark" to list them all) before this plugin is sourced.
There are no default mappings for toggling all marks and for the |:MarkClear|
command, but you can define some yourself: >
@@ -211,7 +250,7 @@ Some people like to create a mark based on the visual selection, like
|v_<Leader>m|, but have whitespace in the selection match any whitespace when
searching (searching for "hello world" will also find "hello<Tab>world" as
well as "hello" at the end of a line, with "world" at the start of the next
-line). The Vim Tips Wiki describes such a setup for the built-in search at
+line). The Vim Tips Wiki describes such a setup for the built-in search at
http://vim.wikia.com/wiki/Search_for_visually_selected_text
You can achieve the same with the Mark plugin through the following scriptlet: >
function! s:GetVisualSelectionAsLiteralWhitespaceIndifferentPattern()
@@ -229,11 +268,11 @@ behavior: >
LIMITATIONS *mark-limitations*
- If the 'ignorecase' setting is changed, there will be discrepancies between
- the highlighted marks and subsequent jumps to marks.
+ the highlighted marks and subsequent jumps to marks.
- If {pattern} in a :Mark command contains atoms that change the semantics of
the entire (|/\c|, |/\C|) or following (|/\v|,|/\V|, |/\M|) regular
expression, there may be discrepancies between the highlighted marks and
- subsequent jumps to marks.
+ subsequent jumps to marks.
KNOWN PROBLEMS *mark-known-problems*
@@ -242,137 +281,161 @@ TODO *mark-todo*
IDEAS *mark-ideas*
Taken from an alternative implementation at
-http://vim.wikia.com/wiki/Highlight_multiple_words:
-- Allow to specify the highlight group number via :[N]Mark {regexp}
-- Use keys 1-9 on the numeric keypad to toggle a highlight group number.
+http://vim.wikia.com/wiki/Highlight_multiple_words:
+- Use keys 1-9 on the numeric keypad to toggle a highlight group number.
==============================================================================
HISTORY *mark-history*
+2.6.1 23-Mar-2012
+- ENH: Add :Marks command that prints all mark highlight groups and their
+ search patterns, plus information about the current search mark, next mark
+ group, and whether marks are disabled.
+- ENH: Show which mark group a pattern was set / added / removed / cleared.
+- FIX: When the cursor is positioned on the current mark, [N]<Leader>n /
+ <Plug>MarkClear with [N] appended the pattern for the current mark (again
+ and again) instead of clearing it. Must not pass current mark pattern when
+ [N] is given.
+- CHG: Show mark group number in same-mark search and rename search types from
+ "any-mark", "same-mark", and "new-mark" to the shorter "mark-*", "mark-N",
+ and "mark-N!", respectively.
+
+2.6.0 22-Mar-2012
+- ENH: Allow [count] for <Leader>m and :Mark to add / subtract match to / from
+ highlight group [count], and use [count]<Leader>n to clear only highlight
+ group [count]. This was also requested by Philipp Marek.
+- FIX: :Mark and <Leader>n actually toggled marks back on when they were
+ already off. Now, they stay off on multiple invocations. Use :call
+ mark#Toggle() / <Plug>MarkToggle if you want toggling.
+
+2.5.3 02-Mar-2012
+- BUG: Version check mistakenly excluded Vim 7.1 versions that do have the
+ matchadd() function. Thanks to Philipp Marek for sending a patch.
+
2.5.2 09-Nov-2011
-Fixed various problems with wrap-around warnings:
-- BUG: With a single match and 'wrapscan' set, a search error was issued.
+Fixed various problems with wrap-around warnings:
+- BUG: With a single match and 'wrapscan' set, a search error was issued.
- FIX: Backwards search with single match leads to wrong error message
- instead.
-- FIX: Wrong logic for determining l:isWrapped lets wrap-around go undetected.
+ instead.
+- FIX: Wrong logic for determining l:isWrapped lets wrap-around go undetected.
2.5.1 17-May-2011
- FIX: == comparison in s:DoMark() leads to wrong regexp (\A vs. \a) being
- cleared when 'ignorecase' is set. Use case-sensitive comparison ==# instead.
-- Refine :MarkLoad messages
+ cleared when 'ignorecase' is set. Use case-sensitive comparison ==# instead.
+- Refine :MarkLoad messages
- Add whitespace-indifferent visual mark configuration example. Thanks to Greg
- Klein for the suggestion.
+ Klein for the suggestion.
2.5.0 07-May-2011
- ENH: Add explicit mark persistence via :MarkLoad and :MarkSave commands and
automatic persistence via the g:mwAutoLoadMarks and g:mwAutoSaveMarks
- configuration flags. (Request from Mun Johl, 16-Apr-2010)
+ configuration flags. (Request from Mun Johl, 16-Apr-2010)
- Expose toggling of mark display (keeping the mark patterns) via new
<Plug>MarkToggle mapping. Offer :MarkClear command as a replacement for the
old argumentless :Mark command, which now just disables, but not clears all
- marks.
+ marks.
2.4.4 18-Apr-2011
- BUG: Include trailing newline character in check for current mark, so that a
mark that matches the entire line (e.g. created by V<Leader>m) can be
- cleared via <Leader>n. Thanks to ping for reporting this.
+ cleared via <Leader>n. Thanks to ping for reporting this.
- FIX: On overlapping marks, mark#CurrentMark() returned the lowest, not the
highest visible mark. So on overlapping marks, the one that was not visible
at the cursor position was removed; very confusing! Use reverse iteration
- order.
+ order.
- FIX: To avoid an arbitrary ordering of highlightings when the highlighting
group names roll over, and to avoid order inconsistencies across different
windows and tabs, we assign a different priority based on the highlighting
- group.
+ group.
2.4.3 16-Apr-2011
- Avoid losing the mark highlightings on :syn on or :colorscheme commands.
- Thanks to Zhou YiChao for alerting me to this issue and suggesting a fix.
+ Thanks to Zhou YiChao for alerting me to this issue and suggesting a fix.
- Made the script more robust when somehow no highlightings have been defined
or when the window-local reckoning of match IDs got lost. I had very
- occasionally encountered such script errors in the past.
+ occasionally encountered such script errors in the past.
- Made global housekeeping variables script-local, only g:mwHistAdd is used
- for configuration.
+ for configuration.
2.4.2 14-Jan-2011 (unreleased)
- FIX: Capturing the visual selection could still clobber the blockwise yank
- mode of the unnamed register.
+ mode of the unnamed register.
2.4.1 13-Jan-2011
- FIX: Using a named register for capturing the visual selection on
{Visual}<Leader>m and {Visual}<Leader>r clobbered the unnamed register. Now
- using the unnamed register.
+ using the unnamed register.
2.4.0 13-Jul-2010
- ENH: The MarkSearch mappings (<Leader>[*#/?]) add the original cursor
position to the jump list, like the built-in [/?*#nN] commands. This allows
to use the regular jump commands for mark matches, like with regular search
- matches.
+ matches.
2.3.3 19-Feb-2010
- BUG: Clearing of an accidental zero-width match (e.g. via :Mark \zs) results
- in endless loop. Thanks to Andy Wokula for the patch.
+ in endless loop. Thanks to Andy Wokula for the patch.
2.3.2 17-Nov-2009
- BUG: Creation of literal pattern via '\V' in {Visual}<Leader>m mapping
collided with individual escaping done in <Leader>m mapping so that an
escaped '\*' would be interpreted as a multi item when both modes are used
- for marking. Thanks to Andy Wokula for the patch.
+ for marking. Thanks to Andy Wokula for the patch.
2.3.1 06-Jul-2009
- Now working correctly when 'smartcase' is set. All mappings and the :Mark
- command use 'ignorecase', but not 'smartcase'.
+ command use 'ignorecase', but not 'smartcase'.
2.3.0 04-Jul-2009
- All jump commands now take an optional [count], so you can quickly skip over
some marks, as with the built-in */# and n/N commands. For this, the entire
core search algorithm has been rewritten. The script's logic has been
- simplified through the use of Vim 7 features like Lists.
-- Now also printing a Vim-alike search error message when 'nowrapscan' is set.
+ simplified through the use of Vim 7 features like Lists.
+- Now also printing a Vim-alike search error message when 'nowrapscan' is set.
2.2.0 02-Jul-2009
-- Split off functions into autoload script.
+- Split off functions into autoload script.
- Initialization of global variables and autocommands is now done lazily on
the first use, not during loading of the plugin. This reduces Vim startup
- time and footprint as long as the functionality isn't yet used.
+ time and footprint as long as the functionality isn't yet used.
- Split off documentation into separate help file. Now packaging as VimBall.
2.1.0 06-Jun-2009
- Replaced highlighting via :syntax with matchadd() / matchdelete(). This
requires Vim 7.2 / 7.1 with patches. This method is faster, there are no
more clashes with syntax highlighting (:match always has preference), and
- the background highlighting does not disappear under 'cursorline'.
+ the background highlighting does not disappear under 'cursorline'.
- Using winrestcmd() to fix effects of :windo: By entering a window, its
- height is potentially increased from 0 to 1.
-- Handling multiple tabs by calling s:UpdateScope() on the TabEnter event.
+ height is potentially increased from 0 to 1.
+- Handling multiple tabs by calling s:UpdateScope() on the TabEnter event.
2.0.0 01-Jun-2009
- Now using Vim List for g:mwWord and thus requiring Vim 7. g:mwCycle is now
- zero-based, but the syntax groups "MarkWordx" are still one-based.
+ zero-based, but the syntax groups "MarkWordx" are still one-based.
- Factored :syntax operations out of s:DoMark() and s:UpdateMark() so that
- they can all be done in a single :windo.
+ they can all be done in a single :windo.
- Normal mode <Plug>MarkSet now has the same semantics as its visual mode
cousin: If the cursor is on an existing mark, the mark is removed.
Beforehand, one could only remove a visually selected mark via again
- selecting it. Now, one simply can invoke the mapping when on such a mark.
+ selecting it. Now, one simply can invoke the mapping when on such a mark.
1.6.1 31-May-2009
-Publication of improved version by Ingo Karkat.
+Publication of improved version by Ingo Karkat.
- Now prepending search type ("any-mark", "same-mark", "new-mark") for better
- identification.
+ identification.
- Retired the algorithm in s:PrevWord in favor of simply using <cword>, which
makes mark.vim work like the * command. At the end of a line, non-keyword
characters may now be marked; the previous algorithm preferred any preceding
- word.
+ word.
- BF: If 'iskeyword' contains characters that have a special meaning in a
- regexp (e.g. [.*]), these are now escaped properly.
+ regexp (e.g. [.*]), these are now escaped properly.
- Highlighting can now actually be overridden in the vimrc (anywhere _before_
- sourcing this script) by using ':hi def'.
-- Added missing setter for re-inclusion guard.
+ sourcing this script) by using ':hi def'.
+- Added missing setter for re-inclusion guard.
1.5.0 01-Sep-2008
-Bug fixes and enhancements by Ingo Karkat.
+Bug fixes and enhancements by Ingo Karkat.
- Added <Plug>MarkAllClear (without a default mapping), which clears all
marks, even when the cursor is on a mark.
- Added <Plug>... mappings for hard-coded \*, \#, \/, \?, * and #, to allow
@@ -388,18 +451,18 @@ Bug fixes and enhancements by Ingo Karkat.
continuing at TOP" and "Pattern not found:..." messages, like the * and n/N
Vim search commands.
- ENH: Jumps now open folds if the occurrence is inside a closed fold, just
- like n/N do.
+ like n/N do.
1.1.8-g 25-Apr-2008
-Last version published by Yuheng Xie on vim.org.
+Last version published by Yuheng Xie on vim.org.
1.1.2 22-Mar-2005
-Initial version published by Yuheng Xie on vim.org.
+Initial version published by Yuheng Xie on vim.org.
==============================================================================
-Copyright: (C) 2005-2008 by Yuheng Xie
- (C) 2008-2011 by Ingo Karkat
-The VIM LICENSE applies to this script; see|copyright|.
+Copyright: (C) 2005-2008 Yuheng Xie
+ (C) 2008-2012 Ingo Karkat
+The VIM LICENSE applies to this script; see|copyright|.
Maintainer: Ingo Karkat <ingo@karkat.de>
==============================================================================
View
2 doc/tags
@@ -76,6 +76,7 @@
:MarkClear mark.txt /*:MarkClear*
:MarkLoad mark.txt /*:MarkLoad*
:MarkSave mark.txt /*:MarkSave*
+:Marks mark.txt /*:Marks*
:MatchDebug matchit.txt /*:MatchDebug*
:NERDTree NERD_tree.txt /*:NERDTree*
:NERDTreeClose NERD_tree.txt /*:NERDTreeClose*
@@ -900,6 +901,7 @@ mark-highlight-colors mark.txt /*mark-highlight-colors*
mark-highlighting mark.txt /*mark-highlighting*
mark-history mark.txt /*mark-history*
mark-ideas mark.txt /*mark-ideas*
+mark-information mark.txt /*mark-information*
mark-installation mark.txt /*mark-installation*
mark-known-problems mark.txt /*mark-known-problems*
mark-limitations mark.txt /*mark-limitations*
View
135 plugin/mark.vim
@@ -1,107 +1,125 @@
" Script Name: mark.vim
-" Description: Highlight several words in different colors simultaneously.
+" Description: Highlight several words in different colors simultaneously.
"
-" Copyright: (C) 2005-2008 by Yuheng Xie
-" (C) 2008-2011 by Ingo Karkat
-" The VIM LICENSE applies to this script; see ':help copyright'.
+" Copyright: (C) 2005-2008 Yuheng Xie
+" (C) 2008-2012 Ingo Karkat
+" The VIM LICENSE applies to this script; see ':help copyright'.
"
-" Maintainer: Ingo Karkat <ingo@karkat.de>
+" Maintainer: Ingo Karkat <ingo@karkat.de>
" Orig Author: Yuheng Xie <elephant@linux.net.cn>
" Contributors:Luc Hermitte, Ingo Karkat
"
" Dependencies:
-" - Requires Vim 7.1 with "matchadd()", or Vim 7.2 or higher.
-" - mark.vim autoload script.
-"
-" Version: 2.5.0
+" - Requires Vim 7.1 with "matchadd()", or Vim 7.2 or higher.
+" - mark.vim autoload script.
+"
+" Version: 2.6.1
" Changes:
+" 23-Mar-2012, Ingo Karkat
+" - ENH: Add :Marks command that prints all mark highlight groups and their
+" search patterns, plus information about the current search mark, next mark
+" group, and whether marks are disabled.
+" - FIX: When the cursor is positioned on the current mark, [N]<Leader>n /
+" <Plug>MarkClear with [N] appended the pattern for the current mark (again
+" and again) instead of clearing it. Must not pass current mark pattern when
+" [N] is given.
+"
+" 22-Mar-2012, Ingo Karkat
+" - ENH: Allow [count] for <Leader>m and :Mark to add / subtract match to / from
+" highlight group [count], and use [count]<Leader>n to clear only highlight
+" group [count]. This was also requested by Philipp Marek.
+"
+" 02-Mar-2012, Philipp Marek
+" - BUG: Version check mistakenly excluded Vim 7.1 versions that do have the
+" matchadd() function.
+"
" 06-May-2011, Ingo Karkat
" - By default, enable g:mwAutoSaveMarks, so that marks are always persisted,
" but disable g:mwAutoLoadMarks, so that persisted marks have to be explicitly
" loaded, if that is desired. I often wondered why I got unexpected mark
" highlightings in a new Vim session until I realized that I had used marks in
-" a previous session and forgot to clear them.
+" a previous session and forgot to clear them.
"
" 21-Apr-2011, Ingo Karkat
" - Expose toggling of mark display (keeping the mark patterns) via new
" <Plug>MarkToggle mapping. Offer :MarkClear command as a replacement for the
" old argumentless :Mark command, which now just disables, but not clears all
-" marks.
+" marks.
" - Implement lazy-loading of disabled persistent marks via g:mwDoDeferredLoad
-" flag passing to autoload/mark.vim.
+" flag passing to autoload/mark.vim.
"
" 19-Apr-2011, Ingo Karkat
" - ENH: Add explicit mark persistence via :MarkLoad and :MarkSave commands and
" automatic persistence via the g:mwAutoLoadMarks and g:mwAutoSaveMarks
-" configuration flags.
+" configuration flags.
"
" 15-Apr-2011, Ingo Karkat
" - Avoid losing the mark highlightings on :syn on or :colorscheme commands.
-" Thanks to Zhou YiChao for alerting me to this issue and suggesting a fix.
+" Thanks to Zhou YiChao for alerting me to this issue and suggesting a fix.
"
" 17-Nov-2009, Ingo Karkat
" - Replaced the (overly) generic mark#GetVisualSelectionEscaped() with
" mark#GetVisualSelectionAsRegexp() and
-" mark#GetVisualSelectionAsLiteralPattern().
+" mark#GetVisualSelectionAsLiteralPattern().
"
" 04-Jul-2009, Ingo Karkat
" - A [count] before any mapping either caused "No range allowed" error or just
" repeated the :call [count] times, resulting in the current search pattern
" echoed [count] times and a hit-enter prompt. Now suppressing [count] via
-" <C-u> and handling it inside the implementation.
-" - Now passing isBackward (0/1) instead of optional 'b' flag into functions.
+" <C-u> and handling it inside the implementation.
+" - Now passing isBackward (0/1) instead of optional 'b' flag into functions.
" Also passing empty regexp to mark#MarkRegex() to avoid any optional
-" arguments.
+" arguments.
"
" 02-Jul-2009, Ingo Karkat
-" - Split off functions into autoload script.
-" - Removed g:force_reload_mark.
+" - Split off functions into autoload script.
+" - Removed g:force_reload_mark.
" - Initialization of global variables and autocommands is now done lazily on
" the first use, not during loading of the plugin. This reduces Vim startup
-" time and footprint as long as the functionality isn't yet used.
+" time and footprint as long as the functionality isn't yet used.
"
" 6-Jun-2009, Ingo Karkat
" 1. Somehow s:WrapMessage() needs a redraw before the :echo to avoid that a
" later Vim redraw clears the wrap message. This happened when there's no
-" statusline and thus :echo'ing into the ruler.
-" 2. Removed line-continuations and ':set cpo=...'. Upper-cased <SID> and <CR>.
-" 3. Added default highlighting for the special search type.
+" statusline and thus :echo'ing into the ruler.
+" 2. Removed line-continuations and ':set cpo=...'. Upper-cased <SID> and <CR>.
+" 3. Added default highlighting for the special search type.
"
" 2-Jun-2009, Ingo Karkat
" 1. Replaced highlighting via :syntax with matchadd() / matchdelete(). This
" requires Vim 7.2 / 7.1 with patches. This method is faster, there are no
" more clashes with syntax highlighting (:match always has preference), and
-" the background highlighting does not disappear under 'cursorline'.
-" 2. Factored :windo application out into s:MarkScope().
+" the background highlighting does not disappear under 'cursorline'.
+" 2. Factored :windo application out into s:MarkScope().
" 3. Using winrestcmd() to fix effects of :windo: By entering a window, its
-" height is potentially increased from 0 to 1.
-" 4. Handling multiple tabs by calling s:UpdateScope() on the TabEnter event.
-"
+" height is potentially increased from 0 to 1.
+" 4. Handling multiple tabs by calling s:UpdateScope() on the TabEnter event.
+"
" 1-Jun-2009, Ingo Karkat
" 1. Now using Vim List for g:mwWord and thus requiring Vim 7. g:mwCycle is now
-" zero-based, but the syntax groups "MarkWordx" are still one-based.
-" 2. Added missing setter for re-inclusion guard.
+" zero-based, but the syntax groups "MarkWordx" are still one-based.
+" 2. Added missing setter for re-inclusion guard.
" 3. Factored :syntax operations out of s:DoMark() and s:UpdateMark() so that
-" they can all be done in a single :windo.
+" they can all be done in a single :windo.
" 4. Normal mode <Plug>MarkSet now has the same semantics as its visual mode
" cousin: If the cursor is on an existing mark, the mark is removed.
" Beforehand, one could only remove a visually selected mark via again
-" selecting it. Now, one simply can invoke the mapping when on such a mark.
+" selecting it. Now, one simply can invoke the mapping when on such a mark.
" 5. Highlighting can now actually be overridden in the vimrc (anywhere
-" _before_ sourcing this script) by using ':hi def'.
+" _before_ sourcing this script) by using ':hi def'.
"
" 31-May-2009, Ingo Karkat
" 1. Refactored s:Search() to optionally take advantage of SearchSpecial.vim
" autoload functionality for echoing of search pattern, wrap and error
-" messages.
+" messages.
" 2. Now prepending search type ("any-mark", "same-mark", "new-mark") for
-" better identification.
+" better identification.
" 3. Retired the algorithm in s:PrevWord in favor of simply using <cword>,
" which makes mark.vim work like the * command. At the end of a line,
" non-keyword characters may now be marked; the previous algorithm prefered
-" any preceding word.
+" any preceding word.
" 4. BF: If 'iskeyword' contains characters that have a special meaning in a
-" regex (e.g. [.*]), these are now escaped properly.
+" regex (e.g. [.*]), these are now escaped properly.
"
" 01-Sep-2008, Ingo Karkat: bugfixes and enhancements
" 1. Added <Plug>MarkAllClear (without a default mapping), which clears all
@@ -123,7 +141,7 @@
" continuing at TOP" and "Pattern not found:..." messages, like the * and
" n/N Vim search commands.
" 9. Jumps now open folds if the occurrence is inside a closed fold, just like n/N
-" do.
+" do.
"
" 10th Mar 2006, Yuheng Xie: jump to ANY mark
" (*) added \* \# \/ \? for the ability of jumping to ANY mark, even when the
@@ -151,8 +169,8 @@
" (*) command :Mark
" -> e.g. :Mark Mark.\{-}\ze(
-" Avoid installing twice or when in unsupported Vim version.
-if exists('g:loaded_mark') || (v:version == 701 && ! exists('*matchadd')) || (v:version < 702)
+" 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
@@ -184,20 +202,20 @@ endfunction
call s:DefaultHighlightings()
autocmd ColorScheme * call <SID>DefaultHighlightings()
-" Default highlighting for the special search type.
+" Default highlighting for the special search type.
" You can override this by defining / linking the 'SearchSpecialSearchType'
-" highlight group before this script is sourced.
+" highlight group before this script is sourced.
highlight def link SearchSpecialSearchType MoreMsg
"- mappings -------------------------------------------------------------------
-nnoremap <silent> <Plug>MarkSet :<C-u>call mark#MarkCurrentWord()<CR>
-vnoremap <silent> <Plug>MarkSet <C-\><C-n>:call mark#DoMark(mark#GetVisualSelectionAsLiteralPattern())<CR>
-nnoremap <silent> <Plug>MarkRegex :<C-u>call mark#MarkRegex('')<CR>
-vnoremap <silent> <Plug>MarkRegex <C-\><C-n>:call mark#MarkRegex(mark#GetVisualSelectionAsRegexp())<CR>
-nnoremap <silent> <Plug>MarkClear :<C-u>call mark#DoMark(mark#CurrentMark()[0])<CR>
+nnoremap <silent> <Plug>MarkSet :<C-u>if !mark#MarkCurrentWord(v:count)<Bar>execute "normal! \<lt>C-\>\<lt>C-n>\<lt>Esc>"<Bar>endif<CR>
+vnoremap <silent> <Plug>MarkSet :<C-u>if !mark#DoMark(v:count, mark#GetVisualSelectionAsLiteralPattern())<Bar>execute "normal! \<lt>C-\>\<lt>C-n>\<lt>Esc>"<Bar>endif<CR>
+nnoremap <silent> <Plug>MarkRegex :<C-u>call mark#MarkRegex('')<CR>
+vnoremap <silent> <Plug>MarkRegex :<C-u>call mark#MarkRegex(mark#GetVisualSelectionAsRegexp())<CR>
+nnoremap <silent> <Plug>MarkClear :<C-u>if !mark#DoMark(v:count, (v:count ? '' : mark#CurrentMark()[0]))<Bar>execute "normal! \<lt>C-\>\<lt>C-n>\<lt>Esc>"<Bar>endif<CR>
nnoremap <silent> <Plug>MarkAllClear :<C-u>call mark#ClearAll()<CR>
-nnoremap <silent> <Plug>MarkToggle :<C-u>call mark#Toggle()<CR>
+nnoremap <silent> <Plug>MarkToggle :<C-u>call mark#Toggle()<CR>
nnoremap <silent> <Plug>MarkSearchCurrentNext :<C-u>call mark#SearchCurrentMark(0)<CR>
nnoremap <silent> <Plug>MarkSearchCurrentPrev :<C-u>call mark#SearchCurrentMark(1)<CR>
@@ -206,7 +224,7 @@ nnoremap <silent> <Plug>MarkSearchAnyPrev :<C-u>call mark#SearchAnyMark(1)<C
nnoremap <silent> <Plug>MarkSearchNext :<C-u>if !mark#SearchNext(0)<Bar>execute 'normal! *zv'<Bar>endif<CR>
nnoremap <silent> <Plug>MarkSearchPrev :<C-u>if !mark#SearchNext(1)<Bar>execute 'normal! #zv'<Bar>endif<CR>
" When typed, [*#nN] open the fold at the search result, but inside a mapping or
-" :normal this must be done explicitly via 'zv'.
+" :normal this must be done explicitly via 'zv'.
if !hasmapto('<Plug>MarkSet', 'n')
@@ -224,8 +242,8 @@ endif
if !hasmapto('<Plug>MarkClear', 'n')
nmap <unique> <silent> <Leader>n <Plug>MarkClear
endif
-" No default mapping for <Plug>MarkAllClear.
-" No default mapping for <Plug>MarkToggle.
+" No default mapping for <Plug>MarkAllClear.
+" No default mapping for <Plug>MarkToggle.
if !hasmapto('<Plug>MarkSearchCurrentNext', 'n')
nmap <unique> <silent> <Leader>* <Plug>MarkSearchCurrentNext
@@ -248,8 +266,9 @@ endif
"- commands -------------------------------------------------------------------
-command! -nargs=? Mark call mark#DoMark(<f-args>)
+command! -count -nargs=? Mark if !mark#DoMark(<count>, <f-args>) | echoerr printf('Only %d mark highlight groups', mark#GetGroupNum()) | endif
command! -bar MarkClear call mark#ClearAll()
+command! -bar Marks call mark#List()
command! -bar MarkLoad call mark#LoadCommand(1)
command! -bar MarkSave call mark#SaveCommand()
@@ -259,19 +278,19 @@ command! -bar MarkSave call mark#SaveCommand()
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.
+ " 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.
+ " 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.
+ " mark mapping or command.
let g:mwDoDeferredLoad = 1
endif
endif
@@ -281,9 +300,9 @@ if g:mwAutoLoadMarks
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.
+ " empty list representation, and also :execute the :call.
autocmd VimEnter * call <SID>AutoLoadMarks()
augroup END
endif
-" vim: ts=2 sw=2
+" vim: ts=4 sts=0 sw=4 noet

0 comments on commit dd63ea9

Please sign in to comment.
Something went wrong with that request. Please try again.