about summary refs log tree commit diff stats
path: root/src/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/api.c6
-rw-r--r--src/plugins/api.h1
-rw-r--r--src/plugins/autocompleters.c50
-rw-r--r--src/plugins/autocompleters.h1
-rw-r--r--src/plugins/c_api.c12
-rw-r--r--src/plugins/profapi.c1
-rw-r--r--src/plugins/profapi.h2
-rw-r--r--src/plugins/python_api.c25
8 files changed, 97 insertions, 1 deletions
diff --git a/src/plugins/api.c b/src/plugins/api.c
index ac419ebe..b504237b 100644
--- a/src/plugins/api.c
+++ b/src/plugins/api.c
@@ -179,6 +179,12 @@ api_completer_clear(const char *const plugin_name, const char *key)
 }
 
 void
+api_filepath_completer_add(const char *const plugin_name, const char *prefix)
+{
+    autocompleters_filepath_add(plugin_name, prefix);
+}
+
+void
 api_notify(const char *message, const char *category, int timeout_ms)
 {
     notify(message, timeout_ms, category);
diff --git a/src/plugins/api.h b/src/plugins/api.h
index 98728eb6..94788615 100644
--- a/src/plugins/api.h
+++ b/src/plugins/api.h
@@ -59,6 +59,7 @@ void api_register_timed(const char *const plugin_name, void *callback, int inter
 void api_completer_add(const char *const plugin_name, const char *key, char **items);
 void api_completer_remove(const char *const plugin_name, const char *key, char **items);
 void api_completer_clear(const char *const plugin_name, const char *key);
+void api_filepath_completer_add(const char *const plugin_name, const char *prefix);
 
 void api_log_debug(const char *message);
 void api_log_info(const char *message);
diff --git a/src/plugins/autocompleters.c b/src/plugins/autocompleters.c
index a4dd80e7..496913e6 100644
--- a/src/plugins/autocompleters.c
+++ b/src/plugins/autocompleters.c
@@ -37,8 +37,10 @@
 #include <glib.h>
 
 #include "tools/autocomplete.h"
+#include "command/cmd_ac.h"
 
 static GHashTable *plugin_to_acs;
+static GHashTable *plugin_to_filepath_acs;
 
 static void
 _free_autocompleters(GHashTable *key_to_ac)
@@ -46,10 +48,17 @@ _free_autocompleters(GHashTable *key_to_ac)
     g_hash_table_destroy(key_to_ac);
 }
 
+static void
+_free_filepath_autocompleters(GHashTable *prefixes)
+{
+    g_hash_table_destroy(prefixes);
+}
+
 void
 autocompleters_init(void)
 {
     plugin_to_acs = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)_free_autocompleters);
+    plugin_to_filepath_acs = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)_free_filepath_autocompleters);
 }
 
 void
@@ -106,7 +115,20 @@ autocompleters_clear(const char *const plugin_name, const char *key)
     autocomplete_clear(ac);
 }
 
-char *
+void
+autocompleters_filepath_add(const char *const plugin_name, const char *prefix)
+{
+    GHashTable *prefixes = g_hash_table_lookup(plugin_to_filepath_acs, plugin_name);
+    if (prefixes) {
+        g_hash_table_add(prefixes, strdup(prefix));
+    } else {
+        prefixes = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+        g_hash_table_add(prefixes, strdup(prefix));
+        g_hash_table_insert(plugin_to_filepath_acs, strdup(plugin_name), prefixes);
+    }
+}
+
+char*
 autocompleters_complete(const char * const input)
 {
     char *result = NULL;
@@ -121,6 +143,7 @@ autocompleters_complete(const char * const input)
         while (curr) {
             result = autocomplete_param_with_ac(input, curr->data, g_hash_table_lookup(key_to_ac, curr->data), TRUE);
             if (result) {
+                g_list_free(ac_hashes);
                 g_list_free(keys);
                 return result;
             }
@@ -132,6 +155,31 @@ autocompleters_complete(const char * const input)
     }
     g_list_free(ac_hashes);
 
+    GList *filepath_hashes = g_hash_table_get_values(plugin_to_filepath_acs);
+    curr_hash = filepath_hashes;
+    while (curr_hash) {
+        GHashTable *prefixes_hash = curr_hash->data;
+        GList *prefixes = g_hash_table_get_keys(prefixes_hash);
+        GList *curr_prefix = prefixes;
+        while (curr_prefix) {
+            char *prefix = curr_prefix->data;
+            if (g_str_has_prefix(input, prefix)) {
+                result = cmd_ac_complete_filepath(input, prefix);
+                if (result) {
+                    g_list_free(filepath_hashes);
+                    g_list_free(prefixes);
+                    return result;
+                }
+            }
+
+            curr_prefix = g_list_next(curr_prefix);
+        }
+        g_list_free(prefixes);
+
+        curr_hash = g_list_next(curr_hash);
+    }
+    g_list_free(filepath_hashes);
+
     return NULL;
 }
 
diff --git a/src/plugins/autocompleters.h b/src/plugins/autocompleters.h
index 15580514..22ec2ca4 100644
--- a/src/plugins/autocompleters.h
+++ b/src/plugins/autocompleters.h
@@ -41,6 +41,7 @@ void autocompleters_init(void);
 void autocompleters_add(const char *const plugin_name, const char *key, char **items);
 void autocompleters_remove(const char *const plugin_name, const char *key, char **items);
 void autocompleters_clear(const char *const plugin_name, const char *key);
