Fixes for #19 and #22

#19 Reorganized commands, making them prefix-oriented. (e.g., old: HardPencil, new: PencilHard). Legacy commands still enabled by default.

#22 Better support of inline syntax for PencilHard mode
This commit is contained in:
Reed Esau
2014-11-05 05:05:23 -07:00
parent 4cffe7021c
commit e661e83bea
3 changed files with 134 additions and 57 deletions

View File

@@ -8,32 +8,34 @@
![demo](http://i.imgur.com/0KYl5vU.gif) ![demo](http://i.imgur.com/0KYl5vU.gif)
- - - - - -
[Note: demo will be updated soon with the _newly_ renamed commands (see
below), but the legacy ones still work.]
# Features # Features
The _pencil_ plugin aspires to make Vim as powerful a tool for writers as The _pencil_ plugin aspires to make Vim as powerful a tool for writers as
it is for coders by focusing narrowly on the handful of tweaks needed to it is for coders by focusing narrowly on the handful of tweaks needed to
smooth the path to writing prose. smooth the path to writing prose.
* For editing prose-oriented file types such as _text_, _markdown_, * For editing prose-oriented file types such as _text_, _markdown_, _mail_,
_mail_, _rst_, _tex_, and _textile_. _rst_, _tex_, and _textile_.
* Agnostic on soft line wrap _versus_ hard line breaks, supporting both * Agnostic on soft line wrap _versus_ hard line breaks, supporting both
* Auto-detects wrap mode via modeline and sampling * Auto-detects wrap mode via modeline and sampling
* Adjusts navigation key mappings to suit the wrap mode * Adjusts navigation key mappings to suit the wrap mode
* Creates undo points on common punctuation during insert, including * Creates undo points on common punctuation during Insert mode, including
deletion via line `<C-U>` and word `<C-W>` deletion via line `<C-U>` and word `<C-W>`
* When using hard line breaks, enables autoformat while inserting text... * When using hard line breaks, enables autoformat while inserting text, except
* ...except for tables and code blocks where you wont want it for tables and code blocks where you wont want it
* Buffer-scoped configuration (with a few minor exceptions, _pencil_ * Buffer-scoped configuration (with a few minor exceptions, _pencil_ preserves
preserves your global settings) your global settings)
* Support for Vims Conceal feature to hide markup defined by Syntax * Support for Vims Conceal feature to hide markup defined by Syntax plugins
plugins (e.g., `_` and `*` markup for styled text in \_*Markdown*\_) (e.g., `_` and `*` markup for styled text in \_*Markdown*\_)
* Support for display of mode indicator (`␍` and `⤸`, e.g.) in the status * Support for display of mode indicator (`␍` and `⤸`, e.g.) in the status line
line
* Pure Vimscript with no dependencies * Pure Vimscript with no dependencies
Need spell-check and other features? Vim is about customization. To Need spell-check, distraction-free editing, and other features? Vim is about
complete your editing environment, learn to configure Vim and draw upon customization. To complete your editing environment, learn to configure Vim and
its rich ecosystem of plugins. draw upon its rich ecosystem of plugins.
# Why use Vim for writing? # Why use Vim for writing?
@@ -143,21 +145,26 @@ if auto-detect might suggest soft line wrap.
## Commands ## Commands
You can enable, disable, and toggle _pencil_ as a command:
* `Pencil` - enable pencil with auto-detection
* `PencilOff` - removes navigation mappings and restores buffer to global settings
* `PencilToggle` - if on, turns off; if off, enables with detection
Because auto-detect might not work as intended, you can invoke a command Because auto-detect might not work as intended, you can invoke a command
to set the behavior for the current buffer: to set the behavior for the current buffer:
* `SoftPencil` - enable soft line wrap mode * `PencilSoft` - enable soft line wrap mode
* `HardPencil` - enable hard line break mode * `PencilHard` - enable hard line break mode
* `NoPencil` - removes navigation mappings and restores buffer to global settings
* `TogglePencil` - if on, turns off; if off, enables with detection
## Automatic formatting ## Automatic formatting
_The autoformat feature affects *HardPencil* (hard line break) mode _The autoformat feature affects *PencilHard* (hard line break) mode
only._ only._
When inserting text while in *HardPencil* mode, Vims autoformat feature will be When inserting text while in *PencilHard* mode, Vims autoformat feature
enabled by default and can offer many of the same benefits as soft line wrap. will be enabled by default and can offer many of the same benefits as
soft line wrap.
A useful exception: if used with popular syntax modules\*, _pencil_ will A useful exception: if used with popular syntax modules\*, _pencil_ will
**disable** autoformat when you enter Insert mode from inside a code block **disable** autoformat when you enter Insert mode from inside a code block
@@ -165,15 +172,15 @@ or table. (See the advanced section below for more details.)
Where you need to manually enable/disable autoformat, you can do so with a command: Where you need to manually enable/disable autoformat, you can do so with a command:
* `AutoPencil` - enables autoformat * `PFormat` - enables autoformat
* `ManualPencil` - disables autoformat * `PFormatOff` - disables autoformat
* `ShiftPencil` - toggle to enable if disabled, etc. * `PFormatToggle` - toggle to enable if disabled, etc.
Or optionally map the toggle command to a key of your choice in your Or optionally map the toggle command to a key of your choice in your
`.vimrc`: `.vimrc`:
```vim ```vim
nnoremap <silent> <leader>p :ShiftPencil<cr> nnoremap <silent> <leader>p :PFormatToggle<cr>
``` ```
To set the default behavior, add to your `.vimrc`: To set the default behavior, add to your `.vimrc`:
@@ -214,9 +221,9 @@ nnoremap <silent> Q gwip
## Default textwidth ## Default textwidth
You can configure the textwidth to be used in **HardPencil** mode when no You can configure the textwidth to be used in **PencilHard** mode when no
textwidth is set globally, locally, or available via modeline. It defaults textwidth is set globally, locally, or available via modeline. It
to `74`, but you can change that value in your `.vimrc`: defaults to `74`, but you can change that value in your `.vimrc`:
```vim ```vim
let g:pencil#textwidth = 74 let g:pencil#textwidth = 74
@@ -291,7 +298,7 @@ terminal to support **bold** and _italic_ styles.
## Status line indicator ## Status line indicator
Your status line can reflect the wrap mode for _pencil_ buffers. For Your status line can reflect the wrap mode for _pencil_ buffers. For
example, `␍` to represent `HardPencil` (hard line break) mode. To example, `␍` to represent `PencilHard` (hard line break) mode. To
configure your status line and ruler, add to your `.vimrc`: configure your status line and ruler, add to your `.vimrc`:
```vim ```vim
@@ -351,13 +358,13 @@ statements into a function.
### Autoformat blacklisting ### Autoformat blacklisting
_The autoformat feature affects *HardPencil* (hard line break) mode _The autoformat feature affects *PencilHard* (hard line break) mode
only._ only._
When editing formatted text, such as a table or code block, autoformat When editing formatted text, such as a table or code block, autoformat
will wreak havoc with the formatting. In these cases you will want to will wreak havoc with the formatting. In these cases you will want to
temporarily deactivate autoformat, such as with the `ManualPencil` or temporarily deactivate autoformat, such as with the `PFormatOff` or
`ShiftPencil` commands described above. However, in most cases, you wont `PFormatToggle` commands described above. However, in most cases, you wont
need to do this. need to do this.
_pencil_ will detect the syntax highlight group at the cursor position to _pencil_ will detect the syntax highlight group at the cursor position to
@@ -370,9 +377,11 @@ _not_ in the blacklist. The current blacklist is:
```vim ```vim
let g:pencil#autoformat_blacklist = [ let g:pencil#autoformat_blacklist = [
\ 'markdownCode', \ 'markdownCode',
\ 'markdownH[0-9]',
\ 'markdownUrl', \ 'markdownUrl',
\ 'markdownIdDeclaration', \ 'markdownIdDeclaration',
\ 'markdownLinkDelimiter', \ 'markdownLink',
\ 'markdownRule',
\ 'markdownHighlight[A-Za-z0-9]+', \ 'markdownHighlight[A-Za-z0-9]+',
\ 'mkdCode', \ 'mkdCode',
\ 'mkdIndentCode', \ 'mkdIndentCode',
@@ -473,10 +482,12 @@ Other plugins of specific interest to writers:
* [tpope/vim-abolish][ab] - search for, substitute, and abbr. multiple variants of a word * [tpope/vim-abolish][ab] - search for, substitute, and abbr. multiple variants of a word
* [tommcdo/vim-exchange][ex] - easy text exchange operator for Vim * [tommcdo/vim-exchange][ex] - easy text exchange operator for Vim
* [junegunn/limelight.vim][jl] - focus mode that brightens current paragraph * [junegunn/limelight.vim][jl] - focus mode that brightens current paragraph
* [junegunn/goyo.vim][jg] - distraction-free editing mode
[ab]: http://github.com/tpope/vim-abolish [ab]: http://github.com/tpope/vim-abolish
[ex]: http://github.com/tommcdo/vim-exchange [ex]: http://github.com/tommcdo/vim-exchange
[jl]: http://github.com/junegunn/limelight.vim [jl]: http://github.com/junegunn/limelight.vim
[jg]: http://github.com/junegunn/goyo.vim
[tvm]: http://github.com/tpope/vim-markdown [tvm]: http://github.com/tpope/vim-markdown
[pvm]: http://github.com/plasticboy/vim-markdown [pvm]: http://github.com/plasticboy/vim-markdown
[mvme]: http://github.com/mattly/vim-markdown-enhancements [mvme]: http://github.com/mattly/vim-markdown-enhancements
@@ -493,7 +504,8 @@ If you find the _pencil_ plugin useful, check out these others by [@reedes][re]:
* [vim-wheel][wh] - screen-anchored cursor movement for Vim * [vim-wheel][wh] - screen-anchored cursor movement for Vim
* [vim-wordy][wo] - uncovering usage problems in writing * [vim-wordy][wo] - uncovering usage problems in writing
Unimpressed by _pencil_? [vim-pandoc][vp] offers prose-oriented features with its own Markdown variant Unimpressed by _pencil_? [vim-pandoc][vp] offers prose-oriented features
with its own Markdown variant.
[cp]: http://github.com/reedes/vim-colors-pencil [cp]: http://github.com/reedes/vim-colors-pencil
[lc]: http://github.com/reedes/vim-litecorrect [lc]: http://github.com/reedes/vim-litecorrect

View File

@@ -5,7 +5,6 @@
" Created: December 28, 2013 " Created: December 28, 2013
" License: The MIT License (MIT) " License: The MIT License (MIT)
" ============================================================================ " ============================================================================
if exists("autoloaded_pencil") | fini | en if exists("autoloaded_pencil") | fini | en
let autoloaded_pencil = 1 let autoloaded_pencil = 1
@@ -58,28 +57,37 @@ fun! s:maybe_enable_autoformat()
let l:okay_to_enable = 1 let l:okay_to_enable = 1
let l:line = line('.') let l:line = line('.')
let l:col = col('.') let l:col = col('.')
let l:last_col = col('$')
let l:stack = [] let l:stack = []
let l:found_empty = 0
" at end of line there may be no synstack, so scan back " at end of line there may be no synstack, so scan back
while l:col > 0 while l:col > 0
let l:stack = synstack(l:line, l:col) let l:stack = synstack(l:line, l:col)
if l:stack != [] if l:stack != []
break break
en en
" the last column will always be empty, so ignore it
if l:col < l:last_col
let l:found_empty = 1
en
let l:col -= 1 let l:col -= 1
endw endw
" if needed, scan towards end of line looking for highlight groups " if needed, scan towards end of line looking for highlight groups
if l:stack == [] if l:stack == []
let l:col = col('.') + 1 let l:col = col('.') + 1
let l:last_col = col('$')
while l:col <= l:last_col while l:col <= l:last_col
let l:stack = synstack(l:line, l:col) let l:stack = synstack(l:line, l:col)
if l:stack != [] if l:stack != []
break break
en en
" the last column will always be empty, so ignore it
if l:col < l:last_col
let l:found_empty = 1
en
let l:col += 1 let l:col += 1
endw endw
en en
" scan for matches to blacklist " enforce blacklist by scanning for syntax matches
for l:sid in l:stack for l:sid in l:stack
if match(synIDattr(l:sid, 'name'), if match(synIDattr(l:sid, 'name'),
\ g:pencil#autoformat_blacklist_re) >= 0 \ g:pencil#autoformat_blacklist_re) >= 0
@@ -87,24 +95,53 @@ fun! s:maybe_enable_autoformat()
break break
en en
endfo 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
" one final check for an empty stack at the start of the line
if !l:found_empty
if synstack(l:line, 1) == []
let l:found_empty = 1
en
en
if l:found_empty
for l:sid in l:stack
if match(synIDattr(l:sid, 'name'),
\ g:pencil#autoformat_inline_whitelist_re) >= 0
let l:okay_to_enable = 1
en
endfo
en
en
if l:okay_to_enable if l:okay_to_enable
set formatoptions+=a set formatoptions+=a
en en
endf endf
fun! pencil#setAutoFormat(mode) fun! pencil#setAutoFormat(af)
" 1=auto, 0=manual, -1=toggle " 1=auto, 0=manual, -1=toggle
if !exists('b:last_autoformat') if !exists('b:last_autoformat')
let b:last_autoformat = 0 let b:last_autoformat = 0
en en
let b:last_autoformat = a:mode ==# -1 ? !b:last_autoformat : a:mode let l:nu_af = a:af ==# -1 ? !b:last_autoformat : a:af
if b:last_autoformat let l:is_hard =
\ exists('b:pencil_wrap_mode') &&
\ b:pencil_wrap_mode ==# s:WRAP_MODE_HARD
if l:nu_af && l:is_hard
aug pencil_autoformat aug pencil_autoformat
au InsertEnter <buffer> call s:maybe_enable_autoformat() au InsertEnter <buffer> call s:maybe_enable_autoformat()
au InsertLeave <buffer> set formatoptions-=a au InsertLeave <buffer> set formatoptions-=a
aug END aug END
let b:last_autoformat = l:nu_af
el el
sil! au! pencil_autoformat * <buffer> sil! au! pencil_autoformat * <buffer>
if l:nu_af && !l:is_hard
echohl WarningMsg
echo "autoformat can only be enabled in hard break line mode"
echohl NONE
return
en
en en
endf endf

View File

@@ -29,11 +29,11 @@ endf
fun! PencilMode() fun! PencilMode()
if exists('b:pencil_wrap_mode') if exists('b:pencil_wrap_mode')
if b:pencil_wrap_mode ==# s:WRAP_MODE_SOFT if b:pencil_wrap_mode ==# s:WRAP_MODE_SOFT
return get(g:pencil#mode_indicators, 'soft', 'soft') return get(g:pencil#mode_indicators, 'soft', 'S')
elsei b:pencil_wrap_mode ==# s:WRAP_MODE_HARD elsei b:pencil_wrap_mode ==# s:WRAP_MODE_HARD
return get(g:pencil#mode_indicators, 'hard', 'hard') return get(g:pencil#mode_indicators, 'hard', 'H')
el el
return get(g:pencil#mode_indicators, 'off', 'off') return get(g:pencil#mode_indicators, 'off', '')
en en
else else
return '' " should be blank for non-prose modes return '' " should be blank for non-prose modes
@@ -61,8 +61,7 @@ if !exists('g:pencil#autoformat_blacklist')
" by default, pencil does NOT start autoformat if inside any of " by default, pencil does NOT start autoformat if inside any of
" the following syntax groups " the following syntax groups
" "
"'markdownCode', 'markdownUrl', 'markdownIdDeclaration', "'markdown*' (tpope/vim-markdown)
"'markdownLinkDelimiter', 'markdownHighlight[A-Za-z0-9]+' (tpope/vim-markdown)
"'mkdCode', 'mkdIndentCode' (plasticboy/vim-markdown) "'mkdCode', 'mkdIndentCode' (plasticboy/vim-markdown)
"'markdownFencedCodeBlock', 'markdownInlineCode' (gabrielelana/vim-markdown) "'markdownFencedCodeBlock', 'markdownInlineCode' (gabrielelana/vim-markdown)
"'mmdTable[A-Za-z0-9]*' (mattly/vim-markdown-enhancements) "'mmdTable[A-Za-z0-9]*' (mattly/vim-markdown-enhancements)
@@ -71,9 +70,11 @@ if !exists('g:pencil#autoformat_blacklist')
"'tex*' (syntax file shipped with vim) "'tex*' (syntax file shipped with vim)
let g:pencil#autoformat_blacklist = [ let g:pencil#autoformat_blacklist = [
\ 'markdownCode', \ 'markdownCode',
\ 'markdownH[0-9]',
\ 'markdownUrl', \ 'markdownUrl',
\ 'markdownIdDeclaration', \ 'markdownIdDeclaration',
\ 'markdownLinkDelimiter', \ 'markdownLink',
\ 'markdownRule',
\ 'markdownHighlight[A-Za-z0-9]+', \ 'markdownHighlight[A-Za-z0-9]+',
\ 'mkdCode', \ 'mkdCode',
\ 'mkdIndentCode', \ 'mkdIndentCode',
@@ -98,6 +99,19 @@ en
let g:pencil#autoformat_blacklist_re = let g:pencil#autoformat_blacklist_re =
\ '\v(' . join(g:pencil#autoformat_blacklist, '|') . ')' \ '\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 = [
\ 'markdownCode',
\ 'markdownLink',
\ ]
en
let g:pencil#autoformat_inline_whitelist_re =
\ '\v(' . join(g:pencil#autoformat_inline_whitelist, '|') . ')'
if !exists('g:pencil#joinspaces') if !exists('g:pencil#joinspaces')
" by default, only one space after full stop (.) " by default, only one space after full stop (.)
let g:pencil#joinspaces = 0 let g:pencil#joinspaces = 0
@@ -137,22 +151,36 @@ if !exists('g:pencil#mode_indicators')
" used to set PencilMode() for statusline " used to set PencilMode() for statusline
if s:unicode_enabled() if s:unicode_enabled()
let g:pencil#mode_indicators = {'hard': '␍', 'soft': '⤸', 'off': '',} let g:pencil#mode_indicators = {'hard': '␍', 'soft': '⤸', 'off': '',}
"let g:pencil#mode_indicators = {'hard': '✐ hard', 'soft': '✎ soft', 'off': '✎ off',}
el el
let g:pencil#mode_indicators = {'hard': 'hard', 'soft': 'soft', 'off': '',} let g:pencil#mode_indicators = {'hard': 'H', 'soft': 'S', 'off': '',}
en en
en en
" # coms " Commands
com -nargs=0 Pencil call pencil#init({'wrap': 'on' })
com -nargs=0 PencilOff call pencil#init({'wrap': 'off' })
com -nargs=0 PencilHard call pencil#init({'wrap': 'hard'})
com -nargs=0 PencilSoft call pencil#init({'wrap': 'soft'})
com -nargs=0 PencilToggle call pencil#init({'wrap': 'toggle'})
com -nargs=0 PFormat call pencil#setAutoFormat(1)
com -nargs=0 PFormatOff call pencil#setAutoFormat(0)
com -nargs=0 PFormatToggle call pencil#setAutoFormat(-1)
" NOTE: legacy commands will be disabled by default at some point
if !exists('g:pencil#legacyCommands')
let g:pencil#legacyCommands = 1
en
if g:pencil#legacyCommands
com -nargs=0 HardPencil call pencil#init({'wrap': 'hard'}) com -nargs=0 HardPencil call pencil#init({'wrap': 'hard'})
com -nargs=0 SoftPencil call pencil#init({'wrap': 'soft'}) com -nargs=0 SoftPencil call pencil#init({'wrap': 'soft'})
com -nargs=0 DropPencil call pencil#init({'wrap': 'off' }) com -nargs=0 DropPencil call pencil#init({'wrap': 'off' })
com -nargs=0 NoPencil call pencil#init({'wrap': 'off' }) com -nargs=0 NoPencil call pencil#init({'wrap': 'off' })
com -nargs=0 TogglePencil call pencil#init({'wrap': 'toggle'}) com -nargs=0 TogglePencil call pencil#init({'wrap': 'toggle'})
com -nargs=0 AutoPencil call pencil#setAutoFormat(1) com -nargs=0 AutoPencil call pencil#setAutoFormat(1)
com -nargs=0 ManualPencil call pencil#setAutoFormat(0) com -nargs=0 ManualPencil call pencil#setAutoFormat(0)
com -nargs=0 ShiftPencil call pencil#setAutoFormat(-1) com -nargs=0 ShiftPencil call pencil#setAutoFormat(-1)
en
let &cpo = s:save_cpo let &cpo = s:save_cpo
unlet s:save_cpo unlet s:save_cpo