Browse Source

Moved basic indentation to Source::View, Clang specific indentation still in Source::ClangView. Some fixes, improved indentation for non-clang files, also added tab_char to Source::Config.

merge-requests/365/head
eidheim 11 years ago
parent
commit
92e2417787
  1. 80
      juci/source.cc
  2. 1
      juci/source.h

80
juci/source.cc

@ -50,9 +50,33 @@ string Source::View::get_line_before_insert() {
return line;
}
//Basic indentation
bool Source::View::on_key_press(GdkEventKey* key) {
const std::regex spaces_regex(std::string("^(")+config.tab_char+"*).*$");
//Indent as in next or previous line
if(key->keyval==GDK_KEY_Return && key->state==0) {
int line_nr=get_source_buffer()->get_insert()->get_iter().get_line();
string line(get_line_before_insert());
std::smatch sm;
if(std::regex_match(line, sm, spaces_regex)) {
if((line_nr+1)<get_source_buffer()->get_line_count()) {
string next_line=get_line(line_nr+1);
std::smatch sm2;
if(std::regex_match(next_line, sm2, spaces_regex)) {
if(sm2[1].str().size()>sm[1].str().size()) {
get_source_buffer()->insert_at_cursor("\n"+sm2[1].str());
scroll_to(get_source_buffer()->get_insert());
return true;
}
}
}
get_source_buffer()->insert_at_cursor("\n"+sm[1].str());
scroll_to(get_source_buffer()->get_insert());
return true;
}
}
//Indent right when clicking tab, no matter where in the line the cursor is. Also works on selected text.
if(key->keyval==GDK_KEY_Tab && key->state==0) {
else if(key->keyval==GDK_KEY_Tab && key->state==0) {
Gtk::TextIter selection_start, selection_end;
get_source_buffer()->get_selection_bounds(selection_start, selection_end);
int line_start=selection_start.get_line();
@ -86,6 +110,22 @@ bool Source::View::on_key_press(GdkEventKey* key) {
}
return true;
}
//"Smart" backspace key
else if(key->keyval==GDK_KEY_BackSpace) {
Gtk::TextIter insert_it=get_source_buffer()->get_insert()->get_iter();
int line_nr=insert_it.get_line();
if(line_nr>0) {
string line=get_line(line_nr);
string previous_line=get_line(line_nr-1);
smatch sm;
if(std::regex_match(previous_line, sm, spaces_regex)) {
if(line==sm[1] || line==(std::string(sm[1])+config.tab) || (line+config.tab==sm[1])) {
Gtk::TextIter line_it = get_source_buffer()->get_iter_at_line(line_nr);
get_source_buffer()->erase(line_it, insert_it);
}
}
}
}
return false;
}
@ -386,15 +426,15 @@ bool Source::ClangView::on_key_release(GdkEventKey* key) {
return true;
}
//TODO: replace indentation methods with a better implementation or
//maybe use libclang
//Clang indentation
//TODO: replace indentation methods with a better implementation or maybe use libclang
bool Source::ClangView::on_key_press(GdkEventKey* key) {
const std::regex bracket_regex("^( *).*\\{ *$");
const std::regex no_bracket_statement_regex("^( *)(if|for|else if|catch|while) *\\(.*[^;}] *$");
const std::regex no_bracket_no_para_statement_regex("^( *)(else|try|do) *$");
const std::regex spaces_regex("^( *).*$");
const std::regex bracket_regex(std::string("^(")+config.tab_char+"*).*\\{ *$");
const std::regex no_bracket_statement_regex(std::string("^(")+config.tab_char+"*)(if|for|else if|catch|while) *\\(.*[^;}] *$");
const std::regex no_bracket_no_para_statement_regex(std::string("^(")+config.tab_char+"*)(else|try|do) *$");
const std::regex spaces_regex(std::string("^(")+config.tab_char+"*).*$");
//Indent as in previous line, and indent right after if/else/etc
//Indent depending on if/else/etc and brackets
if(key->keyval==GDK_KEY_Return && key->state==0) {
string line(get_line_before_insert());
std::smatch sm;
@ -417,14 +457,17 @@ bool Source::ClangView::on_key_press(GdkEventKey* key) {
insert_it--;
scroll_to(get_source_buffer()->get_insert());
get_source_buffer()->place_cursor(insert_it);
return true;
}
else if(std::regex_match(line, sm, no_bracket_statement_regex)) {
get_source_buffer()->insert_at_cursor("\n"+sm[1].str()+config.tab);
scroll_to(get_source_buffer()->get_insert());
return true;
}
else if(std::regex_match(line, sm, no_bracket_no_para_statement_regex)) {
get_source_buffer()->insert_at_cursor("\n"+sm[1].str()+config.tab);
scroll_to(get_source_buffer()->get_insert());
return true;
}
else if(std::regex_match(line, sm, spaces_regex)) {
std::smatch sm2;
@ -444,17 +487,14 @@ bool Source::ClangView::on_key_press(GdkEventKey* key) {
}
}
}
get_source_buffer()->insert_at_cursor("\n"+sm[1].str());
scroll_to(get_source_buffer()->get_insert());
}
return true;
}
//Indent left when writing } on a new line
else if(key->keyval==GDK_KEY_braceright) {
string line=get_line_before_insert();
if(line.size()>=config.tab_size) {
for(auto c: line) {
if(c!=' ')
if(c!=config.tab_char)
return false;
}
Gtk::TextIter insert_it = get_source_buffer()->get_insert()->get_iter();
@ -467,22 +507,6 @@ bool Source::ClangView::on_key_press(GdkEventKey* key) {
}
return false;
}
//"Smart" backspace key
else if(key->keyval==GDK_KEY_BackSpace) {
Gtk::TextIter insert_it=get_source_buffer()->get_insert()->get_iter();
int line_nr=insert_it.get_line();
if(line_nr>0) {
string line=get_line(line_nr);
string previous_line=get_line(line_nr-1);
smatch sm;
if(std::regex_match(previous_line, sm, spaces_regex)) {
if(line==sm[1]) {
Gtk::TextIter line_it = get_source_buffer()->get_iter_at_line(line_nr);
get_source_buffer()->erase(line_it, insert_it);
}
}
}
}
return Source::View::on_key_press(key);
}

1
juci/source.h

@ -22,6 +22,7 @@ namespace Source {
unsigned tab_size;
bool show_line_numbers, highlight_current_line;
std::string tab, background, font;
char tab_char=' ';
std::vector<std::string> extensions;
std::unordered_map<std::string, std::string> tags, types;
}; // class Config

Loading…
Cancel
Save