diff --git a/README.md b/README.md index 325fa77b0995a428235a30ca3d9d487439c79835..ca544dd4097159bf0e53850dcf0e0c98ff84485c 100644 --- a/README.md +++ b/README.md @@ -122,9 +122,52 @@ There are 5 sections: * Stash list: this section contains all stahes. ### Inline modifications -* It is possible to modify the content to be staged or unstaged in magit buffer, with some limitations: +* It is possible to modify the content of a hunk to be staged or unstaged, with some limitations: * only lines starting with a + sign can be modified - * no line can be deleted + * no lines can be deleted + +Let's imagine we have the following hunk: +```diff +-int main() { +- printf("Hello world\n"); +- return 0; ++int main(int argc, const char *argv[]) { ++ int ret = printf("Hello world: %s\n", argv[0]); ++ return (ret > 0); +``` +Ideally, we would like two commits here: one adding the argv parameter, and one checking the printf return value. + +One way to do so is to edit the file, deleting the return value code, stage, commit the argv feature; then, go back to source file, undo previous deletion, stage, and commit the return value feature. + +Another way is to edit the hunk from the magit buffer! + +Enter in edition mode with the mapping <kbd>E</kbd>, and start to edit the +hunk, to remove the return value feature. After edition, you should have this +result: +```diff +-int main() { +- printf("Hello world\n"); +- return 0; ++int main(int argc, const char *argv[]) { ++ printf("Hello world: %s\n", argv[0]); ++ return 0; +``` +Stage the hunk, as is. Now you can see that you have the argv feature in staged section: +```diff +-int main() { +- printf("Hello world\n"); ++int main(int argc, const char *argv[]) { ++ printf("Hello world: %s\n", argv[0]); +``` +And that you have the return value feature in unstaged section: +```diff +- printf("Hello world: %s\n", argv[0]); +- return 0; ++ int ret = printf("Hello world: %s\n", argv[0]); ++ return (ret > 0); +``` + +VoilĂ , you just did your first partial line staging! ### Visual selection @@ -291,6 +334,13 @@ Some mappings are set for the whole magit buffer, others are set for specific se * Add the file under the cursor in .gitgnore +<kbd>E</kbd> + +* Set the magit buffer in edit mode, allowing to edit a hunk before staging it. +* Edit mode is left after stage/unstage command, or a refresh command. + +See [inline modifications](inline_modifications) to learn how to use this feature. + ----------------------------------- <kbd>J</kbd>, <kbd>Ctrl</kbd>+<kbd>]</kbd> diff --git a/autoload/magit/mapping.vim b/autoload/magit/mapping.vim index 58d5f81575702a661f8941207249cbb3ec55695f..7c49a45cee80359763414e882aa546606d8f601d 100644 --- a/autoload/magit/mapping.vim +++ b/autoload/magit/mapping.vim @@ -8,6 +8,7 @@ let g:magit_commit_amend_mapping = get(g:, 'magit_commit_amend_mapping', let g:magit_commit_fixup_mapping = get(g:, 'magit_commit_fixup_mapping', 'CF' ) let g:magit_close_commit_mapping = get(g:, 'magit_close_commit_mapping', 'CU' ) let g:magit_reload_mapping = get(g:, 'magit_reload_mapping', 'R' ) +let g:magit_edit_hunk_mapping = get(g:, 'magit_edit_hunk_mapping', 'E' ) let g:magit_edit_mapping = get(g:, 'magit_edit_mapping', 'J' ) let g:magit_jump_next_hunk = get(g:, 'magit_jump_next_hunk', '<C-N>') @@ -127,6 +128,9 @@ function! magit#mapping#set_default() call s:mg_set_mapping('n', g:magit_ignore_mapping, \ "magit#ignore_file()", '\<\%(un\)\?staged\>') + call s:mg_set_mapping('n', g:magit_edit_hunk_mapping, + \ "magit#edit_hunk()", '\<\%(un\)\?staged\>') + call s:mg_set_mapping('n', g:magit_edit_mapping, \ "magit#jump_to()", '\<\%(un\)\?staged\>') call s:mg_set_mapping('n', '<C-]>', diff --git a/doc/vimagit.txt b/doc/vimagit.txt index 5fddcb242e2cb133ee5b81baeabeb36c47bdaa08..1f4b0317ff3c33918f1ae159b1c5043ef7dc9394 100644 --- a/doc/vimagit.txt +++ b/doc/vimagit.txt @@ -117,10 +117,56 @@ There are 5 sections: INLINE MODIFICATIONS *vimagit-inline-modification* -* It is possible to modify the content to be staged or unstaged in magit - buffer, with some limitations: +* It is possible to modify the content of a hunk to be staged or unstaged, + with some limitations: * only lines starting with a + sign can be modified - * no line can be deleted + * no lines can be deleted + +Let's imagine we have the following hunk: > + -int main() { + - printf("Hello world\n"); + - return 0; + +int main(int argc, const char *argv[]) { + + int ret = printf("Hello world: %s\n", argv[0]); + + return (ret > 0); +< + +Ideally, we would like two commits here: one adding the argv parameter, and +one checking the printf return value. + +One way to do so is to edit the file, deleting the return value code, stage, +commit the argv feature; then, go back to source file, undo previous deletion, +stage, and commit the return value feature. + +Another way is to edit the hunk from the magit buffer! + +Enter in edition mode with the mapping <kbd>E</kbd>, and start to edit the +hunk, to remove the return value feature. After edition, you should have this +result: > + -int main() { + - printf("Hello world\n"); + - return 0; + +int main(int argc, const char *argv[]) { + + printf("Hello world: %s\n", argv[0]); + + return 0; +< + +Stage the hunk, as is. Now you can see that you have the argv feature in +staged section: > + -int main() { + - printf("Hello world\n"); + +int main(int argc, const char *argv[]) { + + printf("Hello world: %s\n", argv[0]); +< + +And that you have the return value feature in unstaged section: > + - printf("Hello world: %s\n", argv[0]); + - return 0; + + int ret = printf("Hello world: %s\n", argv[0]); + + return (ret > 0); +< + +VoilĂ , you just did your first partial line staging! VISUAL SELECTION *vimagit-visual-selection* @@ -325,6 +371,13 @@ section only. <I> Add the file under the cursor in .gitgnore + *vimagit-E* *magit#edit_hunk* + <E> Set the magit buffer in edit mode, allowing to edit a hunk before + staging it. + Edit mode is left after stage/unstage command, or a refresh + command. + See |vimagit-inline-modification| to learn how to use this + feature. *vimagit-J* *magit#jump_to()* *vimagit-<C-]>* diff --git a/plugin/magit.vim b/plugin/magit.vim index 4874876d58c445bf5f8903d9576ac7f0fdabb5d7..68363f602f188cefdbdeb81ebe448befa1ad2086 100644 --- a/plugin/magit.vim +++ b/plugin/magit.vim @@ -30,6 +30,7 @@ let g:magit_auto_close = get(g:, 'magit_auto_close', let g:magit_auto_foldopen = get(g:, 'magit_auto_foldopen', 1) let g:magit_default_sections = get(g:, 'magit_default_sections', ['info', 'global_help', 'commit', 'staged', 'unstaged']) let g:magit_discard_untracked_do_delete = get(g:, 'magit_discard_untracked_do_delete', 0) +let g:magit_default_editable = get(g:, 'magit_default_editable', 0) let g:magit_refresh_gutter = get(g:, 'magit_refresh_gutter' , 1) " Should deprecate the following @@ -571,18 +572,6 @@ function! magit#update_buffer(...) else call s:set_mode_read() endif - " FIXME: find a way to save folding state. According to help, this won't - " help: - " > This does not save fold information. - " Playing with foldenable around does not help. - " mkview does not help either. - let l:winview = winsaveview() - - " remove all signs (needed as long as we wipe buffer) - call magit#sign#remove_all() - - " delete buffer - silent! execute "silent :%delete _" " be smart for the cursor position after refresh, if stage/unstaged " occured @@ -604,6 +593,21 @@ function! magit#update_buffer(...) return endif + setlocal modifiable + + " FIXME: find a way to save folding state. According to help, this won't + " help: + " > This does not save fold information. + " Playing with foldenable around does not help. + " mkview does not help either. + let l:winview = winsaveview() + + " remove all signs (needed as long as we wipe buffer) + call magit#sign#remove_all() + + " delete buffer + silent! execute "silent :%delete _" + for section in g:magit_default_sections try let func = s:mg_display_functions[section] @@ -620,6 +624,12 @@ function! magit#update_buffer(...) call magit#utils#clear_undo() + if ( b:magit_editable ) + setlocal modifiable + else + setlocal nomodifiable + endif + setlocal filetype=magit if ( b:magit_current_commit_mode != '' && b:magit_commit_newly_open == 1 ) @@ -767,6 +777,8 @@ function! magit#show_magit(display, ...) let b:magit_default_fold_level = a:2 endif + let b:magit_editable = g:magit_default_editable + setlocal buftype=nofile setlocal bufhidden=hide setlocal noswapfile @@ -1091,6 +1103,15 @@ function! magit#mark_vselect() range return <SID>mg_mark_lines_in_hunk(a:firstline, a:lastline) endfunction + +function! magit#edit_hunk() + let b:magit_editable = 1 + setlocal modifiable + if exists(':AirlineRefresh') + execute "AirlineRefresh" + endif +endfunction + " magit#ignore_file: this function add the file under cursor to .gitignore " FIXME: git diff adds some strange characters to end of line function! magit#ignore_file() abort @@ -1130,6 +1151,7 @@ function! magit#commit_command(mode) " when we do commit, it is prefered ot commit the way we prepared it " (.i.e normal or amend), whatever we commit with CC or CA. call <SID>mg_git_commit(b:magit_current_commit_mode) + let b:magit_editable = 0 if exists('#User#VimagitLeaveCommit') doautocmd User VimagitLeaveCommit endif @@ -1137,6 +1159,7 @@ function! magit#commit_command(mode) let b:magit_current_commit_mode=a:mode let b:magit_commit_newly_open=1 call s:set_mode_write() + let b:magit_editable = 1 setlocal nomodified endif endif @@ -1263,7 +1286,9 @@ function! magit#show_version() endfunction function! magit#get_current_mode() - if ( b:magit_current_commit_mode == '' ) + if ( b:magit_editable ) + return "STAGING-EDIT" + elseif ( b:magit_current_commit_mode == '' ) return "STAGING" elseif ( b:magit_current_commit_mode == 'CC' ) return "COMMIT" diff --git a/test/addHunk.vader b/test/addHunk.vader index 549df8d37dad5c946f571326d293970529005871..41c4a3655a64ee3adf99a1ab49b5a7187d42d596 100644 --- a/test/addHunk.vader +++ b/test/addHunk.vader @@ -56,6 +56,7 @@ Execute (Stage untracked file with magit#stage_hunk modified hunk): call Search_file('unstaged') call magit#open_close_folding(1) /^+ + call magit#edit_hunk() call setline(line('.'), substitute(getline('.'), '^\(+.*\) .\{-\}$', '\1 vimatest', '')) call Cursor_position() call magit#stage_hunk(0)