Browse Source

Added compile and run support for Julia

merge-requests/404/merge
eidheim 5 years ago
parent
commit
68fe6bab1a
  1. 29
      docs/language_servers.md
  2. 46
      src/project.cpp
  3. 9
      src/project.hpp
  4. 3
      src/source.cpp
  5. 5
      src/source_base.cpp
  6. 2
      src/source_language_protocol.cpp
  7. 10
      src/tooltips.cpp

29
docs/language_servers.md

@ -4,6 +4,7 @@
- [Python3](#python3) - [Python3](#python3)
- [Rust](#rust) - [Rust](#rust)
- [Go](#go) - [Go](#go)
- [Julia](#julia)
- [GLSL](#glsl) - [GLSL](#glsl)
## JavaScript/TypeScript ## JavaScript/TypeScript
@ -110,6 +111,34 @@ ln -s `which gopls` /usr/local/bin/go-language-server
- Additional setup within a Go project: - Additional setup within a Go project:
- Add an empty `.go-format` file to enable style format on save - Add an empty `.go-format` file to enable style format on save
## Julia
- Prerequisites:
- [Julia](https://julialang.org/downloads/)
Install language server, and create symbolic link to enable server in juCi++:
```sh
julia -e 'using Pkg;Pkg.add("LanguageServer");Pkg.add("SymbolServer");Pkg.add("StaticLint");'
# Usually as root:
echo '#!/bin/sh
julia --startup-file=no --history-file=no -e '\''
using LanguageServer;
using Pkg;
import StaticLint;
import SymbolServer;
env_path = dirname(Pkg.Types.Context().env.project_file);
server = LanguageServer.LanguageServerInstance(stdin, stdout, env_path, "");
server.runlinter = true;
run(server);
'\''' > /usr/local/bin/julia-language-server
chmod 755 /usr/local/bin/julia-language-server
```
- Additional setup within a Julia project:
- Add an empty `.julia-format` file to enable style format on save
## GLSL ## GLSL
Install language server, and create a script to enable server in juCi++: Install language server, and create a script to enable server in juCi++:

46
src/project.cpp

@ -184,6 +184,8 @@ std::shared_ptr<Project::Base> Project::create() {
return std::shared_ptr<Project::Base>(new Project::HTML(std::move(build))); return std::shared_ptr<Project::Base>(new Project::HTML(std::move(build)));
if(language_id == "go") if(language_id == "go")
return std::shared_ptr<Project::Base>(new Project::Go(std::move(build))); return std::shared_ptr<Project::Base>(new Project::Go(std::move(build)));
if(language_id == "julia")
return std::shared_ptr<Project::Base>(new Project::Julia(std::move(build)));
} }
} }
else else
@ -853,15 +855,12 @@ void Project::Python::compile_and_run() {
command += filesystem::get_short_path(build->project_path).string(); command += filesystem::get_short_path(build->project_path).string();
path = build->project_path; path = build->project_path;
} }
else { else if(auto view = Notebook::get().get_current_view()) {
auto view = Notebook::get().get_current_view();
if(!view) {
Info::get().print("No executable found");
return;
}
command += filesystem::escape_argument(filesystem::get_short_path(view->file_path).string()); command += filesystem::escape_argument(filesystem::get_short_path(view->file_path).string());
path = view->file_path.parent_path(); path = view->file_path.parent_path();
} }
else
return;
if(Config::get().terminal.clear_on_compile) if(Config::get().terminal.clear_on_compile)
Terminal::get().clear(); Terminal::get().clear();
@ -879,15 +878,12 @@ void Project::JavaScript::compile_and_run() {
command = "npm start"; command = "npm start";
path = build->project_path; path = build->project_path;
} }
else { else if(auto view = Notebook::get().get_current_view()) {
auto view = Notebook::get().get_current_view();
if(!view) {
Info::get().print("No executable found");
return;
}
command = "node " + filesystem::escape_argument(filesystem::get_short_path(view->file_path).string()); command = "node " + filesystem::escape_argument(filesystem::get_short_path(view->file_path).string());
path = view->file_path.parent_path(); path = view->file_path.parent_path();
} }
else
return;
if(Config::get().terminal.clear_on_compile) if(Config::get().terminal.clear_on_compile)
Terminal::get().clear(); Terminal::get().clear();
@ -967,21 +963,33 @@ void Project::Go::compile_and_run() {
command = "go run ."; command = "go run .";
path = build->project_path; path = build->project_path;
} }
else { else if(auto view = Notebook::get().get_current_view()) {
auto view = Notebook::get().get_current_view();
if(!view) {
Info::get().print("No executable found");
return;
}
command = "go run " + filesystem::escape_argument(filesystem::get_short_path(view->file_path).string()); command = "go run " + filesystem::escape_argument(filesystem::get_short_path(view->file_path).string());
path = view->file_path.parent_path(); path = view->file_path.parent_path();
} }
else
return;
if(Config::get().terminal.clear_on_compile) if(Config::get().terminal.clear_on_compile)
Terminal::get().clear(); Terminal::get().clear();
Terminal::get().print("\e[2mRunning: " + command + "\e[m\n"); Terminal::get().print("\e[2mRunning: " + command + "\e[m\n");
Terminal::get().async_process(command, build->project_path, [command](int exit_status) { Terminal::get().async_process(command, path, [command](int exit_status) {
Terminal::get().print("\e[2m" + command + " returned: " + (exit_status == 0 ? "\e[32m" : "\e[31m") + std::to_string(exit_status) + "\e[m\n"); Terminal::get().print("\e[2m" + command + " returned: " + (exit_status == 0 ? "\e[32m" : "\e[31m") + std::to_string(exit_status) + "\e[m\n");
}); });
} }
void Project::Julia::compile_and_run() {
if(auto view = Notebook::get().get_current_view()) {
auto command = "julia " + filesystem::escape_argument(filesystem::get_short_path(Notebook::get().get_current_view()->file_path).string());
auto path = view->file_path.parent_path();
if(Config::get().terminal.clear_on_compile)
Terminal::get().clear();
Terminal::get().print("\e[2mRunning: " + command + "\e[m\n");
Terminal::get().async_process(command, path, [command](int exit_status) {
Terminal::get().print("\e[2m" + command + " returned: " + (exit_status == 0 ? "\e[32m" : "\e[31m") + std::to_string(exit_status) + "\e[m\n");
});
}
}

