From 6d7ddd623567517933eb8f4adf04de9b9b94a672 Mon Sep 17 00:00:00 2001 From: eidheim Date: Wed, 9 Sep 2015 08:56:32 +0200 Subject: [PATCH] Now opens files that are not UTF-8 valid, if a language is found for the file, that is, this does not include binary files. --- src/source.cc | 31 ++++++++++++++++++++----------- src/source.h | 8 ++++---- src/sourcefile.cc | 38 +++++++++++++++++++++++++++++--------- src/sourcefile.h | 3 +++ 4 files changed, 56 insertions(+), 24 deletions(-) diff --git a/src/source.cc b/src/source.cc index 56304b3..1bb3654 100644 --- a/src/source.cc +++ b/src/source.cc @@ -48,13 +48,22 @@ Glib::RefPtr Source::guess_language(const boost::filesystem::path ////////////// AspellConfig* Source::View::spellcheck_config=NULL; -Source::View::View(const boost::filesystem::path &file_path): file_path(file_path) { +Source::View::View(const boost::filesystem::path &file_path, Glib::RefPtr language): file_path(file_path) { set_smart_home_end(Gsv::SMART_HOME_END_BEFORE); + get_source_buffer()->begin_not_undoable_action(); - if(juci::filesystem::read(file_path, get_buffer())==-1) - Singleton::terminal()->print("Error: "+file_path.string()+" is not a valid UTF-8 file."); + if(language) { + if(juci::filesystem::read_non_utf8(file_path, get_buffer())==-1) + Singleton::terminal()->print("Warning: "+file_path.string()+" is not a valid UTF-8 file. Saving might corrupt the file.\n"); + } + else { + if(juci::filesystem::read(file_path, get_buffer())==-1) + Singleton::terminal()->print("Error: "+file_path.string()+" is not a valid UTF-8 file.\n"); + } get_source_buffer()->end_not_undoable_action(); + get_buffer()->place_cursor(get_buffer()->get_iter_at_offset(0)); + search_settings = gtk_source_search_settings_new(); gtk_source_search_settings_set_wrap_around(search_settings, true); search_context = gtk_source_search_context_new(get_source_buffer()->gobj(), search_settings); @@ -908,7 +917,7 @@ std::vector Source::View::spellcheck_get_suggestions(const Gtk::Tex ///////////////////// //// GenericView //// ///////////////////// -Source::GenericView::GenericView(const boost::filesystem::path &file_path, Glib::RefPtr language) : View(file_path) { +Source::GenericView::GenericView(const boost::filesystem::path &file_path, Glib::RefPtr language) : View(file_path, language) { if(language) { get_source_buffer()->set_language(language); Singleton::terminal()->print("Language for file "+file_path.string()+" set to "+language->get_name()+".\n"); @@ -928,8 +937,8 @@ Source::GenericView::GenericView(const boost::filesystem::path &file_path, Glib: //////////////////////// clang::Index Source::ClangViewParse::clang_index(0, 0); -Source::ClangViewParse::ClangViewParse(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path): -Source::View(file_path), project_path(project_path), parse_error(false) { +Source::ClangViewParse::ClangViewParse(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr language): +Source::View(file_path, language), project_path(project_path), parse_error(false) { DEBUG("start"); auto scheme = get_source_buffer()->get_style_scheme(); auto tag_table=get_buffer()->get_tag_table(); @@ -1385,8 +1394,8 @@ bool Source::ClangViewParse::on_key_press_event(GdkEventKey* key) { ////////////////////////////// //// ClangViewAutocomplete /// ////////////////////////////// -Source::ClangViewAutocomplete::ClangViewAutocomplete(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path): -Source::ClangViewParse(file_path, project_path), autocomplete_cancel_starting(false) { +Source::ClangViewAutocomplete::ClangViewAutocomplete(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr language): +Source::ClangViewParse(file_path, project_path, language), autocomplete_cancel_starting(false) { get_buffer()->signal_changed().connect([this](){ if(completion_dialog_shown) delayed_reparse_connection.disconnect(); @@ -1668,8 +1677,8 @@ bool Source::ClangViewAutocomplete::restart_parse() { //// ClangViewRefactor ///// //////////////////////////// -Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path): -Source::ClangViewAutocomplete(file_path, project_path) { +Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr language): +Source::ClangViewAutocomplete(file_path, project_path, language) { similar_tokens_tag=get_buffer()->create_tag(); similar_tokens_tag->property_weight()=Pango::WEIGHT_BOLD; @@ -1814,7 +1823,7 @@ Source::ClangViewRefactor::~ClangViewRefactor() { delayed_tag_similar_tokens_connection.disconnect(); } -Source::ClangView::ClangView(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr language): ClangViewRefactor(file_path, project_path) { +Source::ClangView::ClangView(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr language): ClangViewRefactor(file_path, project_path, language) { if(language) { get_source_buffer()->set_highlight_syntax(true); get_source_buffer()->set_language(language); diff --git a/src/source.h b/src/source.h index 6fb4a18..2d80aad 100644 --- a/src/source.h +++ b/src/source.h @@ -52,7 +52,7 @@ namespace Source { class View : public Gsv::View { public: - View(const boost::filesystem::path &file_path); + View(const boost::filesystem::path &file_path, Glib::RefPtr language); ~View(); void search_highlight(const std::string &text, bool case_sensitive, bool regex); @@ -134,7 +134,7 @@ namespace Source { class ClangViewParse : public View { public: - ClangViewParse(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path); + ClangViewParse(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr language); ~ClangViewParse(); boost::filesystem::path project_path; void start_reparse(); @@ -176,7 +176,7 @@ namespace Source { class ClangViewAutocomplete : public ClangViewParse { public: - ClangViewAutocomplete(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path); + ClangViewAutocomplete(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr language); void async_delete(); bool restart_parse(); protected: @@ -206,7 +206,7 @@ namespace Source { class ClangViewRefactor : public ClangViewAutocomplete { public: - ClangViewRefactor(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path); + ClangViewRefactor(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr language); ~ClangViewRefactor(); private: Glib::RefPtr similar_tokens_tag; diff --git a/src/sourcefile.cc b/src/sourcefile.cc index 2ee7219..ef9fdd6 100644 --- a/src/sourcefile.cc +++ b/src/sourcefile.cc @@ -25,15 +25,6 @@ int juci::filesystem::read(const std::string &path, Glib::RefPtrinsert_at_cursor(ustr); @@ -69,6 +60,35 @@ int juci::filesystem::read(const std::string &path, Glib::RefPtr text_buffer) { + std::ifstream input(path, std::ofstream::binary); + + if(input) { + //need to read the whole file to make this work... + std::stringstream ss; + ss << input.rdbuf(); + Glib::ustring ustr=std::move(ss.str()); + + bool valid=true; + Glib::ustring::iterator iter; + while(!ustr.validate(iter)) { + auto next_char_iter=iter; + next_char_iter++; + ustr.replace(iter, next_char_iter, "?"); + valid=false; + } + + text_buffer->insert_at_cursor(ustr); + + input.close(); + if(valid) + return 1; + else + return -1; + } + return 0; +} + //Only use on small files std::vector juci::filesystem::read_lines(const std::string &path) { std::vector res; diff --git a/src/sourcefile.h b/src/sourcefile.h index 9ddc937..4507ab7 100644 --- a/src/sourcefile.h +++ b/src/sourcefile.h @@ -13,6 +13,9 @@ namespace juci { static int read(const std::string &path, Glib::RefPtr text_buffer); static int read(const boost::filesystem::path &path, Glib::RefPtr text_buffer) { return read(path.string(), text_buffer); } + static int read_non_utf8(const std::string &path, Glib::RefPtr text_buffer); + static int read_non_utf8(const boost::filesystem::path &path, Glib::RefPtr text_buffer) { return read_non_utf8(path.string(), text_buffer); } + static std::vector read_lines(const std::string &path); static std::vector read_lines(const boost::filesystem::path &path) { return read_lines(path.string()); };