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:
2025-04-30 23:27:07 +02:00
parent 314c9ed99d
commit f0bd91a691
6 changed files with 150 additions and 25 deletions

View File

@@ -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];

Binary file not shown.

Binary file not shown.

View File

@@ -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) {

Binary file not shown.

BIN
shell

Binary file not shown.