adding grep to branches commits and stashes
This commit is contained in:
BIN
builtins.o
BIN
builtins.o
Binary file not shown.
@@ -45,8 +45,9 @@ void handle_terminal_resize(NCursesDiffViewer *viewer) {
|
||||
if (viewer->status_bar_win)
|
||||
delwin(viewer->status_bar_win);
|
||||
|
||||
// Clean up fuzzy search windows during resize
|
||||
// Clean up search windows during resize
|
||||
cleanup_fuzzy_search(viewer);
|
||||
cleanup_grep_search(viewer);
|
||||
|
||||
// Reinitialize ncurses with new terminal size
|
||||
endwin();
|
||||
@@ -107,6 +108,9 @@ int init_ncurses_diff_viewer(NCursesDiffViewer *viewer) {
|
||||
// Initialize fuzzy search
|
||||
init_fuzzy_search(viewer);
|
||||
|
||||
// Initialize grep search
|
||||
init_grep_search(viewer);
|
||||
|
||||
viewer->selected_file = 0;
|
||||
viewer->file_scroll_offset = 0;
|
||||
viewer->file_cursor_line = 0;
|
||||
@@ -3221,6 +3225,11 @@ int handle_ncurses_diff_input(NCursesDiffViewer *viewer, int key) {
|
||||
if (viewer->fuzzy_search_active) {
|
||||
return handle_fuzzy_search_input(viewer, key);
|
||||
}
|
||||
|
||||
// Handle grep search input if active
|
||||
if (viewer->grep_search_active) {
|
||||
return handle_grep_search_input(viewer, key);
|
||||
}
|
||||
|
||||
int max_lines_visible = viewer->terminal_height - 4;
|
||||
|
||||
@@ -3734,6 +3743,10 @@ int handle_ncurses_diff_input(NCursesDiffViewer *viewer, int key) {
|
||||
render_status_bar(viewer);
|
||||
}
|
||||
break;
|
||||
|
||||
case '/': // Forward slash - enter grep search mode
|
||||
enter_grep_search_mode(viewer);
|
||||
break;
|
||||
}
|
||||
} else if (viewer->current_mode == NCURSES_MODE_STASH_LIST) {
|
||||
// Stash list mode navigation
|
||||
@@ -3861,6 +3874,10 @@ int handle_ncurses_diff_input(NCursesDiffViewer *viewer, int key) {
|
||||
viewer->critical_operation_in_progress = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case '/': // Forward slash - enter grep search mode
|
||||
enter_grep_search_mode(viewer);
|
||||
break;
|
||||
}
|
||||
} else if (viewer->current_mode == NCURSES_MODE_BRANCH_LIST) {
|
||||
// Branch list mode navigation
|
||||
@@ -4184,6 +4201,10 @@ int handle_ncurses_diff_input(NCursesDiffViewer *viewer, int key) {
|
||||
viewer->critical_operation_in_progress = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case '/': // Forward slash - enter grep search mode
|
||||
enter_grep_search_mode(viewer);
|
||||
break;
|
||||
}
|
||||
} else if (viewer->current_mode == NCURSES_MODE_COMMIT_VIEW) {
|
||||
// Commit view mode navigation (same as file view)
|
||||
@@ -4483,6 +4504,7 @@ int run_ncurses_diff_viewer(void) {
|
||||
render_stash_list_window(&viewer);
|
||||
render_status_bar(&viewer);
|
||||
render_fuzzy_search(&viewer);
|
||||
render_grep_search(&viewer);
|
||||
|
||||
// Main display loop
|
||||
int running = 1;
|
||||
@@ -4528,8 +4550,8 @@ int run_ncurses_diff_viewer(void) {
|
||||
// Update preview based on current selection
|
||||
update_preview_for_current_selection(&viewer);
|
||||
|
||||
// Skip main window rendering if fuzzy search is active to prevent flickering
|
||||
if (!viewer.fuzzy_search_active) {
|
||||
// Skip main window rendering if fuzzy or grep search is active to prevent flickering
|
||||
if (!viewer.fuzzy_search_active && !viewer.grep_search_active) {
|
||||
render_file_list_window(&viewer);
|
||||
render_file_content_window(&viewer);
|
||||
render_commit_list_window(&viewer);
|
||||
@@ -4538,8 +4560,9 @@ int run_ncurses_diff_viewer(void) {
|
||||
render_status_bar(&viewer);
|
||||
}
|
||||
|
||||
// Always render fuzzy search (it handles its own visibility)
|
||||
// Always render search overlays (they handle their own visibility)
|
||||
render_fuzzy_search(&viewer);
|
||||
render_grep_search(&viewer);
|
||||
|
||||
// Keep cursor hidden
|
||||
curs_set(0);
|
||||
@@ -6638,6 +6661,9 @@ void cleanup_ncurses_diff_viewer(NCursesDiffViewer *viewer) {
|
||||
|
||||
// Clean up fuzzy search windows
|
||||
cleanup_fuzzy_search(viewer);
|
||||
|
||||
// Clean up grep search windows
|
||||
cleanup_grep_search(viewer);
|
||||
}
|
||||
endwin();
|
||||
}
|
||||
@@ -7082,3 +7108,494 @@ void select_fuzzy_file(NCursesDiffViewer *viewer) {
|
||||
viewer->current_file_path[sizeof(viewer->current_file_path) - 1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize grep search state
|
||||
*/
|
||||
void init_grep_search(NCursesDiffViewer *viewer) {
|
||||
if (!viewer) return;
|
||||
|
||||
viewer->grep_search_active = 0;
|
||||
viewer->grep_search_mode = NCURSES_MODE_FILE_LIST;
|
||||
viewer->grep_search_query[0] = '\0';
|
||||
viewer->grep_search_query_len = 0;
|
||||
viewer->grep_filtered_count = 0;
|
||||
viewer->grep_selected_index = 0;
|
||||
viewer->grep_scroll_offset = 0;
|
||||
viewer->grep_input_win = NULL;
|
||||
viewer->grep_list_win = NULL;
|
||||
|
||||
// Initialize state tracking
|
||||
viewer->grep_needs_full_redraw = 0;
|
||||
viewer->grep_needs_input_redraw = 0;
|
||||
viewer->grep_needs_list_redraw = 0;
|
||||
viewer->grep_last_query[0] = '\0';
|
||||
viewer->grep_last_selected = -1;
|
||||
viewer->grep_last_scroll = -1;
|
||||
viewer->grep_last_filtered_count = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup grep search windows
|
||||
*/
|
||||
void cleanup_grep_search(NCursesDiffViewer *viewer) {
|
||||
if (!viewer) return;
|
||||
|
||||
if (viewer->grep_input_win) {
|
||||
delwin(viewer->grep_input_win);
|
||||
viewer->grep_input_win = NULL;
|
||||
}
|
||||
if (viewer->grep_list_win) {
|
||||
delwin(viewer->grep_list_win);
|
||||
viewer->grep_list_win = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate grep match score for text content
|
||||
*/
|
||||
int calculate_grep_score(const char *pattern, const char *text) {
|
||||
if (!pattern || !text) return 0;
|
||||
if (strlen(pattern) == 0) return 1000; // Empty pattern matches everything
|
||||
|
||||
int pattern_len = strlen(pattern);
|
||||
int text_len = strlen(text);
|
||||
|
||||
if (pattern_len > text_len) return 0;
|
||||
|
||||
int score = 0;
|
||||
int pattern_pos = 0;
|
||||
int consecutive_matches = 0;
|
||||
int first_char_bonus = 0;
|
||||
|
||||
for (int i = 0; i < text_len && pattern_pos < pattern_len; i++) {
|
||||
char p_char = tolower(pattern[pattern_pos]);
|
||||
char t_char = tolower(text[i]);
|
||||
|
||||
if (p_char == t_char) {
|
||||
// Base score for character match
|
||||
score += 1;
|
||||
|
||||
// Bonus for consecutive matches
|
||||
consecutive_matches++;
|
||||
score += consecutive_matches * 3;
|
||||
|
||||
// Bonus for matching at word boundaries
|
||||
if (i == 0 || text[i-1] == ' ' || text[i-1] == '-' || text[i-1] == '_') {
|
||||
score += 10;
|
||||
}
|
||||
|
||||
// Bonus for matching first character
|
||||
if (pattern_pos == 0 && i == 0) {
|
||||
first_char_bonus = 30;
|
||||
}
|
||||
|
||||
// Bonus for exact position match
|
||||
if (i == pattern_pos) {
|
||||
score += 5;
|
||||
}
|
||||
|
||||
pattern_pos++;
|
||||
} else {
|
||||
consecutive_matches = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Must match all pattern characters
|
||||
if (pattern_pos < pattern_len) return 0;
|
||||
|
||||
score += first_char_bonus;
|
||||
score += (50 - text_len); // Prefer shorter text
|
||||
score += (30 - (text_len - pattern_len)); // Fewer unmatched chars
|
||||
|
||||
return score;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare function for sorting grep scored items
|
||||
*/
|
||||
int compare_grep_scored_items(const void *a, const void *b) {
|
||||
const struct {int item_index; int score;} *item_a = a;
|
||||
const struct {int item_index; int score;} *item_b = b;
|
||||
return item_b->score - item_a->score; // Descending order
|
||||
}
|
||||
|
||||
/**
|
||||
* Update grep search filter based on current query and mode
|
||||
*/
|
||||
void update_grep_filter(NCursesDiffViewer *viewer) {
|
||||
if (!viewer) return;
|
||||
|
||||
viewer->grep_filtered_count = 0;
|
||||
viewer->grep_selected_index = 0;
|
||||
viewer->grep_scroll_offset = 0;
|
||||
|
||||
// Search different data based on current mode
|
||||
switch (viewer->grep_search_mode) {
|
||||
case NCURSES_MODE_COMMIT_LIST:
|
||||
// Search commit titles
|
||||
for (int i = 0; i < viewer->commit_count && viewer->grep_filtered_count < MAX_COMMITS; i++) {
|
||||
int score = calculate_grep_score(viewer->grep_search_query, viewer->commits[i].title);
|
||||
if (score > 0) {
|
||||
viewer->grep_scored_items[viewer->grep_filtered_count].item_index = i;
|
||||
viewer->grep_scored_items[viewer->grep_filtered_count].score = score;
|
||||
viewer->grep_filtered_count++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case NCURSES_MODE_STASH_LIST:
|
||||
// Search stash info
|
||||
for (int i = 0; i < viewer->stash_count && viewer->grep_filtered_count < MAX_COMMITS; i++) {
|
||||
int score = calculate_grep_score(viewer->grep_search_query, viewer->stashes[i].stash_info);
|
||||
if (score > 0) {
|
||||
viewer->grep_scored_items[viewer->grep_filtered_count].item_index = i;
|
||||
viewer->grep_scored_items[viewer->grep_filtered_count].score = score;
|
||||
viewer->grep_filtered_count++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case NCURSES_MODE_BRANCH_LIST:
|
||||
// Search branch names
|
||||
for (int i = 0; i < viewer->branch_count && viewer->grep_filtered_count < MAX_COMMITS; i++) {
|
||||
int score = calculate_grep_score(viewer->grep_search_query, viewer->branches[i].name);
|
||||
if (score > 0) {
|
||||
viewer->grep_scored_items[viewer->grep_filtered_count].item_index = i;
|
||||
viewer->grep_scored_items[viewer->grep_filtered_count].score = score;
|
||||
viewer->grep_filtered_count++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// No grep search for other modes
|
||||
break;
|
||||
}
|
||||
|
||||
// Sort results by score
|
||||
if (viewer->grep_filtered_count > 1) {
|
||||
qsort(viewer->grep_scored_items, viewer->grep_filtered_count,
|
||||
sizeof(viewer->grep_scored_items[0]), compare_grep_scored_items);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enter grep search mode for current view mode
|
||||
*/
|
||||
void enter_grep_search_mode(NCursesDiffViewer *viewer) {
|
||||
if (!viewer) return;
|
||||
|
||||
// Only allow grep search in specific modes
|
||||
if (viewer->current_mode != NCURSES_MODE_COMMIT_LIST &&
|
||||
viewer->current_mode != NCURSES_MODE_STASH_LIST &&
|
||||
viewer->current_mode != NCURSES_MODE_BRANCH_LIST) {
|
||||
return;
|
||||
}
|
||||
|
||||
viewer->grep_search_active = 1;
|
||||
viewer->grep_search_mode = viewer->current_mode;
|
||||
viewer->grep_search_query[0] = '\0';
|
||||
viewer->grep_search_query_len = 0;
|
||||
|
||||
// Create grep search windows
|
||||
int input_height = 3;
|
||||
int list_height = viewer->terminal_height - input_height - 4;
|
||||
int width = viewer->terminal_width - 4;
|
||||
int start_y = (viewer->terminal_height - input_height - list_height) / 2;
|
||||
int start_x = 2;
|
||||
|
||||
viewer->grep_input_win = newwin(input_height, width, start_y, start_x);
|
||||
viewer->grep_list_win = newwin(list_height, width, start_y + input_height, start_x);
|
||||
|
||||
// Initialize with all items
|
||||
update_grep_filter(viewer);
|
||||
|
||||
// Force initial full redraw
|
||||
viewer->grep_needs_full_redraw = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exit grep search mode
|
||||
*/
|
||||
void exit_grep_search_mode(NCursesDiffViewer *viewer) {
|
||||
if (!viewer) return;
|
||||
|
||||
viewer->grep_search_active = 0;
|
||||
cleanup_grep_search(viewer);
|
||||
|
||||
// Force redraw of main windows next time
|
||||
touchwin(stdscr);
|
||||
refresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render grep search input field only
|
||||
*/
|
||||
void render_grep_input(NCursesDiffViewer *viewer) {
|
||||
if (!viewer->grep_input_win) return;
|
||||
|
||||
// Clear only the content area, not the border
|
||||
for (int y = 1; y < getmaxy(viewer->grep_input_win) - 1; y++) {
|
||||
for (int x = 1; x < getmaxx(viewer->grep_input_win) - 1; x++) {
|
||||
mvwaddch(viewer->grep_input_win, y, x, ' ');
|
||||
}
|
||||
}
|
||||
|
||||
// Show current query
|
||||
mvwprintw(viewer->grep_input_win, 1, 2, "> %s", viewer->grep_search_query);
|
||||
|
||||
// Show cursor
|
||||
int cursor_x = 4 + viewer->grep_search_query_len;
|
||||
if (cursor_x < getmaxx(viewer->grep_input_win) - 1) {
|
||||
mvwaddch(viewer->grep_input_win, 1, cursor_x, '_');
|
||||
}
|
||||
|
||||
wrefresh(viewer->grep_input_win);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render grep search list content only (no borders)
|
||||
*/
|
||||
void render_grep_list_content(NCursesDiffViewer *viewer) {
|
||||
if (!viewer->grep_list_win) return;
|
||||
|
||||
int list_height = getmaxy(viewer->grep_list_win) - 2;
|
||||
int list_width = getmaxx(viewer->grep_list_win) - 4;
|
||||
|
||||
// Clear only the content area, not the border
|
||||
for (int y = 1; y <= list_height; y++) {
|
||||
for (int x = 1; x < getmaxx(viewer->grep_list_win) - 1; x++) {
|
||||
mvwaddch(viewer->grep_list_win, y, x, ' ');
|
||||
}
|
||||
}
|
||||
|
||||
// Show filtered results
|
||||
for (int i = 0; i < viewer->grep_filtered_count && i < list_height; i++) {
|
||||
int display_index = i + viewer->grep_scroll_offset;
|
||||
if (display_index >= viewer->grep_filtered_count) break;
|
||||
|
||||
int item_index = viewer->grep_scored_items[display_index].item_index;
|
||||
char display_text[512] = "";
|
||||
|
||||
// Get display text based on mode
|
||||
switch (viewer->grep_search_mode) {
|
||||
case NCURSES_MODE_COMMIT_LIST:
|
||||
snprintf(display_text, sizeof(display_text), "%s %s",
|
||||
viewer->commits[item_index].hash, viewer->commits[item_index].title);
|
||||
break;
|
||||
case NCURSES_MODE_STASH_LIST:
|
||||
strncpy(display_text, viewer->stashes[item_index].stash_info, sizeof(display_text) - 1);
|
||||
break;
|
||||
case NCURSES_MODE_BRANCH_LIST:
|
||||
strncpy(display_text, viewer->branches[item_index].name, sizeof(display_text) - 1);
|
||||
break;
|
||||
default:
|
||||
strcpy(display_text, "Unknown");
|
||||
break;
|
||||
}
|
||||
display_text[sizeof(display_text) - 1] = '\0';
|
||||
|
||||
// Highlight selected item
|
||||
if (display_index == viewer->grep_selected_index) {
|
||||
wattron(viewer->grep_list_win, A_REVERSE);
|
||||
}
|
||||
|
||||
// Show item text
|
||||
mvwprintw(viewer->grep_list_win, i + 1, 2, "%-*.*s",
|
||||
list_width - 2, list_width - 2, display_text);
|
||||
|
||||
if (display_index == viewer->grep_selected_index) {
|
||||
wattroff(viewer->grep_list_win, A_REVERSE);
|
||||
}
|
||||
}
|
||||
|
||||
// Show result count
|
||||
if (viewer->grep_filtered_count > 0) {
|
||||
mvwprintw(viewer->grep_list_win, 0, getmaxx(viewer->grep_list_win) - 15,
|
||||
" %d/%d ", viewer->grep_selected_index + 1, viewer->grep_filtered_count);
|
||||
} else {
|
||||
mvwprintw(viewer->grep_list_win, 0, getmaxx(viewer->grep_list_win) - 10, " 0/0 ");
|
||||
}
|
||||
|
||||
wrefresh(viewer->grep_list_win);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create grep search windows with borders (one-time setup)
|
||||
*/
|
||||
void create_grep_windows_with_borders(NCursesDiffViewer *viewer) {
|
||||
if (!viewer->grep_input_win || !viewer->grep_list_win) return;
|
||||
|
||||
// Get mode name for title
|
||||
const char *mode_name = "Search";
|
||||
switch (viewer->grep_search_mode) {
|
||||
case NCURSES_MODE_COMMIT_LIST:
|
||||
mode_name = "Commit Grep";
|
||||
break;
|
||||
case NCURSES_MODE_STASH_LIST:
|
||||
mode_name = "Stash Grep";
|
||||
break;
|
||||
case NCURSES_MODE_BRANCH_LIST:
|
||||
mode_name = "Branch Grep";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Draw input window border and title
|
||||
wclear(viewer->grep_input_win);
|
||||
box(viewer->grep_input_win, 0, 0);
|
||||
mvwprintw(viewer->grep_input_win, 0, 2, " %s ", mode_name);
|
||||
wrefresh(viewer->grep_input_win);
|
||||
|
||||
// Draw list window border
|
||||
wclear(viewer->grep_list_win);
|
||||
box(viewer->grep_list_win, 0, 0);
|
||||
wrefresh(viewer->grep_list_win);
|
||||
}
|
||||
|
||||
/**
|
||||
* Main grep search render function with granular updates
|
||||
*/
|
||||
void render_grep_search(NCursesDiffViewer *viewer) {
|
||||
if (!viewer || !viewer->grep_search_active) return;
|
||||
if (!viewer->grep_input_win || !viewer->grep_list_win) return;
|
||||
|
||||
// Check what specifically needs to be redrawn
|
||||
int query_changed = strcmp(viewer->grep_search_query, viewer->grep_last_query) != 0;
|
||||
int selection_changed = viewer->grep_selected_index != viewer->grep_last_selected;
|
||||
int scroll_changed = viewer->grep_scroll_offset != viewer->grep_last_scroll;
|
||||
int results_changed = viewer->grep_filtered_count != viewer->grep_last_filtered_count;
|
||||
|
||||
// Full redraw needed on first render
|
||||
if (viewer->grep_needs_full_redraw) {
|
||||
create_grep_windows_with_borders(viewer);
|
||||
render_grep_input(viewer);
|
||||
render_grep_list_content(viewer);
|
||||
viewer->grep_needs_full_redraw = 0;
|
||||
}
|
||||
// Redraw input field if query changed
|
||||
else if (query_changed || viewer->grep_needs_input_redraw) {
|
||||
render_grep_input(viewer);
|
||||
viewer->grep_needs_input_redraw = 0;
|
||||
}
|
||||
|
||||
// Redraw list if results, selection, or scroll changed
|
||||
if (results_changed || selection_changed || scroll_changed || viewer->grep_needs_list_redraw) {
|
||||
render_grep_list_content(viewer);
|
||||
viewer->grep_needs_list_redraw = 0;
|
||||
}
|
||||
|
||||
// Update last rendered state
|
||||
strcpy(viewer->grep_last_query, viewer->grep_search_query);
|
||||
viewer->grep_last_selected = viewer->grep_selected_index;
|
||||
viewer->grep_last_scroll = viewer->grep_scroll_offset;
|
||||
viewer->grep_last_filtered_count = viewer->grep_filtered_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle grep search input
|
||||
*/
|
||||
int handle_grep_search_input(NCursesDiffViewer *viewer, int key) {
|
||||
if (!viewer || !viewer->grep_search_active) return 0;
|
||||
|
||||
switch (key) {
|
||||
case 27: // ESC
|
||||
exit_grep_search_mode(viewer);
|
||||
return 1;
|
||||
|
||||
case KEY_ENTER:
|
||||
case '\n':
|
||||
case '\r':
|
||||
if (viewer->grep_filtered_count > 0) {
|
||||
select_grep_item(viewer);
|
||||
exit_grep_search_mode(viewer);
|
||||
}
|
||||
return 1;
|
||||
|
||||
case KEY_UP:
|
||||
if (viewer->grep_selected_index > 0) {
|
||||
viewer->grep_selected_index--;
|
||||
// Adjust scroll if needed
|
||||
if (viewer->grep_selected_index < viewer->grep_scroll_offset) {
|
||||
viewer->grep_scroll_offset = viewer->grep_selected_index;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
||||
case KEY_DOWN:
|
||||
if (viewer->grep_selected_index < viewer->grep_filtered_count - 1) {
|
||||
viewer->grep_selected_index++;
|
||||
// Adjust scroll if needed
|
||||
int list_height = getmaxy(viewer->grep_list_win) - 2;
|
||||
if (viewer->grep_selected_index >= viewer->grep_scroll_offset + list_height) {
|
||||
viewer->grep_scroll_offset = viewer->grep_selected_index - list_height + 1;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
||||
case KEY_BACKSPACE:
|
||||
case 127:
|
||||
case '\b':
|
||||
if (viewer->grep_search_query_len > 0) {
|
||||
viewer->grep_search_query_len--;
|
||||
viewer->grep_search_query[viewer->grep_search_query_len] = '\0';
|
||||
update_grep_filter(viewer);
|
||||
}
|
||||
return 1;
|
||||
|
||||
default:
|
||||
// Add printable characters to search query
|
||||
if (key >= 32 && key <= 126 && viewer->grep_search_query_len < 255) {
|
||||
viewer->grep_search_query[viewer->grep_search_query_len++] = key;
|
||||
viewer->grep_search_query[viewer->grep_search_query_len] = '\0';
|
||||
update_grep_filter(viewer);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Select item from grep search results
|
||||
*/
|
||||
void select_grep_item(NCursesDiffViewer *viewer) {
|
||||
if (!viewer || viewer->grep_filtered_count == 0) return;
|
||||
|
||||
// Get the actual item index from scored results
|
||||
int item_index = viewer->grep_scored_items[viewer->grep_selected_index].item_index;
|
||||
|
||||
// Update the main selection based on mode
|
||||
switch (viewer->grep_search_mode) {
|
||||
case NCURSES_MODE_COMMIT_LIST:
|
||||
viewer->selected_commit = item_index;
|
||||
viewer->current_mode = NCURSES_MODE_COMMIT_VIEW;
|
||||
// Load the selected commit for viewing
|
||||
if (item_index >= 0 && item_index < viewer->commit_count) {
|
||||
load_commit_for_viewing(viewer, viewer->commits[item_index].hash);
|
||||
}
|
||||
break;
|
||||
|
||||
case NCURSES_MODE_STASH_LIST:
|
||||
viewer->selected_stash = item_index;
|
||||
viewer->current_mode = NCURSES_MODE_STASH_VIEW;
|
||||
// Load the selected stash for viewing
|
||||
if (item_index >= 0 && item_index < viewer->stash_count) {
|
||||
load_stash_for_viewing(viewer, item_index);
|
||||
}
|
||||
break;
|
||||
|
||||
case NCURSES_MODE_BRANCH_LIST:
|
||||
viewer->selected_branch = item_index;
|
||||
viewer->current_mode = NCURSES_MODE_BRANCH_VIEW;
|
||||
// Load commits for the selected branch
|
||||
if (item_index >= 0 && item_index < viewer->branch_count) {
|
||||
load_branch_commits(viewer, viewer->branches[item_index].name);
|
||||
parse_branch_commits_to_lines(viewer);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,6 +180,33 @@ typedef struct {
|
||||
int fuzzy_last_scroll; // Last rendered scroll position
|
||||
int fuzzy_last_filtered_count; // Last rendered result count
|
||||
|
||||
// Generic grep search state (for commits, stashes, branches)
|
||||
int grep_search_active; // 1 if grep search is active
|
||||
NCursesViewMode grep_search_mode; // Which mode grep is searching in
|
||||
char grep_search_query[256]; // Current search query
|
||||
int grep_search_query_len; // Length of current query
|
||||
|
||||
// Scored grep search results
|
||||
struct {
|
||||
int item_index;
|
||||
int score;
|
||||
} grep_scored_items[MAX_COMMITS]; // Scored and sorted results (reuse MAX_COMMITS)
|
||||
|
||||
int grep_filtered_count; // Number of filtered items
|
||||
int grep_selected_index; // Currently selected in grep list
|
||||
int grep_scroll_offset; // Scroll position in grep list
|
||||
WINDOW *grep_input_win; // Input window for search
|
||||
WINDOW *grep_list_win; // Results list window
|
||||
|
||||
// State tracking for grep search rendering
|
||||
int grep_needs_full_redraw; // 1 if full redraw needed
|
||||
int grep_needs_input_redraw; // 1 if input field needs redraw
|
||||
int grep_needs_list_redraw; // 1 if item list needs redraw
|
||||
char grep_last_query[256]; // Last rendered query
|
||||
int grep_last_selected; // Last rendered selection
|
||||
int grep_last_scroll; // Last rendered scroll position
|
||||
int grep_last_filtered_count; // Last rendered result count
|
||||
|
||||
} NCursesDiffViewer;
|
||||
|
||||
/**
|
||||
@@ -483,4 +510,49 @@ int handle_fuzzy_search_input(NCursesDiffViewer *viewer, int key);
|
||||
*/
|
||||
void select_fuzzy_file(NCursesDiffViewer *viewer);
|
||||
|
||||
/**
|
||||
* Initialize grep search state
|
||||
*/
|
||||
void init_grep_search(NCursesDiffViewer *viewer);
|
||||
|
||||
/**
|
||||
* Cleanup grep search windows
|
||||
*/
|
||||
void cleanup_grep_search(NCursesDiffViewer *viewer);
|
||||
|
||||
/**
|
||||
* Enter grep search mode for current view mode
|
||||
*/
|
||||
void enter_grep_search_mode(NCursesDiffViewer *viewer);
|
||||
|
||||
/**
|
||||
* Exit grep search mode
|
||||
*/
|
||||
void exit_grep_search_mode(NCursesDiffViewer *viewer);
|
||||
|
||||
/**
|
||||
* Update grep search filter based on current query and mode
|
||||
*/
|
||||
void update_grep_filter(NCursesDiffViewer *viewer);
|
||||
|
||||
/**
|
||||
* Render grep search UI
|
||||
*/
|
||||
void render_grep_search(NCursesDiffViewer *viewer);
|
||||
|
||||
/**
|
||||
* Handle grep search input
|
||||
*/
|
||||
int handle_grep_search_input(NCursesDiffViewer *viewer, int key);
|
||||
|
||||
/**
|
||||
* Select item from grep search results
|
||||
*/
|
||||
void select_grep_item(NCursesDiffViewer *viewer);
|
||||
|
||||
/**
|
||||
* Calculate grep match score for text content
|
||||
*/
|
||||
int calculate_grep_score(const char *pattern, const char *text);
|
||||
|
||||
#endif // NCURSES_DIFF_VIEWER_H
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user