summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorYutao Yuan <yyt16384@gmail.com>2015-09-14 00:41:22 +0800
committerYutao Yuan <yyt16384@gmail.com>2015-09-21 00:47:53 +0800
commitffd7d6a57d18ea9d193ac20613cb5b9dfa973039 (patch)
tree5ccf04dc4691e3beda38697a36b7c091151b72b5 /src
parent05b552b0c44f0586254a28d4585bdaadebb0b1ad (diff)
Add :source command
Diffstat (limited to 'src')
-rw-r--r--src/ex.c41
-rw-r--r--src/ex.h1
-rw-r--r--src/main.c19
-rw-r--r--src/util.c45
-rw-r--r--src/util.h1
5 files changed, 89 insertions, 18 deletions
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},
};
@@ -499,6 +502,34 @@ VbCmdResult ex_run_string(const char *input, gboolean enable_history)
}
/**
+ * 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.
*/
static gboolean parse(const char **input, ExArg *arg, gboolean *nohist)
@@ -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 */