From cc3e1892ef7f128ef373f93cce79729b280447a5 Mon Sep 17 00:00:00 2001 From: Dm1tr1y147 Date: Sat, 18 Jul 2020 12:31:54 +0500 Subject: [PATCH] Command autocomplete gets options from PATH --- README.md | 3 +-- include/complete.h | 1 + include/utils.h | 1 + src/complete.c | 30 +++++++++++++++++++++++++++++- src/utils.c | 25 +++++++++++++++++++++++++ 5 files changed, 57 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0d30a84..53723e4 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Work is still in porgress, buf when you will see a "finished" topic assigned to * Command input with `left` and `right` arrow, `home` and `end` keys navigation and `backspace`, `delete` support * Running commands in separate process and termination them with `ctrl+c` * `cd`, `exit` and `exec` builtin commands -* Files and commands from `/usr/bin` autocompletion on `Tab` keypress +* Files and commands from `PATH` autocompletion on `Tab` keypress * History of commands and navigation or search through it with `up`/`down` keys * Username, ip address and current path in prompt before each command input * Show previous command return status in prompt and invert it with `!`, separated with space, specified before it @@ -26,5 +26,4 @@ Work is still in porgress, buf when you will see a "finished" topic assigned to * Replace linux `echo` command with builtin one with support of environmental variables * Environmental variables * `Ctrl+Z` running programm with `fd` -* Gettingcommands path from system `PATH` environment variable for autocomplete * `$()` subcommands diff --git a/include/complete.h b/include/complete.h index cdd8963..e3585c8 100644 --- a/include/complete.h +++ b/include/complete.h @@ -16,5 +16,6 @@ ssize_t get_dir_list(char ***dir_list, char *path, int ex); ssize_t get_complete_options(char ***opts, char *line, char **to_complete); ssize_t complete_line(int *pos, int *n, char **line, char **out); ssize_t filter_options(char ***comp_list, ssize_t *size, char *filter_string); +ssize_t get_path_commands_list(char ***opts); #endif \ No newline at end of file diff --git a/include/utils.h b/include/utils.h index caec45c..f3ef3cd 100644 --- a/include/utils.h +++ b/include/utils.h @@ -25,5 +25,6 @@ int get_null_term_arr_size(char **arr); int append_to_str_arr(char ***arr, int *sz, char *str); char *get_curr_dir_name(); int get_num_of_lines(FILE *file); +bool str_is_in_arr(char **arr, size_t sz, char *str); #endif \ No newline at end of file diff --git a/src/complete.c b/src/complete.c index c858ee6..d9b9b56 100644 --- a/src/complete.c +++ b/src/complete.c @@ -145,7 +145,8 @@ ssize_t get_complete_options(char ***opts, char *line, char **to_complete) if (strcmp(args[am - 2], "||") == 0 || strcmp(args[am - 2], "&&") == 0 || strcmp(args[am - 2], ";") == 0) *to_complete = strdup(""); - sz = get_dir_list(opts, "/usr/bin", 1); + sz = get_path_commands_list(opts); + // sz = get_dir_list(opts, "/usr/bin", 1); append_builtin_list(opts, &sz); } @@ -198,4 +199,31 @@ ssize_t filter_options(char ***comp_list, ssize_t *size, char *filter_string) free_str_arr(folders, path_depth); return *size; +} + +ssize_t get_path_commands_list(char ***opts) +{ + char *paths_str = getenv("PATH"); + char **paths = NULL; + int path_am = sep_string(paths_str, &paths, ":"); + ssize_t sz = 0; + + for (int i = 0; i < path_am; i++) + { + char **tmp_list = malloc(0); + ssize_t tmp_sz = get_dir_list(&tmp_list, paths[i], 1); + if (tmp_sz < 0) + continue; + + for (long j = 0; j < tmp_sz; j++) + { + if (i != 0) + if (str_is_in_arr(*opts, sz, tmp_list[j])) + continue; + + append_to_str_arr(opts, &sz, tmp_list[j]); + } + } + + return sz; } \ No newline at end of file diff --git a/src/utils.c b/src/utils.c index 53bfa2f..3dc8eea 100644 --- a/src/utils.c +++ b/src/utils.c @@ -219,4 +219,29 @@ int get_num_of_lines(FILE *file) fseek(file, curr_pos, SEEK_SET); return n; +} + +bool str_is_in_arr(char **arr, size_t sz, char *str) +{ + int first = 0; + int last = sz - 1; + int middle; + + while (first <= last) + { + middle = (first + last) / 2; + int diff = strcmp(arr[middle], str); + if (diff > 0) + { + first = middle + 1; + } + else if (diff == 0) + return true; + else + { + last = middle - 1; + } + } + + return false; } \ No newline at end of file