From b2bb146858bd826a0a6c381b33ac66df0326e241 Mon Sep 17 00:00:00 2001 From: Joshua Potter Date: Tue, 25 Jul 2017 11:06:15 -0700 Subject: [PATCH] Join plugin setup. --- README.md | 34 ++++++++++++ doc/join.txt | 30 +++++++++++ plugin/join.vim | 135 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 199 insertions(+) create mode 100644 README.md create mode 100644 doc/join.txt create mode 100644 plugin/join.vim diff --git a/README.md b/README.md new file mode 100644 index 0000000..f7061f8 --- /dev/null +++ b/README.md @@ -0,0 +1,34 @@ +Smart Join +========== + +[VERSION: 0.1] + +Overview +-------- + +Allows for line joining that respects textwidth and optionally clears +whitespace. + +Refer to ```doc/``` for complete instructions on use. + +Installation +------------ + +I prefer using [vim-plug](https://github.com/junegunn/vim-plug) for plugin +management as follows: + +```vim +Plug 'jrpotter/vim-join' +``` + +Follow use according to plugin manager you use or optionally copy +plugin/join.vim from this repo into ```$VIM_DIR/plugin```. + +Usage +----- + +Create a mapping to SmartJoin to use the new joining functionality. +For instance, + +noremap J SmartJoin + diff --git a/doc/join.txt b/doc/join.txt new file mode 100644 index 0000000..c74799a --- /dev/null +++ b/doc/join.txt @@ -0,0 +1,30 @@ +*smart-join* functionality of smart joining + +============================================================================== +CONTENTS *smart-join-contents* + +1. Usage .................................................. |smart-join-usage| +2. Variables .......................................... |smart-join-variables| + +============================================================================== +Section 1: Usage *highlight-usage* + +SmartJoin Performs a smart join on [count] line and the one below + it. If [count] is too big it is reduced to the number of + lines available. Fails when on the last line of the + buffer. + +============================================================================== +Section 2: Variables *smart-join-variables* + +g:smart_join_strip_whitespace_before + + If true, indicates that before joining we strip any trailing whitespace on + the current line. + +g:smart_join_strip_whitespace_after + + If true, indicates that after joining we strip any trailing whitespace on + the current line. + +vim:tw=78:ts=8:ft=help:norl: diff --git a/plugin/join.vim b/plugin/join.vim new file mode 100644 index 0000000..0e12649 --- /dev/null +++ b/plugin/join.vim @@ -0,0 +1,135 @@ +" ============================================================================== +" File: join.vim +" Maintainer: Joshua Potter +" +" ============================================================================== + +if exists('g:loaded_smart_join') + finish +endif +let g:loaded_smart_join = 1 + + +" GLOBAL VARIABLES: {{{1 +" ============================================================================== + +" g:smart_join_strip_whitespace_before :: Boolean {{{2 +" ------------------------------------------------------------------------------ +" Indicates that before joining, we strip any trailing whitespace on the current +" line. + +if !exists('g:smart_join_strip_whitespace_before') + let g:smart_join_strip_whitespace_before = 1 +endif + + +" g:smart_join_strip_whitespace_after :: Boolean {{{2 +" ------------------------------------------------------------------------------ +" Indicates that after joining, we strip any trailing whitespace on the current +" line. + +if !exists('g:smart_join_strip_whitespace_after') + let g:smart_join_strip_whitespace_after = 1 +endif + + +" FUNCTION: StripTrailing() {{{1 +" ============================================================================== + +function! s:StripTrailing(line) + return substitute(a:line, '\(.\{-}\)\s*$', '\1', '') +endfunction + + +" FUNCTION: SmartJoinLine() {{{1 +" ============================================================================== +" Primary functionality of smart joining. It tests the position of the textwidth +" and the various possibilities of line continuation at this point, deciding if +" it is necessary to introduce a line break or not. Returns true if a line break +" occurred. + +function! s:SmartJoinLine() + if g:smart_join_strip_whitespace_before + call setline('.', s:StripTrailing(getline('.'))) + endif + join + " Have a 0 default value (indicting textwidth disabled) or already fits line. + " As a special precaution, if only one word on the line, do nothing. + let l:line = getline('.') + if &textwidth == 0 || len(l:line) <= &textwidth || + \ len(split(l:line, '\W\+')) <= 1 + return + endif + " Move to textwidth position if possible. If not, joined line was shorter and + " we are finished. Otherwise we can then determine whether or not we must + " insert a line break. + call cursor('.', &textwidth) + if getcurpos()[2] < &textwidth + return + endif + " If the character at textwidth is a whitespace character, we should simply + " place a line break at textwidth. + if match(l:line[&textwidth - 1], '\W\+') != -1 + exe "normal! r\" + return 1 + " If the character following textwidth is a whitespace character, we simply + " create a line break at this point. Note that :join will already clear out + " any trailing whitespace between the two lines. + elseif match(l:line[&textwidth], '\W\+') != -1 + exe "normal! lr\" + return 1 + " The last possibility includes whether or not the current word runs through + " textwidth. + else + " Move to the start of the word and check if we need to break before this. + " In this case, we first check if we are at the beginning of the word + " already (by verifying whether or not there exists a whitespace character + " at the position left of the textwidth). + if match(l:line[&textwidth - 2], '\W\+') == -1 + exe "normal! B" + endif + " Check if WORD goes past textwidth and break at this point if it does. + if getcurpos()[2] + len(expand('')) - 1 > &textwidth + exe "normal! hr\" + return 1 + endif + endif + return 0 +endfunction + + +" FUNCTION: SmartJoin(count) {{{1 +" ============================================================================== +" A wrapper around SmartJoinLine() to incorporate post whitespace-stripping and +" potential recursive functionality. + +function! s:SmartJoin(count) + if a:count > 0 + let l:linebreak = s:SmartJoinLine() + if l:linebreak + exe "normal! j" + endif + if g:smart_join_strip_whitespace_after + call setline('.', s:StripTrailing(getline('.'))) + endif + call s:SmartJoin(a:count - 1) + endif +endfunction + + +" FUNCTION: SaveCursorSmartJoin(count) {{{1 +" ============================================================================== +" A wrapper around SmartJoin(count) used to save the cursor position. + +function! g:SaveCursorSmartJoin(count) + let l:curpos = getcurpos() + call s:SmartJoin(a:count - 1) + call setpos('.', l:curpos) +endfunction + + +" MAPPINGS: {{{1 +" ============================================================================== + +noremap SmartJoin : call g:SaveCursorSmartJoin(v:count1) +