From 59b0e0d2a95ba9d44f691c4fbd6270ce715a781e Mon Sep 17 00:00:00 2001 From: Jerome Reybert Date: Mon, 2 Nov 2015 13:28:03 +0100 Subject: [PATCH 01/13] autoload/magit/state.vim: cache diff only if file is visible (should improve performace) --- autoload/magit/state.vim | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/autoload/magit/state.vim b/autoload/magit/state.vim index 032416e..d8eda27 100644 --- a/autoload/magit/state.vim +++ b/autoload/magit/state.vim @@ -146,6 +146,9 @@ function! magit#state#add_file(mode, status, filename, depth) dict let file.status = a:status let file.depth = a:depth + " discard previous diff + let file.diff = deepcopy(s:diff_template) + if ( a:status == '?' && getftype(a:filename) == 'link' ) let file.status = 'L' let file.symlink = resolve(a:filename) @@ -153,14 +156,18 @@ function! magit#state#add_file(mode, status, filename, depth) dict elseif ( magit#utils#is_submodule(a:filename)) let file.status = 'S' let file.submodule = 1 + if ( !file.is_visible() ) + return + endif let file.diff.hunks[0].header = '' let file.diff.hunks[0].lines = diff_list - if ( file.is_visible() ) - let self.nb_diff_lines += len(diff_list) - endif + let self.nb_diff_lines += len(diff_list) elseif ( a:status == '?' && isdirectory(a:filename) == 1 ) let file.status = 'N' let file.dir = 1 + if ( !file.is_visible() ) + return + endif for subfile in magit#utils#ls_all(a:filename) call self.add_file(a:mode, a:status, subfile, a:depth + 1) endfor @@ -172,6 +179,9 @@ function! magit#state#add_file(mode, status, filename, depth) dict let file.binary = 1 let file.diff.hunks[0].header = 'Binary file' else + if ( !file.is_visible() ) + return + endif let line = 0 " match( while ( line < len(diff_list) && diff_list[line] !~ "^@.*" ) @@ -193,9 +203,7 @@ function! magit#state#add_file(mode, status, filename, depth) dict call add(hunk.lines, diff_line) endfor endif - if ( file.is_visible() ) - let self.nb_diff_lines += len(diff_list) - endif + let self.nb_diff_lines += len(diff_list) endif endfunction From d5b3042ac750894053117a823cdb90109ad6e3b4 Mon Sep 17 00:00:00 2001 From: Jerome Reybert Date: Fri, 6 Nov 2015 13:36:04 +0100 Subject: [PATCH 02/13] plugin/magit.vim: remove warning when opening magit buffer --- plugin/magit.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/magit.vim b/plugin/magit.vim index 8607817..cadcf75 100644 --- a/plugin/magit.vim +++ b/plugin/magit.vim @@ -599,7 +599,7 @@ function! magit#show_magit(display, ...) endif silent! execute "bdelete " . g:magit_buffer_name - execute "file " . g:magit_buffer_name + silent! execute "file " . g:magit_buffer_name setlocal buftype=nofile setlocal bufhidden=delete From 106713019bab37c004350ea26f4d699d4a4bd732 Mon Sep 17 00:00:00 2001 From: Jerome Reybert Date: Fri, 6 Nov 2015 13:36:33 +0100 Subject: [PATCH 03/13] plugin/magit.vim: check that magit buffer exists before removing it (refs #39) --- plugin/magit.vim | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugin/magit.vim b/plugin/magit.vim index cadcf75..37a0a38 100644 --- a/plugin/magit.vim +++ b/plugin/magit.vim @@ -598,7 +598,9 @@ function! magit#show_magit(display, ...) let b:magit_default_fold_level = a:2 endif - silent! execute "bdelete " . g:magit_buffer_name + if ( bufexists(g:magit_buffer_name) ) + silent! execute "bdelete " . g:magit_buffer_name + endif silent! execute "file " . g:magit_buffer_name setlocal buftype=nofile From e5a4ffdaa34aa18c12571213174daacd4b20eb85 Mon Sep 17 00:00:00 2001 From: Jerome Reybert Date: Mon, 9 Nov 2015 14:17:02 +0100 Subject: [PATCH 04/13] plugin/magit.vim: add g:magit_default_sections to let user choose which sections are displayed (fix #37) It also removes default display of stash section. If user wants to display stash, it must add 'stash' entry in g:magit_default_sections --- README.md | 7 +++++ doc/vimagit.txt | 6 ++++ plugin/magit.vim | 80 +++++++++++++++++++++++++++++------------------- 3 files changed, 61 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index 4382746..3c80aa4 100644 --- a/README.md +++ b/README.md @@ -220,6 +220,13 @@ When set to 2, filenames and hunks are unfolded. Default value is 1. > let g:magit_default_fold_level=[012] +#### g:magit_default_sections + +With this variable, the user is able to choose which sections are displayed in magit +buffer, and in which order. +Default value: +> let g:magit_default_sections = ['info', 'global_help', 'commit', 'staged', 'unstaged'] + #### g:magit_warning_max_lines This variable is the maximum number of diff lines that vimagit will display diff --git a/doc/vimagit.txt b/doc/vimagit.txt index ac02191..5cea783 100644 --- a/doc/vimagit.txt +++ b/doc/vimagit.txt @@ -276,6 +276,12 @@ When set to 2, filenames and hunks are unfolded. Default value is 1. let g:magit_default_fold_level=[012] + *vimagit-g:magit_default_sections* +With this variable, the user is able to choose which sections are displayed in +magit buffer, and in which order. +Default value: +let g:magit_default_sections = ['info', 'global_help', 'commit', 'staged', 'unstaged'] + *vimagit-g:magit_warning_max_lines* 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 diff --git a/plugin/magit.vim b/plugin/magit.vim index 37a0a38..db4b20a 100644 --- a/plugin/magit.vim +++ b/plugin/magit.vim @@ -47,6 +47,7 @@ let g:magit_enabled = get(g:, 'magit_enabled', let g:magit_show_help = get(g:, 'magit_show_help', 1) let g:magit_default_show_all_files = get(g:, 'magit_default_show_all_files', 0) let g:magit_default_fold_level = get(g:, 'magit_default_fold_level', 1) +let g:magit_default_sections = get(g:, 'magit_default_sections', ['info', 'global_help', 'commit', 'staged', 'unstaged']) let g:magit_warning_max_lines = get(g:, 'magit_warning_max_lines', 10000) @@ -227,32 +228,34 @@ let s:magit_commit_mode='' " 'CC': prepare a brand new commit message " 'CA': get the last commit message function! s:mg_get_commit_section() - let commit_mode_str="" - if ( s:magit_commit_mode == 'CC' ) - let commit_mode_str="normal" - elseif ( s:magit_commit_mode == 'CA' ) - let commit_mode_str="amend" - endif - silent put ='' - silent put =g:magit_sections.commit_start - silent put ='Commit mode: '.commit_mode_str - call mg_section_help('commit') - silent put =magit#utils#underline(g:magit_sections.commit_start) - silent put ='' + if ( s:magit_commit_mode != '' ) + let commit_mode_str="" + if ( s:magit_commit_mode == 'CC' ) + let commit_mode_str="normal" + elseif ( s:magit_commit_mode == 'CA' ) + let commit_mode_str="amend" + endif + silent put ='' + silent put =g:magit_sections.commit_start + silent put ='Commit mode: '.commit_mode_str + call mg_section_help('commit') + silent put =magit#utils#underline(g:magit_sections.commit_start) + silent put ='' - let git_dir=magit#git#git_dir() - " refresh the COMMIT_EDITMSG file - if ( s:magit_commit_mode == 'CC' ) - silent! call magit#utils#system("GIT_EDITOR=/bin/false git commit -e 2> /dev/null") - elseif ( s:magit_commit_mode == 'CA' ) - silent! call magit#utils#system("GIT_EDITOR=/bin/false git commit --amend -e 2> /dev/null") - endif - if ( filereadable(git_dir . 'COMMIT_EDITMSG') ) - let comment_char=mg_comment_char() - let commit_msg=magit#utils#join_list(filter(readfile(git_dir . 'COMMIT_EDITMSG'), 'v:val !~ "^' . comment_char . '"')) - put =commit_msg + let git_dir=magit#git#git_dir() + " refresh the COMMIT_EDITMSG file + if ( s:magit_commit_mode == 'CC' ) + silent! call magit#utils#system("GIT_EDITOR=/bin/false git commit -e 2> /dev/null") + elseif ( s:magit_commit_mode == 'CA' ) + silent! call magit#utils#system("GIT_EDITOR=/bin/false git commit --amend -e 2> /dev/null") + endif + if ( filereadable(git_dir . 'COMMIT_EDITMSG') ) + let comment_char=mg_comment_char() + let commit_msg=magit#utils#join_list(filter(readfile(git_dir . 'COMMIT_EDITMSG'), 'v:val !~ "^' . comment_char . '"')) + put =commit_msg + endif + put =g:magit_sections.commit_end endif - put =g:magit_sections.commit_end endfunction " s:mg_comment_char: this function gets the commentChar from git config @@ -502,6 +505,16 @@ function! magit#open_close_folding(...) call magit#update_buffer() endfunction +" s:mg_display_functions: Dict wrapping all display related functions +" This Dict should be accessed through g:magit_default_sections +let s:mg_display_functions = { + \ 'info': { 'fn': function("s:mg_get_info"), 'arg': []}, + \ 'global_help': { 'fn': function("s:mg_section_help"), 'arg': ['global']}, + \ 'commit': { 'fn': function("s:mg_get_commit_section"), 'arg': []}, + \ 'staged': { 'fn': function("s:mg_get_staged_section"), 'arg': ['staged']}, + \ 'unstaged': { 'fn': function("s:mg_get_staged_section"), 'arg': ['unstaged']}, + \ 'stash': { 'fn': function("s:mg_get_stashes"), 'arg': []}, +\ } " magit#update_buffer: this function: " 1. checks that current buffer is the wanted one @@ -527,11 +540,6 @@ function! magit#update_buffer() " delete buffer silent! execute "silent :%delete _" - call mg_get_info() - call mg_section_help('global') - if ( s:magit_commit_mode != '' ) - call mg_get_commit_section() - endif call s:state.update() if ( s:state.nb_diff_lines > g:magit_warning_max_lines && b:magit_warning_answered_yes == 0 ) @@ -544,9 +552,17 @@ function! magit#update_buffer() endif endif - call mg_get_staged_section('staged') - call mg_get_staged_section('unstaged') - call mg_get_stashes() + for section in g:magit_default_sections + try + let func = s:mg_display_functions[section] + catch + echohl WarningMsg + echom 'unknown section to display: ' . section + echom 'please check your redefinition of g:magit_default_sections' + echohl None + endtry + call call(func.fn, func.arg) + endfor call winrestview(l:winview) From 8addcf0af0667dd20d6aff46aab60ce1a2ec825e Mon Sep 17 00:00:00 2001 From: Jerome Reybert Date: Mon, 9 Nov 2015 14:44:57 +0100 Subject: [PATCH 05/13] README.md: replace bold subsubsubtitles by real subsubsubtitles. --- README.md | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 3c80aa4..ef77d8e 100644 --- a/README.md +++ b/README.md @@ -120,23 +120,23 @@ For each mapping, user can redefine the behavior with its own mapping. Each vari Following mappings are broadly set, and are applied in all vim buffers. -**\M** +##### \M Open Magit buffer #### Local mappings Following mappings are set locally, for magit buffer only, in normal mode. -**Enter**,**\** +##### Enter,\ * All files are folded by default. To see the changes in a file, move cursor to the filename line, and press Enter. You can close the changes display retyping Enter. -**zo,zO** +##### zo,zO * Typing zo on a file will unhide its diffs. -**zc,zC** +##### zc,zC * Typing zc on a file will hide its diffs. -**S** +##### 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). @@ -144,48 +144,48 @@ Following mappings are set locally, for magit buffer only, in normal mode. * 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. -**F** +##### F * Stage/unstage the whole file at cursor position. * 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** +##### L * Stage the line under the cursor. -**M** +##### 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** +##### DDD * If cursor is in a hunk, discard hunk at cursor position. * If cursor is in diff header, discard whole file at cursor position. * Only works in "Unstaged changes" section. -**CC** +##### CC * If not in commit section, set commit mode to "New commit" and show "Commit message" section with brand new commit message. * If in commit section, commit the all staged changes in commit mode previously set. -**:w** +##### :w * If in commit section, commit the all staged changes in commit mode previously set. -**CA** +##### CA * If not in commit section, set commit mode to "Amend commit" and show "Commit message" section with previous commit message. * If in commit section, commit the staged changes in commit mode previously set. -**CF** +##### CF * Amend the staged changes into the previous commit, without modifying previous commit message. -**I** +##### I * Add the file under the cursor in .gitgnore -**R** +##### R * Refresh magit buffer -**q** +##### q * Close the magit buffer -**h** +##### h * Toggle help showing in magit buffer ### Options From 51e6edd5ccd01e5ab58fcb875690d38227b16d9f Mon Sep 17 00:00:00 2001 From: Jerome Reybert Date: Tue, 10 Nov 2015 13:00:05 +0100 Subject: [PATCH 06/13] autoload/magit/state.vim: rework visible state of files (now visible state set by user with is prioritary) --- autoload/magit/git.vim | 21 +++++++++++++++++++++ autoload/magit/state.vim | 30 +++++++++++++++++++----------- 2 files changed, 40 insertions(+), 11 deletions(-) diff --git a/autoload/magit/git.vim b/autoload/magit/git.vim index 66b0181..6ec578e 100644 --- a/autoload/magit/git.vim +++ b/autoload/magit/git.vim @@ -54,6 +54,27 @@ function! magit#git#git_dir() return s:magit_git_dir endfunction +" magit#git#git_diff: helper function to get diff of a file +" nota: when git fail (due to misformated patch for example), an error +" message is raised. +" param[in] filemane: it must be quoted if it contains spaces +" param[in] status: status of the file (see g:magit_git_status_code) +" param[in] mode: can be staged or unstaged +function! magit#git#git_diff(filename, status, mode) + let dev_null = ( a:status == '?' ) ? " /dev/null " : " " + let staged_flag = ( a:mode == 'staged' ) ? " --staged " : " " + let git_cmd="git diff --no-ext-diff " . staged_flag . + \ "--no-color --patch -- " . dev_null . " " + \ .a:filename + silent let diff_list=magit#utils#systemlist(git_cmd) + if ( empty(diff_list) ) + echohl WarningMsg + echom "diff command \"" . diff_cmd . "\" returned nothing" + echohl None + throw 'diff error' + endif + return diff_list +endfunction " magit#git#git_add: helper function to add a whole file " nota: when git fail (due to misformated patch for example), an error " message is raised. diff --git a/autoload/magit/state.vim b/autoload/magit/state.vim index d8eda27..f71ee25 100644 --- a/autoload/magit/state.vim +++ b/autoload/magit/state.vim @@ -16,6 +16,16 @@ function! magit#state#toggle_file_visible() dict let self.visible = ( self.visible == 0 ) ? 1 : 0 endfunction +" magit#state#init_file_visible: init file visible status, among several conditions +function! magit#state#init_file_visible() dict + if ( !self.new ) + return self.is_visible() + else + call self.set_visible(b:magit_default_show_all_files) + return self.is_visible() + endif +endfunction + " magit#state#is_file_dir: file getter function " return 1 if current file is a directory, 0 otherwise function! magit#state#is_file_dir() dict @@ -70,7 +80,9 @@ let s:diff_template = { " s:file_template: template for file object " WARNING: this variable must be deepcopy()'ied let s:file_template = { +\ 'new': 1, \ 'exists': 0, +\ 'visible': 0, \ 'filename': '', \ 'status': '', \ 'empty': 0, @@ -82,6 +94,7 @@ let s:file_template = { \ 'is_dir': function("magit#state#is_file_dir"), \ 'is_visible': function("magit#state#is_file_visible"), \ 'set_visible': function("magit#state#set_file_visible"), +\ 'init_visible': function("magit#state#init_file_visible"), \ 'toggle_visible': function("magit#state#toggle_file_visible"), \ 'must_be_added': function("magit#state#must_be_added"), \ 'get_header': function("magit#state#file_get_header"), @@ -101,7 +114,6 @@ function! magit#state#get_file(mode, filename, ...) dict let create = ( a:0 == 1 ) ? a:1 : 0 if ( file_exists == 0 && create == 1 ) let self.dict[a:mode][a:filename] = deepcopy(s:file_template) - let self.dict[a:mode][a:filename].visible = b:magit_default_show_all_files let self.dict[a:mode][a:filename].filename = a:filename elseif ( file_exists == 0 && create == 0 ) throw 'file_doesnt_exists' @@ -131,15 +143,6 @@ endfunction " param[in] status: one character status code of the file (AMDRCU?) " param[in] filename: filename function! magit#state#add_file(mode, status, filename, depth) dict - let dev_null = ( a:status == '?' ) ? " /dev/null " : " " - let staged_flag = ( a:mode == 'staged' ) ? " --staged " : " " - let diff_cmd="git diff --no-ext-diff " . staged_flag . - \ "--no-color --patch -- " . dev_null . " " - \ . magit#utils#add_quotes(a:filename) - let diff_list=magit#utils#systemlist(diff_cmd) - if ( empty(diff_list) ) - echoerr "diff command \"" . diff_cmd . "\" returned nothing" - endif let file = self.get_file(a:mode, a:filename, 1) let file.exists = 1 @@ -159,6 +162,8 @@ function! magit#state#add_file(mode, status, filename, depth) dict if ( !file.is_visible() ) return endif + let diff_list=magit#git#git_diff(magit#utils#add_quotes(a:filename), + \ a:status, a:mode) let file.diff.hunks[0].header = '' let file.diff.hunks[0].lines = diff_list let self.nb_diff_lines += len(diff_list) @@ -179,11 +184,13 @@ function! magit#state#add_file(mode, status, filename, depth) dict let file.binary = 1 let file.diff.hunks[0].header = 'Binary file' else - if ( !file.is_visible() ) + if ( !file.init_visible() ) return endif let line = 0 " match( + let diff_list=magit#git#git_diff(magit#utils#add_quotes(a:filename), + \ a:status, a:mode) while ( line < len(diff_list) && diff_list[line] !~ "^@.*" ) call add(file.diff.header, diff_list[line]) let line += 1 @@ -217,6 +224,7 @@ function! magit#state#update() dict for diff_dict_mode in values(self.dict) for file in values(diff_dict_mode) let file.exists = 0 + let file.new = 0 " always discard previous diff let file.diff = deepcopy(s:diff_template) endfor From b719b7b95cd3f955844a122f0a8d611638ed38bf Mon Sep 17 00:00:00 2001 From: Jerome Reybert Date: Tue, 10 Nov 2015 13:12:43 +0100 Subject: [PATCH 07/13] autoload/magit/state.vim: by default, do not show untracked/deleted/added/renamed files diffs (ref #28) --- README.md | 5 +++-- autoload/magit/state.vim | 4 +++- doc/vimagit.txt | 7 ++++--- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index ef77d8e..2c73070 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,7 @@ It takes 3 parameters: - '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 + * show_all_files: define how 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)) @@ -206,7 +206,8 @@ To disable chatty inline help in magit buffer (default 1) #### 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. +When this variable is set to 1, all diff for modified files are shown by default. +When this variable is set to 2, all diff for all 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] diff --git a/autoload/magit/state.vim b/autoload/magit/state.vim index f71ee25..65bc021 100644 --- a/autoload/magit/state.vim +++ b/autoload/magit/state.vim @@ -21,7 +21,9 @@ function! magit#state#init_file_visible() dict if ( !self.new ) return self.is_visible() else - call self.set_visible(b:magit_default_show_all_files) + if ( self.status == 'M' || b:magit_default_show_all_files > 1 ) + call self.set_visible(b:magit_default_show_all_files) + endif return self.is_visible() endif endfunction diff --git a/doc/vimagit.txt b/doc/vimagit.txt index 5cea783..e88224e 100644 --- a/doc/vimagit.txt +++ b/doc/vimagit.txt @@ -121,12 +121,12 @@ It takes 3 parameters: - '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 + * show_all_files: define how file diffs are shown by default for this session (see |vimagit-g:magit_default_show_all_files|) * foldlevel: set default magit buffer foldlevel for this session (see |vimagit-g:magit_default_fold_level|) - *:Magit* *magit#show_magit('v')* + *:Magit* *magit#show_magit('v')* :Magit open magit buffer @@ -263,7 +263,8 @@ let g:magit_show_help=[01] *vimagit-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. +When this variable is set to 1, all diff for modified files are shown by default. +When this variable is set to 2, all diff for all 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] From 297b2cb1345e953bbba17f1a47a30c623dca1c4b Mon Sep 17 00:00:00 2001 From: Jerome Reybert Date: Tue, 10 Nov 2015 13:20:13 +0100 Subject: [PATCH 08/13] plugin/magit.vim: change default diff diff show behavior, now show all modified file diffs by default --- README.md | 4 ++-- doc/vimagit.txt | 4 ++-- plugin/magit.vim | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 2c73070..3abb088 100644 --- a/README.md +++ b/README.md @@ -208,9 +208,9 @@ To disable chatty inline help in magit buffer (default 1) When this variable is set to 0, all diff files are hidden by default. When this variable is set to 1, all diff for modified files are shown by default. When this variable is set to 2, all diff for all files are shown by default. -Default value is 0. +Default value is 1. NB: for repository with large number of differences, display may be slow. -> let g:magit_default_show_all_files=[01] +> let g:magit_default_show_all_files=[012] #### g:magit_default_fold_level diff --git a/doc/vimagit.txt b/doc/vimagit.txt index e88224e..66bfaa9 100644 --- a/doc/vimagit.txt +++ b/doc/vimagit.txt @@ -265,9 +265,9 @@ let g:magit_show_help=[01] When this variable is set to 0, all diff files are hidden by default. When this variable is set to 1, all diff for modified files are shown by default. When this variable is set to 2, all diff for all files are shown by default. -Default value is 0. +Default value is 1. NB: for repository with large number of differences, display may be slow. -let g:magit_default_show_all_files=[01] +let g:magit_default_show_all_files=[012] *vimagit-g:magit_default_fold_level* Default foldlevel for magit buffer. diff --git a/plugin/magit.vim b/plugin/magit.vim index db4b20a..b4b8f48 100644 --- a/plugin/magit.vim +++ b/plugin/magit.vim @@ -45,7 +45,7 @@ let g:magit_folding_close_mapping = get(g:, 'magit_folding_close_mapping', " user options let g:magit_enabled = get(g:, 'magit_enabled', 1) let g:magit_show_help = get(g:, 'magit_show_help', 1) -let g:magit_default_show_all_files = get(g:, 'magit_default_show_all_files', 0) +let g:magit_default_show_all_files = get(g:, 'magit_default_show_all_files', 1) let g:magit_default_fold_level = get(g:, 'magit_default_fold_level', 1) let g:magit_default_sections = get(g:, 'magit_default_sections', ['info', 'global_help', 'commit', 'staged', 'unstaged']) From 99cd0012b10a40fb22b7b4e29d11a70b1296536f Mon Sep 17 00:00:00 2001 From: Jerome Reybert Date: Tue, 10 Nov 2015 14:06:53 +0100 Subject: [PATCH 09/13] autoload/magit/state.vim: get submodule changes with git submodule summary instead of git diff --- autoload/magit/git.vim | 20 ++++++++++++++++++++ autoload/magit/state.vim | 4 ++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/autoload/magit/git.vim b/autoload/magit/git.vim index 6ec578e..0f54775 100644 --- a/autoload/magit/git.vim +++ b/autoload/magit/git.vim @@ -75,6 +75,26 @@ function! magit#git#git_diff(filename, status, mode) endif return diff_list endfunction + +" magit#git#git_sub_summary: helper function to get diff of a submodule +" nota: when git fail (due to misformated patch for example), an error +" message is raised. +" param[in] filemane: it must be quoted if it contains spaces +" param[in] mode: can be staged or unstaged +function! magit#git#git_sub_summary(filename, mode) + let staged_flag = ( a:mode == 'staged' ) ? " --cached " : " --files " + let git_cmd="git submodule summary " . staged_flag . " HEAD " + \ .a:filename + silent let diff_list=magit#utils#systemlist(git_cmd) + if ( empty(diff_list) ) + echohl WarningMsg + echom "diff command \"" . diff_cmd . "\" returned nothing" + echohl None + throw 'diff error' + endif + return diff_list +endfunction + " magit#git#git_add: helper function to add a whole file " nota: when git fail (due to misformated patch for example), an error " message is raised. diff --git a/autoload/magit/state.vim b/autoload/magit/state.vim index 65bc021..b65276a 100644 --- a/autoload/magit/state.vim +++ b/autoload/magit/state.vim @@ -164,8 +164,8 @@ function! magit#state#add_file(mode, status, filename, depth) dict if ( !file.is_visible() ) return endif - let diff_list=magit#git#git_diff(magit#utils#add_quotes(a:filename), - \ a:status, a:mode) + let diff_list=magit#git#git_sub_summary(magit#utils#add_quotes(a:filename), + \ a:mode) let file.diff.hunks[0].header = '' let file.diff.hunks[0].lines = diff_list let self.nb_diff_lines += len(diff_list) From 2e5a561bce263fee8f1703c5eb821703f8500a2a Mon Sep 17 00:00:00 2001 From: Jerome Reybert Date: Tue, 10 Nov 2015 14:08:06 +0100 Subject: [PATCH 10/13] autoload/magit/state.vim: rework g:magit_warning_max_lines (at least it does something useful now) --- autoload/magit/state.vim | 40 ++++++++++++++++++++++++++++++++++++---- plugin/magit.vim | 12 +----------- 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/autoload/magit/state.vim b/autoload/magit/state.vim index b65276a..1be452b 100644 --- a/autoload/magit/state.vim +++ b/autoload/magit/state.vim @@ -75,6 +75,7 @@ let s:hunk_template = { " s:diff_template: template for diff object (nested in s:file_template) " WARNING: this variable must be deepcopy()'ied let s:diff_template = { +\ 'len': 0, \ 'header': [], \ 'hunks': [s:hunk_template], \} @@ -139,6 +140,23 @@ function! magit#state#file_get_filename_header() dict endif endfunction +function! magit#state#check_max_lines(file) dict + let total_lines = self.nb_diff_lines + a:file.diff.len + if ( total_lines > g:magit_warning_max_lines && b:magit_warning_max_lines_answered == 0 ) + echohl WarningMsg + let ret = input("There are " . total_lines . " diff lines to display. Do you want to display all diffs? y(es) / N(o) : ", "") + echohl None + let b:magit_warning_max_lines_answered = 1 + if ( ret !~? '^y\%(e\%(s\)\?\)\?$' ) + call a:file.set_visible(0) + let a:file.diff.len = 0 + let b:magit_default_show_all_files = 0 + return 1 + endif + endif + return 0 +endfunction + " magit#state#add_file: method to add a file with all its " properties (filename, exists, status, header and hunks) " param[in] mode: can be staged or unstaged @@ -166,9 +184,15 @@ function! magit#state#add_file(mode, status, filename, depth) dict endif let diff_list=magit#git#git_sub_summary(magit#utils#add_quotes(a:filename), \ a:mode) + let file.diff.len = len(diff_list) + + if ( self.check_max_lines(file) != 0 ) + return + endif + let file.diff.hunks[0].header = '' let file.diff.hunks[0].lines = diff_list - let self.nb_diff_lines += len(diff_list) + let self.nb_diff_lines += file.diff.len elseif ( a:status == '?' && isdirectory(a:filename) == 1 ) let file.status = 'N' let file.dir = 1 @@ -193,12 +217,18 @@ function! magit#state#add_file(mode, status, filename, depth) dict " match( let diff_list=magit#git#git_diff(magit#utils#add_quotes(a:filename), \ a:status, a:mode) - while ( line < len(diff_list) && diff_list[line] !~ "^@.*" ) + let file.diff.len = len(diff_list) + + if ( self.check_max_lines(file) != 0 ) + return + endif + + while ( line < file.diff.len && diff_list[line] !~ "^@.*" ) call add(file.diff.header, diff_list[line]) let line += 1 endwhile - if ( line < len(diff_list) ) + if ( line < file.diff.len ) let hunk = file.diff.hunks[0] let hunk.header = diff_list[line] @@ -212,8 +242,9 @@ function! magit#state#add_file(mode, status, filename, depth) dict call add(hunk.lines, diff_line) endfor endif - let self.nb_diff_lines += len(diff_list) + let self.nb_diff_lines += file.diff.len endif + endfunction " magit#state#update: update self.dict @@ -301,6 +332,7 @@ let magit#state#state = { \ 'get_files': function("magit#state#get_files"), \ 'add_file': function("magit#state#add_file"), \ 'set_files_visible': function("magit#state#set_files_visible"), + \ 'check_max_lines': function("magit#state#check_max_lines"), \ 'update': function("magit#state#update"), \ 'dict': { 'staged': {}, 'unstaged': {}}, \ } diff --git a/plugin/magit.vim b/plugin/magit.vim index b4b8f48..3a28cd7 100644 --- a/plugin/magit.vim +++ b/plugin/magit.vim @@ -542,16 +542,6 @@ function! magit#update_buffer() call s:state.update() - if ( s:state.nb_diff_lines > g:magit_warning_max_lines && b:magit_warning_answered_yes == 0 ) - let ret = input("There are " . s:state.nb_diff_lines . " diff lines to display. Do you want to display all diffs? y(es) / N(o) : ", "") - if ( ret !~? '^y\%(e\%(s\)\?\)\?$' ) - let b:magit_default_show_all_files = 0 - call s:state.set_files_visible(0) - else - let b:magit_warning_answered_yes = 1 - endif - endif - for section in g:magit_default_sections try let func = s:mg_display_functions[section] @@ -605,7 +595,7 @@ function! magit#show_magit(display, ...) let b:magit_default_show_all_files = g:magit_default_show_all_files let b:magit_default_fold_level = g:magit_default_fold_level - let b:magit_warning_answered_yes = 0 + let b:magit_warning_max_lines_answered = 0 if ( a:0 > 0 ) let b:magit_default_show_all_files = a:1 From 4068d9d4657e32ec1f5adac1be4e9501a71dcb4b Mon Sep 17 00:00:00 2001 From: Jerome Reybert Date: Tue, 10 Nov 2015 19:18:38 +0100 Subject: [PATCH 11/13] plugin/magit.vim: correctly set bufhidden option (fix #35) --- plugin/magit.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/magit.vim b/plugin/magit.vim index 3a28cd7..60dc9c1 100644 --- a/plugin/magit.vim +++ b/plugin/magit.vim @@ -610,7 +610,7 @@ function! magit#show_magit(display, ...) silent! execute "file " . g:magit_buffer_name setlocal buftype=nofile - setlocal bufhidden=delete + setlocal bufhidden=hide setlocal noswapfile setlocal foldmethod=syntax let &l:foldlevel = b:magit_default_fold_level From cb49cfc1ede507d46c26181d9c73e56d56c1564d Mon Sep 17 00:00:00 2001 From: Jerome Reybert Date: Tue, 10 Nov 2015 23:09:23 +0100 Subject: [PATCH 12/13] README.md: update more to come section --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3abb088..0d80e04 100644 --- a/README.md +++ b/README.md @@ -26,8 +26,13 @@ Take a look at [TL;DR](#tldr) to start using it immediatly. * [ ] 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: -* Vizualize and checkout branches. +* Make vimagit more efficient for huge repositories, with a lot of diffs. +* Add a push function, taking care if needed about the remote repository and branch. +* Handle commit fixup! and squash!, with a smart git log popup. +* Handle multiple git repositories within one vim session. +* Stage multiple hunks or file by visually selecting them. * Go through history, cherry-pick changes. +* Vizualize and checkout branches. * Something is missing? Open an [issue](https://github.com/jreybert/vimagit/issues/new)! > Why should I use vimagit, there are already plethora git plugins for vim? From e20670f63fe717ba0498ed932c054927f5871faa Mon Sep 17 00:00:00 2001 From: Jerome Reybert Date: Tue, 10 Nov 2015 23:22:16 +0100 Subject: [PATCH 13/13] doc: add a section about visual selection (fix #33) --- README.md | 12 ++++++++++++ doc/vimagit.txt | 13 +++++++++++++ 2 files changed, 25 insertions(+) diff --git a/README.md b/README.md index 0d80e04..0ed444e 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,18 @@ There are 5 sections: * only lines starting with a + sign can be modified * no line can be deleted +### Visual selection + +It is possible to stage part of hunk, by different ways: +* By visually selecting some lines, then staging the selection with **S**. +* By marking some lines "to be staged" with **M**, then staging these selected lines with **S**. +* Staging individual lines with **L**. + +Visual selection and marked lines have some limitations for the moment: +* It only work for "staging", not for "unstaging". +* Selection/marks must be within a single hunk. +* Marks not within the hunk currently staged are lost during stage process magit buffer refresh. + ### Commands #### magit#show_magit() diff --git a/doc/vimagit.txt b/doc/vimagit.txt index 66bfaa9..2ee997b 100644 --- a/doc/vimagit.txt +++ b/doc/vimagit.txt @@ -109,6 +109,19 @@ INLINE MODIFICATIONS *vimagit-inline-modification* * only lines starting with a + sign can be modified * no line can be deleted +VISUAL SELECTION *vimagit-visual-selection* + +It is possible to stage part of hunk, by different ways: +* By visually selecting some lines, then staging the selection with S. +* By marking some lines "to be staged" with M, then staging these selected + lines with S. +* Staging individual lines with L. + +Visual selection and marked lines have some limitations for the moment: +* It only work for "staging", not for "unstaging". +* Selection/marks must be within a single hunk. +* Marks not within the hunk currently staged are lost during stage process magit + buffer refresh. COMMANDS *vimagit-commands*