Skip to content

Commit

Permalink
Merge pull request #22 from jreybert/next
Browse files Browse the repository at this point in the history
Next
  • Loading branch information
jreybert committed Oct 24, 2015
2 parents 2bebec3 + ee37411 commit 24bd7d4
Show file tree
Hide file tree
Showing 27 changed files with 1,402 additions and 471 deletions.
73 changes: 66 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,20 @@ Take a look at [TL;DR](#tldr) to start using it immediatly.

* [x] See all your changes, staged changes, untracked/removed/renamed files in one unique buffer.
* [x] Staged/unstaged/discard changes with one key press, moving the cursor around. Stage at hunk or file level. Line and partial line staging are ongoing.
* [x] Stage part of hunks, by visual select, lines or selecting bunch of lines with marks.
* [x] Start to write the commit message in one key press, commit also in one key press.
* [x] Modify in line the content just before staging it.
* [x] Visualize stashes. Apply, pop, drop are on going.
* [x] Add file to .gitignore file.
* [ ] Chase all corner cases. Please remember that vimagit is at an early development stage. If you try vimagit and nothing is working, please don't throw it, fill an issue on github :heart: !
* [ ] Chase all corner cases. Please remember that vimagit is at an early development stage. If you try vimagit and nothing is working, please don't throw it, fill an [issue](https://github.com/jreybert/vimagit/issues/new) on github :heart: !

More to come:
* Partial hunk staging (next release).
* Vizualize and checkout branches.
* Go through history, cherry-pick changes.
* Something is missing? Open an [issue](https://github.com/jreybert/vimagit/issues/new)!

The plugin is fully tested for various versions of vim on linux: vim 7.3.249, vim 7.4.273, neovim. It is also tested for macos X: vim, macvim and neovim. Anyway, if you feel that vimagit behaves oddly (slow refresh, weird display order...) please fill an [issue](https://github.com/jreybert/vimagit/issues/new).

For the most enthusiastic, you can try the branch [next](https://github.com/jreybert/vimagit/tree/next). It is quite stable, just check its travis status before fetching it.

> Why should I use vimagit, there are already plethora git plugins for vim?
Expand Down Expand Up @@ -93,7 +95,22 @@ There are 5 sections:

### Commands

**:Magit**
#### magit#show_magit()

Function to open magit buffer.
It takes 3 parameters:
* orientation (mandatory): it can be
- 'v', curent window is split vertically, and magit is displayed in new
buffer
- 'h', curent window is split horizontally, and magit is displayed in
new buffer
- 'c', magit is displayed in current buffer
* show_all_files: define is file diffs are shown by default for this session
(see [g:magit_default_show_all_files](#gmagit_default_show_all_files))
* foldlevel: set default magit buffer foldlevel for this session
(see [g:magit_default_fold_level](#gmagit_default_fold_level))

#### :Magit
* open magit buffer.

### Mappings
Expand Down Expand Up @@ -123,6 +140,8 @@ Following mappings are set locally, for magit buffer only, in normal mode.
**S**
* If cursor is in a hunk, stage/unstage hunk at cursor position.
* If cursor is in diff header, stage/unstage whole file at cursor position.
* If some lines in the hunk are selected (using **v**), stage only visual selected lines (only works for staging).
* If some lines in the hunk are marked (using **M**), stage only marked lines (only works for staging).
* When cursor is in "Unstaged changes" section, it will stage the hunk/file.
* On the other side, when cursor is in "Staged changes" section, it will unstage hunk/file.

Expand All @@ -131,6 +150,14 @@ Following mappings are set locally, for magit buffer only, in normal mode.
* When cursor is in "Unstaged changes" section, it will stage the file.
* On the other side, when cursor is in "Staged changes" section, it will unstage file.

**L**
* Stage the line under the cursor.

**M**
* Mark the line under the cursor "to be staged".
* If some lines in the hunk are selected (using **v**), mark selected lines "to be staged".
* To staged marked lines in a hunk, move cursor to this hunk and press **S**.

**DDD**
* If cursor is in a hunk, discard hunk at cursor position.
* If cursor is in diff header, discard whole file at cursor position.
Expand Down Expand Up @@ -166,11 +193,43 @@ Following mappings are set locally, for magit buffer only, in normal mode.

User can define in its prefered |vimrc| some options.

To disable vimagit plugin
> let g:magit_enabled=0
#### g:magit_enabled

To enable or disable vimagit plugin.
Default value is 1.
> let g:magit_enabled=[01]
#### g:magit_show_help

To disable chatty inline help in magit buffer (default 1)
> let g:magit_show_help=[01]
#### g:magit_default_show_all_files

When this variable is set to 0, all diff files are hidden by default.
When this variable is set to 1, all diff files are shown by default.
Default value is 0.
NB: for repository with large number of differences, display may be slow.
> let g:magit_default_show_all_files=[01]
#### g:magit_default_fold_level

Default foldlevel for magit buffer.
When set to 0, both filenames and hunks are folded.
When set to 1, filenames are unfolded and hunks are folded.
When set to 2, filenames and hunks are unfolded.
Default value is 1.
> let g:magit_default_fold_level=[012]
#### g:magit_warning_max_lines

To disable chatty inline help in magit buffer
> let g:magit_show_help=0
This variable is the maximum number of diff lines that vimagit will display
without warning the user. If the number of diff lines to display is greater than
this variable, vimagit will ask a confirmation to the user before refreshing the
buffer. If user answer is 'yes', vimagit will display diff lines as expected.
If user answer is 'no', vimagit will close all file diffs before refreshing.
Default value is 10000.
> let g:magit_warning_max_lines=val
## Installation

Expand Down
19 changes: 19 additions & 0 deletions autoload/magit/git.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
" magit#git#get_status: this function returns the git status output formated
" into a List of Dict as
" [ {staged', 'unstaged', 'filename'}, ... ]
function! magit#git#get_status()
let file_list = []

" systemlist v7.4.248 problem again
" we can't use git status -z here, because system doesn't make the
" difference between NUL and NL. -status z terminate entries with NUL,
" instead of NF
let status_list=magit#utils#systemlist("git status --porcelain")
for file_status_line in status_list
let line_match = matchlist(file_status_line, '\(.\)\(.\) \%(.\{-\} -> \)\?"\?\(.\{-\}\)"\?$')
let filename = line_match[3]
call add(file_list, { 'staged': line_match[1], 'unstaged': line_match[2], 'filename': filename })
endfor
return file_list
endfunction

118 changes: 118 additions & 0 deletions autoload/magit/sign.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
" Got lot of stuf from vim-gitgutter
" https://github.com/airblade/vim-gitgutter

" Vim doesn't namespace sign ids so every plugin shares the same
" namespace. Sign ids are simply integers so to avoid clashes with other
" signs we guess at a clear run.
"
" Note also we currently never reset s:next_sign_id.
let s:first_sign_id = 42000
let s:next_sign_id = s:first_sign_id
let s:dummy_sign_id = s:first_sign_id - 1
" Remove-all-signs optimisation requires Vim 7.3.596+.
let s:supports_star = v:version > 703 || (v:version == 703 && has("patch596"))

let s:bufnr = bufnr(g:magit_buffer_name)

function! magit#sign#remove_all(...)
if ( a:0 == 1 )
let pattern = a:1
else
let pattern = '^Magit.*'
endif
let signs = magit#sign#find_signs(pattern, 1, line('$'))
call magit#sign#remove_signs(signs)
endfunction

" magit#sign#remove_signs: unplace a list of signs
" param[in] sign_ids: list of signs dict
function! magit#sign#remove_signs(sign_ids)
let bufnr = magit#utils#bufnr()
for sign in values(a:sign_ids)
execute "sign unplace" sign.id
endfor
endfunction

function! magit#sign#add_sign(line, type, bufnr)
let id = <SID>get_next_sign_id()
execute ":sign place " . id .
\ " line=" . a:line . " name=" . s:magit_mark_signs[a:type] .
\ " buffer=" . a:bufnr
return id
endfunction

function! magit#sign#remove_sign(id)
execute ":sign unplace " . a:id
endfunction

" s:get_next_sign_id: helper function to increment sign ids
function! s:get_next_sign_id()
let next_id = s:next_sign_id
let s:next_sign_id += 1
return next_id
endfunction

" magit#sign#find_signs: this function returns signs matching a pattern in a
" range of lines
" param[in] pattern: regex pattern to match
" param[in] startline,endline: range of lines
" FIXME: find since which version "sign place" is sorted
function! magit#sign#find_signs(pattern, startline, endline)
let bufnr = magit#utils#bufnr()
" <line_number (string)>: {'id': <id (number)>, 'name': <name (string)>}
let found_signs = {}

redir => signs
silent execute "sign place buffer=" . bufnr
redir END

for sign_line in filter(split(signs, '\n'), 'v:val =~# "="')
" Typical sign line: line=88 id=1234 name=GitGutterLineAdded
" We assume splitting is faster than a regexp.
let components = split(sign_line)
let name = split(components[2], '=')[1]
let line_number = str2nr(split(components[0], '=')[1])
if ( name =~# a:pattern &&
\ line_number >= a:startline &&
\ line_number <= a:endline )
let id = str2nr(split(components[1], '=')[1])
let found_signs[line_number] = {'id': id, 'name': name}
endif
endfor
return found_signs
endfunction

" magit#sign#find_stage_signs: helper function to get marked lines for stage
" param[in] startline,endline: range of lines
" return Dict of marked lines
function! magit#sign#find_stage_signs(startline, endline)
return magit#sign#find_signs(s:magit_mark_signs.M, a:startline, a:endline)
endfunction

" s:magit_mark_sign: string of the sign for lines to be staged
let s:magit_mark_signs = {'M': 'MagitTBS', 'S': 'MagitBS', 'E': 'MagitBE'}

" magit#sign#init: initializer function for signs
function! magit#sign#init()
execute "sign define " . s:magit_mark_signs.M . " text=S> linehl=Visual"
execute "sign define " . s:magit_mark_signs.S
execute "sign define " . s:magit_mark_signs.E
endfunction

" magit#sign#toggle_signs: toggle marks for range of lines
" marked lines are unmarked, non marked are marked
" param[in] type; type of sign to toggle (see s:magit_mark_signs)
" param[in] startline,endline: range of lines
function! magit#sign#toggle_signs(type, startline, endline)
let bufnr = magit#utils#bufnr()
let current_signs = magit#sign#find_signs(s:magit_mark_signs[a:type], a:startline, a:endline)
let line = a:startline
while ( line <= a:endline )
if ( has_key(current_signs, line) == 0 )
call magit#sign#add_sign(line, a:type, bufnr)
else
call magit#sign#remove_sign(current_signs[line].id)
endif
let line += 1
endwhile
endfunction
Loading

0 comments on commit 24bd7d4

Please sign in to comment.