Added support for space indentation

This commit is contained in:
Paulb23 2017-04-17 14:24:30 +01:00
parent 95a2a7e525
commit 84bca4e72f
9 changed files with 168 additions and 40 deletions

View File

@ -1071,7 +1071,8 @@ void CodeTextEditor::update_editor_settings() {
text_editor->set_auto_brace_completion(EditorSettings::get_singleton()->get("text_editor/completion/auto_brace_complete"));
text_editor->set_scroll_pass_end_of_file(EditorSettings::get_singleton()->get("text_editor/cursor/scroll_past_end_of_file"));
text_editor->set_tab_size(EditorSettings::get_singleton()->get("text_editor/indent/tab_size"));
text_editor->set_indent_using_spaces(EditorSettings::get_singleton()->get("text_editor/indent/type") == "Tabs" ? 0 : 1);
text_editor->set_indent_size(EditorSettings::get_singleton()->get("text_editor/indent/size"));
text_editor->set_draw_tabs(EditorSettings::get_singleton()->get("text_editor/indent/draw_tabs"));
text_editor->set_show_line_numbers(EditorSettings::get_singleton()->get("text_editor/line_numbers/show_line_numbers"));
text_editor->set_line_numbers_zero_padded(EditorSettings::get_singleton()->get("text_editor/line_numbers/line_numbers_zero_padded"));

View File

@ -529,8 +529,11 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
set("text_editor/highlighting/highlight_all_occurrences", true);
set("text_editor/cursor/scroll_past_end_of_file", false);
set("text_editor/indent/tab_size", 4);
hints["text_editor/indent/tab_size"] = PropertyInfo(Variant::INT, "text_editor/indent/tab_size", PROPERTY_HINT_RANGE, "1, 64, 1"); // size of 0 crashes.
set("text_editor/indent/type", 0);
hints["text_editor/indent/type"] = PropertyInfo(Variant::STRING, "text_editor/indent/type", PROPERTY_HINT_ENUM, "Tabs,Spaces");
set("text_editor/indent/size", 4);
hints["text_editor/indent/size"] = PropertyInfo(Variant::INT, "text_editor/indent/size", PROPERTY_HINT_RANGE, "1, 64, 1"); // size of 0 crashes.
set("text_editor/indent/convert_indent_on_save", false);
set("text_editor/indent/draw_tabs", true);
set("text_editor/line_numbers/show_line_numbers", true);

View File

@ -1582,6 +1582,9 @@ void ScriptEditor::_save_layout() {
void ScriptEditor::_editor_settings_changed() {
trim_trailing_whitespace_on_save = EditorSettings::get_singleton()->get("text_editor/files/trim_trailing_whitespace_on_save");
convert_indent_on_save = EditorSettings::get_singleton()->get("text_editor/indent/convert_indent_on_save");
use_space_indentation = EditorSettings::get_singleton()->get("text_editor/indent/type") == "Tabs" ? 0 : 1;
float autosave_time = EditorSettings::get_singleton()->get("text_editor/files/autosave_interval_secs");
if (autosave_time > 0) {
autosave_timer->set_wait_time(autosave_time);

View File

@ -298,10 +298,10 @@ void ScriptTextEditor::convert_indent_to_spaces() {
return;
}
int tab_size = EditorSettings::get_singleton()->get("text_editor/indent/tab_size");
int indent_size = EditorSettings::get_singleton()->get("text_editor/indent/size");
String indent = "";
for (int i = 0; i < tab_size; i++) {
for (int i = 0; i < indent_size; i++) {
indent += " ";
}
@ -340,8 +340,8 @@ void ScriptTextEditor::convert_indent_to_tabs() {
return;
}
int tab_size = EditorSettings::get_singleton()->get("text_editor/indent/tab_size");
tab_size -= 1;
int indent_size = EditorSettings::get_singleton()->get("text_editor/indent/size");
indent_size -= 1;
bool changed_indentation = false;
for (int i = 0; i < tx->get_line_count(); i++) {
@ -357,13 +357,13 @@ void ScriptTextEditor::convert_indent_to_tabs() {
if (line[j] != '\t') {
space_count++;
if (space_count == tab_size) {
if (space_count == indent_size) {
if (!changed_indentation) {
tx->begin_complex_operation();
changed_indentation = true;
}
line = line.left(j - tab_size) + "\t" + line.right(j + 1);
line = line.left(j - indent_size) + "\t" + line.right(j + 1);
j = 0;
space_count = -1;
}

View File

@ -370,7 +370,8 @@ void ShaderEditor::_editor_settings_changed() {
shader_editor->get_text_edit()->set_auto_brace_completion(EditorSettings::get_singleton()->get("text_editor/completion/auto_brace_complete"));
shader_editor->get_text_edit()->set_scroll_pass_end_of_file(EditorSettings::get_singleton()->get("text_editor/cursor/scroll_past_end_of_file"));
shader_editor->get_text_edit()->set_tab_size(EditorSettings::get_singleton()->get("text_editor/indent/tab_size"));
shader_editor->get_text_edit()->set_indent_size(EditorSettings::get_singleton()->get("text_editor/indent/size"));
shader_editor->get_text_edit()->set_indent_using_spaces(EditorSettings::get_singleton()->get("text_editor/indent/type") == "Tabs" ? 0 : 1);
shader_editor->get_text_edit()->set_draw_tabs(EditorSettings::get_singleton()->get("text_editor/indent/draw_tabs"));
shader_editor->get_text_edit()->set_show_line_numbers(EditorSettings::get_singleton()->get("text_editor/line_numbers/show_line_numbers"));
shader_editor->get_text_edit()->set_syntax_coloring(EditorSettings::get_singleton()->get("text_editor/highlighting/syntax_highlighting"));

View File

@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "editor/editor_settings.h"
#include "gd_compiler.h"
#include "gd_script.h"
#include "global_config.h"
@ -2391,8 +2392,27 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_base
#endif
String GDScriptLanguage::_get_indentation() const {
#ifdef TOOLS_ENABLED
bool use_space_indentation = EDITOR_DEF("text_editor/indent/type", "Tabs") == "Tabs" ? 0 : 1;
if (use_space_indentation) {
int indent_size = EDITOR_DEF("text_editor/indent/size", 4);
String space_indent = "";
for (int i = 0; i < indent_size; i++) {
space_indent += " ";
}
return space_indent;
}
#endif
return "\t";
}
void GDScriptLanguage::auto_indent_code(String &p_code, int p_from_line, int p_to_line) const {
String indent = _get_indentation();
Vector<String> lines = p_code.split("\n");
List<int> indent_stack;
@ -2432,8 +2452,9 @@ void GDScriptLanguage::auto_indent_code(String &p_code, int p_from_line, int p_t
if (i >= p_from_line) {
l = "";
for (int j = 0; j < indent_stack.size(); j++)
l += "\t";
for (int j = 0; j < indent_stack.size(); j++) {
l += indent;
}
l += st;
} else if (i > p_to_line) {

View File

@ -390,6 +390,7 @@ public:
#ifdef TOOLS_ENABLED
virtual Error lookup_code(const String &p_code, const String &p_symbol, const String &p_base_path, Object *p_owner, LookupResult &r_result);
#endif
virtual String _get_indentation() const;
virtual void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const;
virtual void add_global_constant(const StringName &p_variable, const Variant &p_value);

View File

@ -101,15 +101,15 @@ void TextEdit::Text::set_font(const Ref<Font> &p_font) {
font = p_font;
}
void TextEdit::Text::set_tab_size(int p_tab_size) {
void TextEdit::Text::set_indent_size(int p_indent_size) {
tab_size = p_tab_size;
indent_size = p_indent_size;
}
void TextEdit::Text::_update_line_cache(int p_line) const {
int w = 0;
int tab_w = font->get_char_size(' ').width * tab_size;
int tab_w = font->get_char_size(' ').width * indent_size;
int len = text[p_line].data.length();
const CharType *str = text[p_line].data.c_str();
@ -456,7 +456,7 @@ void TextEdit::_notification(int p_what) {
int visible_rows = get_visible_rows();
int tab_w = cache.font->get_char_size(' ').width * tab_size;
int tab_w = cache.font->get_char_size(' ').width * indent_size;
Color color = cache.font_color;
int in_region = -1;
@ -1305,7 +1305,38 @@ void TextEdit::backspace_at_cursor() {
_is_pair_left_symbol(text[cursor.line][cursor.column - 1])) {
_consume_backspace_for_pair_symbol(prev_line, prev_column);
} else {
_remove_text(prev_line, prev_column, cursor.line, cursor.column);
// handle space indentation
if (cursor.column - indent_size >= 0 && indent_using_spaces) {
// if there is enough spaces to count as a tab
bool unindent = true;
for (int i = 1; i <= indent_size; i++) {
if (text[cursor.line][cursor.column - i] != ' ') {
unindent = false;
break;
}
}
// and it is before the first character
int i = 0;
while (i < cursor.column && i < text[cursor.line].length()) {
if (text[cursor.line][i] != ' ' && text[cursor.line][i] != '\t') {
unindent = false;
break;
}
i++;
}
// then we can remove it as a single character.
if (unindent) {
_remove_text(cursor.line, cursor.column - indent_size, cursor.line, cursor.column);
prev_column = cursor.column - indent_size;
} else {
_remove_text(prev_line, prev_column, cursor.line, cursor.column);
}
} else {
_remove_text(prev_line, prev_column, cursor.line, cursor.column);
}
}
cursor_set_line(prev_line);
@ -1328,7 +1359,11 @@ void TextEdit::indent_selection_right() {
for (int i = start_line; i <= end_line; i++) {
String line_text = get_line(i);
line_text = '\t' + line_text;
if (indent_using_spaces) {
line_text = space_indent + line_text;
} else {
line_text = '\t' + line_text;
}
set_line(i, line_text);
}
@ -1359,8 +1394,8 @@ void TextEdit::indent_selection_left() {
if (line_text.begins_with("\t")) {
line_text = line_text.substr(1, line_text.length());
set_line(i, line_text);
} else if (line_text.begins_with(" ")) {
line_text = line_text.substr(4, line_text.length());
} else if (line_text.begins_with(space_indent)) {
line_text = line_text.substr(indent_size, line_text.length());
set_line(i, line_text);
}
}
@ -1931,17 +1966,39 @@ void TextEdit::_gui_input(const InputEvent &p_gui_input) {
String ins = "\n";
//keep indentation
int space_count = 0;
for (int i = 0; i < text[cursor.line].length(); i++) {
if (text[cursor.line][i] == '\t')
ins += "\t";
else
if (text[cursor.line][i] == '\t') {
if (indent_using_spaces) {
ins += space_indent;
} else {
ins += "\t";
}
space_count = 0;
} else if (text[cursor.line][i] == ' ') {
space_count++;
if (space_count == indent_size) {
if (indent_using_spaces) {
ins += space_indent;
} else {
ins += "\t";
}
space_count = 0;
}
} else {
break;
}
}
if (auto_indent) {
// indent once again if previous line will end with ':'
// (i.e. colon precedes current cursor position)
if (cursor.column > 0 && text[cursor.line][cursor.column - 1] == ':') {
ins += "\t";
if (indent_using_spaces) {
ins += space_indent;
} else {
ins += "\t";
}
}
}
@ -1987,15 +2044,36 @@ void TextEdit::_gui_input(const InputEvent &p_gui_input) {
} else {
if (k.mod.shift) {
//simple unindent
int cc = cursor.column;
if (cc > 0 && cc <= text[cursor.line].length() && text[cursor.line][cursor.column - 1] == '\t') {
//simple unindent
if (cc > 0 && cc <= text[cursor.line].length()) {
if (text[cursor.line][cursor.column - 1] == '\t') {
backspace_at_cursor();
} else {
if (cursor.column - indent_size >= 0) {
backspace_at_cursor();
bool unindent = true;
for (int i = 1; i <= indent_size; i++) {
if (text[cursor.line][cursor.column - i] != ' ') {
unindent = false;
break;
}
}
if (unindent) {
_remove_text(cursor.line, cursor.column - indent_size, cursor.line, cursor.column);
cursor_set_column(cursor.column - indent_size);
}
}
}
}
} else {
//simple indent
_insert_text_at_cursor("\t");
if (indent_using_spaces) {
_insert_text_at_cursor(space_indent);
} else {
_insert_text_at_cursor("\t");
}
}
}
@ -3103,7 +3181,7 @@ int TextEdit::get_char_pos_for(int p_px, String p_str) const {
int px = 0;
int c = 0;
int tab_w = cache.font->get_char_size(' ').width * tab_size;
int tab_w = cache.font->get_char_size(' ').width * indent_size;
while (c < p_str.length()) {
@ -3135,7 +3213,7 @@ int TextEdit::get_column_x_offset(int p_char, String p_str) {
int px = 0;
int tab_w = cache.font->get_char_size(' ').width * tab_size;
int tab_w = cache.font->get_char_size(' ').width * indent_size;
for (int i = 0; i < p_char; i++) {
@ -3952,10 +4030,24 @@ void TextEdit::_push_current_op() {
current_op.chain_forward = false;
}
void TextEdit::set_tab_size(const int p_size) {
void TextEdit::set_indent_using_spaces(const bool p_use_spaces) {
indent_using_spaces = p_use_spaces;
}
bool TextEdit::is_indent_using_spaces() const {
return indent_using_spaces;
}
void TextEdit::set_indent_size(const int p_size) {
ERR_FAIL_COND(p_size <= 0);
tab_size = p_size;
text.set_tab_size(p_size);
indent_size = p_size;
text.set_indent_size(p_size);
space_indent = "";
for (int i = 0; i < p_size; i++) {
space_indent += " ";
}
update();
}
@ -4542,8 +4634,8 @@ TextEdit::TextEdit() {
cache.breakpoint_gutter_width = 0;
breakpoint_gutter_width = 0;
tab_size = 4;
text.set_tab_size(tab_size);
indent_size = 4;
text.set_indent_size(indent_size);
text.clear();
//text.insert(1,"Mongolia..");
//text.insert(2,"PAIS GENEROSO!!");
@ -4631,6 +4723,8 @@ TextEdit::TextEdit() {
auto_brace_completion_enabled = false;
brace_matching_enabled = false;
highlight_all_occurrences = false;
indent_using_spaces = false;
space_indent = " ";
auto_indent = false;
insert_mode = false;
window_has_focus = true;

View File

@ -141,12 +141,12 @@ class TextEdit : public Control {
const Vector<ColorRegion> *color_regions;
mutable Vector<Line> text;
Ref<Font> font;
int tab_size;
int indent_size;
void _update_line_cache(int p_line) const;
public:
void set_tab_size(int p_tab_size);
void set_indent_size(int p_indent_size);
void set_font(const Ref<Font> &p_font);
void set_color_regions(const Vector<ColorRegion> *p_regions) { color_regions = p_regions; }
int get_line_width(int p_line) const;
@ -163,7 +163,7 @@ class TextEdit : public Control {
void clear();
void clear_caches();
_FORCE_INLINE_ const String &operator[](int p_line) const { return text[p_line].data; }
Text() { tab_size = 4; }
Text() { indent_size = 4; }
};
struct TextOperation {
@ -221,7 +221,9 @@ class TextEdit : public Control {
int max_chars;
bool readonly;
bool syntax_coloring;
int tab_size;
bool indent_using_spaces;
int indent_size;
String space_indent;
Timer *caret_blink_timer;
bool caret_blink_enabled;
@ -461,7 +463,9 @@ public:
void redo();
void clear_undo_history();
void set_tab_size(const int p_size);
void set_indent_using_spaces(const bool p_use_spaces);
bool is_indent_using_spaces() const;
void set_indent_size(const int p_size);
void set_draw_tabs(bool p_draw);
bool is_drawing_tabs() const;