Browse Source

Added Rust installer

pipelines/353213535
eidheim 4 years ago
parent
commit
1dd8cb3e36
  1. 4
      docs/language_servers.md
  2. 15
      src/debug_lldb.cpp
  3. 63
      src/filesystem.cpp
  4. 13
      src/filesystem.hpp
  5. 107
      src/notebook.cpp
  6. 1
      src/notebook.hpp
  7. 23
      src/window.cpp

4
docs/language_servers.md

@ -81,9 +81,7 @@ ln -s `which pyls` /usr/local/bin/python-language-server
Install language server: Install language server:
```sh ```sh
rustup component add rust-src rustup toolchain install nightly --component rust-analyzer-preview
rustup toolchain install nightly
rustup component add --toolchain nightly rust-src rust-analyzer-preview
``` ```
- Additional setup within a Rust project: - Additional setup within a Rust project:

15
src/debug_lldb.cpp

@ -1,8 +1,4 @@
#include "debug_lldb.hpp" #include "debug_lldb.hpp"
#include <cstdio>
#ifdef __APPLE__
#include <cstdlib>
#endif
#include "config.hpp" #include "config.hpp"
#include "filesystem.hpp" #include "filesystem.hpp"
#include "process.hpp" #include "process.hpp"
@ -20,19 +16,12 @@ void log(const char *msg, void *) {
} }
Debug::LLDB::LLDB() : state(lldb::StateType::eStateInvalid), buffer_size(131072) { Debug::LLDB::LLDB() : state(lldb::StateType::eStateInvalid), buffer_size(131072) {
if(!getenv("LLDB_DEBUGSERVER_PATH")) {
#ifndef __APPLE__ #ifndef __APPLE__
auto debug_server_path = filesystem::get_executable("lldb-server").string(); auto debug_server_path = filesystem::get_executable("lldb-server").string();
if(debug_server_path != "lldb-server") { if(debug_server_path != "lldb-server")
#ifdef _WIN32 Glib::setenv("LLDB_DEBUGSERVER_PATH", debug_server_path, false);
Glib::setenv("LLDB_DEBUGSERVER_PATH", debug_server_path.c_str(), 0);
#else
setenv("LLDB_DEBUGSERVER_PATH", debug_server_path.c_str(), 0);
#endif #endif
} }
#endif
}
}
void Debug::LLDB::destroy_() { void Debug::LLDB::destroy_() {
{ {

63
src/filesystem.cpp

@ -6,6 +6,10 @@
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
boost::optional<boost::filesystem::path> filesystem::rust_sysroot_path;
boost::optional<boost::filesystem::path> filesystem::rust_nightly_sysroot_path;
boost::optional<std::vector<boost::filesystem::path>> filesystem::executable_search_paths;
//Only use on small files //Only use on small files
std::string filesystem::read(const std::string &path) { std::string filesystem::read(const std::string &path) {
std::string str; std::string str;
@ -82,8 +86,8 @@ std::string filesystem::unescape_argument(const std::string &argument) {
return unescaped; return unescaped;
} }
boost::filesystem::path filesystem::get_current_path() noexcept { const boost::filesystem::path &filesystem::get_current_path() noexcept {
auto current_path = [] { auto get_path = [] {
#ifdef _WIN32 #ifdef _WIN32
boost::system::error_code ec; boost::system::error_code ec;
auto path = boost::filesystem::current_path(ec); auto path = boost::filesystem::current_path(ec);
@ -104,12 +108,12 @@ boost::filesystem::path filesystem::get_current_path() noexcept {
#endif #endif
}; };
static boost::filesystem::path path = current_path(); static boost::filesystem::path path = get_path();
return path; return path;
} }
boost::filesystem::path filesystem::get_home_path() noexcept { const boost::filesystem::path &filesystem::get_home_path() noexcept {
auto home_path = [] { auto get_path = [] {
std::vector<std::string> environment_variables = {"HOME", "AppData"}; std::vector<std::string> environment_variables = {"HOME", "AppData"};
for(auto &variable : environment_variables) { for(auto &variable : environment_variables) {
if(auto ptr = std::getenv(variable.c_str())) { if(auto ptr = std::getenv(variable.c_str())) {
@ -122,12 +126,12 @@ boost::filesystem::path filesystem::get_home_path() noexcept {
return boost::filesystem::path(); return boost::filesystem::path();
}; };
static boost::filesystem::path path = home_path(); static boost::filesystem::path path = get_path();
return path; return path;
} }
boost::filesystem::path filesystem::get_rust_sysroot_path() noexcept { const boost::filesystem::path &filesystem::get_rust_sysroot_path() noexcept {
auto rust_sysroot_path = [] { auto get_path = [] {
std::string path; std::string path;
TinyProcessLib::Process process( TinyProcessLib::Process process(
"rustc --print sysroot", "", "rustc --print sysroot", "",
@ -143,17 +147,32 @@ boost::filesystem::path filesystem::get_rust_sysroot_path() noexcept {
return boost::filesystem::path(); return boost::filesystem::path();
}; };
static boost::filesystem::path path = rust_sysroot_path(); if(!rust_sysroot_path)
return path; rust_sysroot_path = get_path();
return *rust_sysroot_path;
} }
boost::filesystem::path filesystem::get_rust_nightly_sysroot_path() noexcept { boost::filesystem::path filesystem::get_rust_nightly_sysroot_path() noexcept {
auto path = get_rust_sysroot_path(); auto get_path = [] {
if(path.empty()) std::string path;
return {}; TinyProcessLib::Process process(
auto filename = path.filename().string(); // Slightly complicated since "RUSTUP_TOOLCHAIN=nightly rustc --print sysroot" actually installs nightly toolchain if missing...
auto pos = filename.find('-'); "rustup toolchain list|grep nightly > /dev/null && RUSTUP_TOOLCHAIN=nightly rustc --print sysroot", "",
return path.parent_path() / (pos != std::string::npos ? "nightly" + filename.substr(pos) : "nightly"); [&path](const char *buffer, size_t length) {
path += std::string(buffer, length);
},
[](const char *buffer, size_t n) {});
if(process.get_exit_status() == 0) {
while(!path.empty() && (path.back() == '\n' || path.back() == '\r'))
path.pop_back();
return boost::filesystem::path(path);
}
return boost::filesystem::path();
};
if(!rust_nightly_sysroot_path)
rust_nightly_sysroot_path = get_path();
return *rust_nightly_sysroot_path;
} }
boost::filesystem::path filesystem::get_short_path(const boost::filesystem::path &path) noexcept { boost::filesystem::path filesystem::get_short_path(const boost::filesystem::path &path) noexcept {
@ -299,10 +318,13 @@ boost::filesystem::path filesystem::get_executable(const boost::filesystem::path
// Based on https://stackoverflow.com/a/11295568 // Based on https://stackoverflow.com/a/11295568
const std::vector<boost::filesystem::path> &filesystem::get_executable_search_paths() { const std::vector<boost::filesystem::path> &filesystem::get_executable_search_paths() {
auto executable_search_paths = [] { auto get_paths = [] {
std::vector<boost::filesystem::path> paths; std::vector<boost::filesystem::path> paths;
const std::string env = getenv("PATH"); auto c_env = std::getenv("PATH");
if(!c_env)
return paths;
const std::string env = c_env;
const char delimiter = ':'; const char delimiter = ':';
size_t previous = 0; size_t previous = 0;
@ -316,8 +338,9 @@ const std::vector<boost::filesystem::path> &filesystem::get_executable_search_pa
return paths; return paths;
}; };
static std::vector<boost::filesystem::path> paths = executable_search_paths(); if(!executable_search_paths)
return paths; executable_search_paths = get_paths();
return *executable_search_paths;
} }
boost::filesystem::path filesystem::find_executable(const std::string &executable_name) { boost::filesystem::path filesystem::find_executable(const std::string &executable_name) {

13
src/filesystem.hpp

@ -1,5 +1,6 @@
#pragma once #pragma once
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <boost/optional.hpp>
#include <string> #include <string>
#include <vector> #include <vector>
@ -17,13 +18,17 @@ public:
static std::string unescape_argument(const std::string &argument); static std::string unescape_argument(const std::string &argument);
/// Does not resolve symbolic links. Returns empty path on failure. /// Does not resolve symbolic links. Returns empty path on failure.
static boost::filesystem::path get_current_path() noexcept; static const boost::filesystem::path &get_current_path() noexcept;
/// Returns empty path on failure /// Returns empty path on failure
static boost::filesystem::path get_home_path() noexcept; static const boost::filesystem::path &get_home_path() noexcept;
/// Returns empty path on failure /// Returns empty path on failure
static boost::filesystem::path get_rust_sysroot_path() noexcept; static const boost::filesystem::path &get_rust_sysroot_path() noexcept;
/// Set to {} to reset get_rust_sysroot_path
static boost::optional<boost::filesystem::path> rust_sysroot_path;
/// Returns empty path on failure /// Returns empty path on failure
static boost::filesystem::path get_rust_nightly_sysroot_path() noexcept; static boost::filesystem::path get_rust_nightly_sysroot_path() noexcept;
/// Set to {} to reset get_rust_sysroot_path
static boost::optional<boost::filesystem::path> rust_nightly_sysroot_path;
/// Replaces home path with ~ /// Replaces home path with ~
static boost::filesystem::path get_short_path(const boost::filesystem::path &path) noexcept; static boost::filesystem::path get_short_path(const boost::filesystem::path &path) noexcept;
/// Replaces ~ with home path (boost::filesystem does not recognize ~) /// Replaces ~ with home path (boost::filesystem does not recognize ~)
@ -43,6 +48,8 @@ public:
static boost::filesystem::path get_executable(const boost::filesystem::path &executable_name) noexcept; static boost::filesystem::path get_executable(const boost::filesystem::path &executable_name) noexcept;
static const std::vector<boost::filesystem::path> &get_executable_search_paths(); static const std::vector<boost::filesystem::path> &get_executable_search_paths();
/// Set to {} to reset get_executable_search_paths
static boost::optional<std::vector<boost::filesystem::path>> executable_search_paths;
/// Returns full executable path if found, or empty path otherwise. /// Returns full executable path if found, or empty path otherwise.
static boost::filesystem::path find_executable(const std::string &executable_name); static boost::filesystem::path find_executable(const std::string &executable_name);

107
src/notebook.cpp

@ -68,6 +68,21 @@ Notebook::Notebook() : Gtk::Paned(), notebooks(2) {
}); });
} }
pack1(notebooks[0], true, true); pack1(notebooks[0], true, true);
if(filesystem::find_executable("rustup").empty()) {
// PATH might not be set (for instance after installation)
auto cargo_bin = filesystem::get_home_path() / ".cargo" / "bin";
boost::system::error_code ec;
if(boost::filesystem::is_directory(cargo_bin, ec)) {
std::string env;
if(auto c_env = std::getenv("PATH"))
env = c_env;
Glib::setenv("PATH", !env.empty() ? env + ':' + cargo_bin.string() : cargo_bin.string());
filesystem::rust_sysroot_path = {};
filesystem::rust_nightly_sysroot_path = {};
filesystem::executable_search_paths = {};
}
}
} }
size_t Notebook::size() { size_t Notebook::size() {
@ -179,6 +194,10 @@ bool Notebook::open(const boost::filesystem::path &file_path_, Position position
if(!filesystem::find_executable("rust-analyzer").empty()) if(!filesystem::find_executable("rust-analyzer").empty())
source_views.emplace_back(new Source::LanguageProtocolView(file_path, language, language_protocol_language_id, "rust-analyzer")); source_views.emplace_back(new Source::LanguageProtocolView(file_path, language, language_protocol_language_id, "rust-analyzer"));
else { else {
if(filesystem::find_executable("rustup").empty())
install_rust();
if(!filesystem::find_executable("rustup").empty()) {
// Try find rust-analyzer installed with rustup
auto sysroot = filesystem::get_rust_sysroot_path(); auto sysroot = filesystem::get_rust_sysroot_path();
if(!sysroot.empty()) { if(!sysroot.empty()) {
auto rust_analyzer = sysroot / "bin" / "rust-analyzer"; auto rust_analyzer = sysroot / "bin" / "rust-analyzer";
@ -186,6 +205,7 @@ bool Notebook::open(const boost::filesystem::path &file_path_, Position position
if(boost::filesystem::exists(rust_analyzer, ec)) if(boost::filesystem::exists(rust_analyzer, ec))
source_views.emplace_back(new Source::LanguageProtocolView(file_path, language, language_protocol_language_id, filesystem::escape_argument(rust_analyzer.string()))); source_views.emplace_back(new Source::LanguageProtocolView(file_path, language, language_protocol_language_id, filesystem::escape_argument(rust_analyzer.string())));
else { else {
// Workaround while rust-analyzer is in nightly toolchain only
auto nightly_sysroot = filesystem::get_rust_nightly_sysroot_path(); auto nightly_sysroot = filesystem::get_rust_nightly_sysroot_path();
if(!nightly_sysroot.empty()) { if(!nightly_sysroot.empty()) {
auto nightly_rust_analyzer = nightly_sysroot / "bin" / "rust-analyzer"; auto nightly_rust_analyzer = nightly_sysroot / "bin" / "rust-analyzer";
@ -193,11 +213,14 @@ bool Notebook::open(const boost::filesystem::path &file_path_, Position position
if(boost::filesystem::exists(nightly_rust_analyzer, ec)) if(boost::filesystem::exists(nightly_rust_analyzer, ec))
source_views.emplace_back(new Source::LanguageProtocolView(file_path, language, language_protocol_language_id, filesystem::escape_argument(nightly_rust_analyzer.string()))); source_views.emplace_back(new Source::LanguageProtocolView(file_path, language, language_protocol_language_id, filesystem::escape_argument(nightly_rust_analyzer.string())));
} }
}
}
if(source_views_previous_size == source_views.size()) { if(source_views_previous_size == source_views.size()) {
// Install rust-analyzer
auto install_rust_analyzer = [this](const std::string &command) { auto install_rust_analyzer = [this](const std::string &command) {
Gtk::MessageDialog dialog(*static_cast<Gtk::Window *>(get_toplevel()), "Install rust-analyzer (Rust language server)", false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO); Gtk::MessageDialog dialog(*static_cast<Gtk::Window *>(get_toplevel()), "Install Rust language server", false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO);
dialog.set_default_response(Gtk::RESPONSE_YES); dialog.set_default_response(Gtk::RESPONSE_YES);
dialog.set_secondary_text("Would you like to install rust-analyzer through rustup?"); dialog.set_secondary_text("Rust language server not found. Would you like to install rust-analyzer?");
int result = dialog.run(); int result = dialog.run();
dialog.hide(); dialog.hide();
if(result == Gtk::RESPONSE_YES) { if(result == Gtk::RESPONSE_YES) {
@ -206,7 +229,9 @@ bool Notebook::open(const boost::filesystem::path &file_path_, Position position
canceled = true; canceled = true;
}); });
boost::optional<int> exit_status; boost::optional<int> exit_status;
auto process = Terminal::get().async_process(std::string(command), "", [&exit_status](int exit_status_) {
Terminal::get().print("\e[2mRunning: " + command + "\e[m\n");
auto process = Terminal::get().async_process(command, "", [&exit_status](int exit_status_) {
exit_status = exit_status_; exit_status = exit_status_;
}); });
bool killed = false; bool killed = false;
@ -220,29 +245,32 @@ bool Notebook::open(const boost::filesystem::path &file_path_, Position position
std::this_thread::sleep_for(std::chrono::milliseconds(10)); std::this_thread::sleep_for(std::chrono::milliseconds(10));
} }
if(exit_status == 0) { if(exit_status == 0) {
Terminal::get().print("\e[32mSuccessfully\e[m installed rust-analyzer.\n"); Terminal::get().print("\e[32mSuccess\e[m: installed rust-analyzer\n");
return true; return true;
} }
} }
return false; return false;
}; };
static bool first = true; static bool first = true;
if(first && !filesystem::find_executable("rustup").empty()) { if(first) {
first = false; first = false;
std::stringstream stdin_stream, stdout_stream; std::stringstream stdin_stream, stdout_stream;
// Workaround while rust-analyzer is called rust-analyzer-preview instead of rust-analyzer
if(Terminal::get().process(stdin_stream, stdout_stream, "rustup component list") == 0) { if(Terminal::get().process(stdin_stream, stdout_stream, "rustup component list") == 0) {
bool rust_analyzer_in_toolchain = false; bool rust_analyzer_in_toolchain = false;
std::string line; std::string line;
while(std::getline(stdout_stream, line)) { while(std::getline(stdout_stream, line)) {
if(starts_with(line, "rust-analyzer")) { if(starts_with(line, "rust-analyzer")) {
if(install_rust_analyzer(std::string("rustup component add rust-src ") + (starts_with(line, "rust-analyzer-preview") ? "rust-analyzer-preview" : "rust-analyzer"))) if(install_rust_analyzer(std::string("rustup component add ") + (starts_with(line, "rust-analyzer-preview") ? "rust-analyzer-preview" : "rust-analyzer")))
source_views.emplace_back(new Source::LanguageProtocolView(file_path, language, language_protocol_language_id, filesystem::escape_argument(rust_analyzer.string()))); source_views.emplace_back(new Source::LanguageProtocolView(file_path, language, language_protocol_language_id, filesystem::escape_argument((filesystem::get_rust_sysroot_path() / "bin" / "rust-analyzer").string())));
rust_analyzer_in_toolchain = true; rust_analyzer_in_toolchain = true;
break; break;
} }
} }
if(!rust_analyzer_in_toolchain && install_rust_analyzer("rustup component add rust-src && rustup toolchain install nightly && rustup component add --toolchain nightly rust-src rust-analyzer-preview")) // Workaround while rust-analyzer is in nightly toolchain only
source_views.emplace_back(new Source::LanguageProtocolView(file_path, language, language_protocol_language_id, "rustup run nightly rust-analyzer")); if(!rust_analyzer_in_toolchain && install_rust_analyzer("rustup toolchain install nightly --component rust-analyzer-preview")) {
filesystem::rust_nightly_sysroot_path = {};
source_views.emplace_back(new Source::LanguageProtocolView(file_path, language, language_protocol_language_id, filesystem::escape_argument((filesystem::get_rust_nightly_sysroot_path() / "bin" / "rust-analyzer").string())));
} }
} }
} }
@ -266,15 +294,12 @@ bool Notebook::open(const boost::filesystem::path &file_path_, Position position
} }
else if(language_id == "rust") { else if(language_id == "rust") {
auto rust_installed = !filesystem::get_rust_sysroot_path().empty(); auto rust_installed = !filesystem::get_rust_sysroot_path().empty();
if(!rust_installed) { Terminal::get().print(std::string("\e[33mWarning\e[m: could not find Rust") + (rust_installed ? " language server" : "") + ".\n");
Terminal::get().print("\e[33mWarning\e[m: could not find Rust. You can install Rust by running the following command in a terminal:\n\n");
Terminal::get().print("curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh\n\n");
Terminal::get().print("You will need to restart juCi++ after installing Rust.\n");
}
else {
Terminal::get().print("\e[33mWarning\e[m: could not find Rust language server.\n");
Terminal::get().print("For installation instructions please visit: https://gitlab.com/cppit/jucipp/-/blob/master/docs/language_servers.md#rust.\n"); Terminal::get().print("For installation instructions please visit: https://gitlab.com/cppit/jucipp/-/blob/master/docs/language_servers.md#rust.\n");
} if(!rust_installed)
Terminal::get().print("You will need to restart juCi++ after installing Rust.\n");
shown.emplace(language_id);
shown.emplace(language_id); shown.emplace(language_id);
} }
else if(language_id == "go") { else if(language_id == "go") {
@ -579,6 +604,54 @@ bool Notebook::open(const boost::filesystem::path &file_path_, Position position
return true; return true;
} }
void Notebook::install_rust() {
static bool first = true;
if(first) {
first = false;
Gtk::MessageDialog dialog(*static_cast<Gtk::Window *>(get_toplevel()), "Install Rust", false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO);
dialog.set_default_response(Gtk::RESPONSE_YES);
dialog.set_secondary_text("Rust not found. Would you like to install Rust?");
int result = dialog.run();
dialog.hide();
if(result == Gtk::RESPONSE_YES) {
bool canceled = false;
Dialog::Message message("Installing Rust", [&canceled] {
canceled = true;
});
boost::optional<int> exit_status;
std::string command = "curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y";
Terminal::get().print("\e[2mRunning: " + command + "\e[m\n");
auto process = Terminal::get().async_process(command, "", [&exit_status](int exit_status_) {
exit_status = exit_status_;
});
bool killed = false;
while(!exit_status) {
if(canceled && !killed) {
process->kill();
killed = true;
}
while(Gtk::Main::events_pending())
Gtk::Main::iteration();
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
if(exit_status == 0) {
if(filesystem::find_executable("rustup").empty()) {
std::string env;
if(auto c_env = std::getenv("PATH"))
env = c_env;
auto cargo_bin = filesystem::get_home_path() / ".cargo" / "bin";
Glib::setenv("PATH", !env.empty() ? env + ':' + cargo_bin.string() : cargo_bin.string());
}
filesystem::rust_sysroot_path = {};
filesystem::rust_nightly_sysroot_path = {};
filesystem::executable_search_paths = {};
Terminal::get().print("\e[32mSuccess\e[m: installed Rust and updated PATH environment variable\n");
}
}
}
}
void Notebook::open_uri(const std::string &uri) { void Notebook::open_uri(const std::string &uri) {
#ifdef __APPLE__ #ifdef __APPLE__
Terminal::get().process("open " + filesystem::escape_argument(uri)); Terminal::get().process("open " + filesystem::escape_argument(uri));

1
src/notebook.hpp

@ -45,6 +45,7 @@ public:
}; };
bool open(Source::View *view); bool open(Source::View *view);
bool open(const boost::filesystem::path &file_path, Position position = Position::infer); bool open(const boost::filesystem::path &file_path, Position position = Position::infer);
void install_rust();
void open_uri(const std::string &uri); void open_uri(const std::string &uri);
void configure(size_t index); void configure(size_t index);
bool save(size_t index); bool save(size_t index);

23
src/window.cpp

@ -381,9 +381,9 @@ void Window::set_menu_actions() {
Directories::get().open(project_path); Directories::get().open(project_path);
Notebook::get().open(c_main_path); Notebook::get().open(c_main_path);
Directories::get().update(); Directories::get().update();
Terminal::get().print("C project "); Terminal::get().print("\e[32mSuccess\e[m: created C project ");
Terminal::get().print(project_name, true); Terminal::get().print(project_name, true);
Terminal::get().print(" \e[32mcreated\e[m\n"); Terminal::get().print("\n");
} }
else else
Terminal::get().print("\e[31mError\e[m: could not create project " + filesystem::get_short_path(project_path).string() + "\n", true); Terminal::get().print("\e[31mError\e[m: could not create project " + filesystem::get_short_path(project_path).string() + "\n", true);
@ -438,19 +438,20 @@ void Window::set_menu_actions() {
Directories::get().open(project_path); Directories::get().open(project_path);
Notebook::get().open(cpp_main_path); Notebook::get().open(cpp_main_path);
Directories::get().update(); Directories::get().update();
Terminal::get().print("C++ project "); Terminal::get().print("\e[32mSuccess\e[m: created C++ project ");
Terminal::get().print(project_name, true); Terminal::get().print(project_name, true);
Terminal::get().print(" \e[32mcreated\e[m\n"); Terminal::get().print("\n");
} }
else else
Terminal::get().print("\e[31mError\e[m: could not create project " + filesystem::get_short_path(project_path).string() + "\n", true); Terminal::get().print("\e[31mError\e[m: could not create project " + filesystem::get_short_path(project_path).string() + "\n", true);
} }
}); });
menu.add_action("file_new_project_rust", []() { menu.add_action("file_new_project_rust", []() {
auto sysroot = filesystem::get_rust_sysroot_path(); if(filesystem::find_executable("rustup").empty())
if(sysroot.empty()) { Notebook::get().install_rust();
Terminal::get().print("\e[31mError\e[m: could not find Rust. You can install Rust by running the following command in a terminal:\n\n"); if(filesystem::find_executable("rustup").empty()) {
Terminal::get().print("curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh\n\n"); Terminal::get().print("\e[33mWarning\e[m: could not find Rust.\n");
Terminal::get().print("For installation instructions please visit: https://gitlab.com/cppit/jucipp/-/blob/master/docs/language_servers.md#rust.\n");
Terminal::get().print("You will need to restart juCi++ after installing Rust.\n"); Terminal::get().print("You will need to restart juCi++ after installing Rust.\n");
return; return;
} }
@ -467,9 +468,9 @@ void Window::set_menu_actions() {
Directories::get().open(project_path); Directories::get().open(project_path);
Notebook::get().open(project_path / "src" / "main.rs"); Notebook::get().open(project_path / "src" / "main.rs");
Directories::get().update(); Directories::get().update();
Terminal::get().print("Rust project "); Terminal::get().print("\e[32mSuccess\e[m: created Rust project ");
Terminal::get().print(project_path.filename().string(), true); Terminal::get().print(project_name, true);
Terminal::get().print(" \e[32mcreated\e[m\n"); Terminal::get().print("\n");
} }
else else
Terminal::get().print("\e[31mError\e[m: could not create project " + filesystem::get_short_path(project_path).string() + "\n", true); Terminal::get().print("\e[31mError\e[m: could not create project " + filesystem::get_short_path(project_path).string() + "\n", true);

Loading…
Cancel
Save