From: Yutao Yuan Date: Sun, 13 Sep 2015 16:41:22 +0000 (+0800) Subject: Add :source command X-Git-Url: https://git.owens.tech/style.css/style.css/git?a=commitdiff_plain;h=ffd7d6a57d18ea9d193ac20613cb5b9dfa973039;p=vimb.git Add :source command --- diff --git a/src/ex.c b/src/ex.c index 711190a..b315dfa 100644 --- a/src/ex.c +++ b/src/ex.c @@ -78,6 +78,7 @@ typedef enum { EX_SCR, EX_SET, EX_SHELLCMD, + EX_SOURCE, EX_TABOPEN, } ExCode; @@ -148,6 +149,7 @@ static VbCmdResult ex_save(const ExArg *arg); static VbCmdResult ex_set(const ExArg *arg); static VbCmdResult ex_shellcmd(const ExArg *arg); static VbCmdResult ex_shortcut(const ExArg *arg); +static VbCmdResult ex_source(const ExArg *arg); static VbCmdResult ex_handlers(const ExArg *arg); static gboolean complete(short direction); @@ -198,6 +200,7 @@ static ExInfo commands[] = { {"shortcut-add", EX_SCA, ex_shortcut, EX_FLAG_RHS}, {"shortcut-default", EX_SCD, ex_shortcut, EX_FLAG_RHS}, {"shortcut-remove", EX_SCR, ex_shortcut, EX_FLAG_RHS}, + {"source", EX_SOURCE, ex_source, EX_FLAG_RHS|EX_FLAG_EXP}, {"tabopen", EX_TABOPEN, ex_open, EX_FLAG_CMD}, }; @@ -498,6 +501,34 @@ VbCmdResult ex_run_string(const char *input, gboolean enable_history) return res; } +/** + * Run all ex commands in a file. + */ +gboolean ex_run_file(const char *filename) +{ + char *line, **lines; + + lines = util_get_lines(filename); + + if (!lines) { + return false; + } + + int length = g_strv_length(lines) - 1; + for (int i = 0; i < length; i++) { + line = lines[i]; + if (*line == '#') { + continue; + } + if (ex_run_string(line, false) & VB_CMD_ERROR) { + g_warning("Invalid command in %s: '%s'", filename, line); + } + } + g_strfreev(lines); + + return true; +} + /** * Parses given input string into given ExArg pointer. */ @@ -985,6 +1016,11 @@ static VbCmdResult ex_shellcmd(const ExArg *arg) return res; } +static VbCmdResult ex_source(const ExArg *arg) +{ + return ex_run_file(arg->rhs->str) ? VB_CMD_SUCCESS | VB_CMD_KEEPINPUT : VB_CMD_ERROR; +} + static VbCmdResult ex_handlers(const ExArg *arg) { char *p; @@ -1161,6 +1197,11 @@ static gboolean complete(short direction) break; #endif + case EX_SOURCE: + sort = true; + found = util_filename_fill_completion(store, token); + break; + default: break; } diff --git a/src/ex.h b/src/ex.h index 9b706e3..cd3dccb 100644 --- a/src/ex.h +++ b/src/ex.h @@ -29,5 +29,6 @@ VbResult ex_keypress(int key); void ex_input_changed(const char *text); gboolean ex_fill_completion(GtkListStore *store, const char *input); VbCmdResult ex_run_string(const char *input, gboolean enable_history); +gboolean ex_run_file(const char *filename); #endif /* end of include guard: _EX_H */ diff --git a/src/main.c b/src/main.c index 8790fa3..aec3276 100644 --- a/src/main.c +++ b/src/main.c @@ -1127,24 +1127,7 @@ static void marks_clear(void) static void read_config(void) { - char *line, **lines; - - /* read config from config files */ - lines = util_get_lines(vb.files[FILES_CONFIG]); - - if (lines) { - int length = g_strv_length(lines) - 1; - for (int i = 0; i < length; i++) { - line = lines[i]; - if (*line == '#') { - continue; - } - if (ex_run_string(line, false) & VB_CMD_ERROR ) { - g_warning("Invalid user config: '%s'", line); - } - } - } - g_strfreev(lines); + ex_run_file(vb.files[FILES_CONFIG]); } static void setup_signals() diff --git a/src/util.c b/src/util.c index b1a72c5..dcf2694 100644 --- a/src/util.c +++ b/src/util.c @@ -774,3 +774,48 @@ gboolean util_fill_completion(GtkListStore *store, const char *input, GList *src return found; } + +gboolean util_filename_fill_completion(GtkListStore *store, const char *input) +{ + gboolean found = false; + + const char *last_slash = strrchr(input, '/'); + const char *input_basename = last_slash ? last_slash + 1 : input; + char *input_dirname = g_strndup(input, input_basename - input); + char *real_dirname = util_expand( + *input_dirname ? input_dirname : ".", + UTIL_EXP_TILDE|UTIL_EXP_DOLLAR|UTIL_EXP_SPECIAL + ); + + GError *error = NULL; + GDir *dir = g_dir_open(real_dirname, 0, &error); + if (error) { + /* Can't open directory, likely bad user input */ + g_error_free(error); + } else { + const char *filename; + GtkTreeIter iter; + while ((filename = g_dir_read_name(dir))) { + if (g_str_has_prefix(filename, input_basename)) { + char *fullpath = g_build_filename(real_dirname, filename, NULL); + char *result; + if (g_file_test(fullpath, G_FILE_TEST_IS_DIR)) { + result = g_strconcat(input_dirname, filename, "/", NULL); + } else { + result = g_strconcat(input_dirname, filename, NULL); + } + g_free(fullpath); + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, COMPLETION_STORE_FIRST, result, -1); + g_free(result); + found = true; + } + } + g_dir_close(dir); + } + + g_free(input_dirname); + g_free(real_dirname); + + return found; +} diff --git a/src/util.h b/src/util.h index f73a631..104f116 100644 --- a/src/util.h +++ b/src/util.h @@ -51,5 +51,6 @@ gboolean util_parse_expansion(const char **input, GString *str, int flags, const char *quoteable); gboolean util_wildmatch(const char *pattern, const char *subject); gboolean util_fill_completion(GtkListStore *store, const char *input, GList *src); +gboolean util_filename_fill_completion(GtkListStore *store, const char *input); #endif /* end of include guard: _UTIL_H */