Browse Source

Now supports multifile fixits

pipelines/235045657
eidheim 6 years ago
parent
commit
ebb613b2a5
  1. 2
      lib/libclangmm
  2. 21
      src/source.cc
  3. 3
      src/source.h
  4. 2
      src/source_clang.cc
  5. 4
      src/source_language_protocol.cc
  6. 53
      src/window.cc

2
lib/libclangmm

@ -1 +1 @@
Subproject commit 043d96d0bfbfe4bbb216a0954992d744a35c60ab Subproject commit db8a6d5b3e47ecd72e45b14baab26c6dbe1b15f0

21
src/source.cc

@ -87,7 +87,7 @@ Glib::RefPtr<Gsv::Language> Source::guess_language(const boost::filesystem::path
return language; return language;
} }
Source::FixIt::FixIt(std::string source_, std::pair<Offset, Offset> offsets_) : source(std::move(source_)), offsets(std::move(offsets_)) { Source::FixIt::FixIt(std::string source_, std::string path_, std::pair<Offset, Offset> offsets_) : source(std::move(source_)), path(std::move(path_)), offsets(std::move(offsets_)) {
if(this->source.size() == 0) if(this->source.size() == 0)
type = Type::erase; type = Type::erase;
else { else {
@ -99,17 +99,22 @@ Source::FixIt::FixIt(std::string source_, std::pair<Offset, Offset> offsets_) :
} }
std::string Source::FixIt::string(BaseView &view) { std::string Source::FixIt::string(BaseView &view) {
auto pos_str = " at " + std::to_string(offsets.first.line + 1) + ":" + std::to_string(view.get_iter_at_line_index(offsets.first.line, offsets.first.index).get_line_offset() + 1); bool in_current_view = path == view.file_path;
auto from_pos = (!in_current_view ? boost::filesystem::path(path).filename().string() + ':' : "") + std::to_string(offsets.first.line + 1) + ':' + std::to_string(offsets.first.index + 1);
std::string to_pos, text;
if(type != Type::insert) {
to_pos = std::to_string(offsets.second.line + 1) + ':' + std::to_string(offsets.second.index + 1);
text = in_current_view ? view.get_buffer()->get_text(view.get_iter_at_line_index(offsets.first.line, offsets.first.index),
view.get_iter_at_line_index(offsets.second.line, offsets.second.index)) : "";
}
if(type == Type::insert) if(type == Type::insert)
return "Insert " + source + pos_str; return "Insert " + source + " at " + from_pos;
else if(type == Type::replace) else if(type == Type::replace)
return "Replace " + view.get_buffer()->get_text(view.get_iter_at_line_index(offsets.first.line, offsets.first.index), return "Replace " + (!text.empty() ? text + " at " : "") + from_pos + " - " + to_pos + " with " + source;
view.get_iter_at_line_index(offsets.second.line, offsets.second.index)) +
pos_str + " with " + source;
else else
return "Erase " + view.get_buffer()->get_text(view.get_iter_at_line_index(offsets.first.line, offsets.first.index), return "Erase " + (!text.empty() ? text + " at " : "") + from_pos + " - " + to_pos;
view.get_iter_at_line_index(offsets.second.line, offsets.second.index)) + pos_str;
} }
////////////// //////////////

3
src/source.h

@ -43,12 +43,13 @@ namespace Source {
public: public:
enum class Type { insert, replace, erase }; enum class Type { insert, replace, erase };
FixIt(std::string source_, std::pair<Offset, Offset> offsets_); FixIt(std::string source_, std::string path_, std::pair<Offset, Offset> offsets_);
std::string string(BaseView &view); std::string string(BaseView &view);
Type type; Type type;
std::string source; std::string source;
std::string path;
std::pair<Offset, Offset> offsets; std::pair<Offset, Offset> offsets;
}; };

2
src/source_clang.cc

@ -333,7 +333,7 @@ void Source::ClangViewParse::update_diagnostics() {
offsets.second.line = clang_offsets.second.line - 1; offsets.second.line = clang_offsets.second.line - 1;
offsets.second.index = clang_offsets.second.index - 1; offsets.second.index = clang_offsets.second.index - 1;
fix_its.emplace_back(fix_it.source, offsets); fix_its.emplace_back(fix_it.source, fix_it.path, offsets);
if(fix_its_string.size() > 0) if(fix_its_string.size() > 0)
fix_its_string += '\n'; fix_its_string += '\n';

4
src/source_language_protocol.cc

@ -971,14 +971,13 @@ void Source::LanguageProtocolView::update_diagnostics_async(std::vector<Language
quickfix_diagnostics.emplace_back(it->second); quickfix_diagnostics.emplace_back(it->second);
auto changes = it->second.get_child("edit.changes"); auto changes = it->second.get_child("edit.changes");
for(auto file_it = changes.begin(); file_it != changes.end(); ++file_it) { for(auto file_it = changes.begin(); file_it != changes.end(); ++file_it) {
if(file_it->first == uri) {
for(auto edit_it = file_it->second.begin(); edit_it != file_it->second.end(); ++edit_it) { for(auto edit_it = file_it->second.begin(); edit_it != file_it->second.end(); ++edit_it) {
LanguageProtocol::TextEdit edit(edit_it->second); LanguageProtocol::TextEdit edit(edit_it->second);
for(auto &diagnostic : diagnostics) { for(auto &diagnostic : diagnostics) {
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, 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;
} }
@ -989,7 +988,6 @@ void Source::LanguageProtocolView::update_diagnostics_async(std::vector<Language
} }
} }
} }
}
catch(...) { catch(...) {
} }
} }

