commit 9d395d316f68a9ce4b23a177c47bc82f0e078eca Author: Ernst Widerberg Date: Thu Jan 28 22:51:56 2021 +0100 Initial commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..12a5cd0 --- /dev/null +++ b/README.md @@ -0,0 +1,36 @@ +# vim-secret + +

+ +

+ +## Usage + + + + + + + + + + + + +
:SecretEnable secret view.
:Secret (line | word | char | none)Enable secret view with a specific visibility setting.
:Secret!Disable secret view.
+ +An area around the cursor is unhidden to enable you to see what you are typing. This can be the entire line, the current word, the current character, or it can be disabled completely. + +After a duration of time without input, or invoked manually via a mapping, all characters in the buffer is hidden. For details on this and other configuration options, see [`:help secret`](./doc/secret.txt). + +## FAQ + +> Replacement characters have a background color, which looks weird. + +This is due to how your color scheme styles the `Conceal` highlight group. To remove the background color, you could use something like the following in your `vimrc`/`init.vim`: + +```vim +autocmd! VimEnter,ColorScheme * hi Conceal ctermbg=NONE guibg=NONE +``` + +See [`:help secret-highlight`](./doc/secret.txt#L74) for more info. diff --git a/autoload/secret.vim b/autoload/secret.vim new file mode 100644 index 0000000..3df7667 --- /dev/null +++ b/autoload/secret.vim @@ -0,0 +1,166 @@ +let s:patterns = { + \ 'char': ['\%#\S', '\S\%#'], + \ 'word': ['\S*\%#\s\@!\S*', '\S*\%#\S*'], + \ 'line': ['.*\%#.*', '.*\%#.*'], + \ 'none': ['\_.\@!', '\_.\@!'] } + +function! s:pattern(name, mode) + if index(['char', 'word', 'line', 'none'], a:name) == -1 + throw a:name + endif + return s:patterns[a:name][a:mode] +endfunction + +" Clear augroup secret-WINID-BUFNR and remove BUFNR from w:secret_state +function! s:clear(w, b) + execute 'augroup secret-' . a:w . '-' . a:b + autocmd! + augroup END + execute 'augroup! secret-' . a:w . '-' . a:b + + let active = win_getid() + if getwininfo(a:w) != [] + call win_gotoid(a:w) + unlet w:secret_state[a:b] + if w:secret_state == {} + unlet w:secret_state + endif + endif + call win_gotoid(active) +endfunction + +function! s:enable_mappings() + if exists('g:secret_quickhide') + execute 'nnoremap ' + \ g:secret_quickhide ':syntax clear SecretVisible' + endif +endfunction + +function! s:disable_mappings() + if exists('g:secret_quickhide') + execute 'nunmap ' g:secret_quickhide + endif +endfunction + +function! s:buf_win_autocmd(group, ...) + return 'autocmd ' . a:group . ' if win_getid() == ' . win_getid() + \ . ' | ' . join(a:000, ' | ') . ' | endif' +endfunction + +" Enable secret view +function! s:enable(npat, ipat, cchar) + if !exists('w:secret_state') + let w:secret_state = {} + endif + + if !has_key(w:secret_state, bufnr()) + let w:secret_state[bufnr()] = {} + let w:secret_state[bufnr()].syntax = &syntax + let w:secret_state[bufnr()].concealcursor = &concealcursor + let w:secret_state[bufnr()].conceallevel = &conceallevel + ownsyntax + setlocal concealcursor =nvic + setlocal conceallevel =2 + endif + + call s:enable_mappings() + + syntax clear + execute 'syntax match SecretHidden ''\S'' conceal cchar=' . a:cchar . ' containedin=ALLBUT,SecretVisible' + execute 'syntax match SecretVisible ''' . a:npat . '''' + + execute 'augroup secret-' . win_getid() . '-' . bufnr() + autocmd! + + " Normal mode + execute (s:buf_win_autocmd('InsertLeave,CursorMoved', + \ 'syntax clear SecretVisible', + \ 'syntax match SecretVisible ''' . a:npat . '''')) + + if g:secret_timeout_normal + execute (s:buf_win_autocmd('CursorHold', 'syntax clear SecretVisible')) + endif + + " Insert mode + execute (s:buf_win_autocmd('InsertEnter,CursorMovedI', + \ 'syntax clear SecretVisible', + \ 'syntax match SecretVisible ''' . a:ipat . '''')) + + if g:secret_timeout_insert + execute (s:buf_win_autocmd('CursorHoldI', 'syntax clear SecretVisible')) + endif + + " Window left + execute (s:buf_win_autocmd('WinLeave', + \ 'syntax clear SecretVisible', + \ 'call s:disable_mappings()')) + + " Window entered + execute (s:buf_win_autocmd('WinEnter', 'call s:enable_mappings()')) + + " Window or buffer closed + execute 'autocmd WinEnter * if getwininfo(' . win_getid() . ') == []' + \ '| call s:clear(' . win_getid() . ', ' . bufnr() . ')' + \ '| call s:disable_mappings()' + \ '| endif' + execute 'autocmd BufDelete ' + \ ' call s:clear(' . win_getid() . ', ' . bufnr() . ')' + + " Hidden buffer displayed + execute (s:buf_win_autocmd('BufWinEnter', + \ 'execute ''ownsyntax''', + \ 'syntax clear', + \ 'syntax match SecretHidden ''\S'' conceal cchar=' . a:cchar . ' containedin=ALLBUT,SecretVisible', + \ 'syntax match SecretVisible ''' . a:npat . '''')) + augroup END +endfunction + +" Disable secret view +function! s:disable() + " If secret view not enabled for the current (window, buffer) + if !exists('w:secret_state') || !has_key(w:secret_state, bufnr()) + return + endif + + " Restore saved buffer state + syntax clear + execute 'set syntax =' . w:secret_state[bufnr()].syntax + execute 'setlocal concealcursor =' . w:secret_state[bufnr()].concealcursor + execute 'setlocal conceallevel =' . w:secret_state[bufnr()].conceallevel + + " Clear autocommands and saved state + call s:clear(win_getid(), bufnr()) + + " Clear mappings + call s:disable_mappings() +endfunction + +" Entry point for Secret command +function! secret#secret(enable, ...) + if a:enable + try + if a:0 == 0 + call s:enable( + \ s:pattern(exists('g:secret_visibility_normal') ? + \ g:secret_visibility_normal : g:secret_visibility, 0), + \ s:pattern(exists('g:secret_visibility_insert') ? + \ g:secret_visibility_insert : g:secret_visibility, 1), + \ g:secret_cchar) + elseif a:0 == 1 + call s:enable(s:pattern(a:1, 0), s:pattern(a:1, 1), g:secret_cchar) + elseif a:0 == 2 + call s:enable(s:pattern(a:1, 0), s:pattern(a:2, 1), g:secret_cchar) + else + echohl WarningMsg + echo 'Secret: Too many arguments' + echohl None + endif + catch + echohl WarningMsg + echo 'Secret: Invalid argument "' . v:exception . '"' + echohl None + endtry + else + call s:disable() + endif +endfunction diff --git a/doc/secret.txt b/doc/secret.txt new file mode 100644 index 0000000..485ffdf --- /dev/null +++ b/doc/secret.txt @@ -0,0 +1,91 @@ +*secret.txt* *secret* + +Requires |+conceal|. + +============================================================================== +COMMANDS *:Secret* + +:Secret Enable secret view. + +:Secret! Disable secret view. + +:Secret {visibility} Enable secret view with a given visibility setting. + See |secret-visibility| for possible values. + +:Secret {visibility-normal} {visibility-insert} + Enable secret view with separate visibility settings + for normal and insert mode. + See |secret-visibility| for possible values. + +============================================================================== +VISIBILITY SETTINGS *secret-visibility* + +An area around the cursor is unhidden to enable you to see what you are +typing. This area is specified using the following values: + +Value Description Example~ +'line' The current line. The quick brown fox jumps over the lazy dog. +'word' The current |WORD|. ••• ••••• ••••• fox ••••• •••• ••• •••• •••• +'char' The current character. ••• ••••• ••••• ••x ••••• •••• ••• •••• •••• +'none' Do not show anything. ••• ••••• ••••• ••• ••••• •••• ••• •••• •••• + ^ Cursor position~ + +============================================================================== +CONFIGURATION *secret-configuration* + + *g:secret_cchar* +g:secret_cchar Replacement character used for hidden text. + Default: '•' + + *g:secret_visibility* +g:secret_visibility Default visibility. + See |secret-visibility| for possible values. + Default: 'word' + + *g:secret_visibility_normal* +g:secret_visibility_normal Default normal mode visibility. + See |secret-visibility| for possible values. + Default: |g:secret_visibility| + + *g:secret_visibility_insert* +g:secret_visibility_insert Default insert mode visibility. + See |secret-visibility| for possible values. + Default: |g:secret_visibility| + + *g:secret_timeout_normal* +g:secret_timeout_normal Hide entire buffer after 'updatetime' milliseconds + without input in normal mode. + Default: 1 (enabled) + *g:secret_timeout_insert* +g:secret_timeout_insert Hide entire buffer after 'updatetime' milliseconds + without input in insert mode. + Default: 0 (disabled) + +============================================================================== +MAPPINGS *secret-mappings* + + *g:secret_quickhide* +g:secret_quickhide Hide entire buffer until the cursor is moved. Set this + to a key sequence string: > + + let g:secret_quickhide = 'q' + +============================================================================== +HIGHLIGHTING *secret-highlight* *SecretVisible* + +Two syntax groups are used, |Conceal| and `SecretVisible`. |Conceal| applies to +hidden text, and `SecretVisible` applies to the visible area surrounding the +cursor (see |secret-cursor|). + +To extend an existing color scheme with your own highlighting for |Conceal| and +`SecretVisible`, you can for example use the following autocommand: > + + autocmd! VimEnter,ColorScheme * + \ hi Conceal guifg=green | + \ hi SecretVisible guifg=red + +Implementation note: It would be nice to be able to highlight hidden +characters separately from the global |Conceal| group but this is not +currently possible using Vim's conceal feature. + +vim:tw=78:ft=help:norl: diff --git a/example.svg b/example.svg new file mode 100644 index 0000000..6fad42c --- /dev/null +++ b/example.svg @@ -0,0 +1,208 @@ + + + + + + + + + + + + + + ~ -- INSERT -- Sa Sat Satu Satur Saturd Saturda Saturday Saturday, Saturday, Saturday, N Saturday, No Saturday, Nov Saturday, Nove Saturday, Novem Saturday, Novemb Saturday, Novembe Saturday, November Saturday, November Saturday, November 2 Saturday, November 26 Saturday, November 26t Saturday, November 26th Saturday, November 26th Saturday, November 26th 1 Saturday, November 26th 19 Saturday, November 26th 191 Saturday, November 26th 1910 Saturday, November 26th 1910 Saturday, November 26th 1910 : :S :Se :Sec :Secr :Secre :Secret ••••••••• •••••••• •••• 1910 :Secret ••••••••• •••••••• •••• •••• W We •• •• a •• ad •• adv •• adve •• adver •• advert •• adverti •• advertis •• advertise •• advertised •• •••••••••• •• •••••••••• o •• •••••••••• ou •• •••••••••• our •• •••••••••• ••• •• •••••••••• ••• s •• •••••••••• ••• st •• •••••••••• ••• sta •• •••••••••• ••• star •• •••••••••• ••• start •• •••••••••• ••• ••••• •• •••••••••• ••• ••••• a •• •••••••••• ••• ••••• at •• •••••••••• ••• ••••• •• •• •••••••••• ••• ••••• •• 3 •• •••••••••• ••• ••••• •• • •• •••••••••• ••• ••••• •• • P •• •••••••••• ••• ••••• •• • P. •• •••••••••• ••• ••••• •• • P.M •• •••••••••• ••• ••••• •• • P.M. •• •••••••••• ••• ••••• •• • P.M., •• •••••••••• ••• ••••• •• • ••••• •• •••••••••• ••• ••••• •• • ••••• a •• •••••••••• ••• ••••• •• • ••••• an •• •••••••••• ••• ••••• •• • ••••• and •• •••••••••• ••• ••••• •• • ••••• ••• •• •••••••••• ••• ••••• •• • ••••• ••• a •• •••••••••• ••• ••••• •• • ••••• ••• at •• •••••••••• ••• ••••• •• • ••••• ••• •• •• •••••••••• ••• ••••• •• • ••••• ••• •• t •• •••••••••• ••• ••••• •• • ••••• ••• •• th •• •••••••••• ••• ••••• •• • ••••• ••• •• thr •• •••••••••• ••• ••••• •• • ••••• ••• •• thre •• •••••••••• ••• ••••• •• • ••••• ••• •• three •• •••••••••• ••• ••••• •• • ••••• ••• •• ••••• •• •••••••••• ••• ••••• •• • ••••• ••• •• ••••• m •• •••••••••• ••• ••••• •• • ••••• ••• •• ••••• mi •• •••••••••• ••• ••••• •• • ••••• ••• •• ••••• min •• •••••••••• ••• ••••• •• • ••••• ••• •• ••••• minu •• •••••••••• ••• ••••• •• • ••••• ••• •• ••••• minut •• •••••••••• ••• ••••• •• • ••••• ••• •• ••••• minute •• •••••••••• ••• ••••• •• • ••••• ••• •• ••••• minutes •• •••••••••• ••• ••••• •• • ••••• ••• •• ••••• ••••••• •• •••••••••• ••• ••••• •• • ••••• ••• •• ••••• ••••••• t •• •••••••••• ••• ••••• •• • ••••• ••• •• ••••• ••••••• to •• •••••••••• ••• ••••• •• • ••••• ••• •• ••••• ••••••• •• •• •••••••••• ••• ••••• •• • ••••• ••• •• ••••• ••••••• •• t th tha that •••• •••• h •••• ho •••• hou •••• hour •••• •••• •••• •••• t •••• •••• th •••• •••• the •••• •••• ••• •••• •••• ••• T •••• •••• ••• Te •••• •••• ••• Ter •••• •••• ••• Terr •••• •••• ••• Terra •••• •••• ••• ••••• •••• •••• ••• ••••• N •••• •••• ••• ••••• No •••• •••• ••• ••••• Nov •••• •••• ••• ••••• Nova •••• •••• ••• ••••• •••• •••• •••• ••• ••••• •••• p •••• •••• ••• ••••• •••• pu •••• •••• ••• ••••• •••• pus •••• •••• ••• ••••• •••• push •••• •••• ••• ••••• •••• pushe •••• •••• ••• ••••• •••• pushed •••• •••• ••• ••••• •••• •••••• •••• •••• ••• ••••• •••• •••••• o •••• •••• ••• ••••• •••• •••••• of •••• •••• ••• ••••• •••• •••••• off •••• •••• ••• ••••• •••• •••••• ••• •••• •••• ••• ••••• •••• •••••• ••• f •••• •••• ••• ••••• •••• •••••• ••• fr •••• •••• ••• ••••• •••• •••••• ••• fro •••• •••• ••• ••••• •••• •••••• ••• from •••• •••• ••• ••••• •••• •••••• ••• •••• •••• •••• ••• ••••• •••• •••••• ••• •••• t •••• •••• ••• ••••• •••• •••••• ••• •••• th •••• •••• ••• ••••• •••• •••••• ••• •••• the •••• •••• ••• ••••• •••• •••••• ••• •••• ••• •••• •••• ••• ••••• •••• •••••• ••• •••• ••• j •••• •••• ••• ••••• •••• •••••• ••• •••• ••• je •••• •••• ••• ••••• •••• •••••• ••• •••• ••• jet •••• •••• ••• ••••• •••• •••••• ••• •••• ••• jett •••• •••• ••• ••••• •••• •••••• ••• •••• ••• jetty •••• •••• ••• ••••• •••• •••••• ••• •••• ••• jetty. •••• •••• ••• ••••• •••• •••••• ••• •••• ••• jetty. •••• •••• ••• ••••• •••• •••••• ••• •••• ••• jetty. :q :q! :q! + \ No newline at end of file diff --git a/makefile b/makefile new file mode 100644 index 0000000..9f1bec9 --- /dev/null +++ b/makefile @@ -0,0 +1,20 @@ +VIM = vim -N -u NORC -i NONE --cmd 'set rtp=test/vim-vader packpath=' + +all: v nv + +v: test/vim-vader + $(VIM) -c 'Vader! test/*.vader' + +v-i: test/vim-vader + $(VIM) -c 'Vader test/*.vader' + +nv: test/vim-vader + n$(VIM) --headless -c 'Vader! test/*.vader' + +nv-i: test/vim-vader + n$(VIM) -c 'Vader test/*.vader' + +test/vim-vader: + git clone https://github.com/junegunn/vader.vim test/vim-vader || ( cd test/vim-vader && git pull --rebase ) + +.PHONY: all v v-i nv nv-i diff --git a/plugin/secret.vim b/plugin/secret.vim new file mode 100644 index 0000000..bb5b091 --- /dev/null +++ b/plugin/secret.vim @@ -0,0 +1,17 @@ +command! -bang -nargs=* Secret call secret#secret(1, ) + +if !exists('g:secret_cchar') + let g:secret_cchar = '•' +endif + +if !exists('g:secret_visibility') + let g:secret_visibility = 'word' +endif + +if !exists('g:secret_timeout_normal') + let g:secret_timeout_normal = 1 +endif + +if !exists('g:secret_timeout_insert') + let g:secret_timeout_insert = 0 +endif diff --git a/test/.gitignore b/test/.gitignore new file mode 100644 index 0000000..e5eca29 --- /dev/null +++ b/test/.gitignore @@ -0,0 +1 @@ +vim-vader diff --git a/test/test.vader b/test/test.vader new file mode 100644 index 0000000..89b18ff --- /dev/null +++ b/test/test.vader @@ -0,0 +1,251 @@ +Execute (setup test environment): + set hidden + +Execute (helper functions): + function! AssertSyntax(...) + for i in range(1, a:0) + let line = split(get(a:000, i-1), '\zs') + for j in range(1, len(line)) + if get(line, j-1) == '•' + AssertEqual vader#helper#syntax_at(i, j), 'SecretHidden', 'Expected SecretHidden, got ' . vader#helper#syntax_at(i, j) . ' at line ' . i . ', column ' . j + elseif get(line, j-1) == ' ' + AssertEqual vader#helper#syntax_at(i, j), '', 'Expected None, got ' . vader#helper#syntax_at(i, j) . ' at line ' . i . ', column ' . j + elseif get(line, j-1) == '-' + AssertEqual vader#helper#syntax_at(i, j), 'SecretVisible', 'Expected SecretVisible, got ' . vader#helper#syntax_at(i, j) . ' at line ' . i . ', column ' . j + endif + endfor + endfor + endfunction + command! -nargs=* AssertSyntax call AssertSyntax() + +Before: + source plugin/secret.vim + source autoload/secret.vim + +After: + Secret! + unlet! g:secret_cchar + unlet! g:secret_visibility + unlet! g:secret_visibility_normal + unlet! g:secret_visibility_insert + unlet! g:secret_timeout_normal + unlet! g:secret_timeout_insert + +Given: + Lorem ipsum + dolor sit amet + +Execute (enable/disable): + AssertSyntax ' ', ' ' + Secret + AssertSyntax '----- •••••', '••••• ••• ••••' + Assert exists('w:secret_state') + Assert exists('#secret-' . win_getid() . '-' . bufnr()) + Secret! + AssertSyntax ' ', ' ' + Assert !exists('w:secret_state') + Assert !exists('#secret-' . win_getid() . '-' . bufnr()) + +Execute (word visibility): + Secret + AssertSyntax '----- •••••', '••••• ••• ••••' + normal jw + AssertSyntax '••••• •••••', '••••• --- ••••' + +Execute (line visibility): + let g:secret_visibility = 'line' + Secret + AssertSyntax '-----------', '••••• ••• ••••' + normal j + AssertSyntax '••••• •••••', '--------------' + +Execute (char visibility): + let g:secret_visibility = 'char' + Secret + AssertSyntax '-•••• •••••', '••••• ••• ••••' + normal wll + AssertSyntax '••••• ••-••', '••••• ••• ••••' + +Execute (none visibility): + let g:secret_visibility = 'none' + Secret + AssertSyntax '••••• •••••', '••••• ••• ••••' + normal jww + AssertSyntax '••••• •••••', '••••• ••• ••••' + +Execute (line, insert): + let g:secret_visibility_insert = 'line' + Secret + AssertSyntax '----- •••••', '••••• ••• ••••' + doautocmd InsertEnter + AssertSyntax '-----------', '••••• ••• ••••' + doautocmd InsertLeave + AssertSyntax '----- •••••', '••••• ••• ••••' + +Execute (word, insert): + let g:secret_visibility_insert = 'word' + Secret + AssertSyntax '----- •••••', '••••• ••• ••••' + doautocmd InsertEnter + AssertSyntax '----- •••••', '••••• ••• ••••' + doautocmd InsertLeave + AssertSyntax '----- •••••', '••••• ••• ••••' + +Execute (char, insert): + let g:secret_visibility_insert = 'char' + Secret + AssertSyntax '----- •••••', '••••• ••• ••••' + normal l + doautocmd InsertEnter + AssertSyntax '-•••• •••••', '••••• ••• ••••' + doautocmd InsertLeave + AssertSyntax '----- •••••', '••••• ••• ••••' + +Execute (none, insert): + let g:secret_visibility_insert = 'none' + Secret + AssertSyntax '----- •••••', '••••• ••• ••••' + doautocmd InsertEnter + AssertSyntax '••••• •••••', '••••• ••• ••••' + doautocmd InsertLeave + AssertSyntax '----- •••••', '••••• ••• ••••' + +Execute (timeout, normal): + Secret + AssertSyntax '----- •••••', '••••• ••• ••••' + doautocmd CursorHold + AssertSyntax '••••• •••••', '••••• ••• ••••' + Secret! + let g:secret_timeout_normal = 0 + Secret + doautocmd CursorHold + AssertSyntax '----- •••••', '••••• ••• ••••' + +Execute (timeout, insert): + " Not testable? + +Execute (splits 1): + vsp + Secret + AssertSyntax '----- •••••', '••••• ••• ••••' + let w = win_getid() + let b = bufnr() + wincmd l + Assert !exists('w:secret_state') + Assert exists('#secret-' . w . '-' . b) + AssertSyntax ' ', ' ' + wincmd h " Switch back to secret buffer so it is undone + +Execute (splits 2): + Secret + vsp + Assert !exists('w:secret_state') + AssertSyntax ' ', ' ' + wincmd l + doautocmd CursorMoved + AssertSyntax '----- •••••', '••••• ••• ••••' + +Execute (leave window): + Secret + AssertSyntax '----- •••••', '••••• ••• ••••' + doautocmd WinLeave + AssertSyntax '••••• •••••', '••••• ••• ••••' + +Execute (close buffer): + enew + let b = bufnr() + 0put ='Lorem ipsum' + Secret + AssertSyntax '----- •••••' + bdelete! + Assert !exists('w:secret_state') + Assert !exists('#secret-' . win_getid() . '-' . b) + +Execute (switching buffers in one window): + let a = bufnr() + Secret + AssertSyntax '----- •••••', '••••• ••• ••••' + + enew + let b = bufnr() + Secret + 0put ='Lorem ipsum' + AssertSyntax '----- •••••' + + enew + let c = bufnr() + 0put ='Lorem ibsum' + Secret + normal w + AssertSyntax '••••• -----' + + Assert exists('#secret-' . win_getid() . '-' . a) + Assert exists('#secret-' . win_getid() . '-' . b) + Assert exists('#secret-' . win_getid() . '-' . c) + Assert has_key(w:secret_state, a) + Assert has_key(w:secret_state, b) + Assert has_key(w:secret_state, c) + + execute 'b' a + AssertSyntax '----- •••••', '••••• ••• ••••' + execute 'b' b + AssertSyntax '----- •••••' + execute 'b' c + AssertSyntax '----- •••••' + + execute 'b' a + execute 'bdelete!' c + + Assert exists('#secret-' . win_getid() . '-' . a) + Assert exists('#secret-' . win_getid() . '-' . b) + Assert !exists('#secret-' . win_getid() . '-' . c) + Assert has_key(w:secret_state, a) + Assert has_key(w:secret_state, b) + Assert !has_key(w:secret_state, c) + + execute 'bdelete!' b + + Assert exists('#secret-' . win_getid() . '-' . a) + Assert !exists('#secret-' . win_getid() . '-' . b) + Assert !exists('#secret-' . win_getid() . '-' . c) + Assert has_key(w:secret_state, a) + Assert !has_key(w:secret_state, b) + Assert !has_key(w:secret_state, c) + + b # + execute 'bdelete!' a + Assert !exists('#secret-' . win_getid() . '-' . a) + Assert !exists('#secret-' . win_getid() . '-' . b) + Assert !exists('#secret-' . win_getid() . '-' . c) + Assert !exists('w:secret_state') + +Execute (quickhide mapping): + let g:secret_quickhide = '' + Secret + AssertSyntax '----- •••••', '••••• ••• ••••' + normal  + AssertSyntax '••••• •••••', '••••• ••• ••••' + normal w + doautocmd CursorMoved + AssertSyntax '••••• -----', '••••• ••• ••••' + +Execute (quickhide mapping, moving around): + let g:secret_quickhide = 'q' + vsp + Secret + normal q + AssertSyntax '••••• •••••', '••••• ••• ••••' + enew + 0put ='Lorem ipsum' + AssertEqual maparg('q'), '' + b # + AssertEqual maparg('q'), ':syntax clear SecretVisible' + wincmd l + AssertEqual maparg('q'), '' + wincmd h + doautocmd CursorMoved + AssertSyntax '----- •••••', '••••• ••• ••••' + normal q + AssertSyntax '••••• •••••', '••••• ••• ••••' + Secret! + AssertEqual maparg('q'), ''