mirror of
https://github.com/marcusDenslow/FERRUM.git
synced 2026-10-25 14:38:50 +01:00
added full git stash features
added dropping appluing and shit
This commit is contained in:
@@ -386,3 +386,48 @@ int get_git_stashes(char stashes[][512], int max_stashes) {
|
||||
pclose(fp);
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a git stash by index (keeps stash in list)
|
||||
*/
|
||||
int apply_git_stash(int stash_index) {
|
||||
if (stash_index < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
char cmd[128];
|
||||
snprintf(cmd, sizeof(cmd), "git stash apply stash@{%d} 2>/dev/null >/dev/null", stash_index);
|
||||
|
||||
int result = system(cmd);
|
||||
return (result == 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pop a git stash by index (applies and removes stash from list)
|
||||
*/
|
||||
int pop_git_stash(int stash_index) {
|
||||
if (stash_index < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
char cmd[128];
|
||||
snprintf(cmd, sizeof(cmd), "git stash pop stash@{%d} 2>/dev/null >/dev/null", stash_index);
|
||||
|
||||
int result = system(cmd);
|
||||
return (result == 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop a git stash by index (removes stash without applying)
|
||||
*/
|
||||
int drop_git_stash(int stash_index) {
|
||||
if (stash_index < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
char cmd[128];
|
||||
snprintf(cmd, sizeof(cmd), "git stash drop stash@{%d} 2>/dev/null >/dev/null", stash_index);
|
||||
|
||||
int result = system(cmd);
|
||||
return (result == 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
@@ -62,4 +62,28 @@ int create_git_stash_with_name(const char *stash_name);
|
||||
|
||||
int get_git_stashes(char stashed[][512], int max_stashes);
|
||||
|
||||
/**
|
||||
* Apply a git stash by index (keeps stash in list)
|
||||
*
|
||||
* @param stash_index Index of stash to apply (0 = most recent)
|
||||
* @return 1 if stash was applied successfully, 0 otherwise
|
||||
*/
|
||||
int apply_git_stash(int stash_index);
|
||||
|
||||
/**
|
||||
* Pop a git stash by index (applies and removes stash from list)
|
||||
*
|
||||
* @param stash_index Index of stash to pop (0 = most recent)
|
||||
* @return 1 if stash was popped successfully, 0 otherwise
|
||||
*/
|
||||
int pop_git_stash(int stash_index);
|
||||
|
||||
/**
|
||||
* Drop a git stash by index (removes stash without applying)
|
||||
*
|
||||
* @param stash_index Index of stash to drop (0 = most recent)
|
||||
* @return 1 if stash was dropped successfully, 0 otherwise
|
||||
*/
|
||||
int drop_git_stash(int stash_index);
|
||||
|
||||
#endif // GIT_INTEGRATION_H
|
||||
|
||||
Binary file not shown.
@@ -23,6 +23,7 @@ int init_ncurses_diff_viewer(NCursesDiffViewer *viewer) {
|
||||
memset(viewer, 0, sizeof(NCursesDiffViewer));
|
||||
viewer->selected_file = 0;
|
||||
viewer->file_scroll_offset = 0;
|
||||
viewer->selected_stash = 0;
|
||||
viewer->current_mode = NCURSES_MODE_FILE_LIST;
|
||||
viewer->sync_status = SYNC_STATUS_IDLE;
|
||||
viewer->spinner_frame = 0;
|
||||
@@ -1589,6 +1590,8 @@ void render_status_bar(NCursesDiffViewer *viewer) {
|
||||
strcpy(keybindings, "Stage: <space> | Stage All: a | Stash: s | Commit: c");
|
||||
} else if (viewer->current_mode == NCURSES_MODE_COMMIT_LIST) {
|
||||
strcpy(keybindings, "Push: P | Pull: p | Reset: r/R | Amend: a | Nav: j/k");
|
||||
} else if (viewer->current_mode == NCURSES_MODE_STASH_LIST) {
|
||||
strcpy(keybindings, "Apply: <space> | Pop: g | Drop: d | Nav: j/k");
|
||||
} else if (viewer->current_mode == NCURSES_MODE_FILE_VIEW) {
|
||||
strcpy(keybindings, "Scroll: j/k | Page: Ctrl+U/D | Back: Esc");
|
||||
}
|
||||
@@ -1987,6 +1990,9 @@ int handle_ncurses_diff_input(NCursesDiffViewer *viewer, int key) {
|
||||
case '3':
|
||||
viewer->current_mode = NCURSES_MODE_COMMIT_LIST;
|
||||
break;
|
||||
case '4':
|
||||
viewer->current_mode = NCURSES_MODE_STASH_LIST;
|
||||
break;
|
||||
}
|
||||
|
||||
if (viewer->current_mode == NCURSES_MODE_FILE_LIST) {
|
||||
@@ -2181,6 +2187,98 @@ int handle_ncurses_diff_input(NCursesDiffViewer *viewer, int key) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else if (viewer->current_mode == NCURSES_MODE_STASH_LIST) {
|
||||
// Stash list mode navigation
|
||||
switch (key) {
|
||||
case 27: // ESC
|
||||
case '\t': // Tab - return to file list mode
|
||||
viewer->current_mode = NCURSES_MODE_FILE_LIST;
|
||||
break;
|
||||
|
||||
case KEY_UP:
|
||||
case 'k':
|
||||
if (viewer->selected_stash > 0) {
|
||||
viewer->selected_stash--;
|
||||
}
|
||||
break;
|
||||
|
||||
case KEY_DOWN:
|
||||
case 'j':
|
||||
if (viewer->selected_stash < viewer->stash_count - 1) {
|
||||
viewer->selected_stash++;
|
||||
}
|
||||
break;
|
||||
|
||||
case ' ': // Space - Apply stash (keeps stash in list)
|
||||
if (viewer->stash_count > 0 && viewer->selected_stash < viewer->stash_count) {
|
||||
if (apply_git_stash(viewer->selected_stash)) {
|
||||
// Refresh everything after applying stash
|
||||
get_ncurses_changed_files(viewer);
|
||||
get_commit_history(viewer);
|
||||
|
||||
// Reset file selection if no files remain
|
||||
if (viewer->file_count == 0) {
|
||||
viewer->selected_file = 0;
|
||||
viewer->file_line_count = 0;
|
||||
viewer->file_scroll_offset = 0;
|
||||
} else if (viewer->selected_file >= viewer->file_count) {
|
||||
viewer->selected_file = viewer->file_count - 1;
|
||||
}
|
||||
|
||||
// Reload current file if any files exist
|
||||
if (viewer->file_count > 0 && viewer->selected_file < viewer->file_count) {
|
||||
load_full_file_with_diff(viewer, viewer->files[viewer->selected_file].filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
case 'G': // Pop stash (applies and removes from list)
|
||||
if (viewer->stash_count > 0 && viewer->selected_stash < viewer->stash_count) {
|
||||
if (pop_git_stash(viewer->selected_stash)) {
|
||||
// Refresh everything after popping stash
|
||||
get_ncurses_changed_files(viewer);
|
||||
get_ncurses_git_stashes(viewer);
|
||||
get_commit_history(viewer);
|
||||
|
||||
// Adjust selected stash if needed
|
||||
if (viewer->selected_stash >= viewer->stash_count && viewer->stash_count > 0) {
|
||||
viewer->selected_stash = viewer->stash_count - 1;
|
||||
}
|
||||
|
||||
// Reset file selection if no files remain
|
||||
if (viewer->file_count == 0) {
|
||||
viewer->selected_file = 0;
|
||||
viewer->file_line_count = 0;
|
||||
viewer->file_scroll_offset = 0;
|
||||
} else if (viewer->selected_file >= viewer->file_count) {
|
||||
viewer->selected_file = viewer->file_count - 1;
|
||||
}
|
||||
|
||||
// Reload current file if any files exist
|
||||
if (viewer->file_count > 0 && viewer->selected_file < viewer->file_count) {
|
||||
load_full_file_with_diff(viewer, viewer->files[viewer->selected_file].filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
case 'D': // Drop stash (removes without applying)
|
||||
if (viewer->stash_count > 0 && viewer->selected_stash < viewer->stash_count) {
|
||||
if (drop_git_stash(viewer->selected_stash)) {
|
||||
// Refresh stash list after dropping
|
||||
get_ncurses_git_stashes(viewer);
|
||||
|
||||
// Adjust selected stash if needed
|
||||
if (viewer->selected_stash >= viewer->stash_count && viewer->stash_count > 0) {
|
||||
viewer->selected_stash = viewer->stash_count - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 1; // Continue
|
||||
@@ -2216,15 +2314,15 @@ int run_ncurses_diff_viewer(void) {
|
||||
attron(COLOR_PAIR(3));
|
||||
if (viewer.current_mode == NCURSES_MODE_FILE_LIST) {
|
||||
mvprintw(0, 0,
|
||||
"Git Diff Viewer: 1=files 2=view 3=commits | j/k=nav Space=mark "
|
||||
"Git Diff Viewer: 1=files 2=view 3=commits 4=stashes | j/k=nav Space=mark "
|
||||
"A=all S=stash C=commit P=push | q=quit");
|
||||
} else if (viewer.current_mode == NCURSES_MODE_FILE_VIEW) {
|
||||
mvprintw(0, 0,
|
||||
"Git Diff Viewer: 1=files 2=view 3=commits | j/k=scroll "
|
||||
"Git Diff Viewer: 1=files 2=view 3=commits 4=stashes | j/k=scroll "
|
||||
"Ctrl+U/D=30lines | q=quit");
|
||||
} else {
|
||||
mvprintw(0, 0,
|
||||
"Git Diff Viewer: 1=files 2=view 3=commits | j/k=nav P=push "
|
||||
"Git Diff Viewer: 1=files 2=view 3=commits 4=stashes | j/k=nav P=push "
|
||||
"p=pull r/R=reset a=amend | q=quit");
|
||||
}
|
||||
attroff(COLOR_PAIR(3));
|
||||
@@ -2250,15 +2348,15 @@ int run_ncurses_diff_viewer(void) {
|
||||
attron(COLOR_PAIR(3));
|
||||
if (viewer.current_mode == NCURSES_MODE_FILE_LIST) {
|
||||
mvprintw(0, 0,
|
||||
"Git Diff Viewer: 1=files 2=view 3=commits | j/k=nav "
|
||||
"Git Diff Viewer: 1=files 2=view 3=commits 4=stashes | j/k=nav "
|
||||
"Space=mark A=all S=stash C=commit P=push | q=quit");
|
||||
} else if (viewer.current_mode == NCURSES_MODE_FILE_VIEW) {
|
||||
mvprintw(0, 0,
|
||||
"Git Diff Viewer: 1=files 2=view 3=commits | j/k=scroll "
|
||||
"Git Diff Viewer: 1=files 2=view 3=commits 4=stashes | j/k=scroll "
|
||||
"Ctrl+U/D=30lines | q=quit");
|
||||
} else {
|
||||
mvprintw(0, 0,
|
||||
"Git Diff Viewer: 1=files 2=view 3=commits | j/k=nav P=push "
|
||||
"Git Diff Viewer: 1=files 2=view 3=commits 4=stashes | j/k=nav P=push "
|
||||
"p=pull r/R=reset a=amend | q=quit");
|
||||
}
|
||||
attroff(COLOR_PAIR(3));
|
||||
@@ -2525,6 +2623,16 @@ void render_stash_list_window(NCursesDiffViewer *viewer) {
|
||||
for (int i = 0; i < max_stashes_visible && i < viewer->stash_count; i++) {
|
||||
int y = i + 1;
|
||||
|
||||
// Show selection indicator for stash list mode
|
||||
if (i == viewer->selected_stash &&
|
||||
viewer->current_mode == NCURSES_MODE_STASH_LIST) {
|
||||
wattron(viewer->stash_list_win, COLOR_PAIR(5));
|
||||
mvwprintw(viewer->stash_list_win, y, 1, ">");
|
||||
wattroff(viewer->stash_list_win, COLOR_PAIR(5));
|
||||
} else {
|
||||
mvwprintw(viewer->stash_list_win, y, 1, " ");
|
||||
}
|
||||
|
||||
// Show stash info (truncated to fit panel)
|
||||
int max_stash_len = viewer->file_panel_width - 4;
|
||||
char truncated_stash[256];
|
||||
|
||||
@@ -43,7 +43,8 @@ typedef struct {
|
||||
typedef enum {
|
||||
NCURSES_MODE_FILE_LIST,
|
||||
NCURSES_MODE_FILE_VIEW,
|
||||
NCURSES_MODE_COMMIT_LIST
|
||||
NCURSES_MODE_COMMIT_LIST,
|
||||
NCURSES_MODE_STASH_LIST
|
||||
} NCursesViewMode;
|
||||
|
||||
typedef enum {
|
||||
@@ -80,6 +81,7 @@ typedef struct {
|
||||
int selected_commit;
|
||||
NCursesStash stashes[MAX_STASHES];
|
||||
int stash_count;
|
||||
int selected_stash;
|
||||
WINDOW *file_list_win;
|
||||
WINDOW *file_content_win;
|
||||
WINDOW *commit_list_win;
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user