Add new stuff

This commit is contained in:
ViktorBarzin 2018-02-13 13:16:00 +00:00
parent d763e4742c
commit 69661de82f
471 changed files with 14 additions and 34403 deletions

View file

@ -0,0 +1,99 @@
lion.vim
========
Lion.vim is a tool for aligning text by some character. It defines some
Vim operators that can be used with motion commands to align a targetted
block of text.
The two operators are `gl` and `gL`. `gl` will add spaces to the left of
the alignment character, and `gL` will add spaces to the right. Both
operators accept a count, a motion, and a single character. Without a
count, all occurrences of the character will be aligned.
For example, `glip=` will turn
```php
$i = 5;
$username = 'tommcdo';
$stuff = array(1, 2, 3);
```
into
```php
$i = 5;
$username = 'tommcdo';
$stuff = array(1, 2, 3);
```
Typing `3gLi(,` with the cursor somewhere inside `(` and `)` will turn
```php
$names = array(
'bill', 'samantha', 'ray', 'ronald',
'mo', 'harry', 'susan', 'ted',
'timothy', 'bob', 'wolverine', 'cat',
'lion', 'alfred', 'batman', 'linus',
);
```
into
```php
$names = array(
'bill', 'samantha', 'ray', 'ronald',
'mo', 'harry', 'susan', 'ted',
'timothy', 'bob', 'wolverine', 'cat',
'lion', 'alfred', 'batman', 'linus',
);
```
It is also possible to align text by a pattern. To enter a pattern, use `/` as
the alignment character (e.g. `glip/`) and then you will be prompted to input
the pattern. To align by `/`, simply leave the pattern empty (by pressing
`Enter`).
Installation
------------
If you don't have a preferred installation method, I recommend
installing [pathogen.vim](https://github.com/tpope/vim-pathogen), and
then simply copy and paste:
```sh
cd ~/.vim/bundle
git clone git://github.com/tommcdo/vim-lion.git
```
Once help tags have been generated, you can view the manual with
`:help lion`.
Options
-------
Option | Description | Default
--- | --- | ---
`g:lion_create_maps` | Whether to create mappings | `1`
`b:lion_squeeze_spaces`<br>`g:lion_squeeze_spaces` | Squeeze extra spaces | `0`
`g:lion_map_right` | Mapping for right-align operator | `gl`
`g:lion_map_left` | Mapping for left-align operator | `gL`
If you set: `let b:lion_squeeze_spaces = 1`, and hit `glip=`, you will turn
```php
$i = 5;
$user = 'tommcdo';
$stuff = array(1, 2, 3);
```
into:
```php
$i = 5;
$user = 'tommcdo';
$stuff = array(1, 2, 3);
```
instead of (`b:lion_squeeze_spaces = 0`):
```php
$i = 5;
$user = 'tommcdo';
$stuff = array(1, 2, 3);
```

View file

@ -0,0 +1,69 @@
*lion.txt* Plugin to define a code alignment operator
Author: Tom McDonald <http://tommcdo.com>
License: Same terms as Vim itself (see |license|)
This plugin is only available if 'compatible' is not set.
INTRODUCTION *lion*
This plugin provides operators for aligning text to a specific character.
The operators are designed to work as closely as possible to the built-in
Vim |operators|.
MAPPINGS *lion-mappings*
In the mappings below, if {char} is "/", a prompt will input a pattern to use
for alignment. If the pattern is left blank, "/" will be used.
*gl* *lion-right-align*
[count]gl{motion}{char} Align text within {motion} to [count] occurrences
of {char}. Spaces are added to the left of each
{char} in the line up to the [count]th position in
the line.
If no [count] is specified, align all occurrences.
*gL* *lion-left-align*
[count]gL{motion}{char} Align text within {motion} to [count] occurrences
of {char}. Spaces are added to the right of each
{char} in the line up to the [count]th position in
the line.
If no [count] is specified, align all occurrences.
EXAMPLES *lion-examples*
In the below examples, an asterisk (*) denotes the position of cursor. This
is primarily to help understand {motion}s from the example commands.
Old text Command New text ~
$name = "Tom"; glip= $name = "Tom";
$birthday =* "Jan 12"; $birthday = "Jan 12";
$age = 25; $age = 25;
fish, monkey, giraffe* 2gL3j, fish, monkey, giraffe
a, b, c a, b, c
45, saturday, 0 45, saturday, 0
goodbye, cruel, lamp goodbye, cruel, lamp
CONFIGURATION *lion-configuration*
Mappings can be configured with the following options:
Option Description Default ~
g:lion_create_maps Whether to create mappings 1
b:lion_squeeze_spaces,
g:lion_squeeze_spaces Whether to squeeze extra spaces 0
g:lion_map_right Mapping for right-align operator gl
g:lion_map_left Mapping for left-align operator gL
ISSUES AND TODO *lion-issues* *lion-todo*
See https://github.com/tommcdo/vim-lion/issues for bugs and issues.
MY LOVE *lion-my-love*
The love of my life (and Vim plugin hero) is my beautiful wife, Maya. <3
vim:tw=78:ts=8:ft=help:norl:

View file

@ -0,0 +1,12 @@
gL lion.txt /*gL*
gl lion.txt /*gl*
lion lion.txt /*lion*
lion-configuration lion.txt /*lion-configuration*
lion-examples lion.txt /*lion-examples*
lion-issues lion.txt /*lion-issues*
lion-left-align lion.txt /*lion-left-align*
lion-mappings lion.txt /*lion-mappings*
lion-my-love lion.txt /*lion-my-love*
lion-right-align lion.txt /*lion-right-align*
lion-todo lion.txt /*lion-todo*
lion.txt lion.txt /*lion.txt*

View file

@ -0,0 +1,211 @@
" lion.vim - A Vim plugin for text alignment operators
" Maintainer: Tom McDonald <http://github.com/tommcdo>
" Version: 1.0
let s:count = 1
let s:lion_prompt = get(g:, 'lion_prompt', 'Pattern [/]: ')
function! s:command(func, ...)
let s:count = v:count
if a:0
return ":" . "\<C-U>call " . a:func . "(visualmode(), 1)\<CR>"
else
return ":" . "\<C-U>set opfunc=" . a:func . "\<CR>g@"
endif
endfunction
function! s:alignRight(type, ...)
return s:align('right', a:type, a:0, '')
endfunction
function! s:alignLeft(type, ...)
return s:align('left', a:type, a:0, '')
endfunction
" Align a range to a particular character
function! s:align(mode, type, vis, align_char)
let sel_save = &selection
let &selection = "inclusive"
try
" Do we have a character from argument, or should we get one from input?
let align_pattern = a:align_char
let skip = 0
if align_pattern == ''
let align_pattern = nr2char(getchar())
if align_pattern =~ '[1-9]'
while 1
let char = nr2char(getchar())
if char !~ '[0-9]'
break
endif
let align_pattern .= char
endwhile
if char != "\<CR>"
let skip = str2nr(align_pattern) - 1
let align_pattern = char
endif
endif
endif
if align_pattern == '/'
let align_pattern .= input(s:lion_prompt)
elseif align_pattern == ' '
let align_pattern = '/\S\zs\s'
endif
" Determine range boundaries
if a:vis
let pos = s:getpos("'<", "'>", visualmode())
else
let pos = s:getpos("'[", "']", a:type)
endif
let [start_line, end_line, start_col, end_col, middle_start_col, middle_end_col] = pos
" Check for 'lion_squeeze_spaces' options
if exists('b:lion_squeeze_spaces')
let s:lion_squeeze_spaces = get(b:, 'lion_squeeze_spaces')
elseif exists('g:lion_squeeze_spaces')
let s:lion_squeeze_spaces = get(g:, 'lion_squeeze_spaces')
else
let s:lion_squeeze_spaces = 0
endif
" Squeeze extra spaces before aligning
if s:lion_squeeze_spaces
for lnum in range(start_line, end_line)
call setline(lnum, substitute(getline(lnum), '\(^\s*\)\@<! \{2,}', ' ', 'g'))
endfor
endif
" Align for each character up to count or maximum occurrences
let iteration = 1
while 1
let line_virtual_pos = [] " Keep track of positions
let longest = -1 " Track longest sequence
" Find the longest substring before the align character
for line_number in range(start_line, end_line)
if line_number == start_line
let start = start_col
else
let start = middle_start_col
endif
if line_number == end_line
let end = end_col
else
let end = middle_end_col
endif
let line_str = getline(line_number)
" Find the 'real' and 'virtual' positions of the align character in this line
let [real_pos, virtual_pos] = s:match_pos(a:mode, line_str, align_pattern, skip + iteration, line_number, start, end)
let line_virtual_pos += [[real_pos, virtual_pos]]
let longest = max([longest, virtual_pos])
endfor
" Align each line according to the longest
for line_number in range(start_line, end_line)
let line_str = getline(line_number)
let [real_pos, virtual_pos] = line_virtual_pos[(line_number - start_line)]
if virtual_pos != -1 && virtual_pos < longest
let spaces = repeat(' ', (longest - virtual_pos))
if real_pos == 0
let new_line = spaces . line_str
else
let new_line = line_str[:(real_pos - 1)] . spaces . line_str[(real_pos):]
endif
call setline(line_number, new_line)
endif
endfor
if s:count - iteration == 0 || longest == -1
break
endif
let iteration += 1
endwhile
if align_pattern[0] == '/'
silent! call repeat#set("\<Plug>LionRepeat".align_pattern."\<CR>")
else
silent! call repeat#set("\<Plug>LionRepeat".align_pattern)
endif
finally
let &selection = sel_save
endtry
endfunction
function! s:getpos(start, end, mode)
let [_, start_line, start_col, _] = getpos(a:start)
let [_, end_line, end_col, _] = getpos(a:end)
let [middle_start_col, middle_end_col] = [0, -1]
if a:mode == 'V' || a:mode == 'line'
let [start_col, end_col] = [0, -1]
elseif a:mode == "\<C-V>"
let [middle_start_col, middle_end_col] = [start_col, end_col]
endif
return [start_line, end_line, start_col, end_col, middle_start_col, middle_end_col]
endfunction
" Match the position of a character in a line after accounting for artificial width set by tabs
function! s:match_pos(mode, line, char, count, line_number, start, end)
if strlen(a:char) == 1
let pattern = escape(a:char, '~^$.')
else
let pattern = a:char[1:]
" Add start-of-match anchor at the end if there isn't already one in the pattern
if a:mode == 'left' && match(pattern, '\\zs') == -1
let pattern .= '\zs'
endif
endif
if a:end == -1
let line = a:line
else
let line = a:line[:(a:end - 1)]
endif
if a:mode == 'right'
let real_pos = match(line, pattern, a:start - 1, a:count)
elseif a:mode == 'left'
let real_pos = s:first_non_ws_after(line, pattern, a:start - 1, a:count)
endif
if real_pos == -1
let virtual_pos = -1
else
let virtual_pos = virtcol([a:line_number, real_pos])
endif
return [real_pos, virtual_pos]
endfunction
" Get the first non-whitespace after [count] instances of [char]
function! s:first_non_ws_after(line, pattern, start, count)
let pattern = len(a:pattern) == 1 ? a:pattern . '\zs' : a:pattern
let char_pos = match(a:line, pattern, a:start, a:count)
if char_pos == -1
return -1
else
return match(a:line, '\S', char_pos)
endif
endfunction
" Echo a string and wait for input (used when I'm debugging)
function! s:debug_str(str)
echo a:str
let x = getchar()
endfunction
function! s:assign_map(map, func)
if a:map == ''
return
endif
execute 'nmap <silent> ' . a:map . ' <Plug>Lion' . a:func
execute 'vmap <silent> ' . a:map . ' <Plug>VLion' . a:func
endfunction
nnoremap <silent> <Plug>LionRepeat .
nnoremap <silent> <expr> <Plug>LionRight <SID>command("<SID>alignRight")
vnoremap <silent> <expr> <Plug>VLionRight <SID>command("<SID>alignRight", 1)
nnoremap <silent> <expr> <Plug>LionLeft <SID>command("<SID>alignLeft")
vnoremap <silent> <expr> <Plug>VLionLeft <SID>command("<SID>alignLeft", 1)
if get(g:, 'lion_create_maps', 1)
call s:assign_map(get(g:, 'lion_map_right', 'gl'), 'Right')
call s:assign_map(get(g:, 'lion_map_left', 'gL'), 'Left')
endif