diff --git a/lib/libclangmm b/lib/libclangmm index 043d96d..db8a6d5 160000 --- a/lib/libclangmm +++ b/lib/libclangmm @@ -1 +1 @@ -Subproject commit 043d96d0bfbfe4bbb216a0954992d744a35c60ab +Subproject commit db8a6d5b3e47ecd72e45b14baab26c6dbe1b15f0 diff --git a/src/source.cc b/src/source.cc index fe7547a..4c0165f 100644 --- a/src/source.cc +++ b/src/source.cc @@ -87,7 +87,7 @@ Glib::RefPtr Source::guess_language(const boost::filesystem::path return language; } -Source::FixIt::FixIt(std::string source_, std::pair offsets_) : source(std::move(source_)), offsets(std::move(offsets_)) { +Source::FixIt::FixIt(std::string source_, std::string path_, std::pair offsets_) : source(std::move(source_)), path(std::move(path_)), offsets(std::move(offsets_)) { if(this->source.size() == 0) type = Type::erase; else { @@ -99,17 +99,22 @@ Source::FixIt::FixIt(std::string source_, std::pair offsets_) : } 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) - return "Insert " + source + pos_str; + return "Insert " + source + " at " + from_pos; else if(type == Type::replace) - return "Replace " + 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)) + - pos_str + " with " + source; + return "Replace " + (!text.empty() ? text + " at " : "") + from_pos + " - " + to_pos + " with " + source; else - return "Erase " + 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)) + pos_str; + return "Erase " + (!text.empty() ? text + " at " : "") + from_pos + " - " + to_pos; } ////////////// diff --git a/src/source.h b/src/source.h index 52cf285..6f8800e 100644 --- a/src/source.h +++ b/src/source.h @@ -43,12 +43,13 @@ namespace Source { public: enum class Type { insert, replace, erase }; - FixIt(std::string source_, std::pair offsets_); + FixIt(std::string source_, std::string path_, std::pair offsets_); std::string string(BaseView &view); Type type; std::string source; + std::string path; std::pair offsets; }; diff --git a/src/source_clang.cc b/src/source_clang.cc index 0a609e2..0c04c54 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -333,7 +333,7 @@ void Source::ClangViewParse::update_diagnostics() { offsets.second.line = clang_offsets.second.line - 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) fix_its_string += '\n'; diff --git a/src/source_language_protocol.cc b/src/source_language_protocol.cc index 7ed9503..b138a6e 100644 --- a/src/source_language_protocol.cc +++ b/src/source_language_protocol.cc @@ -971,17 +971,15 @@ void Source::LanguageProtocolView::update_diagnostics_async(std::vectorsecond); auto changes = it->second.get_child("edit.changes"); 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) { - LanguageProtocol::TextEdit edit(edit_it->second); - for(auto &diagnostic : diagnostics) { - 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{}); - pair.first->second.emplace_back(edit.new_text, std::make_pair(Offset(edit.range.start.line, edit.range.start.character), - Offset(edit.range.end.line, edit.range.end.character))); - break; - } + for(auto edit_it = file_it->second.begin(); edit_it != file_it->second.end(); ++edit_it) { + LanguageProtocol::TextEdit edit(edit_it->second); + for(auto &diagnostic : diagnostics) { + 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{}); + pair.first->second.emplace_back(edit.new_text, filesystem::get_path_from_uri(file_it->first).string(), std::make_pair(Offset(edit.range.start.line, edit.range.start.character), + Offset(edit.range.end.line, edit.range.end.character))); + break; } } } diff --git a/src/window.cc b/src/window.cc index d91da9b..11fc3ea 100644 --- a/src/window.cc +++ b/src/window.cc @@ -3,6 +3,7 @@ #ifdef JUCI_ENABLE_DEBUG #include "debug_lldb.h" #endif +#include "compile_commands.h" #include "dialogs.h" #include "directories.h" #include "entrybox.h" @@ -1240,36 +1241,54 @@ void Window::set_menu_actions() { } }); menu.add_action("source_apply_fix_its", []() { - if(auto view = Notebook::get().get_current_view()) { - if(view->get_fix_its) { - auto buffer = view->get_buffer(); - auto fix_its = view->get_fix_its(); + if(auto current_view = Notebook::get().get_current_view()) { + if(current_view->get_fix_its) { + auto fix_its = current_view->get_fix_its(); + + std::set> buffers; + std::set header_views; std::vector, Glib::RefPtr>> fix_it_marks; 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 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; - buffer->begin_user_action(); - for(auto &fix_it : fix_its) { - if(fix_it.type == Source::FixIt::Type::insert) { - buffer->insert(fix_it_marks[c].first->get_iter(), fix_it.source); - } - if(fix_it.type == Source::FixIt::Type::replace) { - buffer->erase(fix_it_marks[c].first->get_iter(), fix_it_marks[c].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()); + + for(auto &buffer : buffers) + buffer->begin_user_action(); + for(size_t i = 0; i < fix_its.size(); ++i) { + auto buffer = fix_it_marks[i].first->get_buffer(); + 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); } - c++; + else if(fix_its[i].type == Source::FixIt::Type::erase) + buffer->erase(fix_it_marks[i].first->get_iter(), fix_it_marks[i].second->get_iter()); } 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.second); } - buffer->end_user_action(); + for(auto &buffer : buffers) + 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); } } });