Skip to content

Commit

Permalink
Squashed '.vim/bundle/coderifous-vim-textobj-word-column/' content fr…
Browse files Browse the repository at this point in the history
…om commit cb40e14

git-subtree-dir: .vim/bundle/coderifous-vim-textobj-word-column
git-subtree-split: cb40e1459817a7fa23741ff6df05e4481bde5a33
  • Loading branch information
Nicola Paolucci committed Jun 20, 2013
0 parents commit 7968939
Show file tree
Hide file tree
Showing 4 changed files with 258 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
doc/tags
26 changes: 26 additions & 0 deletions README.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
## textobj-word-column.vim

The word-based column text-object makes operating on columns of code
conceptually simpler and reduces keystrokes.

![textobj-word-column][1]

The common task of deleting, changing, or adding to a vertical column of code
can be achieved using visual-blocks, however the first step is to establish
the visual block itself. This typically involves moving the cursor to the
start of the block, and then using vim motions to move the cursor to the end of
the block, and finally doing the appropriate operation.

With a text object for columns, establishing the visual block is much easier,
and even unecessary for certain operations.

### Usage

This plugin adds `ic`, `ac`, `iC`, and `aC` as text-objects. Use them in
commands like `vic`, `cic`, and `daC`.

### Learn more in the plugin doc:

https://github.com/coderifous/textobj-word-column.vim/blob/master/doc/textobj-word-column.txt

[1]: http://i.imgur.com/AAgM9.gif
103 changes: 103 additions & 0 deletions doc/textobj-word-column.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
*textobj-word-column.txt* Adds text-objects for word-based columns.

===============================================================================
CONTENTS *textobj-word-column-contents*

1. Intro...............................|textobj-word-column-intro|
2. Commands............................|textobj-word-column-mappings|
3. Mappings............................|textobj-word-column-examples|
4. Contributing........................|textobj-word-column-contributing|
5. Credits.............................|textobj-word-column-credits|
6. Changelog...........................|textobj-word-column-changelog|

===============================================================================
INTRO *textobj-word-column-intro*

The word-based column |text-object| makes operating on columns of code
conceptually simpler and reduces keystrokes.

The common task of deleting, changing, or adding to a vertical column of code
can be achieved using |visual-blocks|, however the first step is to establish
the visual block itself. This typically involves moving the cursor to the
start of the block, and then using vim motions to move the cursor to the end of
the block, and finally doing the appropriate operation.

With a text object for columns, establishing the visual block is much easier,
and even unecessary for certain operations.

===============================================================================
WORD-BASED COLUMN *textobj-word-column-mappings*

*ac* *cac* *dac* *vac* *yac*
ac "a column", a column based on "a word" |aw|.

*ic* *cic* *dic* *vic* *yic*
ic "inner column", a column based on the "inner word" |iw|.

*aC* *caC* *daC* *vaC* *yaC*
aC "a COLUMN", a column based on "a WORD" |aW|.

*iC* *ciC* *diC* *viC* *yiC*
iC "inner COLUMN", a column based on "inner WORD" |iW|.

===============================================================================
USAGE EXAMPLES *textobj-word-column-examples*

vic Visually select a column.

cic Change a column.

dac Delete a column.

vicI Prepend new text to a column.

vicA Append new text to a column.

viC Visually select a WORD based colunn.

===============================================================================
CONTRIBUTING *textobj-word-column-contributing*

The goal of this plugin is to be able to operate on conceptual columns of code
without the hassle of manually demarcating their boundaries. If you find a
case where the selected column wasn't what you expected AND there's a logical
way to fix or add a boundary condition for that case, then submit an issue via
github. If you'd like to add the fix yourself, please fork the plugin, make
your changes in a branch, and then submit a pull request for that branch.

===============================================================================
CREDITS *textobj-word-column-credits*

Developed by Jim Garvin <http://github.com/coderifous>.

Git repository: https://github.com/coderifous/textobj-word-column.vim

===============================================================================
CHANGELOG *textobj-word-column-changelog*

2012/06/18: First Public Release.

2012/06/23: Added smart-column-boundaries:

Smart boundaries do a better job of figuring out where the visual block
should start and stop for columns with variable length words, and are
smarter about when to do when whitespace is in the mix.

>
* Cursor position | vic Without Smart Boundaries | vic With Smart Boundaries
------------------+------------------------------+---------------------------

ab*c omg |abc| omg |abc | omg
abcdef omg |abc|def omg |abcdef| omg
abc omg |abc| omg |abc | omg

abc * omg abc| |omg |abc | omg
abcdef omg abc|def |omg |abcdef| omg
abc omg abc| |omg |abc | omg

abc *omg abc| |omg abc | |omg
abcdef omg abc|def |omg abcdef| |omg
abc omg abc| |omg abc | |omg
<