+void autocompleters_filepath_add(const char *const plugin_name, const char *prefix);
 char* autocompleters_complete(const char * const input);
 void autocompleters_reset(void);
 void autocompleters_destroy(void);
diff --git a/src/plugins/c_api.c b/src/plugins/c_api.c
index 43428140..0b323268 100644
--- a/src/plugins/c_api.c
+++ b/src/plugins/c_api.c
@@ -143,6 +143,17 @@ c_api_completer_clear(const char *filename, const char *key)
 }
 
 static void
+c_api_filepath_completer_add(const char *filename, const char *prefix)
+{
+    char *plugin_name = _c_plugin_name(filename);
+    log_debug("Filepath autocomplete added '%s' for %s", prefix, plugin_name);
+
+    api_filepath_completer_add(plugin_name, prefix);
+
+    free(plugin_name);
+}
+
+static void
 c_api_notify(const char *message, int timeout_ms, const char *category)
 {
     api_notify(message, category, timeout_ms);
@@ -360,6 +371,7 @@ c_api_init(void)
     _prof_completer_add = c_api_completer_add;
     _prof_completer_remove = c_api_completer_remove;
     _prof_completer_clear = c_api_completer_clear;
+    _prof_filepath_completer_add = c_api_filepath_completer_add;
     _prof_win_create = c_api_win_create;
     prof_notify = c_api_notify;
     prof_send_line = c_api_send_line;
diff --git a/src/plugins/profapi.c b/src/plugins/profapi.c
index b2130a01..4601d403 100644
--- a/src/plugins/profapi.c
+++ b/src/plugins/profapi.c
@@ -51,6 +51,7 @@ void (*_prof_register_timed)(const char *filename, TIMED_CB callback, int interv
 void (*_prof_completer_add)(const char *filename, const char *key, char **items) = NULL;
 void (*_prof_completer_remove)(const char *filename, const char *key, char **items) = NULL;
 void (*_prof_completer_clear)(const char *filename, const char *key) = NULL;
+void (*_prof_filepath_completer_add)(const char *filename, const char *prefix) = NULL;
 
 void (*prof_notify)(const char *message, int timeout_ms, const char *category) = NULL;
 
diff --git a/src/plugins/profapi.h b/src/plugins/profapi.h
index e7119a2b..7bc2a9e9 100644
--- a/src/plugins/profapi.h
+++ b/src/plugins/profapi.h
@@ -40,6 +40,7 @@
 #define prof_completer_add(key, items) _prof_completer_add(__FILE__, key, items)
 #define prof_completer_remove(key, items) _prof_completer_remove(__FILE__, key, items)
 #define prof_completer_clear(key) _prof_completer_clear(__FILE__, key)
+#define prof_filepath_completer_add(prefix) _prof_filepath_completer_add(__FILE__, prefix)
 #define prof_win_create(win, input_handler) _prof_win_create(__FILE__, win, input_handler)
 #define prof_disco_add_feature(feature) _prof_disco_add_feature(__FILE__, feature)
 
@@ -62,6 +63,7 @@ void (*_prof_register_timed)(const char *filename, TIMED_CB callback, int interv
 void (*_prof_completer_add)(const char *filename, const char *key, char **items);
 void (*_prof_completer_remove)(const char *filename, const char *key, char **items);
 void (*_prof_completer_clear)(const char *filename, const char *key);
+void (*_prof_filepath_completer_add)(const char *filename, const char *prefix);
 
 void (*prof_notify)(const char *message, int timeout_ms, const char *category);
 
diff --git a/src/plugins/python_api.c b/src/plugins/python_api.c
index f2bce2e3..0b78b055 100644
--- a/src/plugins/python_api.c
+++ b/src/plugins/python_api.c
@@ -340,6 +340,30 @@ python_api_completer_clear(PyObject *self, PyObject *args)
 }
 
 static PyObject*
+python_api_filepath_completer_add(PyObject *self, PyObject *args)
+{
+    PyObject *prefix = NULL;
+
+    if (!PyArg_ParseTuple(args, "O", &prefix)) {
+        Py_RETURN_NONE;
+    }
+
+    char *prefix_str = python_str_or_unicode_to_string(prefix);
+
+    char *plugin_name = _python_plugin_name();
+    log_debug("Filepath autocomplete added '%s' for %s", prefix_str, plugin_name);
+
+    allow_python_threads();
+    api_filepath_completer_add(plugin_name, prefix_str);
+    free(prefix_str);
+    disable_python_threads();
+
+    free(plugin_name);
+
+    Py_RETURN_NONE;
+}
+
+static PyObject*
 python_api_notify(PyObject *self, PyObject *args)
 {
     PyObject *message = NULL;
@@ -1063,6 +1087,7 @@ static PyMethodDef apiMethods[] = {
     { "completer_add", python_api_completer_add, METH_VARARGS, "Add items to an autocompleter." },
     { "completer_remove", python_api_completer_remove, METH_VARARGS, "Remove items from an autocompleter." },
     { "completer_clear", python_api_completer_clear, METH_VARARGS, "Remove all items from an autocompleter." },
+    { "filepath_completer_add", python_api_filepath_completer_add, METH_VARARGS, "Add filepath autocompleter" },
     { "send_line", python_api_send_line, METH_VARARGS, "Send a line of input." },
     { "notify", python_api_notify, METH_VARARGS, "Send desktop notification." },
     { "get_current_recipient", python_api_get_current_recipient, METH_VARARGS, "Return the jid of the recipient of the current window." },