10 changed files with 1806 additions and 0 deletions
@ -0,0 +1 @@
@@ -0,0 +1 @@
|
||||
/doc/tags |
@ -0,0 +1,22 @@
@@ -0,0 +1,22 @@
|
||||
The MIT License (MIT) |
||||
|
||||
Copyright (c) 2015 Kartik Shenoy |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
of this software and associated documentation files (the "Software"), to deal |
||||
in the Software without restriction, including without limitation the rights |
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
copies of the Software, and to permit persons to whom the Software is |
||||
furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included in all |
||||
copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||
SOFTWARE. |
||||
|
@ -0,0 +1,97 @@
@@ -0,0 +1,97 @@
|
||||
#### 2017-09-23: |
||||
Changed the default value of `g:SignatureForceRemoveGlobal` to 0 since using `:wviminfo!`/`:wshada!` is a very heavy hammer and because it goes against a \*vim default. |
||||
|
||||
#### 2016-07-08: |
||||
Signature used to have a mapping conflict with NERDTree as both try to map the `m` key. |
||||
To get around this, I used to delete maps whenever I detected someone entering the NERDTree pane and recreate the maps upon exit. |
||||
However, this had a lot of issues and as of [cfa6452](https://github.com/kshenoy/vim-signature/commit/cfa64525305dbb8cec7eefc16e4ea460f007cd33) I've decided to remove any code that was intended to work around this since it wasn't working anyways. Refer to the discussion [here](https://github.com/kshenoy/vim-signature/issues/3#issuecomment-222565292) for more details. |
||||
Sorry for any inconvenience. If anyone has any ideas or suggestions please let me know. |
||||
|
||||
# vim-signature |
||||
vim-signature is a plugin to place, toggle and display marks. |
||||
|
||||
Apart from the above, you can also |
||||
* Navigate forward/backward by position/alphabetical order |
||||
* Displaying multiple marks (upto 2, limited by the signs feature) |
||||
* Placing custom signs !@#$%^&*() as visual markers |
||||
|
||||
|
||||
### Screenshots |
||||
 |
||||
Displays the marks as signs. Also place visual markers |
||||
|
||||
 |
||||
Alphabetical mark traversal and more. |
||||
|
||||
 |
||||
|
||||
Also supports dynamic highlighting of signs. In the image above the marks are colored according to the state of the line as indicated by gitgutter. |
||||
|
||||
NOTE: This feature is disabled by default |
||||
|
||||
More screenshots [here](http://imgur.com/a/3KQyt) |
||||
|
||||
### Vim.org mirror |
||||
If you like the plugin, spread the love and rate at http://www.vim.org/scripts/script.php?script_id=4118 |
||||
|
||||
|
||||
## Requirements |
||||
Requires Vim to be compiled with +signs to display marks. |
||||
|
||||
|
||||
## Installation |
||||
I recommend using a plugin manager to do the grunt work for you. |
||||
If for some reason, you do not want to use any of them, then unzip the contents of the .zip file to your ~/.vim directory. |
||||
|
||||
Once that's done, out of the box, the followings mappings are defined |
||||
|
||||
```` |
||||
mx Toggle mark 'x' and display it in the leftmost column |
||||
dmx Remove mark 'x' where x is a-zA-Z |
||||
|
||||
m, Place the next available mark |
||||
m. If no mark on line, place the next available mark. Otherwise, remove (first) existing mark. |
||||
m- Delete all marks from the current line |
||||
m<Space> Delete all marks from the current buffer |
||||
]` Jump to next mark |
||||
[` Jump to prev mark |
||||
]' Jump to start of next line containing a mark |
||||
[' Jump to start of prev line containing a mark |
||||
`] Jump by alphabetical order to next mark |
||||
`[ Jump by alphabetical order to prev mark |
||||
'] Jump by alphabetical order to start of next line having a mark |
||||
'[ Jump by alphabetical order to start of prev line having a mark |
||||
m/ Open location list and display marks from current buffer |
||||
|
||||
m[0-9] Toggle the corresponding marker !@#$%^&*() |
||||
m<S-[0-9]> Remove all markers of the same type |
||||
]- Jump to next line having a marker of the same type |
||||
[- Jump to prev line having a marker of the same type |
||||
]= Jump to next line having a marker of any type |
||||
[= Jump to prev line having a marker of any type |
||||
m? Open location list and display markers from current buffer |
||||
m<BS> Remove all markers |
||||
```` |
||||
|
||||
This will allow the use of default behavior of m to set marks and, if the line |
||||
already contains the mark, it'll be unset. |
||||
The default behavior of `]'`, `['`, ``]` `` and ``[` `` is supported and enhanced by |
||||
wrapping around when beginning or end of file is reached. |
||||
|
||||
The command `:SignatureToggle` can be used to show/hide the signs. |
||||
Note that this does not delete any of the marks but only hides them. |
||||
This is a buffer-specific command. |
||||
|
||||
If for some reason, the marks and their sign displays go out of sync, |
||||
use `:SignatureRefresh` to refresh them. |
||||
|
||||
For more details on customization refer the help |
||||
|
||||
|
||||
## Thanks to... |
||||
* Sergey Khorev for [mark-tools](http://www.vim.org/scripts/script.php?script_id=2929) |
||||
* Zak Johnson for [vim-showmarks](https://github.com/zakj/vim-showmarks) |
||||
|
||||
|
||||
## ToDo: |
||||
* Tie the Signature functions to vim commands that affect mark placement |
@ -0,0 +1,38 @@
@@ -0,0 +1,38 @@
|
||||
" vim: fdm=marker:et:ts=4:sw=2:sts=2 |
||||
|
||||
" Maintainer: Kartik Shenoy |
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" |
||||
|
||||
" Exit if the signs feature is not available or if the app has already been loaded (or "compatible" mode set) |
||||
if ( !has('signs') |
||||
\ || &cp |
||||
\ ) |
||||
finish |
||||
endif |
||||
|
||||
"" Exit if vim-signature is not loaded |
||||
if !exists('g:loaded_Signature') |
||||
finish |
||||
endif |
||||
|
||||
if exists('g:loaded_gitgutter') |
||||
if g:SignatureMarkTextHLDynamic |
||||
unlet g:SignatureMarkTextHL |
||||
let g:SignatureMarkTextHL = function("signature#sign#GetGitGutterHLGroup") |
||||
endif |
||||
if g:SignatureMarkerTextHLDynamic |
||||
unlet g:SignatureMarkerTextHL |
||||
let g:SignatureMarkerTextHL = function("signature#sign#GetGitGutterHLGroup") |
||||
endif |
||||
endif |
||||
|
||||
if exists('g:loaded_signify') |
||||
if g:SignatureMarkTextHLDynamic |
||||
unlet g:SignatureMarkTextHL |
||||
let g:SignatureMarkTextHL = function("signature#sign#GetSignifyHLGroup") |
||||
endif |
||||
if g:SignatureMarkerTextHLDynamic |
||||
unlet g:SignatureMarkerTextHL |
||||
let g:SignatureMarkerTextHL = function("signature#sign#GetSignifyHLGroup") |
||||
endif |
||||
endif |
@ -0,0 +1,427 @@
@@ -0,0 +1,427 @@
|
||||
" vim: fdm=marker:et:ts=4:sw=2:sts=1 |
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" |
||||
|
||||
function! signature#mark#Toggle(mark) " {{{1 |
||||
" Description: mark = 'next' : Place new mark on current line else toggle specified mark on current line |
||||
" Arguments: mark [a-z,A-Z] |
||||
|
||||
if a:mark == "next" |
||||
" Place new mark |
||||
let l:marks_list = signature#mark#GetList('free', 'buf_all') |
||||
if empty(l:marks_list) |
||||
if (!g:SignatureRecycleMarks) |
||||
" No marks available and mark re-use not in effect |
||||
call s:ReportNoAvailableMarks() |
||||
return |
||||
endif |
||||
" Remove a local mark |
||||
let l:marks_list = signature#mark#GetList('used', 'buf_curr')[0] |
||||
call signature#mark#Remove(l:marks_list[0]) |
||||
endif |
||||
call s:Place(l:marks_list[0]) |
||||
|
||||
else |
||||
" Toggle Mark |
||||
let l:used_marks = filter(signature#mark#GetList('used', 'buf_all'), 'v:val[0] ==# a:mark') |
||||
if (len(l:used_marks) > 0) |
||||
let l:mark_pos = l:used_marks[0][1] |
||||
let l:mark_buf = l:used_marks[0][2] |
||||
|
||||
if (l:mark_buf == bufnr('%')) |
||||
" If the mark is not in use in current buffer then it's a global ==> Don't worry about deleting it |
||||
if ( (l:mark_pos == line('.')) |
||||
\ && !g:SignatureForceMarkPlacement |
||||
\ ) |
||||
" Mark is present on the current line. Remove it and return |
||||
call signature#mark#Remove(a:mark) |
||||
call signature#sign#ToggleDummy() |
||||
return |
||||
else |
||||
" Mark is present elsewhere in the current buffer ==> Remove it and fall-through to place new mark. |
||||
" If g:SignatureForceMarkPlacement is set, we remove and re-place it so that the sign string can be true |
||||
" to the order in which the marks were placed. |
||||
" For eg. if we place 'a, 'b and then 'a again, the sign string changes from "ab" to "ba" |
||||
" Ask for confirmation before moving mark |
||||
if (g:SignatureDeleteConfirmation) |
||||
let choice = confirm("Mark '" . a:mark . "' has been used elsewhere. Reuse it?", "&Yes\n&No", 1) |
||||
if choice == 2 | return | endif |
||||
endif |
||||
call signature#mark#Remove(a:mark) |
||||
endif |
||||
endif |
||||
endif |
||||
|
||||
" Place new mark |
||||
call s:Place(a:mark) |
||||
endif |
||||
endfunction |
||||
|
||||
|
||||
function! signature#mark#Remove(mark) " {{{1 |
||||
" Description: Remove 'mark' and its associated sign. If called without an argument, obtain it from the user |
||||
" Arguments: mark = [a-z,A-Z] |
||||
|
||||
if !signature#utils#IsValidMark(a:mark) |
||||
return |
||||
endif |
||||
|
||||
let l:lnum = line("'" . a:mark) |
||||
call signature#sign#Remove(a:mark, l:lnum) |
||||
execute 'delmarks ' . a:mark |
||||
call s:ForceGlobalRemoval(a:mark) |
||||
endfunction |
||||
|
||||
|
||||
function! s:Place(mark) " {{{1 |
||||
" Description: Place new mark at current cursor position |
||||
" Arguments: mark = [a-z,A-Z] |
||||
" If a line is deleted or mark is manipulated using any non-signature method then b:sig_marks can go out of sync |
||||
" Thus, we forcibly remove signs for the mark present on any line before proceeding |
||||
call signature#sign#Remove(a:mark, 0) |
||||
execute 'normal! m' . a:mark |
||||
call signature#sign#Place(a:mark, line('.')) |
||||
endfunction |
||||
|
||||
|
||||
function! signature#mark#ToggleAtLine() " {{{1 |
||||
" Description: If no mark on current line, add one. If marks are on the current line, remove one. |
||||
let l:marks_here = filter(signature#mark#GetList('used', 'buf_curr'), 'v:val[1] == ' . line('.')) |
||||
if empty(l:marks_here) |
||||
" Set up for adding a mark |
||||
call signature#mark#Toggle('next') |
||||
else |
||||
" Delete first mark |
||||
call signature#mark#Remove(l:marks_here[0][0]) |
||||
endif |
||||
endfunction |
||||
|
||||
|
||||
function! signature#mark#Purge(mode) " {{{1 |
||||
" Description: Delete all marks from current line |
||||
" Arguments: mode = 'line' : Delete all marks from current line |
||||
" 'all' : Delete all marks used in the buffer |
||||
|
||||
let l:used_marks = signature#mark#GetList('used', 'buf_curr') |
||||
if (a:mode ==? 'line') |
||||
call filter(l:used_marks, 'v:val[1] == ' . line('.')) |
||||
endif |
||||
|
||||
if ( !empty(l:used_marks) |
||||
\ && g:SignaturePurgeConfirmation |
||||
\ ) |
||||
let l:msg = 'Are you sure you want to delete all marks' . (a:mode ==? 'line' ? ' from the current line' : '') . '?' |
||||
let l:ans = confirm(l:msg . ' This cannot be undone.', "&Yes\n&No", 1) |
||||
if (l:ans != 1) | return | endif |
||||
endif |
||||
|
||||
for i in l:used_marks |
||||
call signature#mark#Remove(i[0]) |
||||
endfor |
||||
|
||||
" If marks are modified using any non-signature method, b:sig_marks can go out of sync |
||||
if (a:mode ==? 'all') |
||||
for l:lnum in keys(b:sig_marks) |
||||
call signature#sign#Unplace(l:lnum) |
||||
endfor |
||||
endif |
||||
call signature#sign#ToggleDummy() |
||||
endfunction |
||||
|
||||
|
||||
function! signature#mark#Goto(dir, loc, mode) " {{{1 |
||||
" Arguments: |
||||
" dir = next : Jump forward |
||||
" prev : Jump backward |
||||
" loc = line : Jump to first column of line with mark |
||||
" spot : Jump to exact column of the mark |
||||
" mode = pos : Jump to next mark by position |
||||
" alpha : Jump to next mark by alphabetical order |
||||
" global : Jump only to global marks (applies to all buffers and alphabetical order) |
||||
|
||||
let l:mark = "" |
||||
let l:dir = a:dir |
||||
|
||||
if a:mode ==? "global" |
||||
let l:mark = s:GotoByAlphaGlobal(a:dir) |
||||
elseif a:mode ==? "alpha" |
||||
let l:mark = s:GotoByAlpha(a:dir) |
||||
elseif a:mode ==? "pos" |
||||
let l:mark = s:GotoByPos(a:dir) |
||||
endif |
||||
|
||||
" NOTE: If l:mark is an empty string then no movement will be made |
||||
if l:mark == "" | return | endif |
||||
|
||||
if a:loc ==? "line" |
||||
execute "normal! '" . l:mark |
||||
elseif a:loc ==? "spot" |
||||
execute 'normal! `' . l:mark |
||||
endif |
||||
endfunction |
||||
|
||||
|
||||
function! s:GotoByPos(dir) " {{{1 |
||||
" Description: Jump to next/prev mark by location. |
||||
" Arguments: dir = next : Jump forward |
||||
" prev : Jump backward |
||||
|
||||
" We need at least one mark to be present. If not, then return an empty string so that no movement will be made |
||||
if empty(b:sig_marks) | return "" | endif |
||||
|
||||
let l:lnum = line('.') |
||||
|
||||
" Get list of line numbers of lines with marks. |
||||
if a:dir ==? "next" |
||||
let l:targ = min(sort(keys(b:sig_marks), "signature#utils#NumericSort")) |
||||
let l:mark_lnums = sort(keys(filter(copy(b:sig_marks), 'v:key > l:lnum')), "signature#utils#NumericSort") |
||||
elseif a:dir ==? "prev" |
||||
let l:targ = max(sort(keys(b:sig_marks), "signature#utils#NumericSort")) |
||||
let l:mark_lnums = reverse(sort(keys(filter(copy(b:sig_marks), 'v:key < l:lnum')), "signature#utils#NumericSort")) |
||||
endif |
||||
|
||||
let l:targ = (empty(l:mark_lnums) ? (b:SignatureWrapJumps ? l:targ : "") : l:mark_lnums[0]) |
||||
if empty(l:targ) | return "" | endif |
||||
|
||||
let l:mark = signature#utils#GetChar(b:sig_marks[l:targ], 0) |
||||
return l:mark |
||||
endfunction |
||||
|
||||
|
||||
function! s:GotoByAlpha(dir) " {{{1 |
||||
" Description: Jump to next/prev mark by alphabetical order. Direction specified as input argument |
||||
|
||||
let l:used_marks = signature#mark#GetList('used', 'buf_curr') |
||||
let l:line_marks = filter(copy(l:used_marks), 'v:val[1] == ' . line('.')) |
||||
|
||||
" If there is only one mark in the current file, then return the same |
||||
if (len(l:used_marks) == 1) |
||||
return l:used_marks[0][0] |
||||
endif |
||||
|
||||
" Since we can place multiple marks on a line, to jump by alphabetical order we need to know what the current mark is. |
||||
" This information is kept in the b:sig_GotoByAlpha_CurrMark variable. For instance, if we have marks a, b and c |
||||
" on the current line and b:sig_GotoByAlpha_CurrMark has the value 'a' then we jump to 'b' and set the value of |
||||
" the variable to 'b'. Reinvoking this function will thus now jump to 'c' |
||||
if empty(l:line_marks) |
||||
if exists('b:sig_GotoByAlpha_CurrMark') |
||||
unlet b:sig_GotoByAlpha_CurrMark |
||||
endif |
||||
" If there are no marks present on the current line then call GotoByPos to jump to the next line with a mark |
||||
return s:GotoByPos(a:dir) |
||||
endif |
||||
|
||||
if (( len(l:line_marks) == 1 ) || !exists('b:sig_GotoByAlpha_CurrMark') || (b:sig_GotoByAlpha_CurrMark ==? "")) |
||||
let b:sig_GotoByAlpha_CurrMark = l:line_marks[0][0] |
||||
endif |
||||
|
||||
for i in range( 0, len(l:used_marks) - 1 ) |
||||
if l:used_marks[i][0] ==# b:sig_GotoByAlpha_CurrMark |
||||
if a:dir ==? "next" |
||||
if (( i != len(l:used_marks)-1 ) || b:SignatureWrapJumps) |
||||
let b:sig_GotoByAlpha_CurrMark = l:used_marks[(i+1)%len(l:used_marks)][0] |
||||
endif |
||||
elseif a:dir ==? "prev" |
||||
if ((i != 0) || b:SignatureWrapJumps) |
||||
let b:sig_GotoByAlpha_CurrMark = l:used_marks[i-1][0] |
||||
endif |
||||
endif |
||||
return b:sig_GotoByAlpha_CurrMark |
||||
endif |
||||
endfor |
||||
endfunction |
||||
|
||||
|
||||
function! s:GotoByAlphaGlobal(dir) " {{{1 |
||||
" Description: Jump to next/prev Global mark in any buffer by alphabetical order. |
||||
" Direction is specified as input argument |
||||
|
||||
let l:used_marks = signature#mark#GetList('used', 'buf_all', 'global') |
||||
let l:line_marks = filter(copy(l:used_marks), 'v:val[1] == ' . line('.')) |
||||
|
||||
" If there is only one mark in the current file, return it |
||||
if (len(l:used_marks) == 1) |
||||
return l:used_marks[0][0] |
||||
endif |
||||
" If current line does not have a global mark on it then return the first used global mark |
||||
if empty(l:line_marks) |
||||
if exists('b:sig_GotoByAlphaGlobal_CurrMark') |
||||
unlet b:sig_GotoByAlphaGlobal_CurrMark |
||||
endif |
||||
return l:used_marks[0][0] |
||||
endif |
||||
|
||||
" Since we can place multiple marks on a line, to jump by alphabetical order we need to know what the current mark is. |
||||
" This information is kept in the b:sig_GotoByAlphaGlobal_CurrMark variable. For instance, if we have marks A, B & C |
||||
" on the current line and b:sig_GotoByAlphaGlobal_CurrMark has the value 'A' then we jump to 'B' and set the value of |
||||
" the variable to 'B'. Reinvoking this function will thus now jump to 'C' |
||||
if ( (len(l:line_marks) == 1) |
||||
\ || !exists('b:sig_GotoByAlpha_CurrMark') |
||||
\ || (b:sig_GotoByAlphaGlobal_CurrMark ==? "") |
||||
\ ) |
||||
let b:sig_GotoByAlphaGlobal_CurrMark = l:line_marks[0][0] |
||||
endif |
||||
|
||||
for i in range( 0, len(l:used_marks) - 1 ) |
||||
if l:used_marks[i][0] ==# b:sig_GotoByAlphaGlobal_CurrMark |
||||
if a:dir ==? "next" |
||||
if (( i != len(l:used_marks)-1 ) || b:SignatureWrapJumps) |
||||
let b:sig_GotoByAlphaGlobal_CurrMark = l:used_marks[(i+1)%len(l:used_marks)][0] |
||||
endif |
||||
elseif a:dir ==? "prev" |
||||
if ((i != 0) || b:SignatureWrapJumps) |
||||
let b:sig_GotoByAlphaGlobal_CurrMark = l:used_marks[i-1][0] |
||||
endif |
||||
endif |
||||
return b:sig_GotoByAlphaGlobal_CurrMark |
||||
endif |
||||
endfor |
||||
endfunction |
||||
|
||||
|
||||
function! signature#mark#GetList(mode, scope, ...) " {{{1 |
||||
" Arguments: mode = 'used' : Returns list of [ [used marks, line no., buf no.] ] |
||||
" 'free' : Returns list of [ free marks ] |
||||
" scope = 'buf_curr' : Limits scope to current buffer i.e used/free marks in current buffer |
||||
" 'buf_all' : Set scope to all buffers i.e used/free marks from all buffers |
||||
" [type] = 'global' : Return only global marks |
||||
|
||||
let l:marks_list = [] |
||||
let l:line_tot = line('$') |
||||
let l:buf_curr = bufnr('%') |
||||
let l:type = (a:0 ? a:1 : "") |
||||
|
||||
" Respect order specified in g:SignatureIncludeMarks |
||||
for i in split(b:SignatureIncludeMarks, '\zs') |
||||
if (i =~# "[A-Z]") |
||||
let [ l:buf, l:line, l:col, l:off ] = getpos( "'" . i ) |
||||
let l:marks_list = add(l:marks_list, [i, l:line, l:buf]) |
||||
elseif (l:type !=? "global") |
||||
let l:marks_list = add(l:marks_list, [i, line("'" .i), l:buf_curr]) |
||||
endif |
||||
endfor |
||||
|
||||
if (a:mode ==? 'used') |
||||
if (a:scope ==? 'buf_curr') |
||||
call filter( l:marks_list, '(v:val[2] == l:buf_curr) && (v:val[1] > 0)' ) |
||||
else |
||||
call filter( l:marks_list, 'v:val[1] > 0' ) |
||||
endif |
||||
else |
||||
if (a:scope ==? 'buf_all') |
||||
call filter( l:marks_list, 'v:val[1] == 0' ) |
||||
else |
||||
call filter( l:marks_list, '(v:val[1] == 0) || (v:val[2] != l:buf_curr)' ) |
||||
endif |
||||
call map( l:marks_list, 'v:val[0]' ) |
||||
endif |
||||
|
||||
return l:marks_list |
||||
endfunction |
||||
|
||||
|
||||
function! s:ForceGlobalRemoval(mark) " {{{1 |
||||
" Description: Edit viminfo/shada file to forcibly delete Global mark since vim's handling is iffy |
||||
" Arguments: mark - The mark to delete |
||||
|
||||
if ( (a:mark !~# '[A-Z]') |
||||
\ || !g:SignatureForceRemoveGlobal |
||||
\ ) |
||||
return |
||||
endif |
||||
|
||||
if has('nvim') |
||||
wshada! |
||||
else |
||||
wviminfo! |
||||
endif |
||||
endfunction |
||||
|
||||
|
||||
function! s:ReportNoAvailableMarks() " {{{1 |
||||
if g:SignatureErrorIfNoAvailableMarks |
||||
echoe "Signature: No free marks left." |
||||
else |
||||
echohl WarningMsg |
||||
echomsg "Signature: No free marks left." |
||||
echohl None |
||||
endif |
||||
endfunction |
||||
|
||||
|
||||
function! signature#mark#List(scope, ...) " {{{1 |
||||
" Description: Opens and populates location list with marks |
||||
" Arguments: scope = 0 : List local and global marks from current buffer |
||||
" 1 : List only global marks from all buffers |
||||
" [context] = 0 : Adds context around the mark |
||||
|
||||
let l:list = [] |
||||
let l:buf_curr = bufnr('%') |
||||
let l:list_sep = {'bufnr': '', 'lnum' : ''} |
||||
|
||||
let l:SignatureIncludeMarks = (a:scope == 0 ? b:SignatureIncludeMarks : g:SignatureIncludeMarks) |
||||
for i in split(l:SignatureIncludeMarks, '\zs') |
||||
let [l:bufnr, l:lnum, l:col, l:off] = getpos( "'" . i ) |
||||
|
||||
" Local marks set the buffer no. to 0, replace it with the actual buffer number |
||||
let l:bufnr = (l:bufnr == 0 ? l:buf_curr : l:bufnr) |
||||
|
||||
" Check that |
||||
" 1. Mark is set (lnum > 0) |
||||
" 2. If buf_all = 0, filter out global marks from other buffers |
||||
" 3. If buf_all = 1, filter out local marks from current buffer |
||||
if ( (l:lnum == 0) |
||||
\ || ( (a:scope == 0) |
||||
\ && (l:bufnr != l:buf_curr) |
||||
\ ) |
||||
\ || ( (a:scope == 1) |
||||
\ && (i =~# "[a-z]") |
||||
\ ) |
||||
\ ) |
||||
"echom 'DEBUG: Skipping mark ' . i |
||||
continue |
||||
endif |
||||
|
||||
" If the buffer is not loaded, what's the point of showing empty context? |
||||
let l:context = (bufloaded(l:bufnr) && a:0 ? a:1 : 0) |
||||
|
||||
for context_lnum in range(l:lnum - l:context, l:lnum + l:context) |
||||
let l:text = get(getbufline(l:bufnr, context_lnum), 0, "") |
||||
if (!bufloaded(l:bufnr)) |
||||
" Buffer is not loaded, hence we won't be able to get the line. Opening the file should fix it |
||||
let l:text = "~~~ File is not loaded into memory. Open file and rerun to see the line ~~~" |
||||
elseif (l:text == "") |
||||
" Line does not exist. Possibly because context_lnum > total no. of lines |
||||
"echom 'DEBUG: Skipping line=' . context_lnum . ' for mark=' . i . " because line doesn't exist in buffer=" . l:bufnr |
||||
continue |
||||
endif |
||||
|
||||
if (context_lnum < l:lnum) | let l:text = '-: ' . l:text |
||||
elseif (context_lnum > l:lnum) | let l:text = '+: ' . l:text |
||||
else | let l:text = i . ': ' . l:text |
||||
endif |
||||
|
||||
let l:list = add(l:list, |
||||
\ { 'text' : l:text, |
||||
\ 'bufnr': l:bufnr, |
||||
\ 'lnum' : context_lnum, |
||||
\ 'col' : l:col, |
||||
\ 'type' : 'm' |
||||
\ } |
||||
\ ) |
||||
endfor |
||||
|
||||
" Add separator when showing context |
||||
"if (a:context > 0) |
||||
" let l:list = add(l:list, l:list_sep) |
||||
"endif |
||||
endfor |
||||
|
||||
" Remove the redundant separator at the end when showing context |
||||
"if ( (a:context > 0) |
||||
" \ && (len(l:list) > 0) |
||||
" \ ) |
||||
" call remove(l:list, -1) |
||||
"endif |
||||
|
||||
call setloclist(0, l:list) | lopen |
||||
endfunction |
@ -0,0 +1,174 @@
@@ -0,0 +1,174 @@
|
||||
" vim: fdm=marker:et:ts=4:sw=2:sts=1 |
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" |
||||
|
||||
function! signature#marker#Toggle(marker) " {{{1 |
||||
" Description: Toggle marker on current line |
||||
" Arguments: marker [!@#$%^&*()] |
||||
|
||||
let l:lnum = line('.') |
||||
" If marker is found on current line, remove it, else place it |
||||
if ( (get(b:sig_markers, l:lnum, "") =~# escape(a:marker, '$^')) |
||||
\ && !g:SignatureForceMarkerPlacement |
||||
\ ) |
||||
call signature#sign#Remove(a:marker, l:lnum) |
||||
call signature#sign#ToggleDummy() |
||||
else |
||||
call signature#sign#Place(a:marker, l:lnum) |
||||
endif |
||||
endfunction |
||||
|
||||
|
||||
function! signature#marker#Remove(lnum, marker) " {{{1 |
||||
" Description: Remove marker from specified line number |
||||
" Arguments: lnum - Line no. to delete marker from. If is 0, removes marker from current line |
||||
" a:2 - Marker to delete. If not specified, obtains input from user |
||||
|
||||
if (get(b:sig_markers, a:lnum, '') =~ a:marker) |
||||
call signature#sign#Remove(a:marker, a:lnum) |
||||
endif |
||||
endfunction |
||||
|
||||
|
||||
function! signature#marker#Purge(...) " {{{1 |
||||
" Description: If argument is given, removes marker only of the specified type else all markers are removed |
||||
|
||||
if empty(b:sig_markers) | return | endif |
||||
if g:SignaturePurgeConfirmation |
||||
let choice = confirm('Are you sure you want to delete all markers? This cannot be undone.', '&Yes\n&No', 1) |
||||
if choice == 2 | return | endif |
||||
endif |
||||
|
||||
if a:0 > 0 |
||||
let l:markers = [ a:1 ] |
||||
else |
||||
let l:markers = split(b:SignatureIncludeMarkers, '\zs') |
||||
endif |
||||
|
||||
for l:marker in l:markers |
||||
for l:lnum in keys(filter(copy(b:sig_markers), 'v:val =~# l:marker')) |
||||
call signature#marker#Remove(l:lnum, l:marker) |
||||
endfor |
||||
endfor |
||||
call signature#sign#ToggleDummy() |
||||
endfunction |
||||
|
||||
|
||||
function! signature#marker#Goto( dir, marker_num, count ) " {{{1 |
||||
" Description: Jump to next/prev marker by location. |
||||
" Arguments: dir = next : Jump forward |
||||
" prev : Jump backward |
||||
" marker = same : Jump to a marker of the same type |
||||
" any : Jump to a marker of any type |
||||
" [0-9] : Jump to the corresponding marker |
||||
|
||||
let l:lnum = line('.') |
||||
|
||||
let l:marker = '' |
||||
if (a:marker_num =~ '\v<[0-9]>') |
||||
let l:marker = split(b:SignatureIncludeMarkers, '\zs')[a:marker_num] |
||||
elseif ( (a:marker_num ==? 'same') |
||||
\ && has_key(b:sig_markers, l:lnum) |
||||
\ ) |
||||
let l:marker = signature#utils#GetChar(b:sig_markers[l:lnum], 0) |
||||
endif |
||||
|
||||
" Get list of line numbers of lines with markers. |
||||
" If current line has a marker, filter out line numbers of other markers ... |
||||
if (l:marker != '') |
||||
let l:marker_lnums = sort(keys(filter(copy(b:sig_markers), |
||||
\ 'signature#utils#GetChar(v:val, 0) == l:marker')), "signature#utils#NumericSort") |
||||
else |
||||
let l:marker_lnums = sort(keys(b:sig_markers), "signature#utils#NumericSort") |
||||
endif |
||||
|
||||
if (a:dir ==? 'next') |
||||
let l:marker_lnums = filter(copy(l:marker_lnums), ' v:val > l:lnum') |
||||
\ + filter(copy(l:marker_lnums), '(v:val <= l:lnum) && b:SignatureWrapJumps') |
||||
elseif (a:dir ==? 'prev') |
||||
call reverse(l:marker_lnums) |
||||
let l:marker_lnums = filter(copy(l:marker_lnums), ' v:val < l:lnum') |
||||
\ + filter(copy(l:marker_lnums), '(v:val >= l:lnum) && b:SignatureWrapJumps') |
||||
endif |
||||
|
||||
if (len(l:marker_lnums) == 0) |
||||
return |
||||
endif |
||||
|
||||
let l:count = (a:count == 0 ? 1 : a:count) |
||||
if (b:SignatureWrapJumps) |
||||
let l:count = l:count % len(l:marker_lnums) |
||||
elseif (l:count > len(l:marker_lnums)) |
||||
let l:count = 0 |
||||
endif |
||||
|
||||
let l:targ = l:marker_lnums[l:count - 1] |
||||
execute 'normal! ' . l:targ . 'G' |
||||
endfunction |
||||
|
||||
|
||||
function! signature#marker#List(...) " {{{1 |
||||
" Description: Opens and populates location list with markers from current buffer |
||||
" Show all markers in location list if no argument is provided |
||||
" Argument: [markers] = 0-9 or any of the specified symbols : List only the specified markers |
||||
" [context] = 0 (default) : Adds context around marker |
||||
" To show all markers with 1 line of context call using arguments ("", 1) |
||||
|
||||
let l:markers = (a:0 && (a:1 != "") ? a:1 : b:SignatureIncludeMarkers) |
||||
let l:context = (a:0 > 1 ? a:2 : 0) |
||||
|
||||
if (l:markers =~ '^\d$') |
||||
if ( ( (l:markers == 0) |
||||
\ && (len(b:SignatureIncludeMarkers) != 10) |
||||
\ ) |
||||
\ || (l:markers > len(b:SignatureIncludeMarkers)) |
||||
\ ) |
||||
echoe "Signature: No corresponding marker exists for " . l:markers |
||||
return |
||||
endif |
||||
let l:markers = split(b:SignatureIncludeMarkers, '\zs')[l:markers] |
||||
endif |
||||
|
||||
let l:lines_tot = line('$') |
||||
let l:buf_curr = bufnr('%') |
||||
let l:list_sep = {'bufnr': '', 'lnum' : ''} |
||||
let l:list = [] |
||||
|
||||
" Markers not specified in b:SignatureIncludeMarkers won't be present in b:sig_markers and hence get filtered out |
||||
for l:lnum in sort(keys(filter(copy(b:sig_markers), 'v:val =~ "[" . l:markers . "]"'))) |
||||
|
||||
for context_lnum in range(l:lnum - l:context, l:lnum + l:context) |
||||
if ( (context_lnum < 1) |
||||
\ || (context_lnum > lines_tot) |
||||
\ ) |
||||
continue |
||||
endif |
||||
|
||||
if (context_lnum < l:lnum) | let l:text = '-' . ": " . getline(context_lnum) |
||||
elseif (context_lnum > l:lnum) | let l:text = '+' . ": " . getline(context_lnum) |
||||
else | let l:text = b:sig_markers[l:lnum] . ": " . getline(context_lnum) |
||||
endif |
||||
|
||||
let l:list = add(l:list, |
||||
\ { 'text' : l:text, |
||||
\ 'bufnr': l:buf_curr, |
||||
\ 'lnum' : context_lnum, |
||||
\ 'type' : 'M' |
||||
\ } |
||||
\ ) |
||||
endfor |
||||
|
||||
" Add separator when showing context |
||||
"if (a:context > 0) |
||||
" let l:list = add(l:list, l:list_sep) |
||||
"endif |
||||
endfor |
||||
|
||||
" Remove the redundant separator at the end when showing context |
||||
"if ( (a:context > 0) |
||||
" \ && (len(l:list) > 0) |
||||
" \ ) |
||||
" call remove(l:list, -1) |
||||
"endif |
||||
|
||||
call setloclist(0, l:list,) | lopen |
||||
endfunction |
@ -0,0 +1,375 @@
@@ -0,0 +1,375 @@
|
||||
" vim: fdm=marker:et:ts=4:sw=2:sts=2 |
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" |
||||
|
||||
function! signature#sign#Place(sign, lnum) "{{{1 |
||||
" Description: Place signs for marks/markers on the specified line number |
||||
" Arguments: |
||||
" sign : The mark/marker whose sign is to be placed |
||||
" lnum : Line number on/from which the sign is to be placed/removed |
||||
|
||||
"echom "DEBUG: sign = " . a:sign . ", lnum = " . a:lnum |
||||
|
||||
" If Signature is not enabled, return |
||||
if !b:sig_enabled | return | endif |
||||
|
||||
" FIXME: Highly inefficient. Needs work |
||||
" Place sign only if there are no signs from other plugins (eg. syntastic) |
||||
"let l:present_signs = s:GetInfo(1) |
||||
"if ( b:SignatureDeferPlacement |
||||
" \ && has_key(l:present_signs, a:lnum) |
||||
" \ && (l:present_signs[a:lnum]['name'] !~# '^sig_Sign_') |
||||
" \ ) |
||||
" return |
||||
"endif |
||||
|
||||
if signature#utils#IsValidMarker(a:sign) |
||||
let b:sig_markers[a:lnum] = a:sign . get(b:sig_markers, a:lnum, "") |
||||
elseif signature#utils#IsValidMark(a:sign) |
||||
let b:sig_marks[a:lnum] = a:sign . get(b:sig_marks, a:lnum, "") |
||||
else |
||||
echoerr "Unexpected sign found: " . a:sign |
||||
endif |
||||
"}}}3 |
||||
|
||||
call s:RefreshLine(a:lnum) |
||||
endfunction |
||||
|
||||
|
||||
function! signature#sign#Remove(sign, lnum) "{{{1 |
||||
" Description: Remove signs for marks/markers from the specified line number |
||||
" Arguments: |
||||
" sign : The mark/marker whose sign is to be placed/removed/toggled |
||||
" lnum : Line number from which the sign is to be removed |
||||
" If sign is a marker and lnum is 0, the sign will be removed from all lines |
||||
" If sign is a mark and lnum is 0, the lnum will be found and the sign will be removed from that line |
||||
|
||||
"echom "DEBUG: sign = " . a:sign . ", lnum = " . a:lnum |
||||
|
||||
" If Signature is not enabled, return |
||||
if !b:sig_enabled | return | endif |
||||
|
||||
" Remove sign for markers |
||||
if signature#utils#IsValidMarker(a:sign) |
||||
let b:sig_markers[a:lnum] = substitute(b:sig_markers[a:lnum], "\\C" . escape( a:sign, '$^' ), "", "") |
||||
|
||||
" If there are no markers on the line, delete signs on that line |
||||
if b:sig_markers[a:lnum] == "" |
||||
call remove(b:sig_markers, a:lnum) |
||||
endif |
||||
call s:RefreshLine(a:lnum) |
||||
|
||||
" Remove sign for marks |
||||
else |
||||
" For marks, if a:lnum == 0, find out the line where the mark was placed |
||||
if a:lnum == 0 |
||||
let l:arr = keys(filter(copy(b:sig_marks), 'v:val =~# a:sign')) |
||||
if empty(l:arr) | return | endif |
||||
else |
||||
let l:arr = [a:lnum] |
||||
endif |
||||
if (v:version >= 800) |
||||
call assert_true(len(l:arr) == 1, "Multiple marks found where one was expected") |
||||
elseif (len(l:arr) != 1) |
||||
echoerr "Multiple marks found where one was expected" |
||||
endif |
||||
|
||||
for l:lnum in l:arr |
||||
" FIXME: Placed guard to avoid triggering issue #53 |
||||
if has_key(b:sig_marks, l:lnum) |
||||
let b:sig_marks[l:lnum] = substitute(b:sig_marks[l:lnum], "\\C" . a:sign, "", "") |
||||
" If there are no marks on the line, delete signs on that line |
||||
if b:sig_marks[l:lnum] == "" |
||||
call remove(b:sig_marks, l:lnum) |
||||
endif |
||||
endif |
||||
call s:RefreshLine(l:lnum) |
||||
endfor |
||||
endif |
||||
endfunction |
||||
|
||||
|
||||
function! s:EvaluateHL(expr, lnum, ...) "{{{1 |
||||
" Description: If expr points to a function, call it and use its output as the highlight group. |
||||
" If it is a string, use it directly. |
||||
" If the optional argument is specified, use it as a fallback. If not, return an empty string |
||||
|
||||
if type(a:expr) == type("") |
||||
return a:expr |
||||
elseif type(a:expr) == type(function("tr")) |
||||
let l:retval = a:expr(a:lnum) |
||||
if (l:retval != "") |
||||
return l:retval |
||||
endif |
||||
endif |
||||
|
||||
return (a:0 > 0 ? a:1 : "") |
||||
endfunction |
||||
|
||||
|
||||
function! s:RefreshLine(lnum) "{{{1 |
||||
" Description: Decides what the sign string should be based on if there are any marks or markers (using b:sig_marks |
||||
" and b:sig_markers) on the current line and the value of b:SignaturePrioritizeMarks. |
||||
" Arguments: |
||||
" lnum : Line number for which the sign string is to be modified |
||||
|
||||
let l:id = abs(a:lnum * 1000 + bufnr('%')) |
||||
let l:str = "" |
||||
|
||||
" Place the sign |
||||
if ( has_key(b:sig_marks, a:lnum) |
||||
\ && ( b:SignaturePrioritizeMarks |
||||
\ || !has_key(b:sig_markers, a:lnum) |
||||
\ ) |
||||
\ ) |
||||
let l:SignatureMarkTextHL = s:EvaluateHL(g:SignatureMarkTextHL, a:lnum, "SignatureMarkText") |
||||
let l:SignatureMarkLineHL = s:EvaluateHL(g:SignatureMarkLineHL, a:lnum, "SignatureMarkLine") |
||||
let l:str = substitute(b:SignatureMarkOrder, "\m", signature#utils#GetChar(b:sig_marks[a:lnum], 0), '') |
||||
let l:str = substitute(l:str, "\p", signature#utils#GetChar(b:sig_marks[a:lnum], 1), '') |
||||
|
||||
execute 'sign define Signature_' . l:str . ' text=' . l:str . ' texthl=' . l:SignatureMarkTextHL . ' linehl=' . l:SignatureMarkLineHL |
||||
|
||||
elseif has_key(b:sig_markers, a:lnum) |
||||
let l:SignatureMarkerTextHL = s:EvaluateHL(g:SignatureMarkerTextHL, a:lnum, "SignatureMarkerText") |
||||
let l:SignatureMarkerLineHL = s:EvaluateHL(g:SignatureMarkerLineHL, a:lnum, "SignatureMarkerLine") |
||||
|
||||
" Since the same marker can be placed on multiple lines, we can't use the same sign for all of them. |
||||
" This is because if dynamic highlighting of markers is enabled then the sign placed on eg. a modified line should |
||||
" be highlighted differently than the one placed on an unchanged line. |
||||
" In order to support this, I append the name of the TextHL and LineHL group to the name of the sign. |
||||
let l:txt = signature#utils#GetChar(b:sig_markers[a:lnum], 0) |
||||
let l:str = l:txt . '_' . l:SignatureMarkerTextHL . '_' . l:SignatureMarkerLineHL |
||||
|
||||
execute 'sign define Signature_' . l:str . ' text=' . l:txt . ' texthl=' . l:SignatureMarkerTextHL . ' linehl=' . l:SignatureMarkerLineHL |
||||
else |
||||
call signature#sign#Unplace(a:lnum) |
||||
endif |
||||
|
||||
if (l:str != "") |
||||
execute 'sign place ' . l:id . ' line=' . a:lnum . ' name=Signature_' . l:str . ' buffer=' . bufnr('%') |
||||
endif |
||||
|
||||
" If there is only 1 mark/marker in the file, place a dummy to prevent flickering of the gutter when it is moved |
||||
" If there are no signs left, remove the dummy |
||||
call signature#sign#ToggleDummy() |
||||
endfunction |
||||
|
||||
|
||||
function! signature#sign#Refresh(...) "{{{1 |
||||
" Description: Add signs for new marks/markers and remove signs for deleted marks/markers |
||||
" Arguments: Specify an argument to force a sign refresh |
||||
|
||||
call s:InitializeVars(a:0 && a:1) |
||||
" If Signature is not enabled, return |
||||
if !b:sig_enabled | return | endif |
||||
|
||||
for i in signature#mark#GetList('free', 'buf_curr') |
||||
" ... remove it |
||||
call signature#sign#Remove(i, 0) |
||||
endfor |
||||
|
||||
" Add signs for marks ... |
||||
for [l:mark, l:lnum, _] in signature#mark#GetList('used', 'buf_curr') |
||||
" ... if mark is not present in our b:sig_marks list or if it is present but at the wrong line, |
||||
" remove the old sign and add a new one |
||||
if ( !has_key(b:sig_marks, l:lnum) |
||||
\ || (b:sig_marks[l:lnum] !~# l:mark) |
||||
\ || a:0 |
||||
\ ) |
||||
call signature#sign#Remove(l:mark, 0) |
||||
call signature#sign#Place (l:mark, l:lnum) |
||||
endif |
||||
endfor |
||||
|
||||
call signature#sign#ToggleDummy() |
||||
|
||||
" We do not add signs for markers as SignRefresh is executed periodically and we don't have a way to determine if the |
||||
" marker already has a sign or not |
||||
endfunction |
||||
|
||||
|
||||
function! signature#sign#Unplace(lnum) "{{{1 |
||||
" Description: Remove the sign from the specified line number |
||||
" FIXME: Clean-up. Undefine the sign |
||||
let l:id = abs(a:lnum * 1000 + bufnr('%')) |
||||
silent! execute 'sign unplace ' . l:id |
||||
endfunction |
||||
|
||||
|
||||
function! signature#sign#ToggleDummy(...) "{{{1 |
||||
" Description: Places a dummy sign to prevent flickering of the gutter when the mark is moved or the line containing |
||||
" a mark/marker is deleted and then the delete is undone |
||||
" Arguments: (optional) 0 : force remove |
||||
" 1 : force place |
||||
|
||||
let l:place = a:0 ? a:1 : (len(b:sig_marks) + len(b:sig_markers) == 1) && !b:sig_DummyExists |
||||
let l:remove = a:0 ? !a:1 : (len(b:sig_marks) + len(b:sig_markers) == 0) && b:sig_DummyExists |
||||
|
||||
if (l:place) |
||||
sign define Signature_Dummy |
||||
execute 'sign place 666 line=1 name=Signature_Dummy buffer=' . bufnr('%') |
||||
let b:sig_DummyExists = 1 |
||||
elseif (l:remove) |
||||
silent! execute 'sign unplace 666 buffer=' . bufnr('%') |
||||
let b:sig_DummyExists = 0 |
||||
endif |
||||
endfunction |
||||
|
||||
|
||||
function! s:GetInfo(...) "{{{1 |
||||
" Description: Returns a dic of filenames, each of which is a dic of line numbers on which signs are placed |
||||
" Arguments: filename (optional). |
||||
" If filename is provided, the return value will contain signs only present in the given file |
||||
" Eg. { |
||||
" 'vimrc': { |
||||
" '711': { |
||||
" 'id': '1422', |
||||
" 'name': 'sig_Sign_1422' |
||||
" }, |
||||
" '676': { |
||||
" 'id': '1352', |
||||
" 'name': 'sig_Sign_1352' |
||||
" } |
||||
" } |
||||
" } |
||||
|
||||
" Redirect the input to a variable |
||||
redir => l:sign_str |
||||
silent! sign place |
||||
redir END |
||||
|
||||
" Create a Hash of files to store the info. |
||||
let l:signs_dic = {} |
||||
" The file that is currently being processed is stored into l:file |
||||
let l:match_file = "" |
||||
let l:file_found = 0 |
||||
|
||||
" Split the string into an array of sentences and filter out empty lines |
||||
for i in filter( split( l:sign_str, '\n' ), 'v:val =~ "^[S ]"' ) |
||||
let l:temp_file = matchstr( i, '\v(Signs for )@<=\S+:@=' ) |
||||
|
||||
if l:temp_file != "" |
||||
let l:match_file = l:temp_file |
||||
let l:signs_dic[l:match_file] = {} |
||||
elseif l:match_file != "" |
||||
" Get sign info |
||||
let l:info_match = matchlist( i, '\vline\=(\d+)\s*id\=(\S+)\s*name\=(\S+)' ) |
||||
if !empty( l:info_match ) |
||||
let l:signs_dic[l:match_file][l:info_match[1]] = { |
||||
\ 'id' : l:info_match[2], |
||||
\ 'name' : l:info_match[3], |
||||
\ } |
||||
endif |
||||
endif |
||||
endfor |
||||
|
||||
if a:0 |
||||
"" Search for the full path first in the hash ... |
||||
"let l:curr_filepath = expand('%:p') |
||||
"if has_key( l:signs_dic, l:curr_filepath ) |
||||
" return filter( l:signs_dic, 'v:key ==# l:curr_filepath' )[l:curr_filepath] |
||||
"else |
||||
" ... if no entry is found for the full path, search for the filename in the hash ... |
||||
" Since we're searching for the current file, if present in the hash, it'll be as a filename and not the full path |
||||
let l:curr_filename = expand('%:t') |
||||
if has_key( l:signs_dic, l:curr_filename ) |
||||
return filter( l:signs_dic, 'v:key ==# l:curr_filename' )[l:curr_filename] |
||||
endif |
||||
|
||||
" ... if nothing is found, then return an empty hash to indicate that no signs are present in the current file |
||||
return {} |
||||
endif |
||||
|
||||
return l:signs_dic |
||||
endfunction |
||||
|
||||
|
||||
function! signature#sign#GetGitGutterHLGroup(lnum) "{{{1 |
||||
" Description: This returns the highlight group used by vim-gitgutter depending on how the line was edited |
||||
|
||||
let l:current_bufnr = bufnr('%') |
||||
let l:line_state = filter(copy(gitgutter#diff#process_hunks(l:current_bufnr, gitgutter#hunk#hunks(l:current_bufnr))), 'v:val[0] == a:lnum') |
||||
|
||||
if len(l:line_state) == 0 |
||||
return "" |
||||
endif |
||||
|
||||
if (l:line_state[0][1]) =~ 'added' | return 'GitGutterAdd' |
||||
elseif (l:line_state[0][1]) =~ 'modified_removed' | return 'GitGutterChangeDelete' |
||||
elseif (l:line_state[0][1]) =~ 'modified' | return 'GitGutterChange' |
||||
elseif (l:line_state[0][1]) =~ 'removed' | return 'GitGutterDelete' |
||||
endif |
||||
endfunction |
||||
|
||||
|
||||
function! signature#sign#GetSignifyHLGroup(lnum) "{{{1 |
||||
" Description: This returns the highlight group used by vim-signify depending on how the line was edited |
||||
" Thanks to @michaelmior |
||||
|
||||
if !exists('b:sy') |
||||
return "" |
||||
endif |
||||
call sy#sign#get_current_signs(b:sy) |
||||
|
||||
if has_key(b:sy.internal, a:lnum) |
||||
let l:line_state = b:sy.internal[a:lnum]['type'] |
||||
if l:line_state =~ 'SignifyAdd' | return 'SignifySignAdd' |
||||
elseif l:line_state =~ 'SignifyChange' | return 'SignifySignChange' |
||||
elseif l:line_state =~ 'SignifyDelete' | return 'SignifySignDelete' |
||||
end |
||||
endif |
||||
|
||||
return "" |
||||
endfunction |
||||
|
||||
|
||||
" function! signature#sign#GetMarkSignLine(mark) "{{{1 |
||||
" if !signature#utils#IsValidMark(a:mark) |
||||
" echoe "Signature: Invalid mark " . a:mark |
||||
" return |
||||
" endif |
||||
|
||||
" let l:sign_info=filter(split(execute('sign place'), '\n'), |
||||
" \ 'v:val =~ "\\vSignature_(.?' . a:mark . '|' . a:mark . '.?)$"') |
||||
|
||||
" if (len(l:sign_info) != 1) |
||||
" echoe "Signature: Expected single match, found " . len(l:sign_info) |
||||
" return |
||||
" endif |
||||
|
||||
" return matchstr(l:sign_info[0], '\v(line\=)@<=\d+') |
||||
" endfunction |
||||
|
||||
|
||||
function! s:InitializeVars(...) "{{{1 |
||||
" Description: Initialize variables |
||||
" Arguments: Specify an argument to re-init |
||||
|
||||
if !exists('b:sig_marks') |
||||
" b:sig_marks = { lnum => signs_str } |
||||
let b:sig_marks = {} |
||||
else |
||||
" Lines can be removed using an external tool. Hence, we need to filter out marks placed on line numbers that are |
||||
" now greater than the total number of lines in the file. |
||||
let l:line_tot = line('$') |
||||
call filter( b:sig_marks, 'v:key <= l:line_tot' ) |
||||
endif |
||||
|
||||
if !exists('b:sig_markers') |
||||
" b:sig_markers = { lnum => marker } |
||||
let b:sig_markers = {} |
||||
else |
||||
" Lines can be removed using an external tool. Hence, we need to filter out marks placed on line numbers that are |
||||
" now greater than the total number of lines in the file. |
||||
let l:line_tot = line('$') |
||||
call filter( b:sig_markers, 'v:key <= l:line_tot' ) |
||||
endif |
||||
|
||||
call signature#utils#Set('b:sig_DummyExists' , 0 , a:0 && a:1) |
||||
call signature#utils#Set('b:sig_enabled' , g:SignatureEnabledAtStartup, a:0 && a:1) |
||||
call signature#utils#Set('b:SignatureIncludeMarks' , g:SignatureIncludeMarks , a:0 && a:1) |
||||
call signature#utils#Set('b:SignatureIncludeMarkers' , g:SignatureIncludeMarkers , a:0 && a:1) |
||||
call signature#utils#Set('b:SignatureMarkOrder' , g:SignatureMarkOrder , a:0 && a:1) |
||||
call signature#utils#Set('b:SignaturePrioritizeMarks', g:SignaturePrioritizeMarks , a:0 && a:1) |
||||
call signature#utils#Set('b:SignatureDeferPlacement' , g:SignatureDeferPlacement , a:0 && a:1) |
||||
call signature#utils#Set('b:SignatureWrapJumps' , g:SignatureWrapJumps , a:0 && a:1) |
||||
endfunction |
@ -0,0 +1,195 @@
@@ -0,0 +1,195 @@
|
||||
" vim: fdm=marker:et:ts=4:sw=2:sts=2 |
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" |
||||
|
||||
function! signature#utils#Set(var, value, ...) " {{{1 |
||||
" Description: Assign value to var if var is unset or if an optional 3rd arg is provided to force |
||||
|
||||
if (!exists(a:var) || a:0 && a:1) |
||||
if type(a:value) |
||||
execute 'let' a:var '=' string(a:value) |
||||
else |
||||
execute 'let' a:var '=' a:value |
||||
endif |
||||
endif |
||||
return a:var |
||||
endfunction |
||||
|
||||
|
||||
function! signature#utils#NumericSort(x, y) " {{{1 |
||||
return a:x - a:y |
||||
endfunction |
||||
|
||||
|
||||
function! s:Map(mode, key, map_lhs_default, map_rhs) " {{{1 |
||||
let l:map_lhs = get(g:SignatureMap, a:key, a:map_lhs_default) |
||||
if (l:map_lhs ==? '') |
||||
return |
||||
endif |
||||
if (a:mode ==? 'create') |
||||
silent! execute 'nnoremap <silent> <unique> ' . l:map_lhs . ' ' . ':<C-U>call signature#' . a:map_rhs . '<CR>' |
||||
elseif (a:mode ==? 'remove') |
||||
silent! execute 'nunmap ' . l:map_lhs |
||||
endif |
||||
endfunction |
||||
|
||||
function! signature#utils#Maps(mode) " {{{1 |
||||
" We create separate mappings for PlaceNextMark, mark#Purge('all') and PurgeMarkers instead of combining it with |
||||
" Leader/Input as if the user chooses to use some weird key like <BS> or <CR> for any of these 3, we need to be able |
||||
" to identify it. Eg. the nr2char(getchar()) will fail if the user presses a <BS> |
||||
let l:SignatureMapLeader = get(g:SignatureMap, 'Leader', 'm') |
||||
if (l:SignatureMapLeader == "") |
||||
echoe "Signature: g:SignatureMap.Leader shouldn't be left blank" |
||||
endif |
||||
call s:Map(a:mode, 'Leader' , l:SignatureMapLeader , 'utils#Input()' ) |
||||
call s:Map(a:mode, 'PlaceNextMark' , l:SignatureMapLeader . "," , 'mark#Toggle("next")' ) |
||||
call s:Map(a:mode, 'ToggleMarkAtLine' , l:SignatureMapLeader . "." , 'mark#ToggleAtLine()' ) |
||||
call s:Map(a:mode, 'PurgeMarksAtLine' , l:SignatureMapLeader . "-" , 'mark#Purge("line")' ) |
||||
call s:Map(a:mode, 'PurgeMarks' , l:SignatureMapLeader . "<Space>", 'mark#Purge("all")' ) |
||||
call s:Map(a:mode, 'PurgeMarkers' , l:SignatureMapLeader . "<BS>" , 'marker#Purge()' ) |
||||
call s:Map(a:mode, 'DeleteMark' , "dm" , 'utils#Remove(v:count)' ) |
||||
call s:Map(a:mode, 'GotoNextLineAlpha', "']" , 'mark#Goto("next", "line", "alpha")' ) |
||||
call s:Map(a:mode, 'GotoPrevLineAlpha', "'[" , 'mark#Goto("prev", "line", "alpha")' ) |
||||
call s:Map(a:mode, 'GotoNextSpotAlpha', "`]" , 'mark#Goto("next", "spot", "alpha")' ) |
||||
call s:Map(a:mode, 'GotoPrevSpotAlpha', "`[" , 'mark#Goto("prev", "spot", "alpha")' ) |
||||
call s:Map(a:mode, 'GotoNextLineByPos', "]'" , 'mark#Goto("next", "line", "pos")' ) |
||||
call s:Map(a:mode, 'GotoPrevLineByPos', "['" , 'mark#Goto("prev", "line", "pos")' ) |
||||
call s:Map(a:mode, 'GotoNextSpotByPos', "]`" , 'mark#Goto("next", "spot", "pos")' ) |
||||
call s:Map(a:mode, 'GotoPrevSpotByPos', "[`" , 'mark#Goto("prev", "spot", "pos")' ) |
||||
call s:Map(a:mode, 'GotoNextMarker' , "]-" , 'marker#Goto("next", "same", v:count)') |
||||
call s:Map(a:mode, 'GotoPrevMarker' , "[-" , 'marker#Goto("prev", "same", v:count)') |
||||
call s:Map(a:mode, 'GotoNextMarkerAny', "]=" , 'marker#Goto("next", "any", v:count)') |
||||
call s:Map(a:mode, 'GotoPrevMarkerAny', "[=" , 'marker#Goto("prev", "any", v:count)') |
||||
call s:Map(a:mode, 'ListBufferMarks' , 'm/' , 'mark#List(0, 0)' ) |
||||
call s:Map(a:mode, 'ListBufferMarkers', 'm?' , 'marker#List(v:count, 0)' ) |
||||
endfunction |
||||
|
||||
|
||||
function! signature#utils#Input() " {{{1 |
||||
" Description: Grab input char |
||||
|
||||
if &ft ==# "netrw" |
||||
" Workaround for #104 |
||||
return |
||||
endif |
||||
|
||||
" Obtain input from user ... |
||||
let l:in = nr2char(getchar()) |
||||
|
||||
" ... if the input is not a number eg. '!' ==> Delete all '!' markers |
||||
if signature#utils#IsValidMarker(l:in) |
||||
return signature#marker#Purge(l:in) |
||||
endif |
||||
|
||||
" ... but if input is a number, convert it to corresponding marker before proceeding |
||||
if match(l:in, '\d') >= 0 |
||||
let l:char = signature#utils#GetChar(b:SignatureIncludeMarkers, l:in) |
||||
else |
||||
let l:char = l:in |
||||
endif |
||||
|
||||
if signature#utils#IsValidMarker(l:char) |
||||
return signature#marker#Toggle(l:char) |
||||
elseif signature#utils#IsValidMark(l:char) |
||||
return signature#mark#Toggle(l:char) |
||||
else |
||||
" l:char is probably one of `'[]<> or a space from the gap in b:SignatureIncludeMarkers |
||||
execute 'normal! m' . l:in |
||||
endif |
||||
endfunction |
||||
|
||||
|
||||
function! signature#utils#Remove(lnum) " {{{1 |
||||
" Description: Obtain mark or marker from the user and remove it. |
||||
" There can be multiple markers of the same type on different lines. If a line no. is provided |
||||
" (non-zero), delete the marker from the specified line else delete it from the current line |
||||
" NOTE: lnum is meaningless for a mark and will be ignored |
||||
" Arguments: lnum - Line no. to delete the marker from |
||||
|
||||
let l:char = nr2char(getchar()) |
||||
|
||||
if (l:char =~ '^\d$') |
||||
let l:lnum = (a:lnum == 0 ? line('.') : a:lnum) |
||||
let l:char = split(b:SignatureIncludeMarkers, '\zs')[l:char] |
||||
call signature#marker#Remove(lnum, l:char) |
||||
elseif (l:char =~? '^[a-z]$') |
||||
call signature#mark#Remove(l:char) |
||||
endif |
||||
endfunction |
||||
|
||||
|
||||
function! signature#utils#Toggle() " {{{1 |
||||
" Description: Toggles and refreshes sign display in the buffer. |
||||
|
||||
let b:sig_enabled = !b:sig_enabled |
||||
|
||||
if b:sig_enabled |
||||
" Signature enabled ==> Refresh signs |
||||
call signature#sign#Refresh() |
||||
|
||||
" Add signs for markers ... |
||||
for i in keys(b:sig_markers) |
||||
call signature#sign#Place(b:sig_markers[i], i) |
||||
endfor |
||||
else |
||||
" Signature disabled ==> Remove signs |
||||
for l:lnum in keys(b:sig_markers) |
||||
call signature#sign#Unplace(l:lnum) |
||||
endfor |
||||
for l:lnum in keys(b:sig_marks) |
||||
call signature#sign#Unplace(l:lnum) |
||||
endfor |
||||
" Force removal. Simply toggling doesn't work as we check whether b:sig_markers and b:sig_marks are empty before |
||||
" removing the dummy and b:sig_markers won't be empty |
||||
call signature#sign#ToggleDummy(0) |
||||
unlet b:sig_marks |
||||
endif |
||||
endfunction |
||||
|
||||
|
||||
function! signature#utils#SetupHighlightGroups() " {{{1 |
||||
" Description: Sets up the highlight groups |
||||
|
||||
function! CheckAndSetHL(curr_hl, prefix, attr, targ_color) |
||||
let l:curr_color = synIDattr(synIDtrans(hlID(a:curr_hl)), a:attr, a:prefix) |
||||
|
||||
if ( ( (l:curr_color == "") |
||||
\ || (l:curr_color < 0) |
||||
\ ) |
||||
\ && (a:targ_color != "") |
||||
\ && (a:targ_color >= 0) |
||||
\ ) |
||||
" echom "DEBUG: HL=" . a:curr_hl . " (" . a:prefix . a:attr . ") Curr=" . l:curr_color . ", To=" . a:targ_color |
||||
execute 'highlight ' . a:curr_hl . ' ' . a:prefix . a:attr . '=' . a:targ_color |
||||
endif |
||||
endfunction |
||||
|
||||
let l:prefix = (has('gui_running') || (has('termguicolors') && &termguicolors) ? 'gui' : 'cterm') |
||||
let l:sign_col_color = synIDattr(synIDtrans(hlID('SignColumn')), 'bg', l:prefix) |
||||
|
||||
call CheckAndSetHL('SignatureMarkText', l:prefix, 'fg', 'Red') |
||||
call CheckAndSetHL('SignatureMarkText', l:prefix, 'bg', l:sign_col_color) |
||||
call CheckAndSetHL('SignatureMarkerText', l:prefix, 'fg', 'Green') |
||||
call CheckAndSetHL('SignatureMarkerText', l:prefix, 'bg', l:sign_col_color) |
||||
|
||||
delfunction CheckAndSetHL |
||||
endfunction |
||||
|
||||
|
||||
function! signature#utils#IsValidMark(mark) " {{{1 |
||||
return (b:SignatureIncludeMarks =~# a:mark) |
||||
endfunction |
||||
|
||||
|
||||
function! signature#utils#IsValidMarker(marker) " {{{1 |
||||
return ( (b:SignatureIncludeMarkers =~# a:marker) |
||||
\ && (a:marker != ' ') |
||||
\ ) |
||||
endfunction |
||||
|
||||
|
||||
function! signature#utils#GetChar(string, pos) " {{{1 |
||||
if a:pos > strchars(a:string) - 1 | return "" | endif |
||||
let pattern = '.\{-' . a:pos . '}\(.\).*' |
||||
return substitute(a:string, pattern, '\1', '') |
||||
endfunction |
||||
|
@ -0,0 +1,408 @@
@@ -0,0 +1,408 @@
|
||||
*signature.txt* A plugin to toggle, display and navigate marks |
||||
|
||||
_________.__ __ ~ |
||||
/ _____/|__| ____ ____ _____ _/ |_ __ __ _______ ____ ~ |
||||
\_____ \ | | / ___\ / \ \__ \ \ __\| | \\_ __ \_/ __ \ ~ |
||||
/ \| | / /_/ >| | \ / __ \_ | | | | / | | \/\ ___/ ~ |
||||
/_______ /|__| \___ / |___| /(____ / |__| |____/ |__| \___ > ~ |
||||
\/ /_____/ \/ \/ \/ ~ |
||||
|
||||
|
||||
============================================================================== |
||||
Contents *Signature* |
||||
|
||||
1. Mappings |SignatureMappings| |
||||
2. Commands |SignatureCommands| |
||||
3. Customization |SignatureCustomization| |
||||
4. Contributing |SignatureContributing| |
||||
5. Credits |SignatureCredits| |
||||
6. License |SignatureLicense| |
||||
|
||||
|
||||
============================================================================== |
||||
1. Mappings *SignatureMappings* |
||||
|
||||
Out of the box, the followings mappings are defined by default |
||||
|
||||
mx Toggle mark 'x' and display it in the leftmost column |
||||
dmx Remove mark 'x' where x is a-zA-Z |
||||
|
||||
m, Place the next available mark |
||||
m. If no mark on line, place the next available mark. Otherwise, |
||||
remove (first) existing mark. |
||||
m- Delete all marks from the current line |
||||
m<Space> Delete all marks from the current buffer |
||||
]` Jump to next mark |
||||
[` Jump to prev mark |
||||
]' Jump to start of next line containing a mark |
||||
[' Jump to start of prev line containing a mark |
||||
`] Jump by alphabetical order to next mark |
||||
`[ Jump by alphabetical order to prev mark |
||||
'] Jump by alphabetical order to start of next line having a mark |
||||
'[ Jump by alphabetical order to start of prev line having a mark |
||||
m/ Open location list and display marks from current buffer |
||||
|
||||
m[0-9] Toggle the corresponding marker !@#$%^&*() |
||||
m<S-[0-9]> Remove all markers of the same type |
||||
]- Jump to next line having a marker of the same type |
||||
[- Jump to prev line having a marker of the same type |
||||
]= Jump to next line having a marker of any type |
||||
[= Jump to prev line having a marker of any type |
||||
m? Open location list and display markers from current buffer |
||||
m<BS> Remove all markers |
||||
|
||||
This will allow the use of default behavior of m to set marks and, if |
||||
the line already contains the mark, it'll be unset. The default behavior |
||||
of ]', [', ]` and [` is supported and enhanced by wrapping around when |
||||
beginning or end of file is reached. ]-, [-, ]= and [= also accept a count. |
||||
|
||||
To directly jump to a given marker, the following maps can be used |
||||
> |
||||
nnoremap [1 :call signature#marker#Goto('prev', 1, v:count) |
||||
nnoremap ]1 :call signature#marker#Goto('next', 1, v:count) |
||||
nnoremap [2 :call signature#marker#Goto('prev', 2, v:count) |
||||
nnoremap ]2 :call signature#marker#Goto('next', 2, v:count) |
||||
< |
||||
etc. These are not defined by default |
||||
|
||||
|
||||
============================================================================== |
||||
2. Commands *SignatureCommands* |
||||
|
||||
*:SignatureToggleSigns* |
||||
Toggle the display of signs. This won't affect the marks or the mappings. |
||||
|
||||
*:SignatureRefresh* |
||||
Force the display of signs in the buffer to refresh. Use this to correct |
||||
the signs if things go awry |
||||
|
||||
*:SignatureListBufferMarks* [n] |
||||
List all the marks used in the current buffer in the location list |
||||
Accepts an optional argument to provide 'n' lines of context |
||||
|
||||
*:SignatureListGlobalMarks* [n] |
||||
List only the global marks used in all buffers in the location list |
||||
Accepts an optional argument to provide 'n' lines of context |
||||
|
||||
*:SignatureListMarkers* [marker] [n] |
||||
List all instances of the specified marker(s) used in the current buffer |
||||
in the location list. If no argument is given, it lists all markers |
||||
Accepts an optional argument to provide 'n' lines of context |
||||
> |
||||
:SignatureListMarkers : List all markers |
||||
:SignatureListMarkers 1 : List only the '!' marker |
||||
:SignatureListMarkers @ : List only the '@' marker |
||||
:SignatureListMarkers 0, 2 : List only ) marker with 2 lines of context |
||||
:SignatureListMarkers '', 2 : List all markers with 2 lines of context |
||||
:SignatureListMarkers '!@', 2 : List only the '!' and '@' markers and show |
||||
2 lines of context around them |
||||
< |
||||
|
||||
============================================================================== |
||||
3. Customization *SignatureCustomization* |
||||
|
||||
*g:SignatureMap* |
||||
Type: Dictionary, Default: |
||||
To set up your own mappings copy the following dictionary and edit it |
||||
> |
||||
let g:SignatureMap = { |
||||
\ 'Leader' : "m", |
||||
\ 'PlaceNextMark' : "m,", |
||||
\ 'ToggleMarkAtLine' : "m.", |
||||
\ 'PurgeMarksAtLine' : "m-", |
||||
\ 'DeleteMark' : "dm", |
||||
\ 'PurgeMarks' : "m<Space>", |
||||
\ 'PurgeMarkers' : "m<BS>", |
||||
\ 'GotoNextLineAlpha' : "']", |
||||
\ 'GotoPrevLineAlpha' : "'[", |
||||
\ 'GotoNextSpotAlpha' : "`]", |
||||
\ 'GotoPrevSpotAlpha' : "`[", |
||||
\ 'GotoNextLineByPos' : "]'", |
||||
\ 'GotoPrevLineByPos' : "['", |
||||
\ 'GotoNextSpotByPos' : "]`", |
||||
\ 'GotoPrevSpotByPos' : "[`", |
||||
\ 'GotoNextMarker' : "]-", |
||||
\ 'GotoPrevMarker' : "[-", |
||||
\ 'GotoNextMarkerAny' : "]=", |
||||
\ 'GotoPrevMarkerAny' : "[=", |
||||
\ 'ListBufferMarks' : "m/", |
||||
\ 'ListBufferMarkers' : "m?" |
||||
\ } |
||||
< |
||||
By default, it defines the mappings as shown in |signature-mappings| |
||||
To disable a map entirely, specify it as an empty string. |
||||
If a key is not specified, the default value will be picked up. |
||||
These same characters will be used to invoke the shortcuts. |
||||
|
||||
|
||||
*g:SignatureIncludeMarks* |
||||
String, Default : 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' |
||||
|
||||
Specify the marks that can be controlled by this plugin. |
||||
Only supports Alphabetical marks at the moment. |
||||
'b:SignatureIncludeMarks' can be set separately for buffer-specific marks. |
||||
|
||||
|
||||
*g:SignatureIncludeMarkers* |
||||
String, Default : ')!@#$%^&*(' |
||||
|
||||
Specify the symbols that can be used by the plugin to be placed by 0-9. |
||||
Note that there's a 1:1 correspondence between the symbols and 0-9. |
||||
This string must be at most 10 chars long. Extra char will be ignored. |
||||
Also, this string must not include any alphabetical characters `[a-zA-Z]` |
||||
However, it can contain spaces to indicate blanks. Eg. |
||||
`m0` will place `)` by default |
||||
`m1` will place `!` by default |
||||
`m2` will place `@` by default etc. |
||||
|
||||
If set to `')!'`, `m0` and `m1` will behave as described above but `m[2-9]` will |
||||
not be handled by this plugin. |
||||
|
||||
If set to `' !'` (note the space before !), only `m1` will have any affect |
||||
while `m[0,2-9]` will not have any affect |
||||
|
||||
An example of a use case is for keyboards with alternate layouts wherein |
||||
the symbols associated with 0-9 could be different than the default. |
||||
'b:SignatureIncludeMarkers' can be specified separately for each buffer |
||||
|
||||
|
||||
*g:SignatureMap['Leader']* |
||||
String, Default: 'm' |
||||
|
||||
Set the key used to toggle marks and markers. |
||||
For eg. If this key is set to `<leader>m`, |
||||
`<leader>ma` will toggle the mark 'a' on the current line |
||||
`<leader>m,` will place the next available mark |
||||
`<leader>m.` will place the next available mark if there are no |
||||
marks already on the line; otherwise, will remove |
||||
first mark from line |
||||
`<leader>m<Space>` will delete all marks |
||||
`<leader>m1` will toggle the marker '!' |
||||
`<leader>m!` will remove all the '!' markers |
||||
`<leader>m<BS>` will remove all markers |
||||
|
||||
NOTE: Currently, either marks or markers can be displayed in front of a |
||||
line. Both can't be displayed simultaenously. |
||||
|
||||
To set this to mapleader or maplocalleader |
||||
|
||||
`let g:SignatureMap['Leader'] = '<Leader>'` |
||||
`let g:SignatureMap['Leader'] = '<LocalLeader>'` |
||||
|
||||
|
||||
*g:SignatureWrapJumps* |
||||
Boolean, Default : 1 |
||||
|
||||
Specify if jumping to marks should wrap-around. |
||||
b:SignatureWrapJumps can be set to specify buffer-specific settings. |
||||
|
||||
|
||||
*g:SignatureMarkOrder* |
||||
String, Default : "\p\m" |
||||
|
||||
Signature allows you to display upto marks in front of a line. This controls |
||||
the order in which marks are displayed. |
||||
'\m' indicates the current or latest mark placed on the line |
||||
'\p' indicates the previous mark placed on the line |
||||
|
||||
For eg, |
||||
`g:SignatureMarkOrder="\m."` : Display last mark with '.' suffixed |
||||
`g:SignatureMarkOrder="_\m"` : Display last mark with '_' prefixed |
||||
`g:SignatureMarkOrder=">"` : Display only a ">" for a line with a mark. |
||||
The mark is not displayed |
||||
`g:SignatureMarkOrder="\m\p"` : Display last two marks placed |
||||
|
||||
NOTE: The signs feature allows only 2 characters to be displayed. This limit |
||||
is imposed by vim itself and not by the plugin |
||||
|
||||
|
||||
*g:SignatureMarkTextHL* |
||||
String, Default : 'SignatureMarkText' |
||||
|
||||
The highlight group used for mark signs. This can be set either to a string |
||||
or to a |Funcref|. |
||||
|
||||
If it holds a string, it must be an expression suitable for passing to |
||||
|eval()|. In the simple case, it can be the name of a highlight group. It can |
||||
also hold more complicated expressions, in which case the expression `a:lnum` |
||||
may be helpful. It holds the number of the line where the current mark is to |
||||
be highlighted. |
||||
|
||||
If it holds a |Funcref|, then the function will be called with one argument, |
||||
the line number of the mark to be highlighted. The function should return |
||||
the name of a highlight group. |
||||
|
||||
Example using a string: |
||||
`let g:SignatureMarkTextHL = "Exception"` |
||||
|
||||
Example of |Funcref|: |
||||
`function Example(lineno)` |
||||
`return "Exception"` |
||||
`endfunction` |
||||
`let g:SignatureMarkTextHL = function("Example")` |
||||
|
||||
By default, this is set to SignatureMarkText which is a highlight group |
||||
that is linked to Exception |
||||
|
||||
*g:SignatureMarkTextHLDynamic* |
||||
Boolean, Default: 0 |
||||
|
||||
Highlight signs of marks dynamically based upon state indicated by |
||||
vim-gitgutter. Setting this to `1` prior to plugin initialization overwrites |
||||
|g:SignatureMarkTextHL|. |
||||
|
||||
vim-signify is not supported at the moment. For details, refer |
||||
https://github.com/kshenoy/vim-signature/issues/93#issuecomment-195672354 |
||||
|
||||
*g:SignatureMarkLineHL* |
||||
String, Default : 'SignatureMarkLine' |
||||
|
||||
The highlight group used for hightlighting lines having marks. This can be a |
||||
string or |Funcref|. SignatureMarkLine links to Normal by default. |
||||
See |g:SignatureMarkTextHL| for details. |
||||
|
||||
|
||||
*g:SignatureMarkerTextHL* |
||||
String, Default : 'SignatureMarkerText' |
||||
|
||||
The highlight group used for marker signs. This can be a string or |Funcref|. |
||||
SignatureMarkText links to WarningMsg by default. |
||||
See |g:SignatureMarkTextHL| for details. |
||||
|
||||
|
||||
*g:SignatureMarkerTextHLDynamic* |
||||
Boolean, Default: 0 |
||||
|
||||
Highlight signs of markers dynamically based upon state indicated by |
||||
vim-gitgutter or vim-signify. Setting this to `1` prior to plugin |
||||
initialization overwrites |g:SignatureMarkerTextHL|. |
||||
|
||||
|
||||
*g:SignatureMarkerLineHL* |
||||
String, Default : '' |
||||
|
||||
The highlight group used for hightlighting lines having markers. This can be |
||||
a string or a |Funcref|. SignatureMarkerLine links to Normal by default. |
||||
See |g:SignatureMarkTextHL| for details. |
||||
|
||||
|
||||
*g:SignatureDeleteConfirmation* |
||||
Boolean, Default: 0 |
||||
|
||||
An option for the more clumsy-fingered of us. Asks for confirmation before |
||||
moving/replacing/overwriting any marks |
||||
|
||||
|
||||
*g:SignaturePurgeConfirmation* |
||||
Boolean, Default: 0 |
||||
|
||||
Similar to g:SignatureDeleteConfirmation. Asks for confirmation before |
||||
deleting all marks/markers |
||||
|
||||
|
||||
*g:SignaturePeriodicRefresh* |
||||
Boolean, Default: 1 |
||||
|
||||
Enable the display to refresh periodically. Generally a good thing to have. |
||||
This makes use of the CursorHold autocmd event to execute periodically. |
||||
The frequency of this event can be controlled by changing the value of the |
||||
updatetime variable in milliseconds |
||||
`set updatetime = 100` |
||||
|
||||
|
||||
*g:SignaturePrioritizeMarks* |
||||
Boolean, Default: 1 |
||||
|
||||
When a line has both marks and markers, display the sign for marks. If set |
||||
to 0, it will display the sign for markers instead |
||||
|
||||
|
||||
*g:SignatureEnabledAtStartup* |
||||
Boolean, Default: 1 |
||||
|
||||
Control if the signs should be shown by default. If set to 0, the signs |
||||
won't be visible until `:SignatureToggleSigns` has been called |
||||
|
||||
|
||||
*g:SignatureDeferPlacement* |
||||
Boolean, Default: 1 |
||||
|
||||
NOTE: Not supported currently. Code was highly inefficient. |
||||
Check if any other plugin has already placed a sign and if set to 1, |
||||
Signature will hold off from placing a sign. If set to 0, Signature will |
||||
overwrite any signs that are already present. |
||||
|
||||
|
||||
*g:SignatureUnconditionallyRecycleMarks* |
||||
Boolean, Default: 0 |
||||
|
||||
Controls behavior when trying to place next available mark and all marks |
||||
have been used. If set to 0, then either an error or warning message will be |
||||
emitted, depending on the setting of |g:SignatureErrorIfNoAvailableMarks|. |
||||
If set to 1, then the first local mark (e.g., 'a') will be removed from its |
||||
existing location and applied to the current line. |
||||
|
||||
|
||||
*g:SignatureErrorIfNoAvailableMarks* |
||||
Boolean, Default: 1 |
||||
|
||||
Controls behavior when unable to place a new mark. If set to 1, then an |
||||
error is raised. If set to 0, then just a warning message. |
||||
|
||||
|
||||
*g:SignatureForceRemoveGlobal* |
||||
Boolean, Default: 0 |
||||
|
||||
Vim's handling of global marks is a bit iffy. This option forces the removal |
||||
of global marks by deleting it from the viminfo (or neovim's shada) file. |
||||
|
||||
Note that this is a very heavy hammer since it affects other things too. |
||||
Refer 'viminfo' or 'shada' for more information on features that could be |
||||
affected. |
||||
|
||||
|
||||
*g:SignatureForceMarkPlacement* |
||||
Boolean, Default: 0 |
||||
|
||||
When set to 1, will always place marks instead of toggling them |
||||
|
||||
|
||||
*g:SignatureForceMarkerPlacement* |
||||
Boolean, Default: 0 |
||||
|
||||
When set to 1, will always place markers instead of toggling them |
||||
|
||||
|
||||
============================================================================== |
||||
4. Contributing *SignatureContributing* |
||||
|
||||
Please post any issues and all your suggestions on Github |
||||
https://github.com/kshenoy/vim-signature |
||||
|
||||
Show some love by spreading the word and rating on |
||||
http://www.vim.org/scripts/script.php?script_id=4118 |
||||
|
||||
|
||||
============================================================================== |
||||
5. Credits *SignatureCredits* |
||||
|
||||
A great thanks to these guys for providing the idea and inspiration to develop |
||||
Signature |
||||
|
||||
* Sergey Khorev for mark-tools |
||||
http://www.vim.org/scripts/script.php?script_id=2929 |
||||
|
||||
* Zak Johnson for vim-showmarks |
||||
https://github.com/zakj/vim-showmarks |
||||
|
||||
I'd also like to thank Steve J. Losh for learningvimscriptthehardway.com |
||||
without whose detailed guide this plugin would not have seen the light of day. |
||||
|
||||
|
||||
============================================================================== |
||||
6. License *SignatureLicense* |
||||
|
||||
Signature is MIT/X11 licensed |
||||
|
||||
|
||||
vim:tw=78:ts=2:et:sts=2:sw=2:ft=help |
@ -0,0 +1,69 @@
@@ -0,0 +1,69 @@
|
||||
" vim: fdm=marker:et:ts=4:sw=2:sts=2 |
||||
|
||||
" Description: vim-signature is a plugin to toggle, display and navigate marks. |
||||
" |
||||
" Maintainer: Kartik Shenoy |
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" |
||||
|
||||
" Exit if the signs feature is not available or if the app has already been loaded (or "compatible" mode set) |
||||
if !has('signs') || &cp |
||||
finish |
||||
endif |
||||
if exists('g:loaded_Signature') |
||||
finish |
||||
endif |
||||
let g:loaded_Signature = 1 |
||||
|
||||
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" |
||||
"" Global variables {{{1 |
||||
" |
||||
call signature#utils#Set('g:SignaturePrioritizeMarks', 1 ) |
||||
call signature#utils#Set('g:SignatureIncludeMarks', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') |
||||
call signature#utils#Set('g:SignatureIncludeMarkers', ')!@#$%^&*(' ) |
||||
call signature#utils#Set('g:SignatureMarkTextHL', "SignatureMarkText" ) |
||||
call signature#utils#Set('g:SignatureMarkTextHLDynamic', 0 ) |
||||
call signature#utils#Set('g:SignatureMarkLineHL', "SignatureMarkLine" ) |
||||
call signature#utils#Set('g:SignatureMarkerTextHL', "SignatureMarkerText" ) |
||||
call signature#utils#Set('g:SignatureMarkerTextHLDynamic', 0 ) |
||||
call signature#utils#Set('g:SignatureMarkerLineHL', "SignatureMarkerLine" ) |
||||
call signature#utils#Set('g:SignatureWrapJumps', 1 ) |
||||
call signature#utils#Set('g:SignatureMarkOrder', "\p\m" ) |
||||
call signature#utils#Set('g:SignatureDeleteConfirmation', 0 ) |
||||
call signature#utils#Set('g:SignaturePurgeConfirmation', 0 ) |
||||
call signature#utils#Set('g:SignaturePeriodicRefresh', 1 ) |
||||
call signature#utils#Set('g:SignatureEnabledAtStartup', 1 ) |
||||
call signature#utils#Set('g:SignatureDeferPlacement', 1 ) |
||||
call signature#utils#Set('g:SignatureRecycleMarks', 0 ) |
||||
call signature#utils#Set('g:SignatureErrorIfNoAvailableMarks', 1 ) |
||||
call signature#utils#Set('g:SignatureForceRemoveGlobal', 0 ) |
||||
call signature#utils#Set('g:SignatureForceMarkPlacement', 0 ) |
||||
call signature#utils#Set('g:SignatureForceMarkerPlacement', 0 ) |
||||
call signature#utils#Set('g:SignatureMap', {} ) |
||||
|
||||
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" |
||||
"" Commands, Autocmds and Maps {{{1 |
||||
" |
||||
call signature#utils#Maps('create') |
||||
|
||||
if has('autocmd') |
||||
augroup sig_autocmds |
||||
autocmd! |
||||
|
||||
" This needs to be called upon loading a colorscheme |
||||
" VimEnter is kind of a backup if no colorscheme is explicitly loaded and the default is used |
||||
autocmd VimEnter,ColorScheme * call signature#utils#SetupHighlightGroups() |
||||
|
||||
" This is required to remove signs for global marks that were removed when in another window |
||||
autocmd BufEnter,CmdwinEnter * call signature#sign#Refresh() |
||||
|
||||
autocmd CursorHold * if (g:SignaturePeriodicRefresh) | call signature#sign#Refresh() | endif |
||||
augroup END |
||||
endif |
||||
|
||||
command! -nargs=0 SignatureToggleSigns call signature#utils#Toggle() |
||||
command! -nargs=0 SignatureRefresh call signature#sign#Refresh(1) |
||||
command! -nargs=? SignatureListBufferMarks call signature#mark#List(0, <args>) |
||||
command! -nargs=? SignatureListGlobalMarks call signature#mark#List(1, <args>) |
||||
command! -nargs=* SignatureListMarkers call signature#marker#List(<args>) |
Loading…
Reference in new issue