9
src/project.hpp

@ -171,6 +171,15 @@ namespace Project {
std::string get_language_id() override { return "go"; } std::string get_language_id() override { return "go"; }
}; };
class Julia : public LanguageProtocol {
public:
Julia(std::unique_ptr<Build> &&build) : Base(std::move(build)) {}
void compile_and_run() override;
std::string get_language_id() override { return "julia"; }
};
std::shared_ptr<Base> create(); std::shared_ptr<Base> create();
extern std::shared_ptr<Base> current; extern std::shared_ptr<Base> current;
}; // namespace Project }; // namespace Project

3
src/source.cpp

@ -224,7 +224,8 @@ Source::View::View(const boost::filesystem::path &file_path, const Glib::RefPtr<
if(language_id == "cmake" || language_id == "makefile" || language_id == "python" || if(language_id == "cmake" || language_id == "makefile" || language_id == "python" ||
language_id == "python3" || language_id == "sh" || language_id == "perl" || language_id == "python3" || language_id == "sh" || language_id == "perl" ||
language_id == "ruby" || language_id == "r" || language_id == "asm" || language_id == "ruby" || language_id == "r" || language_id == "asm" ||
language_id == "automake" || language_id == "yaml" || language_id == "docker") language_id == "automake" || language_id == "yaml" || language_id == "docker" ||
language_id == "julia")
comment_characters = "#"; comment_characters = "#";
else if(language_id == "latex" || language_id == "matlab" || language_id == "octave" || language_id == "bibtex") else if(language_id == "latex" || language_id == "matlab" || language_id == "octave" || language_id == "bibtex")
comment_characters = "%"; comment_characters = "%";

5
src/source_base.cpp

@ -291,11 +291,12 @@ Source::BaseView::BaseView(const boost::filesystem::path &file_path, const Glib:
tab_char = Config::get().source.default_tab_char; tab_char = Config::get().source.default_tab_char;
tab_size = Config::get().source.default_tab_size; tab_size = Config::get().source.default_tab_size;
if(language) { if(language) {
if(language->get_id() == "python" || language->get_id() == "rust") { auto language_id = language->get_id();
if(language_id == "python" || language_id == "rust" || language_id == "julia") {
tab_char = ' '; tab_char = ' ';
tab_size = 4; tab_size = 4;
} }
else if(language->get_id() == "go") { else if(language_id == "go") {
tab_char = '\t'; tab_char = '\t';
tab_size = 1; tab_size = 1;
} }

2
src/source_language_protocol.cpp

@ -369,7 +369,7 @@ void LanguageProtocol::Client::write_request(Source::LanguageProtocolView *view,
LockGuard lock(timeout_threads_mutex); LockGuard lock(timeout_threads_mutex);
timeout_threads.emplace_back([this, message_id] { timeout_threads.emplace_back([this, message_id] {
for(size_t c = 0; c < 20; ++c) { for(size_t c = 0; c < 20; ++c) {
std::this_thread::sleep_for(std::chrono::milliseconds(500)); std::this_thread::sleep_for(std::chrono::milliseconds(50000) * (language_id == "julia" ? 100 : 1));
LockGuard lock(read_write_mutex); LockGuard lock(read_write_mutex);
auto id_it = handlers.find(message_id); auto id_it = handlers.find(message_id);
if(id_it == handlers.end()) if(id_it == handlers.end())

10
src/tooltips.cpp

@ -155,19 +155,21 @@ void Tooltip::show(bool disregard_drawn, const std::function<void()> &on_motion)
return true; return true;
} }
const static std::regex regex("^([^:]+):([^:]+):([^:]+)$", std::regex::optimize); const static std::regex regex("^([^:]+):([^:]+)(:[^:]+)?$", std::regex::optimize);
std::smatch sm; std::smatch sm;
if(std::regex_match(link, sm, regex)) { if(std::regex_match(link, sm, regex)) {
auto path = boost::filesystem::path(sm[1].str()); auto path = boost::filesystem::path(sm[1].str());
if(auto source_view = dynamic_cast<Source::View *>(view)) if(path.is_relative()) {
path = filesystem::get_normal_path(source_view->file_path.parent_path() / path); if(auto source_view = dynamic_cast<Source::View *>(view))
path = filesystem::get_normal_path(source_view->file_path.parent_path() / path);
}
boost::system::error_code ec; boost::system::error_code ec;
if(boost::filesystem::is_regular_file(path, ec)) { if(boost::filesystem::is_regular_file(path, ec)) {
if(Notebook::get().open(path)) { if(Notebook::get().open(path)) {
try { try {
auto line = std::stoi(sm[2].str()) - 1; auto line = std::stoi(sm[2].str()) - 1;
auto offset = std::stoi(sm[3].str()) - 1; auto offset = sm.length(3) ? std::stoi(sm[3].str().substr(1)) - 1 : 0;
auto view = Notebook::get().get_current_view(); auto view = Notebook::get().get_current_view();
view->place_cursor_at_line_offset(line, offset); view->place_cursor_at_line_offset(line, offset);
view->scroll_to_cursor_delayed(true, false); view->scroll_to_cursor_delayed(true, false);

Loading…
Cancel
Save