ajwillia-ms pushed a commit to branch master. http://git.enlightenment.org/tools/edi.git/commit/?id=405f93efe1f8cbdb0f30394198bf7bd629b74d63
commit 405f93efe1f8cbdb0f30394198bf7bd629b74d63 Author: Andy Williams <[email protected]> Date: Tue Jul 4 14:10:55 2017 +0100 build: Add support for cargo based rust projects In the process we needed to define if a project can be run... Python and rust can always be run as they will build their binaries whereas make and cmake need to be configured etc... --- src/bin/Makefile.am | 3 +- src/bin/edi_content_provider.c | 14 +++--- src/bin/edi_main.c | 38 +++++--------- src/bin/language/edi_language_provider.c | 20 ++++++-- src/bin/language/edi_language_provider.h | 11 ++++ src/bin/language/edi_language_provider_rust.c | 58 ++++++++++++++++++++++ src/lib/Makefile.am | 1 + src/lib/edi_build_provider.c | 5 ++ src/lib/edi_build_provider.h | 2 + ...rovider_python.c => edi_build_provider_cargo.c} | 49 +++++++++++------- src/lib/edi_build_provider_cmake.c | 43 +++++++++++++++- src/lib/edi_build_provider_make.c | 43 +++++++++++++++- src/lib/edi_build_provider_python.c | 15 ++++++ src/lib/edi_builder.c | 22 ++++++++ src/lib/edi_builder.h | 23 +++++++++ 15 files changed, 290 insertions(+), 57 deletions(-) diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am index c159a8c..17a3a36 100644 --- a/src/bin/Makefile.am +++ b/src/bin/Makefile.am @@ -62,7 +62,8 @@ edi_main.c \ edi_private.h EXTRA_DIST = \ -language/edi_language_provider_c.c +language/edi_language_provider_c.c \ +language/edi_language_provider_rust.c edi_LDADD = @EFL_LIBS@ $(top_builddir)/src/lib/libedi.la $(LTLIBINTL) diff --git a/src/bin/edi_content_provider.c b/src/bin/edi_content_provider.c index d0e0a0a..56a83aa 100644 --- a/src/bin/edi_content_provider.c +++ b/src/bin/edi_content_provider.c @@ -10,6 +10,8 @@ #include "edi_config.h" +#include "language/edi_language_provider.h" + #include "edi_private.h" // TODO move out to edi_content.c or similar just like the editor type @@ -72,17 +74,17 @@ static Edi_Content_Provider _edi_content_provider_registry[] = Edi_Content_Provider *edi_content_provider_for_mime_get(const char *mime) { const char *id = NULL; + Edi_Language_Provider *provider; if (!mime) return NULL; - if (!strcasecmp(mime, "text/plain") || !strcasecmp(mime, "application/x-shellscript")) - id = "text"; - else if (!strcasecmp(mime, "text/x-chdr") || !strcasecmp(mime, "text/x-csrc") - || !strcasecmp(mime, "text/x-modelica")) - id = "code"; - else if (!strcasecmp(mime, "text/x-c++src") || !strcasecmp(mime, "text/x-c++hdr")) + provider = edi_language_provider_for_mime_get(mime); + + if (!!provider) id = "code"; + else if (!strcasecmp(mime, "text/plain") || !strcasecmp(mime, "application/x-shellscript")) + id = "text"; else if (!strncasecmp(mime, "image/", 6)) id = "image"; else if (!strcasecmp(mime, "text/x-diff") || !strcasecmp(mime, "text/x-patch")) diff --git a/src/bin/edi_main.c b/src/bin/edi_main.c index 68c0073..6294b85 100644 --- a/src/bin/edi_main.c +++ b/src/bin/edi_main.c @@ -601,32 +601,6 @@ edi_launcher_config_missing() } static void -_edi_launcher_run(Edi_Project_Config_Launch *launch) -{ - char *full_cmd; - int full_len; - - if (!_edi_project_config->launch.path) - { - edi_launcher_config_missing(); - return; - } - - if (!_edi_project_config->launch.args) - { - ecore_exe_run(launch->path, NULL); - return; - } - - full_len = strlen(_edi_project_config->launch.path) + strlen(_edi_project_config->launch.path); - full_cmd = malloc(sizeof(char) * (full_len + 1)); - snprintf(full_cmd, full_len + 2, "%s %s", _edi_project_config->launch.path, _edi_project_config->launch.args); - ecore_exe_run(full_cmd, NULL); - - free(full_cmd); -} - -static void _edi_project_credentials_missing() { @@ -758,6 +732,18 @@ _edi_build_prep(Evas_Object *button) } static void +_edi_launcher_run(Edi_Project_Config_Launch *launch) +{ + if (!edi_builder_can_run(_edi_project_config->launch.path)) + { + edi_launcher_config_missing(); + return; + } + + edi_builder_run(launch->path, launch->args); +} + +static void _tb_build_cb(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) { if (_edi_build_prep(obj)) diff --git a/src/bin/language/edi_language_provider.c b/src/bin/language/edi_language_provider.c index 2cc12ac..bd5ca7f 100644 --- a/src/bin/language/edi_language_provider.c +++ b/src/bin/language/edi_language_provider.c @@ -9,6 +9,7 @@ #include "edi_private.h" #include "edi_language_provider_c.c" +#include "edi_language_provider_rust.c" static Edi_Language_Provider _edi_language_provider_registry[] = { @@ -17,22 +18,35 @@ static Edi_Language_Provider _edi_language_provider_registry[] = _edi_language_c_mime_name, _edi_language_c_snippet_get, _edi_language_c_lookup, _edi_language_c_lookup_doc }, + { + "rust", _edi_language_rust_add, _edi_language_rust_refresh, _edi_language_rust_del, + _edi_language_rust_mime_name, _edi_language_rust_snippet_get, + NULL, NULL + }, + {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL} }; Edi_Language_Provider *edi_language_provider_get(Edi_Editor *editor) { - Edi_Language_Provider *provider; const char *mime = editor->mimetype; + + return edi_language_provider_for_mime_get(mime); +} + +Edi_Language_Provider *edi_language_provider_for_mime_get(const char *mime) +{ + Edi_Language_Provider *provider; const char *id = NULL; if (!mime) return NULL; - if (!strcasecmp(mime, "text/x-chdr") || !strcasecmp(mime, "text/x-csrc") - || !strcasecmp(mime, "text/x-modelica")) + if (!strcasecmp(mime, "text/x-chdr") || !strcasecmp(mime, "text/x-csrc")) id = "c"; + if (!strcasecmp(mime, "text/rust")) + id = "rust"; if (!id) return NULL; diff --git a/src/bin/language/edi_language_provider.h b/src/bin/language/edi_language_provider.h index 6fd29be..03b2dcf 100644 --- a/src/bin/language/edi_language_provider.h +++ b/src/bin/language/edi_language_provider.h @@ -67,6 +67,17 @@ typedef struct _Edi_Language_Provider Edi_Language_Provider *edi_language_provider_get(Edi_Editor *editor); /** + * Look up a suggest provider based on the mime type provided. + * + * @param mime the mime type for a file you wish to get a suggestion provider for + * + * @return an Edi_Editor_Suggest_Provider if one is registered or NULL otherwise + * + * @ingroup Lookup + */ +Edi_Language_Provider *edi_language_provider_for_mime_get(const char *mime); + +/** * Query whether a suggest provider is available for the specified editor session. * * @param editor the editor session for a file you wish to get a suggestion provider for diff --git a/src/bin/language/edi_language_provider_rust.c b/src/bin/language/edi_language_provider_rust.c new file mode 100644 index 0000000..3323314 --- /dev/null +++ b/src/bin/language/edi_language_provider_rust.c @@ -0,0 +1,58 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <Eina.h> + +#include "edi_language_provider.h" + +#include "edi_config.h" + +#include "edi_private.h" + +void +_edi_language_rust_add(Edi_Editor *editor EINA_UNUSED) +{ +} + +void +_edi_language_rust_refresh(Edi_Editor *editor EINA_UNUSED) +{ +} + +void +_edi_language_rust_del(Edi_Editor *editor EINA_UNUSED) +{ +} + +const char * +_edi_language_rust_mime_name(const char *mime) +{ + if (!strcasecmp(mime, "text/rust")) + return "Rust source"; + + return NULL; +} + +const char * +_edi_language_rust_snippet_get(const char *key) +{ + if (!strcmp(key, "ret")) + return "return"; + if (!strcmp(key, "if")) + return +"if ()\n" \ +" {\n" \ +" }"; + if (!strcmp(key, "ifel")) + return +"if ()\n" \ +" {\n" \ +" }\n" \ +"else\n" \ +" {\n" \ +" }"; + + return NULL; +} + diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 79db366..f6a126c 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -25,6 +25,7 @@ libedi_la_SOURCES = \ edi_private.h \ edi_build_provider_make.c \ edi_build_provider_cmake.c \ +edi_build_provider_cargo.c \ edi_build_provider_python.c \ edi_build_provider.c \ edi_builder.c \ diff --git a/src/lib/edi_build_provider.c b/src/lib/edi_build_provider.c index 8757377..520ac31 100644 --- a/src/lib/edi_build_provider.c +++ b/src/lib/edi_build_provider.c @@ -9,6 +9,7 @@ extern Edi_Build_Provider _edi_build_provider_make; extern Edi_Build_Provider _edi_build_provider_cmake; +extern Edi_Build_Provider _edi_build_provider_cargo; extern Edi_Build_Provider _edi_build_provider_python; EAPI Edi_Build_Provider *edi_build_provider_for_project_get() @@ -26,6 +27,8 @@ EAPI Edi_Build_Provider *edi_build_provider_for_project_path_get(const char *pat if (_edi_build_provider_cmake.path_supported_is(path)) return &_edi_build_provider_cmake; + if (_edi_build_provider_cargo.path_supported_is(path)) + return &_edi_build_provider_cargo; if (_edi_build_provider_python.path_supported_is(path)) return &_edi_build_provider_python; @@ -38,6 +41,8 @@ EAPI Edi_Build_Provider *edi_build_provider_for_id_get(const char *id) return &_edi_build_provider_make; if (!strcmp("cmake", id)) return &_edi_build_provider_cmake; + if (!strcmp("cargo", id)) + return &_edi_build_provider_cargo; if (!strcmp("python", id)) return &_edi_build_provider_python; diff --git a/src/lib/edi_build_provider.h b/src/lib/edi_build_provider.h index 7c9f740..6e68869 100644 --- a/src/lib/edi_build_provider.h +++ b/src/lib/edi_build_provider.h @@ -16,9 +16,11 @@ typedef struct _Edi_Build_Provider Eina_Bool (*path_supported_is)(const char *path); Eina_Bool (*file_hidden_is)(const char *path); + Eina_Bool (*project_runnable_is)(const char *path); void (*build)(void); void (*test)(void); + void (*run)(const char *path, const char *args); void (*clean)(void); } Edi_Build_Provider; diff --git a/src/lib/edi_build_provider_python.c b/src/lib/edi_build_provider_cargo.c similarity index 53% copy from src/lib/edi_build_provider_python.c copy to src/lib/edi_build_provider_cargo.c index c03dbbf..1f8d9c8 100644 --- a/src/lib/edi_build_provider_python.c +++ b/src/lib/edi_build_provider_cargo.c @@ -33,50 +33,65 @@ _exec_cmd(const char *cmd) } static Eina_Bool -_python_project_supported(const char *path) +_cargo_project_supported(const char *path) { - return _relative_path_exists(path, "setup.py"); + return _relative_path_exists(path, "Cargo.toml"); } static Eina_Bool -_python_file_hidden_is(const char *file) +_cargo_file_hidden_is(const char *file) { if (!file || strlen(file) == 0) return EINA_FALSE; - if (eina_str_has_extension(file, ".pyc") || eina_str_has_extension(file, ".pyo")) + if (eina_str_has_extension(file, ".o") || !strcmp(ecore_file_file_get(file), "target")) return EINA_TRUE; return EINA_FALSE; } +static Eina_Bool +_cargo_project_runnable_is(const char *file EINA_UNUSED) +{ + return EINA_TRUE; +} + +static void +_cargo_build(void) +{ + if (chdir(edi_project_get()) == 0) + _exec_cmd("cargo build"); +} + static void -_python_build(void) +_cargo_test(void) { if (chdir(edi_project_get()) == 0) - _exec_cmd("./setup.py build"); + _exec_cmd("cargo test"); } static void -_python_test(void) +_cargo_run(const char *path EINA_UNUSED, const char *args EINA_UNUSED) { if (chdir(edi_project_get()) == 0) - _exec_cmd("./setup.py test"); + _exec_cmd("cargo run"); } static void -_python_clean(void) +_cargo_clean(void) { if (chdir(edi_project_get()) == 0) - _exec_cmd("./setup.py clean --all"); + _exec_cmd("cargo clean"); } -Edi_Build_Provider _edi_build_provider_python = +Edi_Build_Provider _edi_build_provider_cargo = { - "python", - _python_project_supported, - _python_file_hidden_is, - _python_build, - _python_test, - _python_clean + "cargo", + _cargo_project_supported, + _cargo_file_hidden_is, + _cargo_project_runnable_is, + _cargo_build, + _cargo_test, + _cargo_run, + _cargo_clean }; diff --git a/src/lib/edi_build_provider_cmake.c b/src/lib/edi_build_provider_cmake.c index ae9a9d5..525a717 100644 --- a/src/lib/edi_build_provider_cmake.c +++ b/src/lib/edi_build_provider_cmake.c @@ -37,6 +37,15 @@ _cmake_file_hidden_is(const char *file) return EINA_FALSE; } +static Eina_Bool +_cmake_project_runnable_is(const char *path) +{ + if (!path || !path[0]) + return EINA_FALSE; + + return ecore_file_exists(path); +} + static void _cmake_build(void) { @@ -59,6 +68,36 @@ _cmake_test(void) } static void +_cmake_run(const char *path, const char *args) +{ + char *full_cmd; + int full_len; + + if (!path) return; + if (chdir(edi_project_get()) !=0) + ERR("Could not chdir"); + + if (!args) + { + ecore_exe_pipe_run(path, ECORE_EXE_PIPE_READ_LINE_BUFFERED | ECORE_EXE_PIPE_READ | + ECORE_EXE_PIPE_ERROR_LINE_BUFFERED | ECORE_EXE_PIPE_ERROR | + ECORE_EXE_PIPE_WRITE | ECORE_EXE_USE_SH, NULL); + + return; + } + + full_len = strlen(path) + strlen(path); + full_cmd = malloc(sizeof(char) * (full_len + 1)); + snprintf(full_cmd, full_len + 2, "%s %s", path, args); + + ecore_exe_pipe_run(full_cmd, ECORE_EXE_PIPE_READ_LINE_BUFFERED | ECORE_EXE_PIPE_READ | + ECORE_EXE_PIPE_ERROR_LINE_BUFFERED | ECORE_EXE_PIPE_ERROR | + ECORE_EXE_PIPE_WRITE | ECORE_EXE_USE_SH, NULL); + + free(full_cmd); +} + +static void _cmake_clean(void) { if (chdir(edi_project_get()) != 0) @@ -69,5 +108,5 @@ _cmake_clean(void) } Edi_Build_Provider _edi_build_provider_cmake = - {"cmake", _cmake_project_supported, _cmake_file_hidden_is, - _cmake_build, _cmake_test, _cmake_clean}; + {"cmake", _cmake_project_supported, _cmake_file_hidden_is, _cmake_project_runnable_is, + _cmake_build, _cmake_test, _cmake_run, _cmake_clean}; diff --git a/src/lib/edi_build_provider_make.c b/src/lib/edi_build_provider_make.c index daefae8..13fee68 100644 --- a/src/lib/edi_build_provider_make.c +++ b/src/lib/edi_build_provider_make.c @@ -45,6 +45,15 @@ _make_file_hidden_is(const char *file) return EINA_FALSE; } +static Eina_Bool +_make_project_runnable_is(const char *path) +{ + if (!path || !path[0]) + return EINA_FALSE; + + return ecore_file_exists(path); +} + static const char * _make_comand_compound_get(const char *prepend, const char *append) { @@ -127,6 +136,36 @@ _make_test(void) } static void +_make_run(const char *path, const char *args) +{ + char *full_cmd; + int full_len; + + if (!path) return; + if (chdir(edi_project_get()) !=0) + ERR("Could not chdir"); + + if (!args) + { + ecore_exe_pipe_run(path, ECORE_EXE_PIPE_READ_LINE_BUFFERED | ECORE_EXE_PIPE_READ | + ECORE_EXE_PIPE_ERROR_LINE_BUFFERED | ECORE_EXE_PIPE_ERROR | + ECORE_EXE_PIPE_WRITE | ECORE_EXE_USE_SH, NULL); + + return; + } + + full_len = strlen(path) + strlen(path); + full_cmd = malloc(sizeof(char) * (full_len + 1)); + snprintf(full_cmd, full_len + 2, "%s %s", path, args); + + ecore_exe_pipe_run(full_cmd, ECORE_EXE_PIPE_READ_LINE_BUFFERED | ECORE_EXE_PIPE_READ | + ECORE_EXE_PIPE_ERROR_LINE_BUFFERED | ECORE_EXE_PIPE_ERROR | + ECORE_EXE_PIPE_WRITE | ECORE_EXE_USE_SH, NULL); + + free(full_cmd); +} + +static void _make_clean(void) { static const char *cmd = NULL; @@ -141,5 +180,5 @@ _make_clean(void) } Edi_Build_Provider _edi_build_provider_make = - {"make", _make_project_supported, _make_file_hidden_is, - _make_build, _make_test, _make_clean}; + {"make", _make_project_supported, _make_file_hidden_is, _make_project_runnable_is, + _make_build, _make_test, _make_run, _make_clean}; diff --git a/src/lib/edi_build_provider_python.c b/src/lib/edi_build_provider_python.c index c03dbbf..8c446a9 100644 --- a/src/lib/edi_build_provider_python.c +++ b/src/lib/edi_build_provider_python.c @@ -50,6 +50,12 @@ _python_file_hidden_is(const char *file) return EINA_FALSE; } +static Eina_Bool +_python_project_runnable_is(const char *file EINA_UNUSED) +{ + return EINA_TRUE; +} + static void _python_build(void) { @@ -65,6 +71,13 @@ _python_test(void) } static void +_python_run(const char *path EINA_UNUSED, const char *args EINA_UNUSED) +{ + if (chdir(edi_project_get()) == 0) + _exec_cmd("./setup.py run"); +} + +static void _python_clean(void) { if (chdir(edi_project_get()) == 0) @@ -76,7 +89,9 @@ Edi_Build_Provider _edi_build_provider_python = "python", _python_project_supported, _python_file_hidden_is, + _python_project_runnable_is, _python_build, _python_test, + _python_run, _python_clean }; diff --git a/src/lib/edi_builder.c b/src/lib/edi_builder.c index 303fa14..bb5f987 100644 --- a/src/lib/edi_builder.c +++ b/src/lib/edi_builder.c @@ -19,6 +19,16 @@ edi_builder_can_build(void) return !!provider; } +EAPI Eina_Bool +edi_builder_can_run(const char *runpath) +{ + Edi_Build_Provider *provider; + + provider = edi_build_provider_for_project_get(); + + return provider && provider->project_runnable_is(runpath); +} + EAPI void edi_builder_build(void) { @@ -44,6 +54,18 @@ edi_builder_test(void) } EAPI void +edi_builder_run(const char *runpath, const char *args) +{ + Edi_Build_Provider *provider; + + provider = edi_build_provider_for_project_get(); + if (!provider) + return; + + provider->run(runpath, args); +} + +EAPI void edi_builder_clean(void) { Edi_Build_Provider *provider; diff --git a/src/lib/edi_builder.h b/src/lib/edi_builder.h index 1d727e8..cab5918 100644 --- a/src/lib/edi_builder.h +++ b/src/lib/edi_builder.h @@ -33,6 +33,19 @@ EAPI Eina_Bool edi_builder_can_build(void); /** + * Check if Edi can run the current project. + * This may depend on user configuration which is passed into the method. + * + * @return Whether or not the current project has a runnable executable. + * + * @see edi_builder_build(). + * + * @ingroup Builder + */ +EAPI Eina_Bool +edi_builder_can_run(const char *runpath); + +/** * Run a build for the current project. * * @see edi_builder_can_build(). @@ -53,6 +66,16 @@ EAPI void edi_builder_test(void); /** + * Run a resulting executable for the current project. + * + * @see edi_builder_can_run(). + * + * @ingroup Builder + */ +EAPI void +edi_builder_run(const char *runpath, const char *args); + +/** * Run a clean for the current project. * * @see edi_builder_can_build(). --
