From 291c0509bdedb35d3cfe0d5c8e201fd2f2a2dec6 Mon Sep 17 00:00:00 2001 From: eidheim Date: Sat, 12 Dec 2015 12:50:23 +0100 Subject: [PATCH 1/7] Better find tab char and size function --- src/source.cc | 159 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 132 insertions(+), 27 deletions(-) diff --git a/src/source.cc b/src/source.cc index 9987a15..a34755e 100644 --- a/src/source.cc +++ b/src/source.cc @@ -520,7 +520,7 @@ void Source::View::replace_backward(const std::string &replacement) { auto &start=selection_bound; Gtk::TextIter match_start, match_end; if(gtk_source_search_context_backward(search_context, start.gobj(), match_start.gobj(), match_end.gobj())) { - auto offset=match_start.get_offset(); + auto offset=match_start.get_offset(); gtk_source_search_context_replace(search_context, match_start.gobj(), match_end.gobj(), replacement.c_str(), replacement.size(), NULL); get_buffer()->select_range(get_buffer()->get_iter_at_offset(offset), get_buffer()->get_iter_at_offset(offset+replacement.size())); @@ -557,7 +557,7 @@ void Source::View::paste() { bool first_paste_line=true; size_t paste_line_tabs=-1; bool first_paste_line_has_tabs=false; - for(size_t c=0;c Source::View::find_tab_char_and_size() { - auto size=get_buffer()->get_line_count(); std::unordered_map tab_chars; std::unordered_map tab_sizes; - unsigned last_tab_size=0; - for(int c=0;c(str.size()-last_tab_size)); - if(tab_diff>0) { - unsigned tab_diff_unsigned=static_cast(tab_diff); - auto it_size=tab_sizes.find(tab_diff_unsigned); - if(it_size!=tab_sizes.end()) - it_size->second++; - else - tab_sizes[tab_diff_unsigned]=1; + auto iter=get_buffer()->begin(); + long tab_count=-1; + long last_tab_count=0; + bool single_quoted=false; + bool double_quoted=false; + //For bracket languages, TODO: add more language ids + if(language && (language->get_id()=="chdr" || language->get_id()=="cpphdr" || language->get_id()=="c" || + language->get_id()=="cpp" || language->get_id()=="objc" || language->get_id()=="java" || + language->get_id()=="javascript")) { + bool line_comment=false; + bool comment=false; + bool bracket_last_line=false; + char last_char=0; + long last_tab_diff=-1; + while(iter) { + if(iter.starts_line()) { + line_comment=false; + single_quoted=false; + double_quoted=false; + tab_count=0; + if(last_char=='{') + bracket_last_line=true; + else + bracket_last_line=false; + } + if(bracket_last_line && tab_count!=-1) { + if(*iter==' ') { + tab_chars[' ']++; + tab_count++; + } + else if(*iter=='\t') { + tab_chars['\t']++; + tab_count++; + } + else { + auto line_iter=iter; + char last_line_char=0; + while(line_iter && !line_iter.ends_line()) { + if(*line_iter!=' ' && *line_iter!='\t') + last_line_char=*line_iter; + if(*line_iter=='(') + break; + line_iter.forward_char(); + } + if(last_line_char==':' || *iter=='#') { + tab_count=0; + if((iter.get_line()+1) < get_buffer()->get_line_count()) { + iter=get_buffer()->get_iter_at_line(iter.get_line()+1); + continue; + } + } + else if(!iter.ends_line()) { + if(tab_count!=last_tab_count) + tab_sizes[abs(tab_count-last_tab_count)]++; + last_tab_diff=abs(tab_count-last_tab_count); + last_tab_count=tab_count; + last_char=0; + } + } + } + + auto prev_iter=iter; + prev_iter.backward_char(); + auto prev_prev_iter=prev_iter; + prev_prev_iter.backward_char(); + if(!double_quoted && *iter=='\'' && !(*prev_iter=='\\' && *prev_prev_iter!='\\')) + single_quoted=!single_quoted; + else if(!single_quoted && *iter=='\"' && !(*prev_iter=='\\' && *prev_prev_iter!='\\')) + double_quoted=!double_quoted; + else if(!single_quoted && !double_quoted) { + auto next_iter=iter; + next_iter.forward_char(); + if(*iter=='/' && *next_iter=='/') + line_comment=true; + else if(*iter=='/' && *next_iter=='*') + comment=true; + else if(*iter=='*' && *next_iter=='/') { + iter.forward_char(); + iter.forward_char(); + comment=false; + } + } + if(!single_quoted && !double_quoted && !comment && !line_comment && *iter!=' ' && *iter!='\t' && !iter.ends_line()) + last_char=*iter; + if(!single_quoted && !double_quoted && !comment && !line_comment && *iter=='}' && tab_count!=-1 && last_tab_diff!=-1) + last_tab_count-=last_tab_diff; + if(*iter!=' ' && *iter!='\t') + tab_count=-1; + + iter.forward_char(); } - - last_tab_size=str.size(); - - if(str.size()>0) { - auto it_char=tab_chars.find(str[0]); - if(it_char!=tab_chars.end()) - it_char->second++; - else - tab_chars[str[0]]=1; + } + else { + long para_count=0; + while(iter) { + if(iter.starts_line()) + tab_count=0; + if(tab_count!=-1 && para_count==0 && single_quoted==false && double_quoted==false) { + if(*iter==' ') { + tab_chars[' ']++; + tab_count++; + } + else if(*iter=='\t') { + tab_chars['\t']++; + tab_count++; + } + else if(!iter.ends_line()) { + if(tab_count!=last_tab_count) + tab_sizes[abs(tab_count-last_tab_count)]++; + last_tab_count=tab_count; + } + } + auto prev_iter=iter; + prev_iter.backward_char(); + auto prev_prev_iter=prev_iter; + prev_prev_iter.backward_char(); + if(!double_quoted && *iter=='\'' && !(*prev_iter=='\\' && *prev_prev_iter!='\\')) + single_quoted=!single_quoted; + else if(!single_quoted && *iter=='\"' && !(*prev_iter=='\\' && *prev_prev_iter!='\\')) + double_quoted=!double_quoted; + else if(!single_quoted && !double_quoted) { + if(*iter=='(') + para_count++; + else if(*iter==')') + para_count--; + } + if(*iter!=' ' && *iter!='\t') + tab_count=-1; + + iter.forward_char(); } } + char found_tab_char=0; size_t occurences=0; for(auto &tab_char: tab_chars) { From 3b089e7ec6763cd19aad545c289aab855c2f53bc Mon Sep 17 00:00:00 2001 From: eidheim Date: Sat, 12 Dec 2015 12:58:00 +0100 Subject: [PATCH 2/7] Now linked to v1.0.2 of tiny-process-library, which most importingly fixes some file descriptor closing issues --- .gitmodules | 2 +- tiny-process-library | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 6d3904f..dca293e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -5,4 +5,4 @@ [submodule "tiny-process-library"] path = tiny-process-library url = https://github.com/eidheim/tiny-process-library - branch = v1.0.1 + branch = v1.0.2 diff --git a/tiny-process-library b/tiny-process-library index 3307488..2805253 160000 --- a/tiny-process-library +++ b/tiny-process-library @@ -1 +1 @@ -Subproject commit 3307488fbf733b18de9b274fe3249d9d54497a06 +Subproject commit 2805253ae779ac6f8fc28c0c55e96c37b87e571d From 490a09812c2246d0d4e66993101d11e3a3e5cbdd Mon Sep 17 00:00:00 2001 From: "U-olece-PC\\olece" Date: Sat, 12 Dec 2015 15:38:54 +0100 Subject: [PATCH 3/7] Fixed file paths for MSYS2 on new file and open actions --- src/juci.cc | 3 +-- src/window.cc | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/juci.cc b/src/juci.cc index 8c6968a..d09c93b 100644 --- a/src/juci.cc +++ b/src/juci.cc @@ -30,8 +30,7 @@ int Application::on_command_line(const Glib::RefPtr boost::system::error_code ec; auto new_p=boost::filesystem::canonical(parent_p, ec); if(!ec && boost::filesystem::is_directory(new_p)) { - new_p+="/"; - new_p+=p.filename(); + new_p/=p.filename(); files.emplace_back(new_p); } else diff --git a/src/window.cc b/src/window.cc index 2315aa7..4aaca2a 100644 --- a/src/window.cc +++ b/src/window.cc @@ -164,7 +164,7 @@ void Window::set_menu_actions() { if(filesystem::write(path)) { if(Directories::get().current_path!="") Directories::get().update(); - notebook.open(path.string()); + notebook.open(boost::filesystem::canonical(path)); Terminal::get().print("New file "+path.string()+" created.\n"); } else @@ -223,7 +223,7 @@ void Window::set_menu_actions() { menu.add_action("open_file", [this]() { auto path=Dialog::open_file(); if(path!="") - notebook.open(path); + notebook.open(boost::filesystem::canonical(path)); }); menu.add_action("open_folder", [this]() { auto path = Dialog::open_folder(); From 61b2af3a38814fbd197f8a479c612939704f1a9c Mon Sep 17 00:00:00 2001 From: "U-ole-PC\\ole" Date: Sat, 12 Dec 2015 16:09:46 +0100 Subject: [PATCH 4/7] All MSYS2 paths should now be ok --- src/window.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/window.cc b/src/window.cc index 4aaca2a..e0115d2 100644 --- a/src/window.cc +++ b/src/window.cc @@ -148,7 +148,7 @@ void Window::set_menu_actions() { about.present(); }); menu.add_action("preferences", [this]() { - notebook.open(Config::get().juci_home_path()/"config"/"config.json"); + notebook.open(boost::filesystem::canonical(Config::get().juci_home_path()/"config"/"config.json")); }); menu.add_action("quit", [this]() { close(); @@ -197,9 +197,9 @@ void Window::set_menu_actions() { project_name[c]='_'; } auto cmakelists_path=project_path; - cmakelists_path+="/CMakeLists.txt"; + cmakelists_path/="CMakeLists.txt"; auto cpp_main_path=project_path; - cpp_main_path+="/main.cpp"; + cpp_main_path/="main.cpp"; if(boost::filesystem::exists(cmakelists_path)) { Terminal::get().print("Error: "+cmakelists_path.string()+" already exists.\n", true); return; @@ -256,7 +256,7 @@ void Window::set_menu_actions() { file.close(); if(Directories::get().current_path!="") Directories::get().update(); - notebook.open(path); + notebook.open(boost::filesystem::canonical(path)); Terminal::get().print("File saved to: " + notebook.get_current_view()->file_path.string()+"\n"); } else From a77da5e0bec8c652525ec4ddf7a6ea9731d14cff Mon Sep 17 00:00:00 2001 From: "U-olece-PC\\olece" Date: Sun, 13 Dec 2015 07:41:22 +0100 Subject: [PATCH 5/7] Fixed directory tree focus by comparing boost::filesystem instead of std::string --- src/config.cc | 8 ++++---- src/directories.cc | 16 ++++++++-------- src/directories.h | 4 ++-- src/window.cc | 13 +++++++------ 4 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/config.cc b/src/config.cc index 2283f1c..36cbe4d 100644 --- a/src/config.cc +++ b/src/config.cc @@ -14,10 +14,10 @@ Config::Config() { for (auto &variable : environment_variables) { ptr=std::getenv(variable.c_str()); if (ptr!=nullptr && boost::filesystem::exists(ptr)) { - home /= ptr; - home /= ".juci"; - break; - } + home /= ptr; + home /= ".juci"; + break; + } } if(home.empty()) { std::string searched_envs = "["; diff --git a/src/directories.cc b/src/directories.cc index 586f88a..4209ec7 100644 --- a/src/directories.cc +++ b/src/directories.cc @@ -35,13 +35,13 @@ Directories::Directories() : Gtk::TreeView(), stop_update_thread(false) { signal_row_activated().connect([this](const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* column){ auto iter = tree_store->get_iter(path); if (iter) { - auto path_str=iter->get_value(column_record.path); - if(path_str!="") { - if (boost::filesystem::is_directory(boost::filesystem::path(path_str))) { + auto filesystem_path=iter->get_value(column_record.path); + if(filesystem_path!="") { + if (boost::filesystem::is_directory(boost::filesystem::path(filesystem_path))) { row_expanded(path) ? collapse_row(path) : expand_row(path, false); } else { if(on_row_activated) - on_row_activated(path_str); + on_row_activated(filesystem_path); } } } @@ -57,7 +57,7 @@ Directories::Directories() : Gtk::TreeView(), stop_update_thread(false) { }); signal_row_collapsed().connect([this](const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& path){ update_mutex.lock(); - last_write_times.erase(iter->get_value(column_record.path)); + last_write_times.erase(iter->get_value(column_record.path).string()); update_mutex.unlock(); auto children=iter->children(); if(children) { @@ -170,7 +170,7 @@ void Directories::select(const boost::filesystem::path &path) { for(auto &a_path: paths) { tree_store->foreach_iter([this, &a_path](const Gtk::TreeModel::iterator& iter){ - if(iter->get_value(column_record.path)==a_path.string()) { + if(iter->get_value(column_record.path)==a_path) { update_mutex.lock(); add_path(a_path, *iter); update_mutex.unlock(); @@ -181,7 +181,7 @@ void Directories::select(const boost::filesystem::path &path) { } tree_store->foreach_iter([this, &path](const Gtk::TreeModel::iterator& iter){ - if(iter->get_value(column_record.path)==path.string()) { + if(iter->get_value(column_record.path)==path) { auto tree_path=Gtk::TreePath(iter); expand_to_path(tree_path); set_cursor(tree_path); @@ -225,7 +225,7 @@ void Directories::add_path(const boost::filesystem::path& dir_path, const Gtk::T auto child = tree_store->append(*children); not_deleted.emplace(filename); child->set_value(column_record.name, filename); - child->set_value(column_record.path, it->path().string()); + child->set_value(column_record.path, it->path()); if (boost::filesystem::is_directory(it->path())) { child->set_value(column_record.id, "a"+filename); auto grandchild=tree_store->append(child->children()); diff --git a/src/directories.h b/src/directories.h index 0bca969..9314605 100644 --- a/src/directories.h +++ b/src/directories.h @@ -22,7 +22,7 @@ public: } Gtk::TreeModelColumn id; Gtk::TreeModelColumn name; - Gtk::TreeModelColumn path; + Gtk::TreeModelColumn path; Gtk::TreeModelColumn color; }; @@ -38,7 +38,7 @@ public: void update(); void select(const boost::filesystem::path &path); - std::function on_row_activated; + std::function on_row_activated; std::unique_ptr cmake; boost::filesystem::path current_path; diff --git a/src/window.cc b/src/window.cc index e0115d2..8849d2b 100644 --- a/src/window.cc +++ b/src/window.cc @@ -1,3 +1,4 @@ + #include "window.h" #include "logging.h" #include "config.h" @@ -55,8 +56,8 @@ Window::Window() : compiling(false) { show_all_children(); - Directories::get().on_row_activated=[this](const std::string &file) { - notebook.open(file); + Directories::get().on_row_activated=[this](const boost::filesystem::path &path) { + notebook.open(path); }; //Scroll to end of terminal whenever info is printed @@ -148,7 +149,7 @@ void Window::set_menu_actions() { about.present(); }); menu.add_action("preferences", [this]() { - notebook.open(boost::filesystem::canonical(Config::get().juci_home_path()/"config"/"config.json")); + notebook.open(Config::get().juci_home_path()/"config"/"config.json"); }); menu.add_action("quit", [this]() { close(); @@ -164,7 +165,7 @@ void Window::set_menu_actions() { if(filesystem::write(path)) { if(Directories::get().current_path!="") Directories::get().update(); - notebook.open(boost::filesystem::canonical(path)); + notebook.open(path); Terminal::get().print("New file "+path.string()+" created.\n"); } else @@ -223,7 +224,7 @@ void Window::set_menu_actions() { menu.add_action("open_file", [this]() { auto path=Dialog::open_file(); if(path!="") - notebook.open(boost::filesystem::canonical(path)); + notebook.open(path); }); menu.add_action("open_folder", [this]() { auto path = Dialog::open_folder(); @@ -256,7 +257,7 @@ void Window::set_menu_actions() { file.close(); if(Directories::get().current_path!="") Directories::get().update(); - notebook.open(boost::filesystem::canonical(path)); + notebook.open(path); Terminal::get().print("File saved to: " + notebook.get_current_view()->file_path.string()+"\n"); } else From d4964f41cd71e1e4242681c7a7c8fc43b413b395 Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 13 Dec 2015 08:02:42 +0100 Subject: [PATCH 6/7] Changed to version 1.0.0 --- src/files.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/files.h b/src/files.h index 32f6fd2..272a406 100644 --- a/src/files.h +++ b/src/files.h @@ -2,7 +2,7 @@ #define JUCI_FILES_H_ #include -#define JUCI_VERSION "0.9.6" +#define JUCI_VERSION "1.0.0" const std::string configjson = "{\n" From a136eed3cb3c538aa1edfe8de1f0b6de9fd2797b Mon Sep 17 00:00:00 2001 From: eidheim Date: Sun, 13 Dec 2015 10:22:38 +0100 Subject: [PATCH 7/7] Fixed autocomplete error handling --- src/source_clang.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/source_clang.cc b/src/source_clang.cc index 1303bef..7fd0271 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -664,7 +664,7 @@ Source::ClangViewParse(file_path, project_path, language), autocomplete_state(Au return false; }); - autocomplete_error_connection=autocomplete_done.connect([this](){ + autocomplete_done_connection=autocomplete_done.connect([this](){ if(autocomplete_state==AutocompleteState::CANCELED) { set_status(""); soft_reparse(); @@ -932,6 +932,7 @@ bool Source::ClangViewAutocomplete::full_reparse() { if(!parse_state.compare_exchange_strong(expected, ParseState::RESTARTING)) return false; } + autocomplete_state=AutocompleteState::IDLE; soft_reparse_needed=false; full_reparse_running=true; if(full_reparse_thread.joinable()) @@ -1397,7 +1398,7 @@ void Source::ClangView::async_delete() { parse_postprocess_connection.disconnect(); parse_preprocess_connection.disconnect(); parse_error_connection.disconnect(); - autocomplete_error_connection.disconnect(); + autocomplete_done_connection.disconnect(); autocomplete_restart_connection.disconnect(); autocomplete_error_connection.disconnect(); do_restart_parse_connection.disconnect();