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. 2
      tests/filesystem_test.cpp
  15. 23
      tests/process_test.cpp
  16. 16
      tests/terminal_test.cpp

7
src/autocomplete.hpp

@ -16,7 +16,12 @@ class Autocomplete {
Dispatcher dispatcher;
public:
enum class State { idle, starting, restarting, canceled };
enum class State {
idle,
starting,
restarting,
canceled
};
Mutex 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;
};
enum class PathType { known, unknown };
enum class PathType {
known,
unknown
};
class TreeStore : public Gtk::TreeStore {
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) {
Lines lines;
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) {
//Based on https://github.com/atom/git-diff/blob/master/lib/git-diff-view.coffee
auto lines = static_cast<Lines *>(payload);
auto start = hunk->new_start - 1;
auto end = hunk->new_start + hunk->new_lines - 1;
if(hunk->old_lines == 0 && hunk->new_lines > 0)
lines->added.emplace_back(start, end);
else if(hunk->new_lines == 0 && hunk->old_lines > 0)
lines->removed.emplace_back(start);
else
lines->modified.emplace_back(start, end);
return 0;
}, nullptr, &lines);
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) {
//Based on https://github.com/atom/git-diff/blob/master/lib/git-diff-view.coffee
auto lines = static_cast<Lines *>(payload);
auto start = hunk->new_start - 1;
auto end = hunk->new_start + hunk->new_lines - 1;
if(hunk->old_lines == 0 && hunk->new_lines > 0)
lines->added.emplace_back(start, end);
else if(hunk->new_lines == 0 && hunk->old_lines > 0)
lines->removed.emplace_back(start);
else
lines->modified.emplace_back(start, end);
return 0;
},
nullptr, &lines);
if(error)
throw std::runtime_error(error.message());
return lines;
@ -62,11 +63,13 @@ std::vector<Git::Repository::Diff::Hunk> Git::Repository::Diff::get_hunks(const
git_diff_options options;
git_diff_init_options(&options, GIT_DIFF_OPTIONS_VERSION);
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) {
auto hunks = static_cast<std::vector<Git::Repository::Diff::Hunk> *>(payload);
hunks->emplace_back(hunk->old_start, hunk->old_lines, hunk->new_start, hunk->new_lines);
return 0;
}, nullptr, &hunks);
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) {
auto hunks = static_cast<std::vector<Git::Repository::Diff::Hunk> *>(payload);
hunks->emplace_back(hunk->old_start, hunk->old_lines, hunk->new_start, hunk->new_lines);
return 0;
},
nullptr, &hunks);
if(error)
throw std::runtime_error(error.message());
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;
details.second = line_nr;
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) {
auto details = static_cast<std::pair<std::string, int> *>(payload);
auto line_nr = details->second;
auto start = hunk->new_start - 1;
auto end = hunk->new_start + hunk->new_lines - 1;
if(line_nr == start || (line_nr >= start && line_nr < end)) {
if(details->first.empty())
details->first += std::string(hunk->header, hunk->header_len);
details->first += line->origin + std::string(line->content, line->content_len);
}
return 0;
}, &details);
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) {
auto details = static_cast<std::pair<std::string, int> *>(payload);
auto line_nr = details->second;
auto start = hunk->new_start - 1;
auto end = hunk->new_start + hunk->new_lines - 1;
if(line_nr == start || (line_nr >= start && line_nr < end)) {
if(details->first.empty())
details->first += std::string(hunk->header, hunk->header_len);
details->first += line->origin + std::string(line->content, line->content_len);
}
return 0;
},
&details);
if(error)
throw std::runtime_error(error.message());
return details.first;
@ -138,27 +143,27 @@ Git::Repository::Status Git::Repository::get_status() {
Data data{work_path};
{
LockGuard lock(mutex);
error.code = git_status_foreach(repository.get(), [](const char *path, unsigned int status_flags, void *payload) {
auto data = static_cast<Data *>(payload);
bool new_ = false;
bool modified = false;
if((status_flags & (GIT_STATUS_INDEX_NEW | GIT_STATUS_WT_NEW)) > 0)
new_ = true;
else if((status_flags & (GIT_STATUS_INDEX_MODIFIED | GIT_STATUS_WT_MODIFIED)) > 0)
modified = true;
boost::filesystem::path rel_path(path);
do {
if(new_)
data->status.added.emplace((data->work_path / rel_path).generic_string());
else if(modified)
data->status.modified.emplace((data->work_path / rel_path).generic_string());
rel_path = rel_path.parent_path();
} while(!rel_path.empty());
error.code = git_status_foreach(
repository.get(), [](const char *path, unsigned int status_flags, void *payload) {
auto data = static_cast<Data *>(payload);
bool new_ = false;
bool modified = false;
if((status_flags & (GIT_STATUS_INDEX_NEW | GIT_STATUS_WT_NEW)) > 0)
new_ = true;
else if((status_flags & (GIT_STATUS_INDEX_MODIFIED | GIT_STATUS_WT_MODIFIED)) > 0)
modified = true;
boost::filesystem::path rel_path(path);
do {
if(new_)
data->status.added.emplace((data->work_path / rel_path).generic_string());
else if(modified)
data->status.modified.emplace((data->work_path / rel_path).generic_string());
rel_path = rel_path.parent_path();
} while(!rel_path.empty());
return 0;
}, &data);
return 0;
},
&data);
if(error)
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_current_view();
std::vector<Source::View *> &get_views();
enum class Position { left, right, infer, split };
enum class Position {
left,
right,
infer,
split
};
bool open(Source::View *view);
bool open(const boost::filesystem::path &file_path, Position position = Position::infer);
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_format_style(is_generic_view);
std::string comment_characters;
if(is_bracket_language)
comment_characters = "//";
@ -375,8 +376,7 @@ Gsv::DrawSpacesFlags Source::View::parse_show_whitespace_characters(const std::s
namespace qi = boost::spirit::qi;
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)
("leading", Gsv::DRAW_SPACES_LEADING)("text", Gsv::DRAW_SPACES_TEXT)("trailing", Gsv::DRAW_SPACES_TRAILING)("all", Gsv::DRAW_SPACES_ALL);
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);
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) {
const static std::regex no_bracket_statement_regex("^[ \t]*(if( +constexpr)?|for|while) *\\(.*[^;}{] *$|"
"^[ \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();

6
src/source.hpp

@ -41,7 +41,11 @@ namespace Source {
class FixIt {
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_);

107
src/source_clang.cpp

@ -249,8 +249,7 @@ const std::map<int, std::string> &Source::ClangViewParse::clang_types() {
{46, "def:identifier"},
{109, "def:string"},
{702, "def:statement"},
{705, "def:comment"}
};
{705, "def:comment"}};
return types;
}
@ -579,9 +578,7 @@ void Source::ClangViewParse::show_type_tooltips(const Gdk::Rectangle &rectangle)
else if(type_description[pos] == '>')
--angle_count;
++pos;
}
while(pos < type_description.size())
;
} while(pos < type_description.size());
}
}
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(), {}};
auto start_cursor = cursor;
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;
clang_visitChildren(start_cursor.cx_cursor, [](CXCursor cx_cursor, CXCursor cx_parent, CXClientData data_) {
auto data = static_cast<VisitorData *>(data_);
if(clangmm::Cursor(cx_cursor).get_source_range().get_offsets() == data->offsets) {
auto parent = clangmm::Cursor(cx_parent);
if(parent.get_spelling() == data->spelling) {
data->parent = parent;
return CXChildVisit_Break;
}
}
return CXChildVisit_Recurse;
}, &visitor_data);
clang_visitChildren(
start_cursor.cx_cursor, [](CXCursor cx_cursor, CXCursor cx_parent, CXClientData data_) {
auto data = static_cast<VisitorData *>(data_);
if(clangmm::Cursor(cx_cursor).get_source_range().get_offsets() == data->offsets) {
auto parent = clangmm::Cursor(cx_parent);
if(parent.get_spelling() == data->spelling) {
data->parent = parent;
return CXChildVisit_Break;
}
}
return CXChildVisit_Recurse;
},
&visitor_data);
if(visitor_data.parent)
cursor = visitor_data.parent;
}
// Check children
std::vector<clangmm::Cursor> children;
clang_visitChildren(cursor.cx_cursor, [](CXCursor cx_cursor, CXCursor /*parent*/, CXClientData data) {
static_cast<std::vector<clangmm::Cursor> *>(data)->emplace_back(cx_cursor);
return CXChildVisit_Continue;
}, &children);
clang_visitChildren(
cursor.cx_cursor, [](CXCursor cx_cursor, CXCursor /*parent*/, CXClientData data) {
static_cast<std::vector<clangmm::Cursor> *>(data)->emplace_back(cx_cursor);
return CXChildVisit_Continue;
},
&children);
// Check if expression can be called without altering state
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 &__base)", "hex"}, //g++ headers
{"dec(std::ios_base &__str)", "dec"},
{"dec(std::ios_base &__base)", "dec"}
};
{"dec(std::ios_base &__base)", "dec"}};
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()};
// 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_) {
auto client_data = static_cast<ClientData *>(client_data_);
if(client_data->found_include.empty() && include_len > 0) {
auto source_location = clangmm::SourceLocation(inclusion_stack[0]);
if(static_cast<int>(source_location.get_offset().line) - 1 == client_data->line_nr &&
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);
clang_getInclusions(
clang_tu->cx_tu, [](CXFile included_file, CXSourceLocation *inclusion_stack, unsigned include_len, CXClientData client_data_) {
auto client_data = static_cast<ClientData *>(client_data_);
if(client_data->found_include.empty() && include_len > 0) {
auto source_location = clangmm::SourceLocation(inclusion_stack[0]);
if(static_cast<int>(source_location.get_offset().line) - 1 == client_data->line_nr &&
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);
if(!client_data.found_include.empty())
return Offset(0, 0, client_data.found_include);
// 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_) {
auto client_data = static_cast<ClientData *>(client_data_);
if(client_data->found_include.empty()) {
for(unsigned c = 1; c < include_len; ++c) {
auto source_location = clangmm::SourceLocation(inclusion_stack[c]);
if(static_cast<int>(source_location.get_offset().line) - 1 <= client_data->line_nr &&
filesystem::get_normal_path(source_location.get_path()) == client_data->file_path) {
auto included_file_str = clangmm::to_string(clang_getFileName(included_file));
if(ends_with(included_file_str, client_data->sm_str) &&
boost::filesystem::path(included_file_str).filename() == boost::filesystem::path(client_data->sm_str).filename()) {
client_data->found_include = included_file_str;
break;
clang_getInclusions(
clang_tu->cx_tu, [](CXFile included_file, CXSourceLocation *inclusion_stack, unsigned include_len, CXClientData client_data_) {
auto client_data = static_cast<ClientData *>(client_data_);
if(client_data->found_include.empty()) {
for(unsigned c = 1; c < include_len; ++c) {
auto source_location = clangmm::SourceLocation(inclusion_stack[c]);
if(static_cast<int>(source_location.get_offset().line) - 1 <= client_data->line_nr &&
filesystem::get_normal_path(source_location.get_path()) == client_data->file_path) {
auto included_file_str = clangmm::to_string(clang_getFileName(included_file));
if(ends_with(included_file_str, client_data->sm_str) &&
boost::filesystem::path(included_file_str).filename() == boost::filesystem::path(client_data->sm_str).filename()) {
client_data->found_include = included_file_str;
break;
}
}
}
}
}
}
}, &client_data);
},
&client_data);
if(!client_data.found_include.empty())
return Offset(0, 0, client_data.found_include);
@ -1957,9 +1962,11 @@ bool Source::ClangViewRefactor::wait_parsing() {
}
if(!not_parsed_clang_views.empty()) {
bool canceled = false;
auto message = std::make_unique<Dialog::Message>("Please wait while all buffers finish parsing", [&canceled] {
canceled = true;
}, true);
auto message = std::make_unique<Dialog::Message>(
"Please wait while all buffers finish parsing", [&canceled] {
canceled = true;
},
true);
ScopeGuard guard{[&message] {
message->hide();
}};

14
src/source_clang.hpp

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

8
src/source_diff.hpp

@ -11,7 +11,13 @@
namespace Source {
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 {
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::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);
parse_server_message();
}, [](const char *bytes, size_t n) {
std::cerr.write(bytes, n);
}, true, TinyProcessLib::Config{1048576});
parse_server_message(); }, [](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) {
@ -169,38 +167,39 @@ LanguageProtocol::Capabilities LanguageProtocol::Client::initialize(Source::Lang
"initializationOptions": {
"checkOnSave": { "enable": true }
},
"trace": "off")", [this, &result_processed](const boost::property_tree::ptree &result, bool error) {
if(!error) {
if(auto capabilities_pt = result.get_child_optional("capabilities")) {
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));
}
capabilities.hover = capabilities_pt->get<bool>("hoverProvider", false);
capabilities.completion = static_cast<bool>(capabilities_pt->get_child_optional("completionProvider"));
capabilities.signature_help = static_cast<bool>(capabilities_pt->get_child_optional("signatureHelpProvider"));
capabilities.definition = capabilities_pt->get<bool>("definitionProvider", false);
capabilities.references = capabilities_pt->get<bool>("referencesProvider", false);
capabilities.document_highlight = capabilities_pt->get<bool>("documentHighlightProvider", false);
capabilities.workspace_symbol = capabilities_pt->get<bool>("workspaceSymbolProvider", false);
capabilities.document_symbol = capabilities_pt->get<bool>("documentSymbolProvider", false);
capabilities.document_formatting = capabilities_pt->get<bool>("documentFormattingProvider", false);
capabilities.document_range_formatting = capabilities_pt->get<bool>("documentRangeFormattingProvider", false);
capabilities.rename = capabilities_pt->get<bool>("renameProvider", false);
if(!capabilities.rename)
capabilities.rename = capabilities_pt->get<bool>("renameProvider.prepareProvider", false);
capabilities.code_action = capabilities_pt->get<bool>("codeActionProvider", false);
if(!capabilities.code_action)
capabilities.code_action = static_cast<bool>(capabilities_pt->get_child_optional("codeActionProvider.codeActionKinds"));
capabilities.type_coverage = capabilities_pt->get<bool>("typeCoverageProvider", false);
}
"trace": "off")",
[this, &result_processed](const boost::property_tree::ptree &result, bool error) {
if(!error) {
if(auto capabilities_pt = result.get_child_optional("capabilities")) {
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));
}
capabilities.hover = capabilities_pt->get<bool>("hoverProvider", false);
capabilities.completion = static_cast<bool>(capabilities_pt->get_child_optional("completionProvider"));
capabilities.signature_help = static_cast<bool>(capabilities_pt->get_child_optional("signatureHelpProvider"));
capabilities.definition = capabilities_pt->get<bool>("definitionProvider", false);
capabilities.references = capabilities_pt->get<bool>("referencesProvider", false);
capabilities.document_highlight = capabilities_pt->get<bool>("documentHighlightProvider", false);
capabilities.workspace_symbol = capabilities_pt->get<bool>("workspaceSymbolProvider", false);
capabilities.document_symbol = capabilities_pt->get<bool>("documentSymbolProvider", false);
capabilities.document_formatting = capabilities_pt->get<bool>("documentFormattingProvider", false);
capabilities.document_range_formatting = capabilities_pt->get<bool>("documentRangeFormattingProvider", false);
capabilities.rename = capabilities_pt->get<bool>("renameProvider", false);
if(!capabilities.rename)
capabilities.rename = capabilities_pt->get<bool>("renameProvider.prepareProvider", false);
capabilities.code_action = capabilities_pt->get<bool>("codeActionProvider", false);
if(!capabilities.code_action)
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", "");
}
result_processed.set_value();
});
write_notification("initialized", "");
}
result_processed.set_value();
});
result_processed.get_future().get();
initialized = true;
@ -1025,8 +1024,7 @@ void Source::LanguageProtocolView::update_diagnostics_async(std::vector<Language
for(auto &quickfix_diagnostic : quickfix_diagnostics) {
if(diagnostic.message == quickfix_diagnostic.message && diagnostic.range == quickfix_diagnostic.range) {
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),
Offset(edit.range.end.line, edit.range.end.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)));
break;
}
}
@ -1036,8 +1034,7 @@ void Source::LanguageProtocolView::update_diagnostics_async(std::vector<Language
for(auto &diagnostic : diagnostics) {
if(edit.range.start.line == diagnostic.range.start.line) {
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),
Offset(edit.range.end.line, edit.range.end.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)));
break;
}
}