2012/08/05: Bug fix: Switched recursive function with iteration.
128 changes: 128 additions & 0 deletions plugin/textobj/word-column.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
if (exists("g:loaded_textobj_word_column"))
finish
endif

function! TextObjWordBasedColumn(textobj)
let cursor_col = virtcol(".")
exec "silent normal! v" . a:textobj . "\<Esc>"
let start_col = virtcol("'<")
let stop_col = virtcol("'>")
let line_num = line(".")
let indent_level = s:indent_level(".")
let start_line = s:find_boundary_row(line_num, col("'<"), start_col, indent_level, -1)
let stop_line = s:find_boundary_row(line_num, col("'<"), start_col, indent_level, 1)
let whitespace_only = s:whitespace_column_wanted(start_line, stop_line, cursor_col)

if (exists("g:textobj_word_column_no_smart_boundary_cols"))
let col_bounds = [start_col, stop_col]
else
let col_bounds = s:find_smart_boundary_cols(start_line, stop_line, cursor_col, a:textobj, whitespace_only)
endif

exec "keepjumps silent normal!" . start_line . "gg" . col_bounds[0] . "|" . stop_line . "gg" . col_bounds[1] . "|"
endfunction

function! s:find_smart_boundary_cols(start_line, stop_line, cursor_col, textobj, whitespace_only)
let col_bounds = []
let index = a:start_line
if a:whitespace_only
let word_start = ""
let s:col_bounds_fn = function("s:col_bounds_min")
else
let word_start = "lb"
let s:col_bounds_fn = function("s:col_bounds_max")
endif

while index <= a:stop_line
exec "keepjumps silent normal!" index . "gg" . a:cursor_col . "|" . word_start . "v" . a:textobj . "\<Esc>"
let start_col = virtcol("'<")
let stop_col = virtcol("'>")
let col_bounds = s:col_bounds_fn(start_col, stop_col, col_bounds)
let index = index + 1
endwhile

return col_bounds
endfunction

function! s:col_bounds_max(start_col, stop_col, col_bounds)
if a:col_bounds == []
return [a:start_col, a:stop_col]
endif
if a:start_col < a:col_bounds[0]
let a:col_bounds[0] = a:start_col
endif
if a:stop_col > a:col_bounds[1]
let a:col_bounds[1] = a:stop_col
endif
return a:col_bounds
endfunction

function! s:col_bounds_min(start_col, stop_col, col_bounds)
if a:col_bounds == []
return [a:start_col, a:stop_col]
endif
if a:start_col > a:col_bounds[0]
let a:col_bounds[0] = a:start_col
endif
if a:stop_col < a:col_bounds[1]
let a:col_bounds[1] = a:stop_col
endif
return a:col_bounds
endfunction

function! s:whitespace_column_wanted(start_line, stop_line, cursor_col)
let index = a:start_line
let expanded_tabs = repeat(" ", &tabstop)
while index <= a:stop_line
let line = substitute(getline(index), "\t", expanded_tabs, "g")
let char = line[a:cursor_col - 1]
if char != " " && char != "\t"
return 0
end
let index = index + 1
endwhile
return 1
endfunction

function! s:find_boundary_row(start_line, start_col, start_vcol, indent_level, step)
let current_line = a:start_line
let max_boundary = 0
if a:step == 1
let max_boundary = line("$")
endif
while current_line != max_boundary
let next_line = current_line + a:step
let non_blank = getline(next_line) =~ "[^ \t]"
let same_indent = s:indent_level(next_line) == a:indent_level
let has_width = getline(next_line) =~ '\%'.a:start_vcol.'v'
let is_not_comment = ! s:is_comment(next_line, a:start_col)
if same_indent && non_blank && has_width && is_not_comment
let current_line = next_line
else
return current_line
endif
endwhile
return max_boundary
endfunction

function! s:indent_level(line_num)
let line = getline(a:line_num)
return match(line, "[^ \t]")
endfunction

function! s:is_comment(line_num, column)
return synIDattr(synIDtrans(synID(a:line_num, a:column, 1)),"name") == "Comment"
endfunction

if (!exists("g:skip_default_textobj_word_column_mappings"))
xnoremap <silent> ac :<C-u>call TextObjWordBasedColumn("aw")<cr>
xnoremap <silent> aC :<C-u>call TextObjWordBasedColumn("aW")<cr>
xnoremap <silent> ic :<C-u>call TextObjWordBasedColumn("iw")<cr>
xnoremap <silent> iC :<C-u>call TextObjWordBasedColumn("iW")<cr>
onoremap <silent> ac :call TextObjWordBasedColumn("aw")<cr>
onoremap <silent> aC :call TextObjWordBasedColumn("aW")<cr>
onoremap <silent> ic :call TextObjWordBasedColumn("iw")<cr>
onoremap <silent> iC :call TextObjWordBasedColumn("iW")<cr>
endif

let g:loaded_textobj_word_column = 1

0 comments on commit 7968939

Please sign in to comment.