From f89a3ac9984285c9db69b388a9bebbfb6db693a6 Mon Sep 17 00:00:00 2001 From: Reed Esau Date: Mon, 7 Sep 2015 00:26:37 -0600 Subject: [PATCH] Blacklist (and whitelist) config by file type --- README.markdown | 60 +++++++++++++++++++---------------- autoload/pencil.vim | 53 +++++++++++++++++-------------- plugin/pencil.vim | 77 ++++++++++++++++++++++++++++----------------- 3 files changed, 111 insertions(+), 79 deletions(-) diff --git a/README.markdown b/README.markdown index ae900a0..bbe723c 100644 --- a/README.markdown +++ b/README.markdown @@ -23,7 +23,7 @@ smooth the path to writing prose. deletion via line `` and word `` * When using hard line breaks, _pencil_ enables Vim’s autoformat while inserting text, except for tables and code blocks where you won’t want - it + it (**NEW: blacklisting now based on filetype**) * Buffer-scoped configuration (with a few minor exceptions, _pencil_ preserves your global settings) * Support for Vim’s Conceal feature to hide markup defined by Syntax plugins @@ -101,8 +101,6 @@ Plugin 'reedes/vim-pencil' :PluginInstall ``` -For Vundle version < 0.10.2, replace `Plugin` with `Bundle` above. - #### Plug Add to your `.vimrc` and save: @@ -429,7 +427,7 @@ augroup END Alternatives include `after/ftplugin` modules as well as refactoring initialization statements into a function. -### Autoformat blacklisting +### Autoformat blacklisting (and whitelisting) _The ‘autoformat’ feature affects *HardPencil* (hard line break) mode only._ @@ -443,31 +441,39 @@ won’t need to do this. _pencil_ will detect the syntax highlight group at the cursor position to determine whether or not autoformat should be activated. -If autoformat is on, it will be activated at the time you enter Insert -mode provided that the syntax highlighting group at the cursor position is -_not_ in the blacklist. The current blacklist is: +If you haven’t explicitly disabled autoformat, it will be activated at +the time you enter Insert mode provided that the syntax highlighting +group at the cursor position is _not_ in the blacklist. + +Blacklists are now declared by file type. The default blacklists (and +whitelists) are declared in the `plugin/pencil.vim` module. Here’s an +excerpt showing the configuration for the ‘markdown’ file type: ```vim - let g:pencil#autoformat_blacklist = [ - \ 'markdown(Code|H[0-9]|Url|IdDeclaration|Link|Rule|Highlight[A-Za-z0-9]+)', - \ 'mkd(Code|Rule|Delimiter|Link|ListItem|IndentCode)', - \ 'htmlH[0-9]', - \ 'markdown(FencedCodeBlock|InlineCode)', - \ 'mmdTable[A-Za-z0-9]*', - \ 'txtCode', - \ 'rst(CodeBlock|Directive|LiteralBlock|Sections)', - \ 'tex(BeginEndName|Delimiter|DocType|InputFile|Math|RefZone|Title)', - \ 'texSection$', - \ 'asciidoc(AttributeList|ListLabel|Literal|SideBar|Source|Sect[0-9])', - \ 'asciidoc[A-Za-z]*(Block|Macro|Title)', - \ ] -``` - -_WARNING: the implementation of this blacklist will be changing in the -future._ - -You can override this in your `.vimrc`. Additions to defaults with good -use cases are welcome. + let g:pencil#autoformat_config = { + \ 'markdown': { + \ 'black': [ + \ 'markdown(Code|H[0-9]|Url|IdDeclaration|Link|Rule|Highlight[A-Za-z0-9]+)', + \ 'htmlH[0-9]', + \ 'markdown(FencedCodeBlock|InlineCode)', + \ 'mmdTable[A-Za-z0-9]*', + \ ], + \ 'white': [ + \ 'markdown(Code|Link)', + \ ], + \ }, + [snip] + \ } +``` + +For example, if editing a file of type ‘markdown’ and you enter Insert +mode from inside a `markdownFencedCodeBlock` highlight group, then Vim’s +autoformat will _not_ be enabled. + +The whitelist can override the blacklist and allow Vim’s autoformat to be +enabled if text that would normally be blacklisted doesn’t dominate the +entire line. This allows autoformat to work with `inline` snippets of +code or links. ### Auto-detecting wrap mode diff --git a/autoload/pencil.vim b/autoload/pencil.vim index 68fc8ed..b50b3ed 100644 --- a/autoload/pencil.vim +++ b/autoload/pencil.vim @@ -53,7 +53,18 @@ fun! s:imap(preserve_completion, key, icmd) abort endf fun! s:maybe_enable_autoformat() abort - " don't enable autoformat if in a code block or table + " don't enable autoformat if in a blacklisted code block or table, + " allowing for reprieve via whitelist in certain cases + + let l:af_cfg = get(g:pencil#autoformat_config, &ft, {}) + let l:black = get(l:af_cfg, 'black', []) + let l:white = get(l:af_cfg, 'white', []) + let l:has_black_re = len(l:black) > 0 + let l:has_white_re = len(l:white) > 0 + let l:black_re = l:has_black_re ? '\v(' . join( l:black, '|') . ')' : '' + let l:white_re = l:has_white_re ? '\v(' . join( l:white, '|') . ')' : '' + let l:enforce_previous_line = get(l:af_cfg, 'enforce-previous-line', 0) + let l:okay_to_enable = 1 let l:line = line('.') let l:col = col('.') @@ -88,21 +99,21 @@ fun! s:maybe_enable_autoformat() abort endw en " enforce blacklist by scanning for syntax matches - for l:sid in l:stack - if match(synIDattr(l:sid, 'name'), - \ g:pencil#autoformat_blacklist_re) >= 0 - let l:okay_to_enable = 0 - "echohl WarningMsg - "echo 'hit blacklist line=' . l:line . ' col=' . l:col . - " \ ' name=' . synIDattr(l:sid, 'name') - "echohl NONE - break - en - endfo - " enforce whitelist by detecting inline `markup` for - " which we DO want autoformat to be enabled (e.g., - " tpope's markdownCode) - if !l:okay_to_enable + if l:has_black_re + for l:sid in l:stack + if match(synIDattr(l:sid, 'name'), l:black_re) >= 0 + let l:okay_to_enable = 0 + "echohl WarningMsg + "echo 'hit blacklist line=' . l:line . ' col=' . l:col . + " \ ' name=' . synIDattr(l:sid, 'name') + "echohl NONE + break + en + endfo + en + " enforce whitelist by detecting inline `markup` for which we DO want + " autoformat to be enabled (e.g., tpope's markdownCode) + if l:has_white_re && !l:okay_to_enable " one final check for an empty stack at the start and end of line, " either of which greenlights a whitelist check if !l:found_empty @@ -113,8 +124,7 @@ fun! s:maybe_enable_autoformat() abort en if l:found_empty for l:sid in l:stack - if match(synIDattr(l:sid, 'name'), - \ g:pencil#autoformat_inline_whitelist_re) >= 0 + if match(synIDattr(l:sid, 'name'), l:white_re) >= 0 let l:okay_to_enable = 1 break en @@ -122,14 +132,11 @@ fun! s:maybe_enable_autoformat() abort en en " disallow enable if start of previous line is in blacklist, - " (To avoid problem of autowrap screwing up adding a new item - " to a list.) - if l:okay_to_enable && l:line > 1 + if l:has_black_re && l:enforce_previous_line && l:okay_to_enable && l:line > 1 let l:prev_stack = synstack(l:line - 1, 1) for l:sid in l:prev_stack if len(l:sid) > 0 && - \ match(synIDattr(l:sid, 'name'), - \ g:pencil#autoformat_blacklist_re) >= 0 + \ match(synIDattr(l:sid, 'name'), l:black_re) >= 0 let l:okay_to_enable = 0 break en diff --git a/plugin/pencil.vim b/plugin/pencil.vim index 235a78c..fa866e0 100644 --- a/plugin/pencil.vim +++ b/plugin/pencil.vim @@ -61,7 +61,7 @@ if !exists('g:pencil#autoformat') let g:pencil#autoformat = 1 en -if !exists('g:pencil#autoformat_blacklist') +if !exists('g:pencil#autoformat_config') " do not engage autoformat if cursor is inside any of " the following syntax groups " @@ -71,35 +71,54 @@ if !exists('g:pencil#autoformat_blacklist') " mmdTable[A-Za-z0-9]* (mattly/vim-markdown-enhancements) " txtCode (timcharper/textile.vim) " rst*,tex*,asciidoc* (syntax file shipped with vim) - let g:pencil#autoformat_blacklist = [ - \ 'markdown(Code|H[0-9]|Url|IdDeclaration|Link|Rule|Highlight[A-Za-z0-9]+)', - \ 'mkd(Code|Rule|Delimiter|Link|ListItem|IndentCode)', - \ 'htmlH[0-9]', - \ 'markdown(FencedCodeBlock|InlineCode)', - \ 'mmdTable[A-Za-z0-9]*', - \ 'txtCode', - \ 'rst(CodeBlock|Directive|LiteralBlock|Sections)', - \ 'tex(BeginEndName|Delimiter|DocType|InputFile|Math|RefZone|Title)', - \ 'texSection$', - \ 'asciidoc(AttributeList|ListLabel|Literal|SideBar|Source|Sect[0-9])', - \ 'asciidoc[A-Za-z]*(Block|Macro|Title)', - \ ] + let g:pencil#autoformat_config = { + \ 'markdown': { + \ 'black': [ + \ 'markdown(Code|H[0-9]|Url|IdDeclaration|Link|Rule|Highlight[A-Za-z0-9]+)', + \ 'htmlH[0-9]', + \ 'markdown(FencedCodeBlock|InlineCode)', + \ 'mmdTable[A-Za-z0-9]*', + \ ], + \ 'white': [ + \ 'markdown(Code|Link)', + \ ], + \ }, + \ 'mkd': { + \ 'black': [ + \ 'mkd(Code|Rule|Delimiter|Link|ListItem|IndentCode)', + \ 'htmlH[0-9]', + \ 'mmdTable[A-Za-z0-9]*', + \ ], + \ }, + \ 'tex': { + \ 'black': [ + \ 'tex(BeginEndName|Delimiter|DocType|InputFile|Math|RefZone|Title)', + \ 'texSection$', + \ ], + \ 'enforce-previous-line': 1, + \ }, + \ 'asciidoc': { + \ 'black': [ + \ 'asciidoc(AttributeList|AttributeEntry|ListLabel|Literal|SideBar|Source|Sect[0-9])', + \ 'asciidoc[A-Za-z]*(Block|Macro|Title)', + \ ], + \ 'white': [ + \ 'asciidoc(AttributeRef|Macro)', + \ ], + \ 'enforce-previous-line': 1, + \ }, + \ 'rst': { + \ 'black': [ + \ 'rst(CodeBlock|Directive|LiteralBlock|Sections)', + \ ], + \ }, + \ 'textile': { + \ 'black': [ + \ 'txtCode', + \ ], + \ }, + \ } en -let g:pencil#autoformat_blacklist_re = - \ '\v(' . join(g:pencil#autoformat_blacklist, '|') . ')' - -if !exists('g:pencil#autoformat_inline_whitelist') - " grant autoformat a reprieve (allow enabling) if any of - " following syntax groups doesn't dominate the whole line - " - "'markdownCode' (tpope/vim-markdown) - let g:pencil#autoformat_inline_whitelist = [ - \ 'markdown(Code|Link)', - \ 'asciidoc(AttributeRef|Macro)', - \ ] -en -let g:pencil#autoformat_inline_whitelist_re = - \ '\v(' . join(g:pencil#autoformat_inline_whitelist, '|') . ')' if !exists('g:pencil#joinspaces') " by default, only one space after full stop (.)