|
|
|
|
@ -1,23 +1,23 @@
|
|
|
|
|
#include "source.h" |
|
|
|
|
#include "config.h" |
|
|
|
|
#include "directories.h" |
|
|
|
|
#include "filesystem.h" |
|
|
|
|
#include "terminal.h" |
|
|
|
|
#include "git.h" |
|
|
|
|
#include "info.h" |
|
|
|
|
#include "directories.h" |
|
|
|
|
#include "menu.h" |
|
|
|
|
#include "selection_dialog.h" |
|
|
|
|
#include "git.h" |
|
|
|
|
#include <gtksourceview/gtksource.h> |
|
|
|
|
#include "terminal.h" |
|
|
|
|
#include <boost/property_tree/json_parser.hpp> |
|
|
|
|
#include <boost/spirit/home/qi/char.hpp> |
|
|
|
|
#include <boost/spirit/home/qi/operator.hpp> |
|
|
|
|
#include <boost/spirit/home/qi/string.hpp> |
|
|
|
|
#include <gtksourceview/gtksource.h> |
|
|
|
|
#include <iostream> |
|
|
|
|
#include <limits> |
|
|
|
|
#include <map> |
|
|
|
|
#include <numeric> |
|
|
|
|
#include <set> |
|
|
|
|
#include <regex> |
|
|
|
|
#include <limits> |
|
|
|
|
#include <set> |
|
|
|
|
|
|
|
|
|
Glib::RefPtr<Gsv::LanguageManager> Source::LanguageManager::get_default() { |
|
|
|
|
static auto instance = Gsv::LanguageManager::create(); |
|
|
|
|
@ -388,24 +388,15 @@ Gsv::DrawSpacesFlags Source::View::parse_show_whitespace_characters(const std::s
|
|
|
|
|
namespace qi = boost::spirit::qi; |
|
|
|
|
|
|
|
|
|
qi::symbols<char, Gsv::DrawSpacesFlags> options; |
|
|
|
|
options.add |
|
|
|
|
("space", Gsv::DRAW_SPACES_SPACE) |
|
|
|
|
("tab", Gsv::DRAW_SPACES_TAB) |
|
|
|
|
("newline", Gsv::DRAW_SPACES_NEWLINE) |
|
|
|
|
("nbsp", Gsv::DRAW_SPACES_NBSP) |
|
|
|
|
("leading", Gsv::DRAW_SPACES_LEADING) |
|
|
|
|
("text", Gsv::DRAW_SPACES_TEXT) |
|
|
|
|
("trailing", Gsv::DRAW_SPACES_TRAILING) |
|
|
|
|
("all", Gsv::DRAW_SPACES_ALL); |
|
|
|
|
options.add("space", Gsv::DRAW_SPACES_SPACE)("tab", Gsv::DRAW_SPACES_TAB)("newline", Gsv::DRAW_SPACES_NEWLINE)("nbsp", Gsv::DRAW_SPACES_NBSP) |
|
|
|
|
("leading", Gsv::DRAW_SPACES_LEADING)("text", Gsv::DRAW_SPACES_TEXT)("trailing", Gsv::DRAW_SPACES_TRAILING)("all", Gsv::DRAW_SPACES_ALL); |
|
|
|
|
|
|
|
|
|
std::set<Gsv::DrawSpacesFlags> out; |
|
|
|
|
|
|
|
|
|
// parse comma-separated list of options
|
|
|
|
|
qi::phrase_parse(text.begin(), text.end(), options % ',', qi::space, out); |
|
|
|
|
|
|
|
|
|
return out.count(Gsv::DRAW_SPACES_ALL)>0 ? |
|
|
|
|
Gsv::DRAW_SPACES_ALL : |
|
|
|
|
static_cast<Gsv::DrawSpacesFlags>(std::accumulate(out.begin(), out.end(), 0)); |
|
|
|
|
return out.count(Gsv::DRAW_SPACES_ALL) > 0 ? Gsv::DRAW_SPACES_ALL : static_cast<Gsv::DrawSpacesFlags>(std::accumulate(out.begin(), out.end(), 0)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool Source::View::save() { |
|
|
|
|
@ -684,7 +675,8 @@ void Source::View::setup_format_style(bool is_generic_view) {
|
|
|
|
|
hide_tooltips(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
catch(...) {} |
|
|
|
|
catch(...) { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else if(is_generic_view) { |
|
|
|
|
@ -705,7 +697,8 @@ void Source::View::setup_format_style(bool is_generic_view) {
|
|
|
|
|
|
|
|
|
|
add_diagnostic_tooltip(start, end, sm[1].str(), true); |
|
|
|
|
} |
|
|
|
|
catch(...) {} |
|
|
|
|
catch(...) { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if(is_generic_view) { |
|
|
|
|
@ -1266,12 +1259,14 @@ Gtk::TextIter Source::View::find_non_whitespace_code_iter_backward(Gtk::TextIter
|
|
|
|
|
*iter == '/' || |
|
|
|
|
#endif |
|
|
|
|
*iter == ' ' || *iter == '\t' || iter.ends_line()) && |
|
|
|
|
iter.backward_char()) {} |
|
|
|
|
iter.backward_char()) { |
|
|
|
|
} |
|
|
|
|
return iter; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Gtk::TextIter Source::View::get_start_of_expression(Gtk::TextIter iter) { |
|
|
|
|
while(!iter.starts_line() && (*iter==' ' || *iter=='\t' || iter.ends_line() || !is_code_iter(iter) || *iter=='/') && iter.backward_char()) {} |
|
|
|
|
while(!iter.starts_line() && (*iter == ' ' || *iter == '\t' || iter.ends_line() || !is_code_iter(iter) || *iter == '/') && iter.backward_char()) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if(iter.starts_line()) |
|
|
|
|
return iter; |
|
|
|
|
@ -1332,12 +1327,14 @@ Gtk::TextIter Source::View::get_start_of_expression(Gtk::TextIter iter) {
|
|
|
|
|
if(!stream_operator_found && !colon_found) { |
|
|
|
|
auto previous_iter = iter; |
|
|
|
|
previous_iter.backward_char(); |
|
|
|
|
while(!previous_iter.starts_line() && (*previous_iter==' ' || previous_iter.ends_line()) && previous_iter.backward_char()) {} |
|
|
|
|
while(!previous_iter.starts_line() && (*previous_iter == ' ' || previous_iter.ends_line()) && previous_iter.backward_char()) { |
|
|
|
|
} |
|
|
|
|
if(*previous_iter != ',' && *previous_iter != ':' && *previous_iter != '=' && *previous_iter != '&' && *previous_iter != '|') |
|
|
|
|
return iter; |
|
|
|
|
else if(*previous_iter == ':' && is_code_iter(previous_iter)) { |
|
|
|
|
previous_iter.backward_char(); |
|
|
|
|
while(!previous_iter.starts_line() && *previous_iter==' ' && previous_iter.backward_char()) {} |
|
|
|
|
while(!previous_iter.starts_line() && *previous_iter == ' ' && previous_iter.backward_char()) { |
|
|
|
|
} |
|
|
|
|
if(*previous_iter == ')') { |
|
|
|
|
auto token = get_token(get_tabs_end_iter(get_buffer()->get_iter_at_line(previous_iter.get_line()))); |
|
|
|
|
if(token == "case") |
|
|
|
|
@ -1594,11 +1591,13 @@ void Source::View::cleanup_whitespace_characters_on_return(const Gtk::TextIter &
|
|
|
|
|
auto start_blank_iter = iter; |
|
|
|
|
auto end_blank_iter = iter; |
|
|
|
|
while((*end_blank_iter == ' ' || *end_blank_iter == '\t') && |
|
|
|
|
!end_blank_iter.ends_line() && end_blank_iter.forward_char()) {} |
|
|
|
|
!end_blank_iter.ends_line() && end_blank_iter.forward_char()) { |
|
|
|
|
} |
|
|
|
|
if(!start_blank_iter.starts_line()) { |
|
|
|
|
start_blank_iter.backward_char(); |
|
|
|
|
while((*start_blank_iter == ' ' || *start_blank_iter == '\t') && |
|
|
|
|
!start_blank_iter.starts_line() && start_blank_iter.backward_char()) {} |
|
|
|
|
!start_blank_iter.starts_line() && start_blank_iter.backward_char()) { |
|
|
|
|
} |
|
|
|
|
if(*start_blank_iter != ' ' && *start_blank_iter != '\t') |
|
|
|
|
start_blank_iter.forward_char(); |
|
|
|
|
} |
|
|
|
|
@ -1768,12 +1767,14 @@ bool Source::View::on_key_press_event_basic(GdkEventKey* key) {
|
|
|
|
|
// Special case if insert is at beginning of empty line:
|
|
|
|
|
if(iter.starts_line() && iter.ends_line() && !get_buffer()->get_has_selection()) { |
|
|
|
|
auto prev_line_iter = iter; |
|
|
|
|
while(prev_line_iter.starts_line() && prev_line_iter.backward_char()) {} |
|
|
|
|
while(prev_line_iter.starts_line() && prev_line_iter.backward_char()) { |
|
|
|
|
} |
|
|
|
|
prev_line_iter = get_start_of_expression(prev_line_iter); |
|
|
|
|
auto prev_line_tabs_end_iter = get_tabs_end_iter(prev_line_iter); |
|
|
|
|
|
|
|
|
|
auto next_line_iter = iter; |
|
|
|
|
while(next_line_iter.starts_line() && next_line_iter.forward_char()) {} |
|
|
|
|
while(next_line_iter.starts_line() && next_line_iter.forward_char()) { |
|
|
|
|
} |
|
|
|
|
auto next_line_tabs_end_iter = get_tabs_end_iter(next_line_iter); |
|
|
|
|
|
|
|
|
|
Gtk::TextIter tabs_end_iter; |
|
|
|
|
@ -1889,7 +1890,8 @@ bool Source::View::on_key_press_event_basic(GdkEventKey* key) {
|
|
|
|
|
} while(iter.forward_char()); |
|
|
|
|
if(do_smart_delete) { |
|
|
|
|
if(!insert_iter.starts_line()) { |
|
|
|
|
while((*iter==' ' || *iter=='\t') && iter.forward_char()) {} |
|
|
|
|
while((*iter == ' ' || *iter == '\t') && iter.forward_char()) { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
get_buffer()->erase(insert_iter, iter); |
|
|
|
|
return true; |
|
|
|
|
@ -2224,7 +2226,8 @@ bool Source::View::on_key_press_event_bracket_language(GdkEventKey* key) {
|
|
|
|
|
// Indenting after for instance: if(...)\n...;\n
|
|
|
|
|
else if(*condition_iter == ';' && condition_iter.get_line() > 0 && is_code_iter(condition_iter)) { |
|
|
|
|
auto previous_end_iter = start_iter; |
|
|
|
|
while(previous_end_iter.backward_char() && !previous_end_iter.ends_line()) {} |
|
|
|
|
while(previous_end_iter.backward_char() && !previous_end_iter.ends_line()) { |
|
|
|
|
} |
|
|
|
|
previous_end_iter = find_non_whitespace_code_iter_backward(previous_end_iter); |
|
|
|
|
auto previous_start_iter = get_tabs_end_iter(get_buffer()->get_iter_at_line(get_start_of_expression(previous_end_iter).get_line())); |
|
|
|
|
auto previous_tabs = get_line_before(previous_start_iter); |
|
|
|
|
@ -2242,7 +2245,8 @@ bool Source::View::on_key_press_event_bracket_language(GdkEventKey* key) {
|
|
|
|
|
else if(*condition_iter == ':' && is_code_iter(condition_iter)) { |
|
|
|
|
bool perform_indent = true; |
|
|
|
|
auto iter = condition_iter; |
|
|
|
|
while(!iter.starts_line() && *iter==' ' && iter.backward_char()) {} |
|
|
|
|
while(!iter.starts_line() && *iter == ' ' && iter.backward_char()) { |
|
|
|
|
} |
|
|
|
|
if(*iter == ')') { |
|
|
|
|
auto token = get_token(get_tabs_end_iter(get_buffer()->get_iter_at_line(iter.get_line()))); |
|
|
|
|
if(token != "case") |
|
|
|
|
@ -2310,7 +2314,8 @@ bool Source::View::on_key_press_event_bracket_language(GdkEventKey* key) {
|
|
|
|
|
size_t line_nr = iter.get_line(); |
|
|
|
|
if(line_nr > 0 && tabs.size() >= tab_size && iter == tabs_end_iter) { |
|
|
|
|
auto previous_end_iter = iter; |
|
|
|
|
while(previous_end_iter.backward_char() && !previous_end_iter.ends_line()) {} |
|
|
|
|
while(previous_end_iter.backward_char() && !previous_end_iter.ends_line()) { |
|
|
|
|
} |
|
|
|
|
auto condition_iter = find_non_whitespace_code_iter_backward(previous_end_iter); |
|
|
|
|
auto previous_start_iter = get_tabs_end_iter(get_buffer()->get_iter_at_line(get_start_of_expression(condition_iter).get_line())); |
|
|
|
|
auto previous_tabs = get_line_before(previous_start_iter); |
|
|
|
|
@ -2351,7 +2356,8 @@ bool Source::View::on_key_press_event_bracket_language(GdkEventKey* key) {
|
|
|
|
|
if(*condition_iter == ';' && condition_iter.get_line() > 0 && is_code_iter(condition_iter)) { |
|
|
|
|
auto start_iter = get_start_of_expression(condition_iter); |
|
|
|
|
auto previous_end_iter = start_iter; |
|
|
|
|
while(previous_end_iter.backward_char() && !previous_end_iter.ends_line()) {} |
|
|
|
|
while(previous_end_iter.backward_char() && !previous_end_iter.ends_line()) { |
|
|
|
|
} |
|
|
|
|
previous_end_iter = find_non_whitespace_code_iter_backward(previous_end_iter); |
|
|
|
|
auto previous_start_iter = get_tabs_end_iter(get_buffer()->get_iter_at_line(get_start_of_expression(previous_end_iter).get_line())); |
|
|
|
|
auto previous_tabs = get_line_before(previous_start_iter); |
|
|
|
|
@ -2995,7 +3001,8 @@ bool Source::View::on_button_press_event(GdkEventButton *event) {
|
|
|
|
|
if(iter) |
|
|
|
|
get_buffer()->place_cursor(iter); |
|
|
|
|
Menu::get().right_click_line_menu->popup(event->button, event->time); |
|
|
|
|
} else { |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
Menu::get().right_click_selected_menu->popup(event->button, event->time); |
|
|
|
|
} |
|
|
|
|
return true; |
|
|
|
|
|