diff --git a/CMakeLists.txt b/CMakeLists.txt index e4802d4..7d483a9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required (VERSION 2.8.8) project(juci) -set(JUCI_VERSION "1.2.1.5") +set(JUCI_VERSION "1.2.1.6") set(CPACK_PACKAGE_NAME "jucipp") set(CPACK_PACKAGE_CONTACT "Ole Christian Eidheim ") diff --git a/src/config.cc b/src/config.cc index f43e70c..790a890 100644 --- a/src/config.cc +++ b/src/config.cc @@ -195,6 +195,8 @@ void Config::get_source() { source.cleanup_whitespace_characters=source_json.get("cleanup_whitespace_characters"); source.show_whitespace_characters=source_json.get("show_whitespace_characters"); + source.format_style_on_save=source_json.get("format_style_on_save"); + source.smart_brackets=source_json.get("smart_brackets"); source.smart_inserts=source_json.get("smart_inserts"); if(source.smart_inserts) diff --git a/src/config.h b/src/config.h index d3580bc..6e4f8c9 100644 --- a/src/config.h +++ b/src/config.h @@ -60,6 +60,8 @@ public: bool cleanup_whitespace_characters; std::string show_whitespace_characters; + bool format_style_on_save; + bool smart_brackets; bool smart_inserts; diff --git a/src/files.h b/src/files.h index 205490b..f62b028 100644 --- a/src/files.h +++ b/src/files.h @@ -41,6 +41,8 @@ R"RAW( "cleanup_whitespace_characters": false, "show_whitespace_characters_comment": "Determines what kind of whitespaces should be drawn. Use comma-separated list of: space, tab, newline, nbsp, leading, text, trailing or all", "show_whitespace_characters": "", + "format_style_on_save_comment": "Performs clang-format on save for C/C++ and other curly-bracket languages supported by clang-format", + "format_style_on_save": false, "smart_brackets_comment": "If smart_inserts is enabled, this option is automatically enabled. When inserting an already closed bracket, the cursor might instead be moved, avoiding the need of arrow keys after autocomplete", "smart_brackets": true, "smart_inserts_comment": "When for instance inserting (, () gets inserted. Applies to: (), [], \", '. Also enables pressing ; inside an expression before a final ) to insert ; at the end of line, and deletions of empty insertions", diff --git a/src/source.cc b/src/source.cc index 81242ce..933f432 100644 --- a/src/source.cc +++ b/src/source.cc @@ -172,7 +172,7 @@ Source::View::View(const boost::filesystem::path &file_path, Glib::RefPtrget_id()=="go" || language->get_id()=="scala" || language->get_id()=="opencl")) { is_bracket_language=true; - auto_indent=[this]() { + format_style=[this]() { auto command=Config::get().terminal.clang_format_command; bool use_style_file=false; @@ -208,47 +208,11 @@ Source::View::View(const boost::filesystem::path &file_path, Glib::RefPtrget_iter_at_line(get_buffer()->get_line_count()-1); - if(iter!=get_buffer()->end()) - get_buffer()->insert(get_buffer()->end(), "\n"); std::stringstream stdin_stream(get_buffer()->get_text()), stdout_stream; auto exit_status=Terminal::get().process(stdin_stream, stdout_stream, command, this->file_path.parent_path()); if(exit_status==0) { - get_buffer()->begin_user_action(); - auto iter=get_buffer()->get_insert()->get_iter(); - auto cursor_line_nr=iter.get_line(); - auto cursor_line_offset=iter.get_line_offset(); - - //Insert new text without moving scrolled window - auto new_text=stdout_stream.str(); - size_t start_line_index=0; - int line_nr=0; - for(size_t c=0;cget_line_count()) { - auto start_iter=get_buffer()->get_iter_at_line(line_nr); - auto end_iter=get_iter_at_line_end(line_nr); - get_buffer()->erase(start_iter, end_iter); - } - else - get_buffer()->insert(get_buffer()->end(), "\n"); - auto iter=get_buffer()->get_iter_at_line(line_nr); - get_buffer()->insert(iter, new_text.substr(start_line_index, c-start_line_index)); - ++line_nr; - start_line_index=c+1; - } - } - iter=get_buffer()->get_iter_at_line(get_buffer()->get_line_count()-1); - if(iter!=get_buffer()->end()) - get_buffer()->insert(get_buffer()->end(), "\n"); - if(line_nrget_line_count()-1) { - auto iter=get_buffer()->get_iter_at_line(line_nr); - get_buffer()->erase(iter, get_buffer()->end()); - } - get_buffer()->end_user_action(); - - place_cursor_at_line_offset(cursor_line_nr, cursor_line_offset); + replace_text(stdout_stream.str()); } }; } @@ -452,6 +416,9 @@ bool Source::View::save(const std::vector &views) { if(Config::get().source.cleanup_whitespace_characters) cleanup_whitespace_characters(); + if(Config::get().source.format_style_on_save && format_style) + format_style(); + if(filesystem::write(file_path, get_buffer())) { boost::system::error_code ec; last_write_time=boost::filesystem::last_write_time(file_path, ec); @@ -467,6 +434,63 @@ bool Source::View::save(const std::vector &views) { } } +void Source::View::replace_text(const std::string &text) { + get_buffer()->begin_user_action(); + auto iter=get_buffer()->get_insert()->get_iter(); + auto cursor_line_nr=iter.get_line(); + auto cursor_line_offset=iter.get_line_offset(); + + size_t start_line_index=0; + int line_nr=0; + for(size_t c=0;cget_line_count()) { + auto start_iter=get_buffer()->get_iter_at_line(line_nr); + auto end_iter=get_iter_at_line_end(line_nr); + + if(get_buffer()->get_text(start_iter, end_iter)!=line) { + get_buffer()->erase(start_iter, end_iter); + iter=get_buffer()->get_iter_at_line(line_nr); + get_buffer()->insert(iter, line); + } + } + else { + iter=get_buffer()->end(); + get_buffer()->insert(iter, '\n'+line); + } + + ++line_nr; + start_line_index=c+1; + } + } + + if(text[text.size()-1]=='\n') { + Gtk::TextIter iter; + get_buffer()->insert(get_iter_at_line_end(line_nr-1), "\n"); + ++line_nr; + } + + if(line_nrget_line_count()) { + auto iter=get_iter_at_line_end(line_nr-1); + get_buffer()->erase(iter, get_buffer()->end()); + } + + get_buffer()->end_user_action(); + + place_cursor_at_line_offset(cursor_line_nr, cursor_line_offset); +} + void Source::View::configure() { SpellCheckView::configure(); DiffView::configure(); diff --git a/src/source.h b/src/source.h index f4c0760..1d2360f 100644 --- a/src/source.h +++ b/src/source.h @@ -47,6 +47,9 @@ namespace Source { void rename(const boost::filesystem::path &path); virtual bool save(const std::vector &views); + ///Set new text without moving scrolled window + void replace_text(const std::string &text); + void configure() override; void search_highlight(const std::string &text, bool case_sensitive, bool regex); @@ -61,7 +64,7 @@ namespace Source { Glib::RefPtr language; - std::function auto_indent; + std::function format_style; std::function get_declaration_location; std::function(const std::vector &views)> get_implementation_locations; std::function >(const std::vector &views)> get_usages; diff --git a/src/window.cc b/src/window.cc index c7cdfa6..5509dab 100644 --- a/src/window.cc +++ b/src/window.cc @@ -489,8 +489,8 @@ void Window::set_menu_actions() { }); menu.add_action("source_indentation_auto_indent_buffer", [this]() { auto view=Notebook::get().get_current_view(); - if(view && view->auto_indent) - view->auto_indent(); + if(view && view->format_style) + view->format_style(); }); menu.add_action("source_goto_line", [this]() { @@ -1077,7 +1077,7 @@ void Window::activate_menu_items() { menu.actions["source_goto_line"]->set_enabled(view); menu.actions["source_center_cursor"]->set_enabled(view); - menu.actions["source_indentation_auto_indent_buffer"]->set_enabled(view && static_cast(view->auto_indent)); + menu.actions["source_indentation_auto_indent_buffer"]->set_enabled(view && static_cast(view->format_style)); menu.actions["source_find_symbol_ctags"]->set_enabled(view); menu.actions["source_comments_toggle"]->set_enabled(view && static_cast(view->toggle_comments)); menu.actions["source_comments_add_documentation"]->set_enabled(view && static_cast(view->add_documentation));