Browse Source

Merge pull request #93 from eidheim/master

Fixes #92 and use of ' in spellchecks, and some cleanups.
merge-requests/365/head
Jørgen Lien Sellæg 10 years ago
parent
commit
4eedbca28d
  1. 10
      src/notebook.cc
  2. 4
      src/selectiondialog.h
  3. 17
      src/source.cc
  4. 7
      src/source.h
  5. 66
      src/source_clang.cc
  6. 25
      src/source_clang.h
  7. 24
      src/window.cc

10
src/notebook.cc

@ -205,7 +205,7 @@ bool Notebook::save(int page, bool reparse_needed) {
for(auto a_view: source_views) {
if(auto a_clang_view=dynamic_cast<Source::ClangView*>(a_view)) {
if(clang_view!=a_clang_view)
a_clang_view->reparse_needed=true;
a_clang_view->soft_reparse_needed=true;
}
}
}
@ -230,12 +230,8 @@ bool Notebook::save(int page, bool reparse_needed) {
if(project_path!="") {
for(auto source_view: source_views) {
if(auto source_clang_view=dynamic_cast<Source::ClangView*>(source_view)) {
if(project_path==source_clang_view->project_path) {
if(source_clang_view->restart_parse())
Singleton::terminal->async_print("Reparsing "+source_clang_view->file_path.string()+"\n");
else
Singleton::terminal->async_print("Error: failed to reparse "+source_clang_view->file_path.string()+". Please reopen the file manually.\n", true);
}
if(project_path==source_clang_view->project_path)
source_clang_view->full_reparse_needed=true;
}
}
}

4
src/selectiondialog.h

@ -58,13 +58,13 @@ class SelectionDialog : public SelectionDialogBase {
public:
SelectionDialog(Gtk::TextView& text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, bool show_search_entry=true, bool use_markup=false);
bool on_key_press(GdkEventKey* key);
void show();
void show() override;
};
class CompletionDialog : public SelectionDialogBase {
public:
CompletionDialog(Gtk::TextView& text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark);
void show();
void show() override;
bool on_key_release(GdkEventKey* key);
bool on_key_press(GdkEventKey* key);

17
src/source.cc

@ -396,7 +396,7 @@ void Source::View::set_tooltip_events() {
delayed_tooltips_connection=Glib::signal_timeout().connect([this, x, y]() {
Tooltips::init();
Gdk::Rectangle rectangle(x, y, 1, 1);
if(source_readable) {
if(parsed) {
show_type_tooltips(rectangle);
show_diagnostic_tooltips(rectangle);
}
@ -426,7 +426,7 @@ void Source::View::set_tooltip_events() {
rectangle.set_x(location_window_x-2);
rectangle.set_y(location_window_y);
rectangle.set_width(5);
if(source_readable) {
if(parsed) {
show_type_tooltips(rectangle);
show_diagnostic_tooltips(rectangle);
}
@ -1245,7 +1245,18 @@ std::pair<Gtk::TextIter, Gtk::TextIter> Source::View::spellcheck_get_word(Gtk::T
}
void Source::View::spellcheck_word(const Gtk::TextIter& start, const Gtk::TextIter& end) {
auto word=get_buffer()->get_text(start, end);
auto spellcheck_start=start;
auto spellcheck_end=end;
if((spellcheck_end.get_offset()-spellcheck_start.get_offset())>=2) {
auto last_char=spellcheck_end;
last_char.backward_char();
if(*spellcheck_start=='\'' && *last_char=='\'') {
spellcheck_start.forward_char();
spellcheck_end.backward_char();
}
}
auto word=get_buffer()->get_text(spellcheck_start, spellcheck_end);
if(word.size()>0) {
auto correct = aspell_speller_check(spellcheck_checker, word.data(), word.bytes());
if(correct==0)

7
src/source.h

@ -101,8 +101,13 @@ namespace Source {
void set_tab_char_and_size(char tab_char, unsigned tab_size);
std::pair<char, unsigned> get_tab_char_and_size() {return {tab_char, tab_size};}
bool soft_reparse_needed=false;
bool full_reparse_needed=false;
virtual void soft_reparse() {}
virtual bool full_reparse() {return true;}
protected:
bool source_readable;
bool parsed=false;
Tooltips diagnostic_tooltips;
Tooltips type_tooltips;
virtual void show_diagnostic_tooltips(const Gdk::Rectangle &rectangle) {}

66
src/source_clang.cc

@ -48,7 +48,7 @@ Source::View(file_path, project_path, language), parse_error(false) {
if(parsing_mutex.try_lock()) {
update_syntax();
update_diagnostics();
source_readable=true;
parsed=true;
set_status("");
parsing_mutex.unlock();
}
@ -67,7 +67,7 @@ Source::View(file_path, project_path, language), parse_error(false) {
init_parse();
get_buffer()->signal_changed().connect([this]() {
start_reparse();
soft_reparse();
type_tooltips.hide();
diagnostic_tooltips.hide();
});
@ -108,7 +108,7 @@ void Source::ClangViewParse::configure() {
void Source::ClangViewParse::init_parse() {
type_tooltips.hide();
diagnostic_tooltips.hide();
source_readable=false;
parsed=false;
parse_thread_go=true;
parse_thread_mapped=false;
parse_thread_stop=false;
@ -170,12 +170,12 @@ std::map<std::string, std::string> Source::ClangViewParse::get_buffer_map() cons
return buffer_map;
}
void Source::ClangViewParse::start_reparse() {
void Source::ClangViewParse::soft_reparse() {
parse_thread_mapped=false;
source_readable=false;
parsed=false;
delayed_reparse_connection.disconnect();
delayed_reparse_connection=Glib::signal_timeout().connect([this]() {
source_readable=false;
parsed=false;
parse_thread_go=true;
set_status("parsing...");
return false;
@ -367,7 +367,7 @@ void Source::ClangViewParse::show_diagnostic_tooltips(const Gdk::Rectangle &rect
}
void Source::ClangViewParse::show_type_tooltips(const Gdk::Rectangle &rectangle) {
if(source_readable) {
if(parsed) {
Gtk::TextIter iter;
int location_x, location_y;
window_to_buffer_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, rectangle.get_x(), rectangle.get_y(), location_x, location_y);
@ -650,7 +650,7 @@ Source::ClangViewParse(file_path, project_path, language), autocomplete_cancel_s
autocomplete_fail_connection=autocomplete_fail.connect([this]() {
Singleton::terminal->print("Error: autocomplete failed, reparsing "+this->file_path.string()+"\n", true);
restart_parse();
full_reparse();
autocomplete_starting=false;
autocomplete_cancel_starting=false;
});
@ -661,9 +661,9 @@ Source::ClangViewParse(file_path, project_path, language), autocomplete_cancel_s
do_delete_object_connection.disconnect();
delete this;
});
do_restart_parse.connect([this](){
do_full_reparse.connect([this](){
init_parse();
restart_parse_running=false;
full_reparse_running=false;
});
}
@ -738,8 +738,8 @@ void Source::ClangViewAutocomplete::autocomplete() {
completion_dialog->on_hide=[this](){
get_source_buffer()->end_user_action();
completion_dialog_shown=false;
source_readable=false;
start_reparse();
parsed=false;
soft_reparse();
};
completion_dialog->on_select=[this, rows](const std::string& selected, bool hide_window) {
auto row = rows->at(selected);
@ -798,11 +798,11 @@ void Source::ClangViewAutocomplete::autocomplete() {
completion_dialog->show();
}
else
start_reparse();
soft_reparse();
}
else {
set_status("");
start_reparse();
soft_reparse();
start_autocomplete();
}
});
@ -874,8 +874,8 @@ void Source::ClangViewAutocomplete::async_delete() {
parse_thread_stop=true;
delete_thread=std::thread([this](){
//TODO: Is it possible to stop the clang-process in progress?
if(restart_parse_thread.joinable())
restart_parse_thread.join();
if(full_reparse_thread.joinable())
full_reparse_thread.join();
if(parse_thread.joinable())
parse_thread.join();
if(autocomplete_thread.joinable())
@ -884,19 +884,19 @@ void Source::ClangViewAutocomplete::async_delete() {
});
}
bool Source::ClangViewAutocomplete::restart_parse() {
if(!restart_parse_running && !parse_error) {
reparse_needed=false;
restart_parse_running=true;
bool Source::ClangViewAutocomplete::full_reparse() {
if(!full_reparse_running && !parse_error) {
soft_reparse_needed=false;
full_reparse_running=true;
parse_thread_stop=true;
if(restart_parse_thread.joinable())
restart_parse_thread.join();
restart_parse_thread=std::thread([this](){
if(full_reparse_thread.joinable())
full_reparse_thread.join();
full_reparse_thread=std::thread([this](){
if(parse_thread.joinable())
parse_thread.join();
if(autocomplete_thread.joinable())
autocomplete_thread.join();
do_restart_parse();
do_full_reparse();
});
return true;
}
@ -972,7 +972,7 @@ Source::ClangViewAutocomplete(file_path, project_path, language) {
};
get_token=[this]() -> Token {
if(source_readable) {
if(parsed) {
auto iter=get_buffer()->get_insert()->get_iter();
auto line=(unsigned)iter.get_line();
auto index=(unsigned)iter.get_line_index();
@ -994,7 +994,7 @@ Source::ClangViewAutocomplete(file_path, project_path, language) {
rename_similar_tokens=[this](const Token &token, const std::string &text) {
size_t number=0;
if(source_readable && token.language &&
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;
@ -1029,7 +1029,7 @@ Source::ClangViewAutocomplete(file_path, project_path, language) {
get_declaration_location=[this](){
Offset location;
if(source_readable) {
if(parsed) {
auto iter=get_buffer()->get_insert()->get_iter();
auto line=(unsigned)iter.get_line();
auto index=(unsigned)iter.get_line_index();
@ -1055,7 +1055,7 @@ Source::ClangViewAutocomplete(file_path, project_path, language) {
get_usages=[this](const Token &token) {
std::vector<std::pair<Offset, std::string> > usages;
if(source_readable && token.language &&
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) {
@ -1096,7 +1096,7 @@ Source::ClangViewAutocomplete(file_path, project_path, language) {
};
goto_method=[this](){
if(source_readable) {
if(parsed) {
auto iter=get_buffer()->get_insert()->get_iter();
Gdk::Rectangle visible_rect;
get_visible_rect(visible_rect);
@ -1167,7 +1167,7 @@ Source::ClangViewAutocomplete(file_path, project_path, language) {
};
std::vector<std::string> data;
if(source_readable) {
if(parsed) {
auto iter=get_buffer()->get_insert()->get_iter();
auto line=(unsigned)iter.get_line();
auto index=(unsigned)iter.get_line_index();
@ -1261,7 +1261,7 @@ Source::ClangViewAutocomplete(file_path, project_path, language) {
};
goto_next_diagnostic=[this]() {
if(source_readable) {
if(parsed) {
auto insert_offset=get_buffer()->get_insert()->get_iter().get_offset();
for(auto offset: diagnostic_offsets) {
if(offset>insert_offset) {
@ -1280,7 +1280,7 @@ Source::ClangViewAutocomplete(file_path, project_path, language) {
apply_fix_its=[this]() {
std::vector<std::pair<Glib::RefPtr<Gtk::TextMark>, Glib::RefPtr<Gtk::TextMark> > > fix_it_marks;
if(source_readable) {
if(parsed) {
for(auto &fix_it: fix_its) {
auto start_iter=get_buffer()->get_iter_at_line_index(fix_it.offsets.first.line-1, fix_it.offsets.first.index-1);
auto end_iter=get_buffer()->get_iter_at_line_index(fix_it.offsets.second.line-1, fix_it.offsets.second.index-1);
@ -1311,7 +1311,7 @@ Source::ClangViewAutocomplete(file_path, project_path, language) {
}
void Source::ClangViewRefactor::tag_similar_tokens(const Token &token) {
if(source_readable) {
if(parsed) {
if(token && last_tagged_token!=token) {
for(auto &mark: similar_token_marks) {
get_buffer()->remove_tag(similar_tokens_tag, mark.first->get_iter(), mark.second->get_iter());

25
src/source_clang.h

@ -22,13 +22,13 @@ namespace Source {
};
ClangViewParse(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr<Gsv::Language> language);
virtual void configure();
bool on_key_press_event(GdkEventKey* key) override;
void start_reparse();
bool reparse_needed=false;
void configure() override;
void soft_reparse() override;
protected:
void init_parse();
bool on_key_press_event(GdkEventKey* key);
std::unique_ptr<clang::TranslationUnit> clang_tu;
std::mutex parsing_mutex;
std::unique_ptr<clang::Tokens> clang_tokens;
@ -39,8 +39,8 @@ namespace Source {
std::atomic<bool> parse_thread_stop;
std::atomic<bool> parse_error;
virtual void show_diagnostic_tooltips(const Gdk::Rectangle &rectangle);
virtual void show_type_tooltips(const Gdk::Rectangle &rectangle);
void show_diagnostic_tooltips(const Gdk::Rectangle &rectangle) override;
void show_type_tooltips(const Gdk::Rectangle &rectangle) override;
boost::regex bracket_regex;
boost::regex no_bracket_statement_regex;
@ -81,10 +81,11 @@ namespace Source {
};
ClangViewAutocomplete(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr<Gsv::Language> language);
bool on_key_press_event(GdkEventKey* key) override;
virtual void async_delete();
bool restart_parse();
bool full_reparse() override;
protected:
bool on_key_press_event(GdkEventKey* key);
std::thread autocomplete_thread;
sigc::connection autocomplete_done_connection;
sigc::connection autocomplete_fail_connection;
@ -105,10 +106,10 @@ namespace Source {
std::mutex prefix_mutex;
Glib::Dispatcher do_delete_object;
Glib::Dispatcher do_restart_parse;
Glib::Dispatcher do_full_reparse;
std::thread delete_thread;
std::thread restart_parse_thread;
bool restart_parse_running=false;
std::thread full_reparse_thread;
bool full_reparse_running=false;
};
class ClangViewRefactor : public ClangViewAutocomplete {
@ -127,7 +128,7 @@ namespace Source {
class ClangView : public ClangViewRefactor {
public:
ClangView(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr<Gsv::Language> language);
virtual void async_delete();
void async_delete() override;
};
}

24
src/window.cc

@ -81,26 +81,30 @@ Window::Window() : compiling(false) {
notebook.signal_switch_page().connect([this](Gtk::Widget* page, guint page_num) {
if(notebook.get_current_page()!=-1) {
auto view=notebook.get_current_view();
if(search_entry_shown && entry_box.labels.size()>0) {
notebook.get_current_view()->update_search_occurrences=[this](int number){
view->update_search_occurrences=[this](int number){
entry_box.labels.begin()->update(0, std::to_string(number));
};
notebook.get_current_view()->search_highlight(last_search, case_sensitive_search, regex_search);
view->search_highlight(last_search, case_sensitive_search, regex_search);
}
activate_menu_items();
Singleton::directories->select(notebook.get_current_view()->file_path);
Singleton::directories->select(view->file_path);
if(auto source_view=dynamic_cast<Source::ClangView*>(notebook.get_current_view())) {
if(source_view->reparse_needed) {
source_view->start_reparse();
source_view->reparse_needed=false;
if(view->full_reparse_needed) {
if(!view->full_reparse())
Singleton::terminal->async_print("Error: failed to reparse "+view->file_path.string()+". Please reopen the file manually.\n", true);
view->full_reparse_needed=false;
}
else if(view->soft_reparse_needed) {
view->soft_reparse();
view->soft_reparse_needed=false;
}
notebook.get_current_view()->set_status(notebook.get_current_view()->status);
notebook.get_current_view()->set_info(notebook.get_current_view()->info);
view->set_status(view->status);
view->set_info(view->info);
}
});
notebook.signal_page_removed().connect([this](Gtk::Widget* page, guint page_num) {
@ -674,7 +678,7 @@ bool Window::on_key_press_event(GdkEventKey *event) {
}
#endif
return Gtk::Window::on_key_press_event(event);
return Gtk::ApplicationWindow::on_key_press_event(event);
}
bool Window::on_delete_event(GdkEventAny *event) {

Loading…
Cancel
Save