Browse Source

Cleanup of refactoring methods

merge-requests/365/head
eidheim 10 years ago
parent
commit
8b7ae10a77
  1. 3
      src/info.cc
  2. 1
      src/info.h
  3. 3
      src/notebook.h
  4. 4
      src/source.cc
  5. 28
      src/source.h
  6. 227
      src/source_clang.cc
  7. 18
      src/source_clang.h
  8. 123
      src/window.cc

3
src/info.cc

@ -38,9 +38,6 @@ Info::Info() {
}
void Info::print(const std::string &text) {
if(!enabled)
return;
timeout_connection.disconnect();
//Timeout based on https://en.wikipedia.org/wiki/Words_per_minute
//(average_words_per_minute*average_letters_per_word)/60 => (228*4.5)/60 = 17.1

1
src/info.h

@ -12,7 +12,6 @@ public:
}
void print(const std::string &text);
bool enabled=true;
private:
Gtk::Label label;

3
src/notebook.h

@ -37,11 +37,12 @@ public:
void configure(int view_nr);
boost::filesystem::path get_current_folder();
std::vector<Source::View*> source_views; //Is NOT freed in destructor, this is intended for quick program exit.
Gtk::Label info;
Gtk::Label status;
private:
bool save_modified_dialog(int page);
std::vector<Source::View*> source_views; //Is NOT freed in destructor, this is intended for quick program exit.
std::vector<std::unique_ptr<Gtk::Widget> > source_maps;
std::vector<std::unique_ptr<Gtk::ScrolledWindow> > scrolled_windows;
std::vector<std::unique_ptr<Gtk::HBox> > hboxes;

4
src/source.cc