53
src/window.cc

@ -3,6 +3,7 @@
#ifdef JUCI_ENABLE_DEBUG #ifdef JUCI_ENABLE_DEBUG
#include "debug_lldb.h" #include "debug_lldb.h"
#endif #endif
#include "compile_commands.h"
#include "dialogs.h" #include "dialogs.h"
#include "directories.h" #include "directories.h"
#include "entrybox.h" #include "entrybox.h"
@ -1240,36 +1241,54 @@ void Window::set_menu_actions() {
} }
}); });
menu.add_action("source_apply_fix_its", []() { menu.add_action("source_apply_fix_its", []() {
if(auto view = Notebook::get().get_current_view()) { if(auto current_view = Notebook::get().get_current_view()) {
if(view->get_fix_its) { if(current_view->get_fix_its) {
auto buffer = view->get_buffer(); auto fix_its = current_view->get_fix_its();
auto fix_its = view->get_fix_its();
std::set<Glib::RefPtr<Gtk::TextBuffer>> buffers;
std::set<Source::View *> header_views;
std::vector<std::pair<Glib::RefPtr<Gtk::TextMark>, Glib::RefPtr<Gtk::TextMark>>> fix_it_marks; std::vector<std::pair<Glib::RefPtr<Gtk::TextMark>, Glib::RefPtr<Gtk::TextMark>>> fix_it_marks;
for(auto &fix_it : fix_its) { for(auto &fix_it : fix_its) {
auto view = current_view;
if(fix_it.path != current_view->file_path) {
Notebook::get().open(fix_it.path);
view = Notebook::get().get_current_view();
if(CompileCommands::is_header(view->file_path))
header_views.emplace(view);
}
auto start_iter = view->get_iter_at_line_pos(fix_it.offsets.first.line, fix_it.offsets.first.index); auto start_iter = view->get_iter_at_line_pos(fix_it.offsets.first.line, fix_it.offsets.first.index);
auto end_iter = view->get_iter_at_line_pos(fix_it.offsets.second.line, fix_it.offsets.second.index); auto end_iter = view->get_iter_at_line_pos(fix_it.offsets.second.line, fix_it.offsets.second.index);
fix_it_marks.emplace_back(buffer->create_mark(start_iter), buffer->create_mark(end_iter)); fix_it_marks.emplace_back(view->get_buffer()->create_mark(start_iter), view->get_buffer()->create_mark(end_iter));
buffers.emplace(view->get_buffer());
} }
size_t c = 0;
for(auto &buffer : buffers)
buffer->begin_user_action(); buffer->begin_user_action();
for(auto &fix_it : fix_its) { for(size_t i = 0; i < fix_its.size(); ++i) {
if(fix_it.type == Source::FixIt::Type::insert) { auto buffer = fix_it_marks[i].first->get_buffer();
buffer->insert(fix_it_marks[c].first->get_iter(), fix_it.source); if(fix_its[i].type == Source::FixIt::Type::insert)
buffer->insert(fix_it_marks[i].first->get_iter(), fix_its[i].source);
else if(fix_its[i].type == Source::FixIt::Type::replace) {
buffer->erase(fix_it_marks[i].first->get_iter(), fix_it_marks[i].second->get_iter());
buffer->insert(fix_it_marks[i].first->get_iter(), fix_its[i].source);
} }
if(fix_it.type == Source::FixIt::Type::replace) { else if(fix_its[i].type == Source::FixIt::Type::erase)
buffer->erase(fix_it_marks[c].first->get_iter(), fix_it_marks[c].second->get_iter()); buffer->erase(fix_it_marks[i].first->get_iter(), fix_it_marks[i].second->get_iter());
buffer->insert(fix_it_marks[c].first->get_iter(), fix_it.source);
}
if(fix_it.type == Source::FixIt::Type::erase) {
buffer->erase(fix_it_marks[c].first->get_iter(), fix_it_marks[c].second->get_iter());
}
c++;
} }
for(auto &mark_pair : fix_it_marks) { for(auto &mark_pair : fix_it_marks) {
auto buffer = mark_pair.first->get_buffer();
buffer->delete_mark(mark_pair.first); buffer->delete_mark(mark_pair.first);
buffer->delete_mark(mark_pair.second); buffer->delete_mark(mark_pair.second);
} }
for(auto &buffer : buffers)
buffer->end_user_action(); buffer->end_user_action();
for(auto &view : header_views) {
if(view->save())
Info::get().print("Saved Fix-Its to header file: " + filesystem::get_short_path(view->file_path).string());
}
if(current_view != Notebook::get().get_current_view())
Notebook::get().open(current_view->file_path);
} }
} }
}); });

Loading…
Cancel
Save