diff options
author | Campbell Barton <ideasman42@gmail.com> | 2015-09-15 20:30:02 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2015-09-15 20:35:25 +0300 |
commit | b8a8059e21d2e28bf79b578d338f518c78a88382 (patch) | |
tree | cb98dded2e2a7ac9a3855c5a2e4833de971b853f /source | |
parent | 860e25fe29c3f6732860c23dccb1f4813d4e387e (diff) |
Fix for text editor un-indent undo
Same issue as T44381, re-use logic for indent.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/intern/text.c | 226 |
1 files changed, 99 insertions, 127 deletions
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c index 89456763b95..77d6043d6f3 100644 --- a/source/blender/blenkernel/intern/text.c +++ b/source/blender/blenkernel/intern/text.c @@ -1914,9 +1914,13 @@ struct LinkInt { int value; }; -/* unindentLines points to a ListBase composed of LinkInt elements, listing the numbers - * of the lines that should not be indented back. */ -static void txt_undo_add_unindent_op(Text *text, const ListBase *line_index_mask, const int line_index_mask_len) +/** + * UnindentLines points to a #ListBase composed of #LinkInt elements, listing the numbers + * of the lines that should not be indented back. + */ +static void txt_undo_add_unprefix_op( + Text *text, char undo_op, + const ListBase *line_index_mask, const int line_index_mask_len) { struct LinkInt *idata; @@ -1929,7 +1933,7 @@ static void txt_undo_add_unindent_op(Text *text, const ListBase *line_index_mask /* Opening buffer sequence with OP */ text->undo_pos++; - text->undo_buf[text->undo_pos] = UNDO_UNINDENT; + text->undo_buf[text->undo_pos] = undo_op; text->undo_pos++; /* Adding number of line numbers to read */ txt_undo_store_uint32(text->undo_buf, &text->undo_pos, line_index_mask_len); @@ -1944,7 +1948,7 @@ static void txt_undo_add_unindent_op(Text *text, const ListBase *line_index_mask /* Adding current selection */ txt_undo_store_cursors(text); /* Closing with OP (same as above) */ - text->undo_buf[text->undo_pos] = UNDO_UNINDENT; + text->undo_buf[text->undo_pos] = undo_op; /* Marking as last undo operation */ text->undo_buf[text->undo_pos + 1] = 0; } @@ -2244,7 +2248,6 @@ void txt_do_undo(Text *text) break; case UNDO_INDENT: case UNDO_COMMENT: - case UNDO_UNCOMMENT: case UNDO_DUPLICATE: case UNDO_MOVE_LINES_UP: case UNDO_MOVE_LINES_DOWN: @@ -2259,9 +2262,6 @@ void txt_do_undo(Text *text) else if (op == UNDO_COMMENT) { txt_uncomment(text); } - else if (op == UNDO_UNCOMMENT) { - txt_comment(text); - } else if (op == UNDO_DUPLICATE) { txt_delete_line(text, text->curl->next); } @@ -2275,7 +2275,10 @@ void txt_do_undo(Text *text) text->undo_pos--; break; case UNDO_UNINDENT: + case UNDO_UNCOMMENT: { + void (*txt_prefix_fn)(Text *); + void (*txt_unprefix_fn)(Text *); int count; int i; /* Get and restore the cursors */ @@ -2284,7 +2287,16 @@ void txt_do_undo(Text *text) txt_move_to(text, selln, selc, 1); /* Un-unindent */ - txt_indent(text); + if (op == UNDO_UNINDENT) { + txt_prefix_fn = txt_indent; + txt_unprefix_fn = txt_unindent; + } + else { + txt_prefix_fn = txt_comment; + txt_unprefix_fn = txt_uncomment; + } + + txt_prefix_fn(text); /* Get the count */ count = txt_undo_read_uint32(text->undo_buf, &text->undo_pos); @@ -2293,8 +2305,8 @@ void txt_do_undo(Text *text) for (i = 0; i < count; i++) { txt_move_to(text, txt_undo_read_uint32(text->undo_buf, &text->undo_pos), 0, 0); - /* Un-un-unindent */ - txt_unindent(text); + /* Un-un-unindent/comment */ + txt_unprefix_fn(text); } /* Restore selection */ txt_move_to(text, curln, curc, 0); @@ -2823,26 +2835,19 @@ bool txt_replace_char(Text *text, unsigned int add) return true; } -void txt_indent(Text *text) +/** + * Generic prefix operation, use for comment & indent. + * + * \note caller must handle undo. + */ +static void txt_select_prefix(Text *text, const char *add) { int len, num, curc_old; char *tmp; - const char *add = "\t"; - int indentlen = 1; - - /* hardcoded: TXT_TABSIZE = 4 spaces: */ - int spaceslen = TXT_TABSIZE; + const int indentlen = strlen(add); - if (ELEM(NULL, text->curl, text->sell)) { - return; - } - - /* insert spaces rather than tabs */ - if (text->flags & TXT_TABSTOSPACES) { - add = tab_to_spaces; - indentlen = spaceslen; - } + BLI_assert(!ELEM(NULL, text->curl, text->sell)); curc_old = text->curc; @@ -2886,36 +2891,31 @@ void txt_indent(Text *text) num--; } - if (!undoing) { - txt_undo_add_op(text, UNDO_INDENT); - } + /* caller must handle undo */ } -void txt_unindent(Text *text) +/** + * Generic un-prefix operation, use for comment & indent. + * + * \param r_line_index_mask: List of lines that are already at indent level 0, + * to store them later into the undo buffer. + * + * \note caller must handle undo. + */ +static void txt_select_unprefix( + Text *text, const char *remove, + ListBase *r_line_index_mask, int *r_line_index_mask_len) { int num = 0; - const char *remove = "\t"; - int indentlen = 1; + const int indentlen = strlen(remove); bool unindented_first = false; - - /* List of lines that are already at indent level 0, to store them later into the undo buffer */ - ListBase line_index_mask = {NULL, NULL}; - int line_index_mask_len = 0; - int curl_span_init = 0; - - /* hardcoded: TXT_TABSIZE = 4 spaces: */ - int spaceslen = TXT_TABSIZE; + int curl_span_init = 0; - if (ELEM(NULL, text->curl, text->sell)) { - return; - } + BLI_assert(!ELEM(NULL, text->curl, text->sell)); - /* insert spaces rather than tabs */ - if (text->flags & TXT_TABSTOSPACES) { - remove = tab_to_spaces; - indentlen = spaceslen; - } + BLI_listbase_clear(r_line_index_mask); + *r_line_index_mask_len = 0; if (!undoing) { curl_span_init = txt_get_span(text->lines.first, text->curl); @@ -2936,8 +2936,8 @@ void txt_unindent(Text *text) struct LinkInt *idata = MEM_mallocN(sizeof(struct LinkInt), __func__); idata->value = curl_span_init + num; BLI_assert(idata->value == txt_get_span(text->lines.first, text->curl)); - BLI_addtail(&line_index_mask, idata); - line_index_mask_len += 1; + BLI_addtail(r_line_index_mask, idata); + (*r_line_index_mask_len) += 1; } } @@ -2964,57 +2964,20 @@ void txt_unindent(Text *text) text->curl = text->curl->prev; num--; } - - if (!undoing) { - txt_undo_add_unindent_op(text, &line_index_mask, line_index_mask_len); - } - BLI_freelistN(&line_index_mask); + /* caller must handle undo */ } void txt_comment(Text *text) { - int len, num; - char *tmp; - char add = '#'; + const char *prefix = "#"; - if (!text->curl) return; - if (!text->sell) return; // Need to change this need to check if only one line is selected to more than one + if (ELEM(NULL, text->curl, text->sell)) { + return; + } - num = 0; - while (true) { - tmp = MEM_mallocN(text->curl->len + 2, "textline_string"); - - text->curc = 0; - if (text->curc) memcpy(tmp, text->curl->line, text->curc); - tmp[text->curc] = add; - - len = text->curl->len - text->curc; - if (len > 0) memcpy(tmp + text->curc + 1, text->curl->line + text->curc, len); - tmp[text->curl->len + 1] = 0; + txt_select_prefix(text, prefix); - make_new_line(text->curl, tmp); - - text->curc++; - - txt_make_dirty(text); - txt_clean_text(text); - - if (text->curl == text->sell) { - text->selc = text->sell->len; - break; - } - else { - text->curl = text->curl->next; - num++; - } - } - text->curc = 0; - while (num > 0) { - text->curl = text->curl->prev; - num--; - } - if (!undoing) { txt_undo_add_op(text, UNDO_COMMENT); } @@ -3022,46 +2985,55 @@ void txt_comment(Text *text) void txt_uncomment(Text *text) { - int num = 0; - char remove = '#'; + const char *prefix = "#"; + ListBase line_index_mask; + int line_index_mask_len; - if (!text->curl) return; - if (!text->sell) return; + if (ELEM(NULL, text->curl, text->sell)) { + return; + } - while (true) { - int i = 0; - - if (text->curl->line[i] == remove) { - while (i < text->curl->len) { - text->curl->line[i] = text->curl->line[i + 1]; - i++; - } - text->curl->len--; - } - - - txt_make_dirty(text); - txt_clean_text(text); - - if (text->curl == text->sell) { - text->selc = text->sell->len; - break; - } - else { - text->curl = text->curl->next; - num++; - } - + txt_select_unprefix(text, prefix, &line_index_mask, &line_index_mask_len); + + if (!undoing) { + txt_undo_add_unprefix_op(text, UNDO_UNCOMMENT, &line_index_mask, line_index_mask_len); } - text->curc = 0; - while (num > 0) { - text->curl = text->curl->prev; - num--; + + BLI_freelistN(&line_index_mask); +} + +void txt_indent(Text *text) +{ + const char *prefix = (text->flags & TXT_TABSTOSPACES) ? tab_to_spaces : "\t"; + + if (ELEM(NULL, text->curl, text->sell)) { + return; } + + txt_select_prefix(text, prefix); + + if (!undoing) { + txt_undo_add_op(text, UNDO_INDENT); + } +} + +void txt_unindent(Text *text) +{ + const char *prefix = (text->flags & TXT_TABSTOSPACES) ? tab_to_spaces : "\t"; + ListBase line_index_mask; + int line_index_mask_len; + if (ELEM(NULL, text->curl, text->sell)) { + return; + } + + txt_select_unprefix(text, prefix, &line_index_mask, &line_index_mask_len); + if (!undoing) { - txt_undo_add_op(text, UNDO_UNCOMMENT); + txt_undo_add_unprefix_op(text, UNDO_UNINDENT, &line_index_mask, line_index_mask_len); } + + BLI_freelistN(&line_index_mask); } void txt_move_lines(struct Text *text, const int direction) |