Browse Source

use correct format on certain parts

pipelines/235045657
Jørgen Lien Sellæg 5 years ago
parent
commit
bca93a62dc
  1. 7
      src/autocomplete.hpp
  2. 5
      src/directories.hpp
  3. 107
      src/git.cpp
  4. 8
      src/notebook.hpp
  5. 7
      src/source.cpp
  6. 6
      src/source.hpp
  7. 107
      src/source_clang.cpp
  8. 14
      src/source_clang.hpp
  9. 8
      src/source_diff.hpp
  10. 77
      src/source_language_protocol.cpp
  11. 37
      src/terminal.cpp
  12. 78
      src/usages_clang.cpp
  13. 77
      src/window.cpp
  14. 23
      tests/process_test.cpp
  15. 16
      tests/terminal_test.cpp

7
src/autocomplete.hpp

@ -16,7 +16,12 @@ class Autocomplete {
Dispatcher dispatcher; Dispatcher dispatcher;
public: public:
enum class State { idle, starting, restarting, canceled }; enum class State {
idle,
starting,
restarting,
canceled
};
Mutex prefix_mutex; Mutex prefix_mutex;
Glib::ustring prefix GUARDED_BY(prefix_mutex); Glib::ustring prefix GUARDED_BY(prefix_mutex);

5
src/directories.hpp

@ -18,7 +18,10 @@ class Directories : public Gtk::ListViewText {
std::shared_ptr<sigc::connection> connection; std::shared_ptr<sigc::connection> connection;
}; };
enum class PathType { known, unknown }; enum class PathType {
known,
unknown
};
class TreeStore : public Gtk::TreeStore { class TreeStore : public Gtk::TreeStore {
protected: protected:

107
src/git.cpp

@ -36,20 +36,21 @@ Git::Repository::Diff::Diff(const boost::filesystem::path &path, git_repository
Git::Repository::Diff::Lines Git::Repository::Diff::get_lines(const std::string &buffer) { Git::Repository::Diff::Lines Git::Repository::Diff::get_lines(const std::string &buffer) {
Lines lines; Lines lines;
LockGuard lock(mutex); LockGuard lock(mutex);
error.code = git_diff_blob_to_buffer(blob.get(), nullptr, buffer.c_str(), buffer.size(), nullptr, &options, nullptr, nullptr, [](const git_diff_delta *delta, const git_diff_hunk *hunk, void *payload) { error.code = git_diff_blob_to_buffer(
//Based on https://github.com/atom/git-diff/blob/master/lib/git-diff-view.coffee blob.get(), nullptr, buffer.c_str(), buffer.size(), nullptr, &options, nullptr, nullptr, [](const git_diff_delta *delta, const git_diff_hunk *hunk, void *payload) {
auto lines = static_cast<Lines *>(payload); //Based on https://github.com/atom/git-diff/blob/master/lib/git-diff-view.coffee
auto start = hunk->new_start - 1; auto lines = static_cast<Lines *>(payload);
auto end = hunk->new_start + hunk->new_lines - 1; auto start = hunk->new_start - 1;
if(hunk->old_lines == 0 && hunk->new_lines > 0) auto end = hunk->new_start + hunk->new_lines - 1;
lines->added.emplace_back(start, end); if(hunk->old_lines == 0 && hunk->new_lines > 0)
else if(hunk->new_lines == 0 && hunk->old_lines > 0) lines->added.emplace_back(start, end);
lines->removed.emplace_back(start); else if(hunk->new_lines == 0 && hunk->old_lines > 0)
else lines->removed.emplace_back(start);
lines->modified.emplace_back(start, end); else
lines->modified.emplace_back(start, end);
return 0; return 0;
}, nullptr, &lines); },
nullptr, &lines);
if(error) if(error)
throw std::runtime_error(error.message()); throw std::runtime_error(error.message());
return lines; return lines;
@ -62,11 +63,13 @@ std::vector<Git::Repository::Diff::Hunk> Git::Repository::Diff::get_hunks(const
git_diff_options options; git_diff_options options;
git_diff_init_options(&options, GIT_DIFF_OPTIONS_VERSION); git_diff_init_options(&options, GIT_DIFF_OPTIONS_VERSION);
options.context_lines = 0; options.context_lines = 0;
error.code = git_diff_buffers(old_buffer.c_str(), old_buffer.size(), nullptr, new_buffer.c_str(), new_buffer.size(), nullptr, &options, nullptr, nullptr, [](const git_diff_delta *delta, const git_diff_hunk *hunk, void *payload) { error.code = git_diff_buffers(
auto hunks = static_cast<std::vector<Git::Repository::Diff::Hunk> *>(payload); old_buffer.c_str(), old_buffer.size(), nullptr, new_buffer.c_str(), new_buffer.size(), nullptr, &options, nullptr, nullptr, [](const git_diff_delta *delta, const git_diff_hunk *hunk, void *payload) {
hunks->emplace_back(hunk->old_start, hunk->old_lines, hunk->new_start, hunk->new_lines); auto hunks = static_cast<std::vector<Git::Repository::Diff::Hunk> *>(payload);
return 0; hunks->emplace_back(hunk->old_start, hunk->old_lines, hunk->new_start, hunk->new_lines);
}, nullptr, &hunks); return 0;
},
nullptr, &hunks);
if(error) if(error)
throw std::runtime_error(error.message()); throw std::runtime_error(error.message());
return hunks; return hunks;
@ -76,18 +79,20 @@ std::string Git::Repository::Diff::get_details(const std::string &buffer, int li
std::pair<std::string, int> details; std::pair<std::string, int> details;
details.second = line_nr; details.second = line_nr;
LockGuard lock(mutex); LockGuard lock(mutex);
error.code = git_diff_blob_to_buffer(blob.get(), nullptr, buffer.c_str(), buffer.size(), nullptr, &options, nullptr, nullptr, nullptr, [](const git_diff_delta *delta, const git_diff_hunk *hunk, const git_diff_line *line, void *payload) { error.code = git_diff_blob_to_buffer(
auto details = static_cast<std::pair<std::string, int> *>(payload); blob.get(), nullptr, buffer.c_str(), buffer.size(), nullptr, &options, nullptr, nullptr, nullptr, [](const git_diff_delta *delta, const git_diff_hunk *hunk, const git_diff_line *line, void *payload) {
auto line_nr = details->second; auto details = static_cast<std::pair<std::string, int> *>(payload);
auto start = hunk->new_start - 1; auto line_nr = details->second;
auto end = hunk->new_start + hunk->new_lines - 1; auto start = hunk->new_start - 1;
if(line_nr == start || (line_nr >= start && line_nr < end)) { auto end = hunk->new_start + hunk->new_lines - 1;
if(details->first.empty()) if(line_nr == start || (line_nr >= start && line_nr < end)) {
details->first += std::string(hunk->header, hunk->header_len); if(details->first.empty())
details->first += line->origin + std::string(line->content, line->content_len); details->first += std::string(hunk->header, hunk->header_len);
} details->first += line->origin + std::string(line->content, line->content_len);
return 0; }
}, &details); return 0;
},
&details);
if(error) if(error)
throw std::runtime_error(error.message()); throw std::runtime_error(error.message());
return details.first; return details.first;
@ -138,27 +143,27 @@ Git::Repository::Status Git::Repository::get_status() {
Data data{work_path}; Data data{work_path};
{ {
LockGuard lock(mutex); LockGuard lock(mutex);
error.code = git_status_foreach(repository.get(), [](const char *path, unsigned int status_flags, void *payload) { error.code = git_status_foreach(
auto data = static_cast<Data *>(payload); repository.get(), [](const char *path, unsigned int status_flags, void *payload) {
auto data = static_cast<Data *>(payload);
bool new_ = false; bool new_ = false;
bool modified = false; bool modified = false;
if((status_flags & (GIT_STATUS_INDEX_NEW | GIT_STATUS_WT_NEW)) > 0) if((status_flags & (GIT_STATUS_INDEX_NEW | GIT_STATUS_WT_NEW)) > 0)
new_ = true; new_ = true;
else if((status_flags & (GIT_STATUS_INDEX_MODIFIED | GIT_STATUS_WT_MODIFIED)) > 0) else if((status_flags & (GIT_STATUS_INDEX_MODIFIED | GIT_STATUS_WT_MODIFIED)) > 0)
modified = true; modified = true;
boost::filesystem::path rel_path(path);
boost::filesystem::path rel_path(path); do {
do { if(new_)
if(new_) data->status.added.emplace((data->work_path / rel_path).generic_string());
data->status.added.emplace((data->work_path / rel_path).generic_string()); else if(modified)
else if(modified) data->status.modified.emplace((data->work_path / rel_path).generic_string());
data->status.modified.emplace((data->work_path / rel_path).generic_string()); rel_path = rel_path.parent_path();
rel_path = rel_path.parent_path(); } while(!rel_path.empty());
} while(!rel_path.empty());
return 0; return 0;
}, &data); },
&data);
if(error) if(error)
throw std::runtime_error(error.message()); throw std::runtime_error(error.message());

8
src/notebook.hpp

@ -37,8 +37,12 @@ public:
Source::View *get_view(size_t index); Source::View *get_view(size_t index);
Source::View *get_current_view(); Source::View *get_current_view();
std::vector<Source::View *> &get_views(); std::vector<Source::View *> &get_views();
enum class Position {
enum class Position { left, right, infer, split }; left,
right,
infer,
split
};
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 open_uri(const std::string &uri); void open_uri(const std::string &uri);

7
src/source.cpp

@ -203,6 +203,7 @@ Source::View::View(const boost::filesystem::path &file_path, const Glib::RefPtr<
setup_signals(); setup_signals();
setup_format_style(is_generic_view); setup_format_style(is_generic_view);
std::string comment_characters; std::string comment_characters;
if(is_bracket_language) if(is_bracket_language)
comment_characters = "//"; comment_characters = "//";
@ -375,8 +376,7 @@ Gsv::DrawSpacesFlags Source::View::parse_show_whitespace_characters(const std::s
namespace qi = boost::spirit::qi; namespace qi = boost::spirit::qi;
qi::symbols<char, Gsv::DrawSpacesFlags> options; qi::symbols<char, Gsv::DrawSpacesFlags> options;
options.add("space", Gsv::DRAW_SPACES_SPACE)("tab", Gsv::DRAW_SPACES_TAB)("newline", Gsv::DRAW_SPACES_NEWLINE)("nbsp", Gsv::DRAW_SPACES_NBSP) options.add("space", Gsv::DRAW_SPACES_SPACE)("tab", Gsv::DRAW_SPACES_TAB)("newline", Gsv::DRAW_SPACES_NEWLINE)("nbsp", Gsv::DRAW_SPACES_NBSP)("leading", Gsv::DRAW_SPACES_LEADING)("text", Gsv::DRAW_SPACES_TEXT)("trailing", Gsv::DRAW_SPACES_TRAILING)("all", Gsv::DRAW_SPACES_ALL);
("leading", Gsv::DRAW_SPACES_LEADING)("text", Gsv::DRAW_SPACES_TEXT)("trailing", Gsv::DRAW_SPACES_TRAILING)("all", Gsv::DRAW_SPACES_ALL);
std::set<Gsv::DrawSpacesFlags> out; std::set<Gsv::DrawSpacesFlags> out;
@ -2282,7 +2282,8 @@ bool Source::View::on_key_press_event_basic(GdkEventKey *event) {
bool Source::View::on_key_press_event_bracket_language(GdkEventKey *event) { bool Source::View::on_key_press_event_bracket_language(GdkEventKey *event) {
const static std::regex no_bracket_statement_regex("^[ \t]*(if( +constexpr)?|for|while) *\\(.*[^;}{] *$|" const static std::regex no_bracket_statement_regex("^[ \t]*(if( +constexpr)?|for|while) *\\(.*[^;}{] *$|"
"^[ \t]*[}]? *else if( +constexpr)? *\\(.*[^;}{] *$|" "^[ \t]*[}]? *else if( +constexpr)? *\\(.*[^;}{] *$|"
"^[ \t]*[}]? *else *$", std::regex::extended | std::regex::optimize); "^[ \t]*[}]? *else *$",
std::regex::extended | std::regex::optimize);
auto iter = get_buffer()->get_insert()->get_iter(); auto iter = get_buffer()->get_insert()->get_iter();

6
src/source.hpp

@ -41,7 +41,11 @@ namespace Source {
class FixIt { class FixIt {
public: public:
enum class Type { insert, replace, erase }; enum class Type {
insert,
replace,
erase
};
FixIt(std::string source_, std::string path_, std::pair<Offset, Offset> offsets_); FixIt(std::string source_, std::string path_, std::pair<Offset, Offset> offsets_);

107
src/source_clang.cpp

@ -249,8 +249,7 @@ const std::map<int, std::string> &Source::ClangViewParse::clang_types() {
{46, "def:identifier"}, {46, "def:identifier"},
{109, "def:string"}, {109, "def:string"},
{702, "def:statement"}, {702, "def:statement"},
{705, "def:comment"} {705, "def:comment"}};
};
return types; return types;
} }
@ -579,9 +578,7 @@ void Source::ClangViewParse::show_type_tooltips(const Gdk::Rectangle &rectangle)
else if(type_description[pos] == '>') else if(type_description[pos] == '>')
--angle_count; --angle_count;
++pos; ++pos;
} } while(pos < type_description.size());
while(pos < type_description.size())
;
} }
} }
tooltip.insert_code(type_description, language); tooltip.insert_code(type_description, language);
@ -647,29 +644,34 @@ void Source::ClangViewParse::show_type_tooltips(const Gdk::Rectangle &rectangle)
VisitorData visitor_data{cursor.get_source_range().get_offsets(), cursor.get_spelling(), {}}; VisitorData visitor_data{cursor.get_source_range().get_offsets(), cursor.get_spelling(), {}};
auto start_cursor = cursor; auto start_cursor = cursor;
for(auto parent = cursor.get_semantic_parent(); parent.get_kind() != clangmm::Cursor::Kind::TranslationUnit && for(auto parent = cursor.get_semantic_parent(); parent.get_kind() != clangmm::Cursor::Kind::TranslationUnit &&
parent.get_kind() != clangmm::Cursor::Kind::ClassDecl; parent = parent.get_semantic_parent()) parent.get_kind() != clangmm::Cursor::Kind::ClassDecl;
parent = parent.get_semantic_parent())
start_cursor = parent; start_cursor = parent;
clang_visitChildren(start_cursor.cx_cursor, [](CXCursor cx_cursor, CXCursor cx_parent, CXClientData data_) { clang_visitChildren(
auto data = static_cast<VisitorData *>(data_); start_cursor.cx_cursor, [](CXCursor cx_cursor, CXCursor cx_parent, CXClientData data_) {
if(clangmm::Cursor(cx_cursor).get_source_range().get_offsets() == data->offsets) { auto data = static_cast<VisitorData *>(data_);
auto parent = clangmm::Cursor(cx_parent); if(clangmm::Cursor(cx_cursor).get_source_range().get_offsets() == data->offsets) {
if(parent.get_spelling() == data->spelling) { auto parent = clangmm::Cursor(cx_parent);
data->parent = parent; if(parent.get_spelling() == data->spelling) {
return CXChildVisit_Break; data->parent = parent;
} return CXChildVisit_Break;
} }
return CXChildVisit_Recurse; }
}, &visitor_data); return CXChildVisit_Recurse;
},
&visitor_data);
if(visitor_data.parent) if(visitor_data.parent)
cursor = visitor_data.parent; cursor = visitor_data.parent;
} }
// Check children // Check children
std::vector<clangmm::Cursor> children; std::vector<clangmm::Cursor> children;
clang_visitChildren(cursor.cx_cursor, [](CXCursor cx_cursor, CXCursor /*parent*/, CXClientData data) { clang_visitChildren(
static_cast<std::vector<clangmm::Cursor> *>(data)->emplace_back(cx_cursor); cursor.cx_cursor, [](CXCursor cx_cursor, CXCursor /*parent*/, CXClientData data) {
return CXChildVisit_Continue; static_cast<std::vector<clangmm::Cursor> *>(data)->emplace_back(cx_cursor);
}, &children); return CXChildVisit_Continue;
},
&children);
// Check if expression can be called without altering state // Check if expression can be called without altering state
bool call_expression = true; bool call_expression = true;
@ -1151,8 +1153,7 @@ const std::unordered_map<std::string, std::string> &Source::ClangViewAutocomplet
{"hex(std::ios_base &__str)", "hex"}, //clang++ headers {"hex(std::ios_base &__str)", "hex"}, //clang++ headers
{"hex(std::ios_base &__base)", "hex"}, //g++ headers {"hex(std::ios_base &__base)", "hex"}, //g++ headers
{"dec(std::ios_base &__str)", "dec"}, {"dec(std::ios_base &__str)", "dec"},
{"dec(std::ios_base &__base)", "dec"} {"dec(std::ios_base &__base)", "dec"}};
};
return map; return map;
} }
@ -1317,37 +1318,41 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
ClientData client_data{this->file_path, std::string(), get_buffer()->get_insert()->get_iter().get_line(), sm[1].str()}; ClientData client_data{this->file_path, std::string(), get_buffer()->get_insert()->get_iter().get_line(), sm[1].str()};
// Attempt to find the 100% correct include file first // Attempt to find the 100% correct include file first
clang_getInclusions(clang_tu->cx_tu, [](CXFile included_file, CXSourceLocation *inclusion_stack, unsigned include_len, CXClientData client_data_) { clang_getInclusions(
auto client_data = static_cast<ClientData *>(client_data_); clang_tu->cx_tu, [](CXFile included_file, CXSourceLocation *inclusion_stack, unsigned include_len, CXClientData client_data_) {
if(client_data->found_include.empty() && include_len > 0) { auto client_data = static_cast<ClientData *>(client_data_);
auto source_location = clangmm::SourceLocation(inclusion_stack[0]); if(client_data->found_include.empty() && include_len > 0) {
if(static_cast<int>(source_location.get_offset().line) - 1 == client_data->line_nr && auto source_location = clangmm::SourceLocation(inclusion_stack[0]);
filesystem::get_normal_path(source_location.get_path()) == client_data->file_path) if(static_cast<int>(source_location.get_offset().line) - 1 == client_data->line_nr &&
client_data->found_include = clangmm::to_string(clang_getFileName(included_file)); filesystem::get_normal_path(source_location.get_path()) == client_data->file_path)
} client_data->found_include = clangmm::to_string(clang_getFileName(included_file));
}, &client_data); }
},
&client_data);
if(!client_data.found_include.empty()) if(!client_data.found_include.empty())
return Offset(0, 0, client_data.found_include); return Offset(0, 0, client_data.found_include);
// Find a matching include file if no include was found previously // Find a matching include file if no include was found previously
clang_getInclusions(clang_tu->cx_tu, [](CXFile included_file, CXSourceLocation *inclusion_stack, unsigned include_len, CXClientData client_data_) { clang_getInclusions(
auto client_data = static_cast<ClientData *>(client_data_); clang_tu->cx_tu, [](CXFile included_file, CXSourceLocation *inclusion_stack, unsigned include_len, CXClientData client_data_) {
if(client_data->found_include.empty()) { auto client_data = static_cast<ClientData *>(client_data_);
for(unsigned c = 1; c < include_len; ++c) { if(client_data->found_include.empty()) {
auto source_location = clangmm::SourceLocation(inclusion_stack[c]); for(unsigned c = 1; c < include_len; ++c) {
if(static_cast<int>(source_location.get_offset().line) - 1 <= client_data->line_nr && auto source_location = clangmm::SourceLocation(inclusion_stack[c]);
filesystem::get_normal_path(source_location.get_path()) == client_data->file_path) { if(static_cast<int>(source_location.get_offset().line) - 1 <= client_data->line_nr &&
auto included_file_str = clangmm::to_string(clang_getFileName(included_file)); filesystem::get_normal_path(source_location.get_path()) == client_data->file_path) {
if(ends_with(included_file_str, client_data->sm_str) && auto included_file_str = clangmm::to_string(clang_getFileName(included_file));
boost::filesystem::path(included_file_str).filename() == boost::filesystem::path(client_data->sm_str).filename()) { if(ends_with(included_file_str, client_data->sm_str) &&
client_data->found_include = included_file_str; boost::filesystem::path(included_file_str).filename() == boost::filesystem::path(client_data->sm_str).filename()) {
break; client_data->found_include = included_file_str;
break;
}
}
} }
} }
} },
} &client_data);
}, &client_data);
if(!client_data.found_include.empty()) if(!client_data.found_include.empty())
return Offset(0, 0, client_data.found_include); return Offset(0, 0, client_data.found_include);
@ -1957,9 +1962,11 @@ bool Source::ClangViewRefactor::wait_parsing() {
} }
if(!not_parsed_clang_views.empty()) { if(!not_parsed_clang_views.empty()) {
bool canceled = false; bool canceled = false;
auto message = std::make_unique<Dialog::Message>("Please wait while all buffers finish parsing", [&canceled] { auto message = std::make_unique<Dialog::Message>(
canceled = true; "Please wait while all buffers finish parsing", [&canceled] {
}, true); canceled = true;
},
true);
ScopeGuard guard{[&message] { ScopeGuard guard{[&message] {
message->hide(); message->hide();
}}; }};

14
src/source_clang.hpp

@ -13,8 +13,18 @@
namespace Source { namespace Source {
class ClangViewParse : public View { class ClangViewParse : public View {
protected: protected:
enum class ParseState { processing, restarting, stop }; enum class ParseState {
enum class ParseProcessState { idle, starting, preprocessing, processing, postprocessing }; processing,
restarting,
stop
};
enum class ParseProcessState {
idle,
starting,
preprocessing,
processing,
postprocessing
};
public: public:
ClangViewParse(const boost::filesystem::path &file_path, const Glib::RefPtr<Gsv::Language> &language); ClangViewParse(const boost::filesystem::path &file_path, const Glib::RefPtr<Gsv::Language> &language);

8
src/source_diff.hpp

@ -11,7 +11,13 @@
namespace Source { namespace Source {
class DiffView : virtual public Source::BaseView { class DiffView : virtual public Source::BaseView {
enum class ParseState { idle, starting, preprocessing, processing, postprocessing }; enum class ParseState {
idle,
starting,
preprocessing,
processing,
postprocessing
};
class Renderer : public Gsv::GutterRenderer { class Renderer : public Gsv::GutterRenderer {
public: public:

77
src/source_language_protocol.cpp

@ -50,12 +50,10 @@ LanguageProtocol::Diagnostic::Diagnostic(const boost::property_tree::ptree &pt)
LanguageProtocol::TextEdit::TextEdit(const boost::property_tree::ptree &pt, std::string new_text_) : range(pt.get_child("range")), new_text(new_text_.empty() ? pt.get<std::string>("newText") : std::move(new_text_)) {} LanguageProtocol::TextEdit::TextEdit(const boost::property_tree::ptree &pt, std::string new_text_) : range(pt.get_child("range")), new_text(new_text_.empty() ? pt.get<std::string>("newText") : std::move(new_text_)) {}
LanguageProtocol::Client::Client(boost::filesystem::path root_path_, std::string language_id_) : root_path(std::move(root_path_)), language_id(std::move(language_id_)) { LanguageProtocol::Client::Client(boost::filesystem::path root_path_, std::string language_id_) : root_path(std::move(root_path_)), language_id(std::move(language_id_)) {
process = std::make_unique<TinyProcessLib::Process>(filesystem::escape_argument(language_id + "-language-server"), root_path.string(), [this](const char *bytes, size_t n) { process = std::make_unique<TinyProcessLib::Process>(
filesystem::escape_argument(language_id + "-language-server"), root_path.string(), [this](const char *bytes, size_t n) {
server_message_stream.write(bytes, n); server_message_stream.write(bytes, n);
parse_server_message(); parse_server_message(); }, [](const char *bytes, size_t n) { std::cerr.write(bytes, n); }, true, TinyProcessLib::Config{1048576});
}, [](const char *bytes, size_t n) {
std::cerr.write(bytes, n);
}, true, TinyProcessLib::Config{1048576});
} }
std::shared_ptr<LanguageProtocol::Client> LanguageProtocol::Client::get(const boost::filesystem::path &file_path, const std::string &language_id) { std::shared_ptr<LanguageProtocol::Client> LanguageProtocol::Client::get(const boost::filesystem::path &file_path, const std::string &language_id) {
@ -169,38 +167,39 @@ LanguageProtocol::Capabilities LanguageProtocol::Client::initialize(Source::Lang
"initializationOptions": { "initializationOptions": {
"checkOnSave": { "enable": true } "checkOnSave": { "enable": true }
}, },
"trace": "off")", [this, &result_processed](const boost::property_tree::ptree &result, bool error) { "trace": "off")",
if(!error) { [this, &result_processed](const boost::property_tree::ptree &result, bool error) {
if(auto capabilities_pt = result.get_child_optional("capabilities")) { if(!error) {
try { if(auto capabilities_pt = result.get_child_optional("capabilities")) {
capabilities.text_document_sync = static_cast<LanguageProtocol::Capabilities::TextDocumentSync>(capabilities_pt->get<int>("textDocumentSync")); try {
} capabilities.text_document_sync = static_cast<LanguageProtocol::Capabilities::TextDocumentSync>(capabilities_pt->get<int>("textDocumentSync"));
catch(...) { }
capabilities.text_document_sync = static_cast<LanguageProtocol::Capabilities::TextDocumentSync>(capabilities_pt->get<int>("textDocumentSync.change", 0)); catch(...) {
} capabilities.text_document_sync = static_cast<LanguageProtocol::Capabilities::TextDocumentSync>(capabilities_pt->get<int>("textDocumentSync.change", 0));
capabilities.hover = capabilities_pt->get<bool>("hoverProvider", false); }
capabilities.completion = static_cast<bool>(capabilities_pt->get_child_optional("completionProvider")); capabilities.hover = capabilities_pt->get<bool>("hoverProvider", false);
capabilities.signature_help = static_cast<bool>(capabilities_pt->get_child_optional("signatureHelpProvider")); capabilities.completion = static_cast<bool>(capabilities_pt->get_child_optional("completionProvider"));
capabilities.definition = capabilities_pt->get<bool>("definitionProvider", false); capabilities.signature_help = static_cast<bool>(capabilities_pt->get_child_optional("signatureHelpProvider"));
capabilities.references = capabilities_pt->get<bool>("referencesProvider", false); capabilities.definition = capabilities_pt->get<bool>("definitionProvider", false);
capabilities.document_highlight = capabilities_pt->get<bool>("documentHighlightProvider", false); capabilities.references = capabilities_pt->get<bool>("referencesProvider", false);
capabilities.workspace_symbol = capabilities_pt->get<bool>("workspaceSymbolProvider", false); capabilities.document_highlight = capabilities_pt->get<bool>("documentHighlightProvider", false);
capabilities.document_symbol = capabilities_pt->get<bool>("documentSymbolProvider", false); capabilities.workspace_symbol = capabilities_pt->get<bool>("workspaceSymbolProvider", false);
capabilities.document_formatting = capabilities_pt->get<bool>("documentFormattingProvider", false); capabilities.document_symbol = capabilities_pt->get<bool>("documentSymbolProvider", false);
capabilities.document_range_formatting = capabilities_pt->get<bool>("documentRangeFormattingProvider", false); capabilities.document_formatting = capabilities_pt->get<bool>("documentFormattingProvider", false);
capabilities.rename = capabilities_pt->get<bool>("renameProvider", false); capabilities.document_range_formatting = capabilities_pt->get<bool>("documentRangeFormattingProvider", false);
if(!capabilities.rename) capabilities.rename = capabilities_pt->get<bool>("renameProvider", false);
capabilities.rename = capabilities_pt->get<bool>("renameProvider.prepareProvider", false); if(!capabilities.rename)
capabilities.code_action = capabilities_pt->get<bool>("codeActionProvider", false); capabilities.rename = capabilities_pt->get<bool>("renameProvider.prepareProvider", false);
if(!capabilities.code_action) capabilities.code_action = capabilities_pt->get<bool>("codeActionProvider", false);
capabilities.code_action = static_cast<bool>(capabilities_pt->get_child_optional("codeActionProvider.codeActionKinds")); if(!capabilities.code_action)
capabilities.type_coverage = capabilities_pt->get<bool>("typeCoverageProvider", false); capabilities.code_action = static_cast<bool>(capabilities_pt->get_child_optional("codeActionProvider.codeActionKinds"));
} capabilities.type_coverage = capabilities_pt->get<bool>("typeCoverageProvider", false);
}
write_notification("initialized", ""); write_notification("initialized", "");
} }
result_processed.set_value(); result_processed.set_value();
}); });
result_processed.get_future().get(); result_processed.get_future().get();
initialized = true; initialized = true;
@ -1025,8 +1024,7 @@ void Source::LanguageProtocolView::update_diagnostics_async(std::vector<Language
for(auto &quickfix_diagnostic : quickfix_diagnostics) { for(auto &quickfix_diagnostic : quickfix_diagnostics) {
if(diagnostic.message == quickfix_diagnostic.message && diagnostic.range == quickfix_diagnostic.range) { if(diagnostic.message == quickfix_diagnostic.message && diagnostic.range == quickfix_diagnostic.range) {
auto pair = diagnostic.quickfixes.emplace(title, std::vector<Source::FixIt>{}); auto pair = diagnostic.quickfixes.emplace(title, std::vector<Source::FixIt>{});
pair.first->second.emplace_back(edit.new_text, filesystem::get_path_from_uri(file_it->first).string(), std::make_pair<Offset, Offset>(Offset(edit.range.start.line, edit.range.start.character), pair.first->second.emplace_back(edit.new_text, filesystem::get_path_from_uri(file_it->first).string(), std::make_pair<Offset, Offset>(Offset(edit.range.start.line, edit.range.start.character), Offset(edit.range.end.line, edit.range.end.character)));
Offset(edit.range.end.line, edit.range.end.character)));
break; break;
} }
} }
@ -1036,8 +1034,7 @@ void Source::LanguageProtocolView::update_diagnostics_async(std::vector<Language
for(auto &diagnostic : diagnostics) { for(auto &diagnostic : diagnostics) {
if(edit.range.start.line == diagnostic.range.start.line) { if(edit.range.start.line == diagnostic.range.start.line) {
auto pair = diagnostic.quickfixes.emplace(title, std::vector<Source::FixIt>{}); auto pair = diagnostic.quickfixes.emplace(title, std::vector<Source::FixIt>{});
pair.first->second.emplace_back(edit.new_text, filesystem::get_path_from_uri(file_it->first).string(), std::make_pair<Offset, Offset>(Offset(edit.range.start.line, edit.range.start.character), pair.first->second.emplace_back(edit.new_text, filesystem::get_path_from_uri(file_it->first).string(), std::make_pair<Offset, Offset>(Offset(edit.range.start.line, edit.range.start.character), Offset(edit.range.end.line, edit.range.end.character)));
Offset(edit.range.end.line, edit.range.end.character)));
break; break;
} }
} }

37
src/terminal.cpp

@ -55,7 +55,12 @@ Terminal::Terminal() : Source::SearchView() {
} }
}; };
class ParseAnsiEscapeSequence { class ParseAnsiEscapeSequence {
enum class State { none = 1, escaped, parameter_bytes, intermediate_bytes }; enum class State {
none = 1,
escaped,
parameter_bytes,
intermediate_bytes
};
State state = State::none; State state = State::none;
std::string parameters; std::string parameters;
size_t length = 0; size_t length = 0;
@ -205,11 +210,8 @@ int Terminal::process(const std::string &command, const boost::filesystem::path
std::unique_ptr<TinyProcessLib::Process> process; std::unique_ptr<TinyProcessLib::Process> process;
if(use_pipes) if(use_pipes)
process = std::make_unique<TinyProcessLib::Process>(command, path.string(), [this](const char *bytes, size_t n) { process = std::make_unique<TinyProcessLib::Process>(
async_print(std::string(bytes, n)); command, path.string(), [this](const char *bytes, size_t n) { async_print(std::string(bytes, n)); }, [this](const char *bytes, size_t n) { async_print(std::string(bytes, n), true); });
}, [this](const char *bytes, size_t n) {
async_print(std::string(bytes, n), true);
});
else else
process = std::make_unique<TinyProcessLib::Process>(command, path.string()); process = std::make_unique<TinyProcessLib::Process>(command, path.string());
@ -225,7 +227,8 @@ int Terminal::process(std::istream &stdin_stream, std::ostream &stdout_stream, c
if(scroll_to_bottom) if(scroll_to_bottom)
scroll_to_bottom(); scroll_to_bottom();
TinyProcessLib::Process process(command, path.string(), [&stdout_stream](const char *bytes, size_t n) { TinyProcessLib::Process process(
command, path.string(), [&stdout_stream](const char *bytes, size_t n) {
Glib::ustring umessage(std::string(bytes, n)); Glib::ustring umessage(std::string(bytes, n));
Glib::ustring::iterator iter; Glib::ustring::iterator iter;
while(!umessage.validate(iter)) { while(!umessage.validate(iter)) {
@ -233,13 +236,11 @@ int Terminal::process(std::istream &stdin_stream, std::ostream &stdout_stream, c
next_char_iter++; next_char_iter++;
umessage.replace(iter, next_char_iter, "?"); umessage.replace(iter, next_char_iter, "?");
} }
stdout_stream.write(umessage.data(), n); stdout_stream.write(umessage.data(), n); }, [this, stderr_stream](const char *bytes, size_t n) {
}, [this, stderr_stream](const char *bytes, size_t n) {
if(stderr_stream) if(stderr_stream)
stderr_stream->write(bytes, n); stderr_stream->write(bytes, n);
else else
async_print(std::string(bytes, n), true); async_print(std::string(bytes, n), true); }, true);
}, true);
if(process.get_id() <= 0) { if(process.get_id() <= 0) {
async_print("\e[31mError\e[m: failed to run command: " + command + "\n", true); async_print("\e[31mError\e[m: failed to run command: " + command + "\n", true);
@ -266,7 +267,8 @@ std::shared_ptr<TinyProcessLib::Process> Terminal::async_process(const std::stri
scroll_to_bottom(); scroll_to_bottom();
stdin_buffer.clear(); stdin_buffer.clear();
auto process = std::make_shared<TinyProcessLib::Process>(command, path.string(), [this, quiet](const char *bytes, size_t n) { auto process = std::make_shared<TinyProcessLib::Process>(
command, path.string(), [this, quiet](const char *bytes, size_t n) {
if(!quiet) { if(!quiet) {
// Print stdout message sequentially to avoid the GUI becoming unresponsive // Print stdout message sequentially to avoid the GUI becoming unresponsive
std::promise<void> message_printed; std::promise<void> message_printed;
@ -275,8 +277,7 @@ std::shared_ptr<TinyProcessLib::Process> Terminal::async_process(const std::stri
message_printed.set_value(); message_printed.set_value();
}); });
message_printed.get_future().get(); message_printed.get_future().get();
} } }, [this, quiet](const char *bytes, size_t n) {
}, [this, quiet](const char *bytes, size_t n) {
if(!quiet) { if(!quiet) {
// Print stderr message sequentially to avoid the GUI becoming unresponsive // Print stderr message sequentially to avoid the GUI becoming unresponsive
std::promise<void> message_printed; std::promise<void> message_printed;
@ -285,8 +286,7 @@ std::shared_ptr<TinyProcessLib::Process> Terminal::async_process(const std::stri
message_printed.set_value(); message_printed.set_value();
}); });
message_printed.get_future().get(); message_printed.get_future().get();
} } }, true);
}, true);
auto pid = process->get_id(); auto pid = process->get_id();
if(pid <= 0) { if(pid <= 0) {
@ -384,8 +384,9 @@ boost::optional<Terminal::Link> Terminal::find_link(const std::string &line, siz
size_t subs = (sub == 1 || size_t subs = (sub == 1 ||
sub == 1 + 4 + 3 + 3 || sub == 1 + 4 + 3 + 3 ||
sub == 1 + 4 + 3 + 3 + 4 + 3 + 3 + 3 + 3 || sub == 1 + 4 + 3 + 3 + 4 + 3 + 3 + 3 + 3 ||
sub == 1 + 4 + 3 + 3 + 4 + 3 + 3 + 3 + 3 + 4) ? sub == 1 + 4 + 3 + 3 + 4 + 3 + 3 + 3 + 3 + 4)
4 : 3; ? 4
: 3;
if(sm.length(sub + 1)) { if(sm.length(sub + 1)) {
auto start_pos = static_cast<int>(sm.position(sub + 1) - sm.length(sub)); auto start_pos = static_cast<int>(sm.position(sub + 1) - sm.length(sub));
auto end_pos = static_cast<int>(sm.position(sub + subs - 1) + sm.length(sub + subs - 1)); auto end_pos = static_cast<int>(sm.position(sub + subs - 1) + sm.length(sub + subs - 1));

78
src/usages_clang.cpp

@ -75,25 +75,27 @@ Usages::Clang::Cache::Cache(boost::filesystem::path project_path_, boost::filesy
}; };
VisitorData visitor_data{this->project_path, path, before_parse_time, paths_and_last_write_times}; VisitorData visitor_data{this->project_path, path, before_parse_time, paths_and_last_write_times};
clang_getInclusions(translation_unit->cx_tu, [](CXFile included_file, CXSourceLocation *inclusion_stack, unsigned include_len, CXClientData data) { clang_getInclusions(
auto visitor_data = static_cast<VisitorData *>(data); translation_unit->cx_tu, [](CXFile included_file, CXSourceLocation *inclusion_stack, unsigned include_len, CXClientData data) {
auto path = filesystem::get_normal_path(clangmm::to_string(clang_getFileName(included_file))); auto visitor_data = static_cast<VisitorData *>(data);
if(filesystem::file_in_path(path, visitor_data->project_path)) { auto path = filesystem::get_normal_path(clangmm::to_string(clang_getFileName(included_file)));
for(unsigned c = 0; c < include_len; ++c) { if(filesystem::file_in_path(path, visitor_data->project_path)) {
auto from_path = filesystem::get_normal_path(clangmm::SourceLocation(inclusion_stack[c]).get_path()); for(unsigned c = 0; c < include_len; ++c) {
if(from_path == visitor_data->path) { auto from_path = filesystem::get_normal_path(clangmm::SourceLocation(inclusion_stack[c]).get_path());
boost::system::error_code ec; if(from_path == visitor_data->path) {
auto last_write_time = boost::filesystem::last_write_time(path, ec); boost::system::error_code ec;
if(ec) auto last_write_time = boost::filesystem::last_write_time(path, ec);
last_write_time = 0; if(ec)
if(last_write_time > visitor_data->before_parse_time) last_write_time = 0;
last_write_time = 0; if(last_write_time > visitor_data->before_parse_time)
visitor_data->paths_and_last_write_times.emplace(path, last_write_time); last_write_time = 0;
break; visitor_data->paths_and_last_write_times.emplace(path, last_write_time);
break;
}
}
} }
} },
} &visitor_data);
}, &visitor_data);
} }
std::vector<std::pair<clangmm::Offset, clangmm::Offset>> Usages::Clang::Cache::get_similar_token_offsets(clangmm::Cursor::Kind kind, const std::string &spelling, std::vector<std::pair<clangmm::Offset, clangmm::Offset>> Usages::Clang::Cache::get_similar_token_offsets(clangmm::Cursor::Kind kind, const std::string &spelling,
@ -163,9 +165,11 @@ boost::optional<std::vector<Usages::Clang::Usages>> Usages::Clang::get_usages(co
std::unique_ptr<Dialog::Message> message; std::unique_ptr<Dialog::Message> message;
std::atomic<bool> canceled(false); std::atomic<bool> canceled(false);
auto create_message = [&canceled] { auto create_message = [&canceled] {
return std::make_unique<Dialog::Message>("Please wait while finding usages", [&canceled] { return std::make_unique<Dialog::Message>(
canceled = true; "Please wait while finding usages", [&canceled] {
}, true); canceled = true;
},
true);
}; };
size_t tasks = cache_in_progress_count; size_t tasks = cache_in_progress_count;
std::atomic<size_t> tasks_completed = {0}; std::atomic<size_t> tasks_completed = {0};
@ -330,15 +334,17 @@ void Usages::Clang::cache(const boost::filesystem::path &project_path, const boo
VisitorData visitor_data{project_path, {}}; VisitorData visitor_data{project_path, {}};
auto translation_unit_cursor = clang_getTranslationUnitCursor(translation_unit->cx_tu); auto translation_unit_cursor = clang_getTranslationUnitCursor(translation_unit->cx_tu);
clang_visitChildren(translation_unit_cursor, [](CXCursor cx_cursor, CXCursor cx_parent, CXClientData data) { clang_visitChildren(
auto visitor_data = static_cast<VisitorData *>(data); translation_unit_cursor, [](CXCursor cx_cursor, CXCursor cx_parent, CXClientData data) {
auto visitor_data = static_cast<VisitorData *>(data);
auto path = filesystem::get_normal_path(clangmm::Cursor(cx_cursor).get_source_location().get_path()); auto path = filesystem::get_normal_path(clangmm::Cursor(cx_cursor).get_source_location().get_path());
if(filesystem::file_in_path(path, visitor_data->project_path)) if(filesystem::file_in_path(path, visitor_data->project_path))
visitor_data->paths.emplace(path); visitor_data->paths.emplace(path);
return CXChildVisit_Continue; return CXChildVisit_Continue;
}, &visitor_data); },
&visitor_data);
visitor_data.paths.erase(path); visitor_data.paths.erase(path);
@ -528,15 +534,17 @@ void Usages::Clang::add_usages_from_includes(const boost::filesystem::path &proj
VisitorData visitor_data{project_path, spelling, visited, {}}; VisitorData visitor_data{project_path, spelling, visited, {}};
auto translation_unit_cursor = clang_getTranslationUnitCursor(translation_unit->cx_tu); auto translation_unit_cursor = clang_getTranslationUnitCursor(translation_unit->cx_tu);
clang_visitChildren(translation_unit_cursor, [](CXCursor cx_cursor, CXCursor cx_parent, CXClientData data) { clang_visitChildren(
auto visitor_data = static_cast<VisitorData *>(data); translation_unit_cursor, [](CXCursor cx_cursor, CXCursor cx_parent, CXClientData data) {
auto visitor_data = static_cast<VisitorData *>(data);
auto path = filesystem::get_normal_path(clangmm::Cursor(cx_cursor).get_source_location().get_path()); auto path = filesystem::get_normal_path(clangmm::Cursor(cx_cursor).get_source_location().get_path());
if(visitor_data->visited.find(path) == visitor_data->visited.end() && filesystem::file_in_path(path, visitor_data->project_path)) if(visitor_data->visited.find(path) == visitor_data->visited.end() && filesystem::file_in_path(path, visitor_data->project_path))
visitor_data->paths.emplace(path); visitor_data->paths.emplace(path);
return CXChildVisit_Continue; return CXChildVisit_Continue;
}, &visitor_data); },
&visitor_data);
for(auto &path : visitor_data.paths) for(auto &path : visitor_data.paths)
add_usages(project_path, build_path, path, usages, visited, spelling, cursor, translation_unit, store_in_cache); add_usages(project_path, build_path, path, usages, visited, spelling, cursor, translation_unit, store_in_cache);

77
src/window.cpp

@ -45,7 +45,8 @@ Window::Window() {
.juci_terminal_scrolledwindow {padding-left: 3px;} .juci_terminal_scrolledwindow {padding-left: 3px;}
.juci_info {border-radius: 5px;} .juci_info {border-radius: 5px;}
.juci_tooltip_window {background-color: transparent;} .juci_tooltip_window {background-color: transparent;}
.juci_tooltip_box {)" + border_radius_style + R"(padding: 3px;} .juci_tooltip_box {)" + border_radius_style +
R"(padding: 3px;}
)"); )");
get_style_context()->add_provider_for_screen(screen, provider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); get_style_context()->add_provider_for_screen(screen, provider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
@ -1323,10 +1324,12 @@ void Window::set_menu_actions() {
label_it->set_text("Synopsis: [environment_variable=value]... executable [argument]...\nSet empty to let juCi++ deduce executable."); label_it->set_text("Synopsis: [environment_variable=value]... executable [argument]...\nSet empty to let juCi++ deduce executable.");
}; };
label_it->update(0, ""); label_it->update(0, "");
EntryBox::get().entries.emplace_back(run_arguments.second, [run_arguments_first = std::move(run_arguments.first)](const std::string &content) { EntryBox::get().entries.emplace_back(
Project::run_arguments[run_arguments_first] = content; run_arguments.second, [run_arguments_first = std::move(run_arguments.first)](const std::string &content) {
EntryBox::get().hide(); Project::run_arguments[run_arguments_first] = content;
}, 50); EntryBox::get().hide();
},
50);
auto entry_it = EntryBox::get().entries.begin(); auto entry_it = EntryBox::get().entries.begin();
entry_it->set_placeholder_text("Run Arguments"); entry_it->set_placeholder_text("Run Arguments");
EntryBox::get().buttons.emplace_back("Set Run Arguments", [entry_it]() { EntryBox::get().buttons.emplace_back("Set Run Arguments", [entry_it]() {
@ -1379,20 +1382,22 @@ void Window::set_menu_actions() {
label_it->set_text("Run Command directory order: opened directory, file path, current directory"); label_it->set_text("Run Command directory order: opened directory, file path, current directory");
}; };
label_it->update(0, ""); label_it->update(0, "");
EntryBox::get().entries.emplace_back(last_run_command, [this](const std::string &content) { EntryBox::get().entries.emplace_back(
if(!content.empty()) { last_run_command, [this](const std::string &content) {
last_run_command = content; if(!content.empty()) {
auto directory_folder = Project::get_preferably_directory_folder(); last_run_command = content;
if(Config::get().terminal.clear_on_run_command) auto directory_folder = Project::get_preferably_directory_folder();
Terminal::get().clear(); if(Config::get().terminal.clear_on_run_command)
Terminal::get().async_print("\e[2mRunning: " + content + "\e[m\n"); Terminal::get().clear();
Terminal::get().async_print("\e[2mRunning: " + content + "\e[m\n");
Terminal::get().async_process(content, directory_folder, [content](int exit_status) {
Terminal::get().async_print("\e[2m" + content + " returned: " + (exit_status == 0 ? "\e[32m" : "\e[31m") + std::to_string(exit_status) + "\e[m\n"); Terminal::get().async_process(content, directory_folder, [content](int exit_status) {
}); Terminal::get().async_print("\e[2m" + content + " returned: " + (exit_status == 0 ? "\e[32m" : "\e[31m") + std::to_string(exit_status) + "\e[m\n");
} });
EntryBox::get().hide(); }
}, 30); EntryBox::get().hide();
},
30);
auto entry_it = EntryBox::get().entries.begin(); auto entry_it = EntryBox::get().entries.begin();
entry_it->set_placeholder_text("Command"); entry_it->set_placeholder_text("Command");
EntryBox::get().buttons.emplace_back("Run Command", [entry_it]() { EntryBox::get().buttons.emplace_back("Run Command", [entry_it]() {
@ -1422,10 +1427,12 @@ void Window::set_menu_actions() {
label_it->set_text("Synopsis: [environment_variable=value]... executable [argument]...\nSet empty to let juCi++ deduce executable."); label_it->set_text("Synopsis: [environment_variable=value]... executable [argument]...\nSet empty to let juCi++ deduce executable.");
}; };
label_it->update(0, ""); label_it->update(0, "");
EntryBox::get().entries.emplace_back(run_arguments.second, [run_arguments_first = std::move(run_arguments.first)](const std::string &content) { EntryBox::get().entries.emplace_back(
Project::debug_run_arguments[run_arguments_first].arguments = content; run_arguments.second, [run_arguments_first = std::move(run_arguments.first)](const std::string &content) {
EntryBox::get().hide(); Project::debug_run_arguments[run_arguments_first].arguments = content;
}, 50); EntryBox::get().hide();
},
50);
auto entry_it = EntryBox::get().entries.begin(); auto entry_it = EntryBox::get().entries.begin();
entry_it->set_placeholder_text("Debug Run Arguments"); entry_it->set_placeholder_text("Debug Run Arguments");
@ -1491,17 +1498,19 @@ void Window::set_menu_actions() {
}); });
menu.add_action("debug_run_command", [this]() { menu.add_action("debug_run_command", [this]() {
EntryBox::get().clear(); EntryBox::get().clear();
EntryBox::get().entries.emplace_back(last_run_debug_command, [this](const std::string &content) { EntryBox::get().entries.emplace_back(
if(!content.empty()) { last_run_debug_command, [this](const std::string &content) {
if(Project::current) { if(!content.empty()) {
if(Config::get().terminal.clear_on_run_command) if(Project::current) {
Terminal::get().clear(); if(Config::get().terminal.clear_on_run_command)
Project::current->debug_run_command(content); Terminal::get().clear();
} Project::current->debug_run_command(content);
last_run_debug_command = content; }
} last_run_debug_command = content;
EntryBox::get().hide(); }
}, 30); EntryBox::get().hide();
},
30);
auto entry_it = EntryBox::get().entries.begin(); auto entry_it = EntryBox::get().entries.begin();
entry_it->set_placeholder_text("Debug Command"); entry_it->set_placeholder_text("Debug Command");
EntryBox::get().buttons.emplace_back("Run Debug Command", [entry_it]() { EntryBox::get().buttons.emplace_back("Run Debug Command", [entry_it]() {

23
tests/process_test.cpp

@ -14,11 +14,8 @@ int main() {
} }
{ {
TinyProcessLib::Process process("echo Test && ls an_incorrect_path", "", [output](const char *bytes, size_t n) { TinyProcessLib::Process process(
*output += std::string(bytes, n); "echo Test && ls an_incorrect_path", "", [output](const char *bytes, size_t n) { *output += std::string(bytes, n); }, [error](const char *bytes, size_t n) { *error += std::string(bytes, n); });
}, [error](const char *bytes, size_t n) {
*error += std::string(bytes, n);
});
g_assert(process.get_exit_status() > 0); g_assert(process.get_exit_status() > 0);
g_assert(output->substr(0, 4) == "Test"); g_assert(output->substr(0, 4) == "Test");
g_assert(!error->empty()); g_assert(!error->empty());
@ -27,9 +24,11 @@ int main() {
} }
{ {
TinyProcessLib::Process process("bash", "", [output](const char *bytes, size_t n) { TinyProcessLib::Process process(
*output += std::string(bytes, n); "bash", "", [output](const char *bytes, size_t n) {
}, nullptr, true); *output += std::string(bytes, n);
},
nullptr, true);
process.write("echo Test\n"); process.write("echo Test\n");
process.write("exit\n"); process.write("exit\n");
g_assert(process.get_exit_status() == 0); g_assert(process.get_exit_status() == 0);
@ -38,9 +37,11 @@ int main() {
} }
{ {
TinyProcessLib::Process process("cat", "", [output](const char *bytes, size_t n) { TinyProcessLib::Process process(
*output += std::string(bytes, n); "cat", "", [output](const char *bytes, size_t n) {
}, nullptr, true); *output += std::string(bytes, n);
},
nullptr, true);
process.write("Test\n"); process.write("Test\n");
process.close_stdin(); process.close_stdin();
g_assert(process.get_exit_status() == 0); g_assert(process.get_exit_status() == 0);

16
tests/terminal_test.cpp

@ -238,9 +238,11 @@ int main() {
{ {
terminal.clear(); terminal.clear();
std::promise<int> done; std::promise<int> done;
terminal.async_process("echo test", "", [&done](int exit_status) { terminal.async_process(
done.set_value(exit_status); "echo test", "", [&done](int exit_status) {
}, true); done.set_value(exit_status);
},
true);
auto future = done.get_future(); auto future = done.get_future();
while(future.wait_for(std::chrono::milliseconds(10)) != std::future_status::ready) { while(future.wait_for(std::chrono::milliseconds(10)) != std::future_status::ready) {
while(Gtk::Main::events_pending()) while(Gtk::Main::events_pending())
@ -269,9 +271,11 @@ int main() {
{ {
terminal.clear(); terminal.clear();
std::promise<int> done; std::promise<int> done;
terminal.async_process("testing_invalid_command", "", [&done](int exit_status) { terminal.async_process(
done.set_value(exit_status); "testing_invalid_command", "", [&done](int exit_status) {
}, true); done.set_value(exit_status);
},
true);
auto future = done.get_future(); auto future = done.get_future();
while(future.wait_for(std::chrono::milliseconds(10)) != std::future_status::ready) { while(future.wait_for(std::chrono::milliseconds(10)) != std::future_status::ready) {
while(Gtk::Main::events_pending()) while(Gtk::Main::events_pending())

Loading…
Cancel
Save