37
src/terminal.cpp

@ -55,7 +55,12 @@ Terminal::Terminal() : Source::SearchView() {
}
};
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;
std::string parameters;
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;
if(use_pipes)
process = std::make_unique<TinyProcessLib::Process>(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);
});
process = std::make_unique<TinyProcessLib::Process>(
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); });
else
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)
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::iterator iter;
while(!umessage.validate(iter)) {
@ -233,13 +236,11 @@ int Terminal::process(std::istream &stdin_stream, std::ostream &stdout_stream, c
next_char_iter++;
umessage.replace(iter, next_char_iter, "?");
}
stdout_stream.write(umessage.data(), n);
}, [this, stderr_stream](const char *bytes, size_t n) {
stdout_stream.write(umessage.data(), n); }, [this, stderr_stream](const char *bytes, size_t n) {
if(stderr_stream)
stderr_stream->write(bytes, n);
else
async_print(std::string(bytes, n), true);
}, true);
async_print(std::string(bytes, n), true); }, true);
if(process.get_id() <= 0) {
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();
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) {
// Print stdout message sequentially to avoid the GUI becoming unresponsive
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.get_future().get();
}
}, [this, quiet](const char *bytes, size_t n) {
} }, [this, quiet](const char *bytes, size_t n) {
if(!quiet) {
// Print stderr message sequentially to avoid the GUI becoming unresponsive
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.get_future().get();
}
}, true);
} }, true);
auto pid = process->get_id();
if(pid <= 0) {
@ -384,8 +384,9 @@ boost::optional<Terminal::Link> Terminal::find_link(const std::string &line, siz
size_t subs = (sub == 1 ||
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 + 4) ?
4 : 3;
sub == 1 + 4 + 3 + 3 + 4 + 3 + 3 + 3 + 3 + 4)
? 4
: 3;
if(sm.length(sub + 1)) {
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));

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};
clang_getInclusions(translation_unit->cx_tu, [](CXFile included_file, CXSourceLocation *inclusion_stack, unsigned include_len, CXClientData data) {
auto visitor_data = static_cast<VisitorData *>(data);
auto path = filesystem::get_normal_path(clangmm::to_string(clang_getFileName(included_file)));
if(filesystem::file_in_path(path, visitor_data->project_path)) {
for(unsigned c = 0; c < include_len; ++c) {
auto from_path = filesystem::get_normal_path(clangmm::SourceLocation(inclusion_stack[c]).get_path());
if(from_path == visitor_data->path) {
boost::system::error_code ec;
auto last_write_time = boost::filesystem::last_write_time(path, ec);
if(ec)
last_write_time = 0;
if(last_write_time > visitor_data->before_parse_time)
last_write_time = 0;
visitor_data->paths_and_last_write_times.emplace(path, last_write_time);
break;
clang_getInclusions(
translation_unit->cx_tu, [](CXFile included_file, CXSourceLocation *inclusion_stack, unsigned include_len, CXClientData data) {
auto visitor_data = static_cast<VisitorData *>(data);
auto path = filesystem::get_normal_path(clangmm::to_string(clang_getFileName(included_file)));
if(filesystem::file_in_path(path, visitor_data->project_path)) {
for(unsigned c = 0; c < include_len; ++c) {
auto from_path = filesystem::get_normal_path(clangmm::SourceLocation(inclusion_stack[c]).get_path());
if(from_path == visitor_data->path) {
boost::system::error_code ec;
auto last_write_time = boost::filesystem::last_write_time(path, ec);
if(ec)
last_write_time = 0;
if(last_write_time > visitor_data->before_parse_time)
last_write_time = 0;
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,
@ -163,9 +165,11 @@ boost::optional<std::vector<Usages::Clang::Usages>> Usages::Clang::get_usages(co
std::unique_ptr<Dialog::Message> message;
std::atomic<bool> canceled(false);
auto create_message = [&canceled] {
return std::make_unique<Dialog::Message>("Please wait while finding usages", [&canceled] {
canceled = true;
}, true);
return std::make_unique<Dialog::Message>(
"Please wait while finding usages", [&canceled] {
canceled = true;
},
true);
};
size_t tasks = cache_in_progress_count;
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, {}};
auto translation_unit_cursor = clang_getTranslationUnitCursor(translation_unit->cx_tu);
clang_visitChildren(translation_unit_cursor, [](CXCursor cx_cursor, CXCursor cx_parent, CXClientData data) {
auto visitor_data = static_cast<VisitorData *>(data);
clang_visitChildren(
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());
if(filesystem::file_in_path(path, visitor_data->project_path))
visitor_data->paths.emplace(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))
visitor_data->paths.emplace(path);
return CXChildVisit_Continue;
}, &visitor_data);
return CXChildVisit_Continue;
},
&visitor_data);
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, {}};
auto translation_unit_cursor = clang_getTranslationUnitCursor(translation_unit->cx_tu);
clang_visitChildren(translation_unit_cursor, [](CXCursor cx_cursor, CXCursor cx_parent, CXClientData data) {
auto visitor_data = static_cast<VisitorData *>(data);
clang_visitChildren(
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());
if(visitor_data->visited.find(path) == visitor_data->visited.end() && filesystem::file_in_path(path, visitor_data->project_path))
visitor_data->paths.emplace(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))
visitor_data->paths.emplace(path);
return CXChildVisit_Continue;
}, &visitor_data);
return CXChildVisit_Continue;
},
&visitor_data);
for(auto &path : visitor_data.paths)
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_info {border-radius: 5px;}
.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);
@ -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->update(0, "");
EntryBox::get().entries.emplace_back(run_arguments.second, [run_arguments_first = std::move(run_arguments.first)](const std::string &content) {
Project::run_arguments[run_arguments_first] = content;
EntryBox::get().hide();
}, 50);
EntryBox::get().entries.emplace_back(
run_arguments.second, [run_arguments_first = std::move(run_arguments.first)](const std::string &content) {
Project::run_arguments[run_arguments_first] = content;
EntryBox::get().hide();
},
50);
auto entry_it = EntryBox::get().entries.begin();
entry_it->set_placeholder_text("Run Arguments");
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->update(0, "");
EntryBox::get().entries.emplace_back(last_run_command, [this](const std::string &content) {
if(!content.empty()) {
last_run_command = content;
auto directory_folder = Project::get_preferably_directory_folder();
if(Config::get().terminal.clear_on_run_command)
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");
});
}
EntryBox::get().hide();
}, 30);
EntryBox::get().entries.emplace_back(
last_run_command, [this](const std::string &content) {
if(!content.empty()) {
last_run_command = content;
auto directory_folder = Project::get_preferably_directory_folder();
if(Config::get().terminal.clear_on_run_command)
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");
});
}
EntryBox::get().hide();
},
30);
auto entry_it = EntryBox::get().entries.begin();
entry_it->set_placeholder_text("Command");
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->update(0, "");
EntryBox::get().entries.emplace_back(run_arguments.second, [run_arguments_first = std::move(run_arguments.first)](const std::string &content) {
Project::debug_run_arguments[run_arguments_first].arguments = content;
EntryBox::get().hide();
}, 50);
EntryBox::get().entries.emplace_back(
run_arguments.second, [run_arguments_first = std::move(run_arguments.first)](const std::string &content) {
Project::debug_run_arguments[run_arguments_first].arguments = content;
EntryBox::get().hide();
},
50);
auto entry_it = EntryBox::get().entries.begin();
entry_it->set_placeholder_text("Debug Run Arguments");
@ -1491,17 +1498,19 @@ void Window::set_menu_actions() {
});
menu.add_action("debug_run_command", [this]() {
EntryBox::get().clear();
EntryBox::get().entries.emplace_back(last_run_debug_command, [this](const std::string &content) {
if(!content.empty()) {
if(Project::current) {
if(Config::get().terminal.clear_on_run_command)
Terminal::get().clear();
Project::current->debug_run_command(content);
}
last_run_debug_command = content;
}
EntryBox::get().hide();
}, 30);
EntryBox::get().entries.emplace_back(
last_run_debug_command, [this](const std::string &content) {
if(!content.empty()) {
if(Project::current) {
if(Config::get().terminal.clear_on_run_command)
Terminal::get().clear();
Project::current->debug_run_command(content);
}
last_run_debug_command = content;
}
EntryBox::get().hide();
},
30);
auto entry_it = EntryBox::get().entries.begin();
entry_it->set_placeholder_text("Debug Command");
EntryBox::get().buttons.emplace_back("Run Debug Command", [entry_it]() {

2
tests/filesystem_test.cpp

@ -91,4 +91,4 @@ int main() {
g_assert(uri == "file:///ro%20ot/te%20st%C3%A6%C3%B8%C3%A5.txt");
g_assert(path == filesystem::get_path_from_uri(uri));
}
}
}

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

16
tests/terminal_test.cpp

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

Loading…
Cancel
Save