Fix for text editor un-indent undo
Same issue as T44381, re-use logic for indent.
This commit is contained in:
parent
860e25fe29
commit
b8a8059e21
|
@ -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;
|
||||
|
||||
BLI_assert(!ELEM(NULL, text->curl, text->sell));
|
||||
|
||||
/* hardcoded: TXT_TABSIZE = 4 spaces: */
|
||||
int spaceslen = TXT_TABSIZE;
|
||||
|
||||
if (ELEM(NULL, text->curl, text->sell)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* 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
|
||||
|
||||
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;
|
||||
|
||||
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++;
|
||||
}
|
||||
if (ELEM(NULL, text->curl, text->sell)) {
|
||||
return;
|
||||
}
|
||||
text->curc = 0;
|
||||
while (num > 0) {
|
||||
text->curl = text->curl->prev;
|
||||
num--;
|
||||
}
|
||||
|
||||
|
||||
txt_select_prefix(text, prefix);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
txt_select_unprefix(text, prefix, &line_index_mask, &line_index_mask_len);
|
||||
|
||||
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++;
|
||||
}
|
||||
|
||||
}
|
||||
text->curc = 0;
|
||||
while (num > 0) {
|
||||
text->curl = text->curl->prev;
|
||||
num--;
|
||||
}
|
||||
|
||||
if (!undoing) {
|
||||
txt_undo_add_op(text, UNDO_UNCOMMENT);
|
||||
txt_undo_add_unprefix_op(text, UNDO_UNCOMMENT, &line_index_mask, line_index_mask_len);
|
||||
}
|
||||
|
||||
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_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)
|
||||
|
|
Loading…
Reference in New Issue