@ -395,7 +395,7 @@ Gsv::DrawSpacesFlags Source::View::parse_show_whitespace_characters(const std::s
static_cast<Gsv::DrawSpacesFlags>(std::accumulate(out.begin(), out.end(), 0));
}
bool Source::View::save(const std::vector<Source::View*> views) {
bool Source::View::save(const std::vector<Source::View*> &views) {
if(file_path.empty() || !get_buffer()->get_modified())
return false;
//Remove trailing whitespace characters on save, and add trailing newline if missing
@ -1617,7 +1617,7 @@ bool Source::View::on_focus_in_event(GdkEventFocus* focus_event){
boost::system::error_code ec;
auto last_write_time=boost::filesystem::last_write_time(file_path, ec);
if(!ec && last_write_time>last_read_time)
Info::get().print(file_path.filename().string() + " was changed outside juCi++, continue with caution.");
Info::get().print("Caution: " + file_path.filename().string() + " was altered outside of juCi++");
return Gsv::View::on_focus_in_event(focus_event);
};

28
src/source.h

@ -26,27 +26,11 @@
namespace Source {
Glib::RefPtr<Gsv::Language> guess_language(const boost::filesystem::path &file_path);
class Token {
public:
Token(): type(-1) {}
Token(Glib::RefPtr<Gsv::Language> language, int type, const std::string &spelling, const std::string &usr):
language(language), type(type), spelling(spelling), usr(usr) {}
operator bool() const {return (type>=0 && spelling.size()>0 && usr.size()>0);}
bool operator==(const Token &o) const {return (type==o.type &&
spelling==o.spelling &&
usr==o.usr);}
bool operator!=(const Token &o) const {return !(*this==o);}
Glib::RefPtr<Gsv::Language> language;
int type;
std::string spelling;
std::string usr;
};
class Offset {
public:
Offset() {}
Offset(unsigned line, unsigned index, const boost::filesystem::path &file_path=""): line(line), index(index), file_path(file_path) {}
operator bool() { return !file_path.empty(); }
bool operator==(const Offset &o) {return (line==o.line && index==o.index);}
unsigned line;
@ -72,7 +56,7 @@ namespace Source {
View(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
~View();
virtual bool save(const std::vector<Source::View*> views);
virtual bool save(const std::vector<Source::View*> &views);
virtual void configure();
void search_highlight(const std::string &text, bool case_sensitive, bool regex);
@ -90,12 +74,12 @@ namespace Source {
std::function<void()> auto_indent;
std::function<Offset()> get_declaration_location;
std::function<Offset(const Token &token)> get_implementation_location;
std::function<std::vector<std::pair<Offset, std::string> >(const Token &token)> get_usages;
std::function<Offset(const std::vector<Source::View*> &views)> get_implementation_location;
std::function<std::vector<std::pair<Offset, std::string> >(const std::vector<Source::View*> &views)> get_usages;
std::function<void()> goto_method;
std::function<Token()> get_token;
std::function<std::vector<std::string>()> get_token_data;
std::function<size_t(const Token &token, const std::string &text)> rename_similar_tokens;
std::function<std::string()> get_token_spelling;
std::function<std::vector<std::pair<boost::filesystem::path, size_t> >(const std::vector<Source::View*> &views, const std::string &text)> rename_similar_tokens;
std::function<void()> goto_next_diagnostic;
std::function<void()> apply_fix_its;

227
src/source_clang.cc

@ -43,7 +43,7 @@ Source::View(file_path, language) {
});
}
bool Source::ClangViewParse::save(const std::vector<Source::View*> views) {
bool Source::ClangViewParse::save(const std::vector<Source::View*> &views) {
if(!Source::View::save(views))
return false;
@ -191,7 +191,7 @@ void Source::ClangViewParse::soft_reparse() {
std::vector<std::string> Source::ClangViewParse::get_compilation_commands() {
auto build=Project::Build::create(file_path);
if(build->project_path.empty())
Info::get().print("Could not find a supported build system");
Info::get().print(file_path.filename().string()+": could not find a supported build system");
auto default_build_path=build->get_default_path();
build->update_default();
clang::CompilationDatabase db(default_build_path.string());
@ -423,7 +423,7 @@ void Source::ClangViewParse::show_type_tooltips(const Gdk::Rectangle &rectangle)
for(auto &token: *tokens) {
auto cursor=token.get_cursor();
if(token.get_kind()==clang::Token_Identifier && cursor.has_type()) {
if(static_cast<unsigned>(token.get_cursor().get_kind())==103) //These cursors are buggy
if(token.get_cursor().get_kind()==clang::CursorKind::CallExpr) //These cursors are buggy
continue;
auto start=get_buffer()->get_iter_at_line_index(token.offsets.first.line-1, token.offsets.first.index-1);
auto end=get_buffer()->get_iter_at_line_index(token.offsets.second.line-1, token.offsets.second.index-1);
@ -876,60 +876,59 @@ Source::ClangViewAutocomplete(file_path, language) {
}
});
get_token=[this]() -> Token {
get_token_spelling=[this]() {
if(!parsed) {
Info::get().print("Buffer is parsing");
return Token();
return std::string();
}
auto iter=get_buffer()->get_insert()->get_iter();
auto line=static_cast<unsigned>(iter.get_line());
auto index=static_cast<unsigned>(iter.get_line_index());
for(auto &token: *clang_tokens) {
auto cursor=token.get_cursor();
if(token.get_kind()==clang::Token_Identifier && cursor.has_type()) {
if(line==token.offsets.first.line-1 && index>=token.offsets.first.index-1 && index <=token.offsets.second.index-1) {
if(static_cast<unsigned>(token.get_cursor().get_kind())==103) //These cursors are buggy
continue;
auto referenced=cursor.get_referenced();
if(referenced)
return Token(this->language, static_cast<int>(referenced.get_kind()), token.get_spelling(), referenced.get_usr());
}
}
}
return Token();
return get_token().spelling;
};
rename_similar_tokens=[this](const Token &token, const std::string &text) {
size_t number=0;
if(parsed && token.language &&
(token.language->get_id()=="chdr" || token.language->get_id()=="cpphdr" || token.language->get_id()=="c" || token.language->get_id()=="cpp" || token.language->get_id()=="objc")) {
auto offsets=clang_tokens->get_similar_token_offsets(static_cast<clang::CursorKind>(token.type), token.spelling, token.usr);
std::vector<std::pair<Glib::RefPtr<Gtk::TextMark>, Glib::RefPtr<Gtk::TextMark> > > marks;
for(auto &offset: offsets) {
marks.emplace_back(get_buffer()->create_mark(get_buffer()->get_iter_at_line_index(offset.first.line-1, offset.first.index-1)), get_buffer()->create_mark(get_buffer()->get_iter_at_line_index(offset.second.line-1, offset.second.index-1)));
number++;
}
get_source_buffer()->begin_user_action();
for(auto &mark: marks) {
renaming=true;
get_buffer()->erase(mark.first->get_iter(), mark.second->get_iter());
get_buffer()->insert(mark.first->get_iter(), text);
get_buffer()->delete_mark(mark.first);
get_buffer()->delete_mark(mark.second);
rename_similar_tokens=[this](const std::vector<Source::View*> &views, const std::string &text) {
std::vector<std::pair<boost::filesystem::path, size_t> > renamed;
if(!parsed) {
Info::get().print("Buffer is parsing");
return renamed;
}
auto token=get_token();
if(token) {
std::vector<Source::View*> renamed_views;
for(auto &view: views) {
if(auto clang_view=dynamic_cast<Source::ClangView*>(view)) {
auto offsets=clang_view->clang_tokens->get_similar_token_offsets(token.kind, token.spelling, token.usr);
std::vector<std::pair<Glib::RefPtr<Gtk::TextMark>, Glib::RefPtr<Gtk::TextMark> > > marks;
for(auto &offset: offsets) {
marks.emplace_back(clang_view->get_buffer()->create_mark(clang_view->get_buffer()->get_iter_at_line_index(offset.first.line-1, offset.first.index-1)),
clang_view->get_buffer()->create_mark(clang_view->get_buffer()->get_iter_at_line_index(offset.second.line-1, offset.second.index-1)));
}
if(!marks.empty()) {
clang_view->renaming=true;
clang_view->get_source_buffer()->begin_user_action();
for(auto &mark: marks) {
clang_view->get_buffer()->erase(mark.first->get_iter(), mark.second->get_iter());
clang_view->get_buffer()->insert(mark.first->get_iter(), text);
clang_view->get_buffer()->delete_mark(mark.first);
clang_view->get_buffer()->delete_mark(mark.second);
}
clang_view->get_source_buffer()->end_user_action();
clang_view->renaming=false;
clang_view->save(views);
renamed_views.emplace_back(clang_view);
renamed.emplace_back(clang_view->file_path, marks.size());
}
}
}
get_source_buffer()->end_user_action();
renaming=false;
for(auto &view: renamed_views)
view->soft_reparse_needed=false;
}
return number;
return renamed;
};
get_buffer()->signal_mark_set().connect([this](const Gtk::TextBuffer::iterator& iterator, const Glib::RefPtr<Gtk::TextBuffer::Mark>& mark){
if(mark->get_name()=="insert") {
delayed_tag_similar_tokens_connection.disconnect();
delayed_tag_similar_tokens_connection=Glib::signal_timeout().connect([this]() {
Info::get().enabled=false;
auto token=get_token();
Info::get().enabled=true;
tag_similar_tokens(token);
return false;
}, 100);
@ -963,23 +962,32 @@ Source::ClangViewAutocomplete(file_path, language) {
return location;
};
get_implementation_location=[this](const Token &token){
get_implementation_location=[this](const std::vector<Source::View*> &views){
Offset location;
if(parsed && this->language && this->language->get_id()!="chdr" && this->language->get_id()!="cpphdr") {
for(auto token_it=clang_tokens->rbegin();token_it!=clang_tokens->rend();++token_it) {
auto cursor=token_it->get_cursor();
auto kind=cursor.get_kind();
if((kind==clang::CursorKind::FunctionDecl || kind==clang::CursorKind::CXXMethod ||
kind==clang::CursorKind::Constructor || kind==clang::CursorKind::Destructor) &&
token_it->get_kind()==clang::Token_Identifier && cursor.has_type()) {
auto referenced=cursor.get_referenced();
if(referenced && static_cast<clang::CursorKind>(token.type)==referenced.get_kind() &&
token.spelling==token_it->get_spelling() && token.usr==referenced.get_usr()) {
location.file_path=cursor.get_source_location().get_path();
auto clang_offset=cursor.get_source_location().get_offset();
location.line=clang_offset.line;
location.index=clang_offset.index;
break;
if(!parsed) {
Info::get().print("Buffer is parsing");
return location;
}
auto token=get_token();
for(auto &view: views) {
if(auto clang_view=dynamic_cast<Source::ClangView*>(view)) {
if(clang_view->language && clang_view->language->get_id()!="chdr" && clang_view->language->get_id()!="cpphdr") {
for(auto token_it=clang_view->clang_tokens->rbegin();token_it!=clang_view->clang_tokens->rend();++token_it) {
auto cursor=token_it->get_cursor();
auto kind=cursor.get_kind();
if((kind==clang::CursorKind::FunctionDecl || kind==clang::CursorKind::CXXMethod ||
kind==clang::CursorKind::Constructor || kind==clang::CursorKind::Destructor) &&
token_it->get_kind()==clang::Token_Identifier && cursor.has_type()) {
auto referenced=cursor.get_referenced();
if(referenced && token.kind==referenced.get_kind() &&
token.spelling==token_it->get_spelling() && token.usr==referenced.get_usr()) {
location.file_path=cursor.get_source_location().get_path();
auto clang_offset=cursor.get_source_location().get_offset();
location.line=clang_offset.line;
location.index=clang_offset.index;
return location;
}
}
}
}
}
@ -987,42 +995,54 @@ Source::ClangViewAutocomplete(file_path, language) {
return location;
};
get_usages=[this](const Token &token) {
get_usages=[this](const std::vector<Source::View*> &views) {
std::vector<std::pair<Offset, std::string> > usages;
if(parsed && token.language &&
(token.language->get_id()=="chdr" || token.language->get_id()=="cpphdr" || token.language->get_id()=="c" || token.language->get_id()=="cpp" || token.language->get_id()=="objc")) {
auto offsets=clang_tokens->get_similar_token_offsets(static_cast<clang::CursorKind>(token.type), token.spelling, token.usr);
for(auto &offset: offsets) {
size_t whitespaces_removed=0;
auto start_iter=get_buffer()->get_iter_at_line(offset.first.line-1);
while(!start_iter.ends_line() && (*start_iter==' ' || *start_iter=='\t')) {
start_iter.forward_char();
whitespaces_removed++;
}
auto end_iter=start_iter;
while(!end_iter.ends_line())
end_iter.forward_char();
std::string line=Glib::Markup::escape_text(get_buffer()->get_text(start_iter, end_iter));
//markup token as bold
size_t token_start_pos=offset.first.index-1-whitespaces_removed;
size_t token_end_pos=offset.second.index-1-whitespaces_removed;
size_t pos=0;
while((pos=line.find('&', pos))!=std::string::npos) {
size_t pos2=line.find(';', pos+2);
if(token_start_pos>pos) {
token_start_pos+=pos2-pos;
token_end_pos+=pos2-pos;
if(!parsed) {
Info::get().print("Buffer is parsing");
return usages;
}
auto token=get_token();
std::vector<Source::View*> views_reordered;
views_reordered.emplace_back(this);
for(auto &view: views) {
if(view!=this)
views_reordered.emplace_back(view);
}
for(auto &view: views_reordered) {
if(auto clang_view=dynamic_cast<Source::ClangView*>(view)) {
auto offsets=clang_view->clang_tokens->get_similar_token_offsets(token.kind, token.spelling, token.usr);
for(auto &offset: offsets) {
size_t whitespaces_removed=0;
auto start_iter=clang_view->get_buffer()->get_iter_at_line(offset.first.line-1);
while(!start_iter.ends_line() && (*start_iter==' ' || *start_iter=='\t')) {
start_iter.forward_char();
whitespaces_removed++;
}
else if(token_end_pos>pos)
token_end_pos+=pos2-pos;
else
break;
pos=pos2+1;
auto end_iter=start_iter;
while(!end_iter.ends_line())
end_iter.forward_char();
std::string line=Glib::Markup::escape_text(clang_view->get_buffer()->get_text(start_iter, end_iter));
//markup token as bold
size_t token_start_pos=offset.first.index-1-whitespaces_removed;
size_t token_end_pos=offset.second.index-1-whitespaces_removed;
size_t pos=0;
while((pos=line.find('&', pos))!=std::string::npos) {
size_t pos2=line.find(';', pos+2);
if(token_start_pos>pos) {
token_start_pos+=pos2-pos;
token_end_pos+=pos2-pos;
}
else if(token_end_pos>pos)
token_end_pos+=pos2-pos;
else
break;
pos=pos2+1;
}
line.insert(token_end_pos, "</b>");
line.insert(token_start_pos, "<b>");
usages.emplace_back(Offset(offset.first.line-1, offset.first.index-1, clang_view->file_path), line);
}
line.insert(token_end_pos, "</b>");
line.insert(token_start_pos, "<b>");
usages.emplace_back(Offset(offset.first.line-1, offset.first.index-1, this->file_path), line);
}
}
@ -1237,6 +1257,27 @@ Source::ClangViewAutocomplete(file_path, language) {
};
}
Source::ClangViewRefactor::Token Source::ClangViewRefactor::get_token() {
if(!parsed)
return Token();
auto iter=get_buffer()->get_insert()->get_iter();
auto line=static_cast<unsigned>(iter.get_line());
auto index=static_cast<unsigned>(iter.get_line_index());
for(auto &token: *clang_tokens) {
auto cursor=token.get_cursor();
if(token.get_kind()==clang::Token_Identifier && cursor.has_type()) {
if(line==token.offsets.first.line-1 && index>=token.offsets.first.index-1 && index <=token.offsets.second.index-1) {
if(token.get_cursor().get_kind()==clang::CursorKind::CallExpr) //These cursors are buggy
continue;
auto referenced=cursor.get_referenced();
if(referenced)
return Token(referenced.get_kind(), token.get_spelling(), referenced.get_usr());
}
}
}
return Token();
}
void Source::ClangViewRefactor::tag_similar_tokens(const Token &token) {
if(parsed) {
if(token && last_tagged_token!=token) {
@ -1246,7 +1287,7 @@ void Source::ClangViewRefactor::tag_similar_tokens(const Token &token) {
get_buffer()->delete_mark(mark.second);
}
similar_token_marks.clear();
auto offsets=clang_tokens->get_similar_token_offsets(static_cast<clang::CursorKind>(token.type), token.spelling, token.usr);
auto offsets=clang_tokens->get_similar_token_offsets(token.kind, token.spelling, token.usr);
for(auto &offset: offsets) {
auto start_iter=get_buffer()->get_iter_at_line_index(offset.first.line-1, offset.first.index-1);
auto end_iter=get_buffer()->get_iter_at_line_index(offset.second.line-1, offset.second.index-1);

18
src/source_clang.h

@ -15,7 +15,7 @@ namespace Source {
protected:
enum class ParseState {PROCESSING, RESTARTING, STOP};
enum class ParseProcessState {IDLE, STARTING, PREPROCESSING, PROCESSING, POSTPROCESSING};
public:
class TokenRange {
public:
TokenRange(std::pair<clang::Offset, clang::Offset> offsets, int kind):
@ -24,9 +24,10 @@ namespace Source {
int kind;
};
public:
ClangViewParse(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
bool save(const std::vector<Source::View*> views) override;
bool save(const std::vector<Source::View*> &views) override;
void configure() override;
void soft_reparse() override;
@ -99,11 +100,24 @@ namespace Source {
};
class ClangViewRefactor : public ClangViewAutocomplete {
class Token {
public:
Token(clang::CursorKind kind, const std::string &spelling, const std::string &usr) : kind(kind), spelling(spelling), usr(usr) {}
Token() : kind(static_cast<clang::CursorKind>(0)) {}
operator bool() const { return static_cast<int>(kind)!=0; }
bool operator==(const Token &other) const { return (kind==other.kind && spelling==other.spelling && usr==other.usr); }
bool operator!=(const Token &other) const { return !(*this==other); }
clang::CursorKind kind;
std::string spelling;
std::string usr;
};
public:
ClangViewRefactor(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
protected:
sigc::connection delayed_tag_similar_tokens_connection;
private:
Token get_token();
std::list<std::pair<Glib::RefPtr<Gtk::TextMark>, Glib::RefPtr<Gtk::TextMark> > > similar_token_marks;
void tag_similar_tokens(const Token &token);
Glib::RefPtr<Gtk::TextTag> similar_tokens_tag;

123
src/window.cc

@ -436,7 +436,7 @@ void Window::set_menu_actions() {
if(notebook.get_current_page()!=-1) {
if(notebook.get_current_view()->get_declaration_location) {
auto location=notebook.get_current_view()->get_declaration_location();
if(!location.file_path.empty()) {
if(location) {
boost::filesystem::path declaration_file;
boost::system::error_code ec;
declaration_file=boost::filesystem::canonical(location.file_path, ec);
@ -454,72 +454,51 @@ void Window::set_menu_actions() {
});
menu.add_action("source_goto_implementation", [this]() {
if(notebook.get_current_page()!=-1) {
auto current_view=notebook.get_current_view();
if(current_view->get_token) {
auto token=current_view->get_token();
if(token) {
for(int page=0;page<notebook.size();page++) {
auto view=notebook.get_view(page);
if(view->get_implementation_location) {
auto location=view->get_implementation_location(token);
if(!location.file_path.empty()) {
boost::filesystem::path implementation_path;
boost::system::error_code ec;
implementation_path=boost::filesystem::canonical(location.file_path, ec);
if(ec)
return;
notebook.open(implementation_path);
auto view=notebook.get_current_view();
auto line=static_cast<int>(location.line)-1;
auto index=static_cast<int>(location.index)-1;
view->place_cursor_at_line_index(line, index);
view->scroll_to_cursor_delayed(view, true, false);
return;
}
}
}
Info::get().print("Could not find implementation");
auto view=notebook.get_current_view();
if(view->get_implementation_location) {
auto location=view->get_implementation_location(notebook.source_views);
if(location) {
boost::filesystem::path implementation_path;
boost::system::error_code ec;
implementation_path=boost::filesystem::canonical(location.file_path, ec);
if(ec)
return;
notebook.open(implementation_path);
auto view=notebook.get_current_view();
auto line=static_cast<int>(location.line)-1;
auto index=static_cast<int>(location.index)-1;
view->place_cursor_at_line_index(line, index);
view->scroll_to_cursor_delayed(view, true, false);
return;
}
Info::get().print("Could not find implementation");
}
}
});
menu.add_action("source_goto_usage", [this]() {
if(notebook.get_current_page()!=-1) {
auto current_view=notebook.get_current_view();
if(current_view->get_token && current_view->get_usages) {
auto token=current_view->get_token();
if(token) {
auto iter=current_view->get_iter_for_dialog();
current_view->selection_dialog=std::unique_ptr<SelectionDialog>(new SelectionDialog(*current_view, current_view->get_buffer()->create_mark(iter), true, true));
auto view=notebook.get_current_view();
if(view->get_usages) {
auto usages=view->get_usages(notebook.source_views);
if(!usages.empty()) {
auto iter=view->get_iter_for_dialog();
view->selection_dialog=std::unique_ptr<SelectionDialog>(new SelectionDialog(*view, view->get_buffer()->create_mark(iter), true, true));
auto rows=std::make_shared<std::unordered_map<std::string, Source::Offset> >();
//First add usages in current file
auto usages=current_view->get_usages(token);
for(auto &usage: usages) {
auto iter=current_view->get_buffer()->get_iter_at_line_index(usage.first.line, usage.first.index);
auto row=std::to_string(iter.get_line()+1)+':'+std::to_string(iter.get_line_offset()+1)+' '+usage.second;
std::string row;
//add file name if usage is not in current tab
if(view->file_path!=usage.first.file_path)
row=usage.first.file_path.filename().string()+":";
row+=std::to_string(usage.first.line+1)+": "+usage.second;
(*rows)[row]=usage.first;
current_view->selection_dialog->add_row(row);
}
//Then the remaining opened files
for(int page=0;page<notebook.size();page++) {
auto view=notebook.get_view(page);
if(view!=current_view) {
if(view->get_usages) {
auto usages=view->get_usages(token);
for(auto &usage: usages) {
auto iter=view->get_buffer()->get_iter_at_line_index(usage.first.line, usage.first.index);
auto row=usage.first.file_path.filename().string()+":"+std::to_string(iter.get_line()+1)+':'+std::to_string(iter.get_line_offset()+1)+' '+usage.second;
(*rows)[row]=usage.first;
current_view->selection_dialog->add_row(row);
}
}
}
view->selection_dialog->add_row(row);
}
if(rows->size()==0)
return;
current_view->selection_dialog->on_select=[this, rows](const std::string& selected, bool hide_window) {
view->selection_dialog->on_select=[this, rows](const std::string &selected, bool hide_window) {
auto offset=rows->at(selected);
boost::filesystem::path declaration_file;
boost::system::error_code ec;
@ -532,7 +511,7 @@ void Window::set_menu_actions() {
view->scroll_to(view->get_buffer()->get_insert(), 0.0, 1.0, 0.5);
view->delayed_tooltips_connection.disconnect();
};
current_view->selection_dialog->show();
view->selection_dialog->show();
}
}
}
@ -1087,33 +1066,29 @@ void Window::goto_line_entry() {
void Window::rename_token_entry() {
EntryBox::get().clear();
if(notebook.get_current_page()!=-1) {
if(notebook.get_current_view()->get_token) {
auto token=std::make_shared<Source::Token>(notebook.get_current_view()->get_token());
if(*token) {
auto view=notebook.get_current_view();
if(view->get_token_spelling && view->rename_similar_tokens) {
auto spelling=std::make_shared<std::string>(view->get_token_spelling());
if(!spelling->empty()) {
EntryBox::get().labels.emplace_back();
auto label_it=EntryBox::get().labels.begin();
label_it->update=[label_it](int state, const std::string& message){
label_it->set_text("Warning: only opened and parsed tabs will have its content renamed, and modified files will be saved");
};
label_it->update(0, "");
EntryBox::get().entries.emplace_back(token->spelling, [this, token](const std::string& content){
if(notebook.get_current_page()!=-1 && content!=token->spelling) {
std::vector<int> modified_pages;
for(int c=0;c<notebook.size();c++) {
auto view=notebook.get_view(c);
if(view->rename_similar_tokens) {
auto number=view->rename_similar_tokens(*token, content);
if(number>0) {
Terminal::get().print("Replaced "+std::to_string(number)+" occurrences in file "+view->file_path.string()+"\n");
notebook.save(c);
modified_pages.emplace_back(c);
}
}
}
for(auto &page: modified_pages)
notebook.get_view(page)->soft_reparse_needed=false;
EntryBox::get().hide();
auto iter=std::make_shared<Gtk::TextIter>(view->get_buffer()->get_insert()->get_iter());
EntryBox::get().entries.emplace_back(*spelling, [this, view, spelling, iter](const std::string& content){
//TODO: gtk needs a way to check if iter is valid without dumping g_error message
//iter->get_buffer() will print such a message, but no segfault will occur
if(notebook.get_current_page()!=-1 && notebook.get_current_view()==view &&
content!=*spelling && iter->get_buffer() && view->get_buffer()->get_insert()->get_iter()==*iter) {
auto renamed_pairs=view->rename_similar_tokens(notebook.source_views, content);
for(auto &renamed: renamed_pairs)
Terminal::get().print("Replaced "+std::to_string(renamed.second)+" occurrences in file "+renamed.first.string()+"\n");
}
else
Info::get().print("Operation canceled");
EntryBox::get().hide();
});
auto entry_it=EntryBox::get().entries.begin();
entry_it->set_placeholder_text("New name");

Loading…
Cancel
Save