mirror of
https://github.com/marcusDenslow/FERRUM.git
synced 2026-10-25 12:22:24 +01:00
new git features and touched up suggestions
the suggestion that is currently "hovered" over in the suggestion list will be appended inline to the prompt. also hitting tab when only one match is found will now accept that suggestion instead of opening the menu added gg o flag to open the current repo in github if it is a git repo
This commit is contained in:
58
builtins.c
58
builtins.c
@@ -722,12 +722,70 @@ int lsh_gg(char **args) {
|
||||
printf(" d - diff\n");
|
||||
printf(" b - branch\n");
|
||||
printf(" ch - checkout\n");
|
||||
printf(" o - open in GitHub browser\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Execute the appropriate git command based on shorthand
|
||||
if (strcmp(args[1], "s") == 0) {
|
||||
system("git status");
|
||||
} else if (strcmp(args[1], "b") == 0) {
|
||||
system("git branch");
|
||||
} else if (strcmp(args[1], "o") == 0) {
|
||||
// Get the remote URL
|
||||
FILE *fp;
|
||||
char remote_url[1024] = {0};
|
||||
fp = popen("git config --get remote.origin.url 2>/dev/null", "r");
|
||||
if (fp) {
|
||||
fgets(remote_url, sizeof(remote_url), fp);
|
||||
pclose(fp);
|
||||
|
||||
// Trim trailing newline
|
||||
char *newline = strchr(remote_url, '\n');
|
||||
if (newline) *newline = '\0';
|
||||
|
||||
if (strlen(remote_url) > 0) {
|
||||
// Convert SSH URLs to HTTPS
|
||||
char https_url[1024] = {0};
|
||||
if (strstr(remote_url, "git@github.com:")) {
|
||||
// Convert ssh format (git@github.com:user/repo.git) to https
|
||||
char *repo_path = strchr(remote_url, ':');
|
||||
if (repo_path) {
|
||||
repo_path++; // Skip the colon
|
||||
// Remove .git suffix if present
|
||||
char *git_suffix = strstr(repo_path, ".git");
|
||||
if (git_suffix) *git_suffix = '\0';
|
||||
|
||||
sprintf(https_url, "https://github.com/%s", repo_path);
|
||||
}
|
||||
} else if (strstr(remote_url, "https://github.com/")) {
|
||||
// Already HTTPS format
|
||||
strcpy(https_url, remote_url);
|
||||
// Remove .git suffix if present
|
||||
char *git_suffix = strstr(https_url, ".git");
|
||||
if (git_suffix) *git_suffix = '\0';
|
||||
}
|
||||
|
||||
if (strlen(https_url) > 0) {
|
||||
// Open the URL in the default browser
|
||||
char command[1100];
|
||||
// Use xdg-open on Linux
|
||||
sprintf(command, "xdg-open %s >/dev/null 2>&1", https_url);
|
||||
int result = system(command);
|
||||
if (result == 0) {
|
||||
printf("Opening %s in browser\n", https_url);
|
||||
} else {
|
||||
printf("Failed to open browser. URL: %s\n", https_url);
|
||||
}
|
||||
} else {
|
||||
printf("Could not parse GitHub URL from: %s\n", remote_url);
|
||||
}
|
||||
} else {
|
||||
printf("No remote URL found. Is this a Git repository with a GitHub remote?\n");
|
||||
}
|
||||
} else {
|
||||
printf("Not in a Git repository or no remote configured\n");
|
||||
}
|
||||
} else if (strcmp(args[1], "c") == 0) {
|
||||
if (args[2] != NULL) {
|
||||
char command[1024];
|
||||
|
||||
BIN
builtins.o
BIN
builtins.o
Binary file not shown.
BIN
fzf_native.o
BIN
fzf_native.o
Binary file not shown.
117
line_reader.c
117
line_reader.c
@@ -462,21 +462,26 @@ void update_suggestions(const char *buffer, int position) {
|
||||
|
||||
// If we have suggestions, use the first one
|
||||
if (suggestion_count > 0) {
|
||||
has_suggestion = 1;
|
||||
suggestion_index = 0;
|
||||
|
||||
// Create the full suggestion string that would be accepted
|
||||
if (prefix_start > 0) {
|
||||
// We're completing an argument
|
||||
strncpy(full_suggestion, buffer, prefix_start);
|
||||
full_suggestion[prefix_start] = '\0';
|
||||
strncat(full_suggestion, suggestions[suggestion_index],
|
||||
sizeof(full_suggestion) - strlen(full_suggestion) - 1);
|
||||
// Skip showing "./" suggestions as they're often not useful
|
||||
if (strcmp(suggestions[0], "./") == 0) {
|
||||
has_suggestion = 0;
|
||||
} else {
|
||||
// We're completing a command
|
||||
strncpy(full_suggestion, suggestions[suggestion_index], sizeof(full_suggestion) - 1);
|
||||
has_suggestion = 1;
|
||||
suggestion_index = 0;
|
||||
|
||||
// Create the full suggestion string that would be accepted
|
||||
if (prefix_start > 0) {
|
||||
// We're completing an argument
|
||||
strncpy(full_suggestion, buffer, prefix_start);
|
||||
full_suggestion[prefix_start] = '\0';
|
||||
strncat(full_suggestion, suggestions[suggestion_index],
|
||||
sizeof(full_suggestion) - strlen(full_suggestion) - 1);
|
||||
} else {
|
||||
// We're completing a command
|
||||
strncpy(full_suggestion, suggestions[suggestion_index], sizeof(full_suggestion) - 1);
|
||||
}
|
||||
full_suggestion[sizeof(full_suggestion) - 1] = '\0';
|
||||
}
|
||||
full_suggestion[sizeof(full_suggestion) - 1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -639,16 +644,12 @@ void refresh_display(const char *prompt_buffer, const char *buffer, int position
|
||||
// Always clear any existing menu first
|
||||
clear_menu();
|
||||
|
||||
// Always redraw the command line to ensure prompt is visible
|
||||
printf("\r\033[K%s%s", prompt_buffer, buffer);
|
||||
fflush(stdout);
|
||||
// Always show inline suggestion - even in menu mode
|
||||
display_inline_suggestion(prompt_buffer, buffer, position);
|
||||
|
||||
if (menu_mode) {
|
||||
// Show menu of options below the input line
|
||||
// Also show menu of options below the input line
|
||||
display_menu(prompt_buffer, buffer, position);
|
||||
} else {
|
||||
// Show inline suggestion
|
||||
display_inline_suggestion(prompt_buffer, buffer, position);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -765,9 +766,10 @@ char *lsh_read_line(void) {
|
||||
printf("\r\033[K%s%s", prompt_buffer, buffer);
|
||||
fflush(stdout);
|
||||
|
||||
// Update suggestions for new state
|
||||
update_suggestions(buffer, position);
|
||||
display_inline_suggestion(prompt_buffer, buffer, position);
|
||||
// Don't immediately show a new suggestion after accepting one
|
||||
// The user likely wants to execute the command first
|
||||
// update_suggestions(buffer, position);
|
||||
// display_inline_suggestion(prompt_buffer, buffer, position);
|
||||
}
|
||||
} else {
|
||||
// Not in menu mode: execute the command as is
|
||||
@@ -804,11 +806,48 @@ char *lsh_read_line(void) {
|
||||
// Already in menu mode: cycle to next suggestion
|
||||
if (suggestion_count > 0) {
|
||||
suggestion_index = (suggestion_index + 1) % suggestion_count;
|
||||
|
||||
// Update full_suggestion with the newly selected suggestion
|
||||
if (prefix_start > 0) {
|
||||
// We're completing an argument
|
||||
strncpy(full_suggestion, buffer, prefix_start);
|
||||
full_suggestion[prefix_start] = '\0';
|
||||
strncat(full_suggestion, suggestions[suggestion_index],
|
||||
sizeof(full_suggestion) - strlen(full_suggestion) - 1);
|
||||
} else {
|
||||
// We're completing a command
|
||||
strncpy(full_suggestion, suggestions[suggestion_index], sizeof(full_suggestion) - 1);
|
||||
}
|
||||
full_suggestion[sizeof(full_suggestion) - 1] = '\0';
|
||||
|
||||
refresh_display(prompt_buffer, buffer, position);
|
||||
}
|
||||
} else {
|
||||
// Enter menu mode if we have suggestions
|
||||
if (has_suggestion && suggestion_count > 0) {
|
||||
// If there's only one suggestion, accept it directly
|
||||
if (has_suggestion && suggestion_count == 1) {
|
||||
// Update buffer with the single suggestion
|
||||
if (prefix_start > 0) {
|
||||
// We're completing an argument
|
||||
char temp[LSH_RL_BUFSIZE];
|
||||
strncpy(temp, buffer, prefix_start);
|
||||
temp[prefix_start] = '\0';
|
||||
strncat(temp, suggestions[suggestion_index],
|
||||
LSH_RL_BUFSIZE - strlen(temp) - 1);
|
||||
|
||||
strncpy(buffer, temp, bufsize - 1);
|
||||
} else {
|
||||
// We're completing a command
|
||||
strncpy(buffer, suggestions[suggestion_index], bufsize - 1);
|
||||
}
|
||||
buffer[bufsize - 1] = '\0';
|
||||
position = strlen(buffer);
|
||||
|
||||
// Redraw the line with accepted suggestion
|
||||
printf("\r\033[K%s%s", prompt_buffer, buffer);
|
||||
fflush(stdout);
|
||||
}
|
||||
// Otherwise enter menu mode if we have multiple suggestions
|
||||
else if (has_suggestion && suggestion_count > 1) {
|
||||
menu_mode = 1;
|
||||
suggestion_index = 0; // Start with first suggestion
|
||||
refresh_display(prompt_buffer, buffer, position);
|
||||
@@ -818,12 +857,40 @@ char *lsh_read_line(void) {
|
||||
// In menu mode, up arrow goes to previous suggestion
|
||||
if (suggestion_count > 0) {
|
||||
suggestion_index = (suggestion_index + suggestion_count - 1) % suggestion_count;
|
||||
|
||||
// Update full_suggestion with the newly selected suggestion
|
||||
if (prefix_start > 0) {
|
||||
// We're completing an argument
|
||||
strncpy(full_suggestion, buffer, prefix_start);
|
||||
full_suggestion[prefix_start] = '\0';
|
||||
strncat(full_suggestion, suggestions[suggestion_index],
|
||||
sizeof(full_suggestion) - strlen(full_suggestion) - 1);
|
||||
} else {
|
||||
// We're completing a command
|
||||
strncpy(full_suggestion, suggestions[suggestion_index], sizeof(full_suggestion) - 1);
|
||||
}
|
||||
full_suggestion[sizeof(full_suggestion) - 1] = '\0';
|
||||
|
||||
refresh_display(prompt_buffer, buffer, position);
|
||||
}
|
||||
} else if (c == KEY_DOWN && menu_mode) {
|
||||
// In menu mode, down arrow goes to next suggestion
|
||||
if (suggestion_count > 0) {
|
||||
suggestion_index = (suggestion_index + 1) % suggestion_count;
|
||||
|
||||
// Update full_suggestion with the newly selected suggestion
|
||||
if (prefix_start > 0) {
|
||||
// We're completing an argument
|
||||
strncpy(full_suggestion, buffer, prefix_start);
|
||||
full_suggestion[prefix_start] = '\0';
|
||||
strncat(full_suggestion, suggestions[suggestion_index],
|
||||
sizeof(full_suggestion) - strlen(full_suggestion) - 1);
|
||||
} else {
|
||||
// We're completing a command
|
||||
strncpy(full_suggestion, suggestions[suggestion_index], sizeof(full_suggestion) - 1);
|
||||
}
|
||||
full_suggestion[sizeof(full_suggestion) - 1] = '\0';
|
||||
|
||||
refresh_display(prompt_buffer, buffer, position);
|
||||
}
|
||||
} else if (c == KEY_UP && !menu_mode) {
|
||||
|
||||
BIN
line_reader.o
BIN
line_reader.o
Binary file not shown.
Reference in New Issue
Block a user