diff --git a/edit/bookmark.c b/edit/bookmark.c index cc5db53c7..4ab2b9700 100644 --- a/edit/bookmark.c +++ b/edit/bookmark.c @@ -226,118 +226,125 @@ void book_mark_dec (WEdit * edit, int line) ***************************************************************************** */ -/* note, if there is more than one collapsed lines on a line, then they are - appended after each other and the last one is always the one found - by collapsed_found() i.e. last in is the one seen */ - -static inline struct collapsed_lines *double_collapse (WEdit * edit, struct collapsed_lines *p) -{ - (void) edit; - - if (p->next) - while (p->next->start_line == p->start_line) - p = p->next; - return p; -} - /* returns the first collapsed region on or before this line */ -struct collapsed_lines *collapse_find (WEdit * edit, int start_line) +GList * +book_mark_collapse_find (GList * list, int line) { - struct collapsed_lines *p; - if (!edit->collapsed) { -/* must have an imaginary top bookmark at line -1 to make things less complicated */ - edit->collapsed = g_malloc0 (sizeof (struct collapsed_lines)); - edit->collapsed->start_line = -1; - return edit->collapsed; + GList *cl, *l; + struct collapsed_lines *collapsed; + l = list; + if (!l) + return NULL; + l = g_list_first (list); + cl = l; + while (cl) { + collapsed = (struct collapsed_lines *) cl->data; + if ( collapsed->start_line>=line && line <= collapsed->end_line ) + return cl; + cl = g_list_next (cl); } - for (p = edit->collapsed; p; p = p->next) { - if (p->start_line > start_line) - break; /* gone past it going downward */ - if (p->start_line <= start_line) { - if (p->next) { - if (p->next->start_line > start_line) { - edit->collapsed = p; - return double_collapse (edit, p); - } - } else { - edit->collapsed = p; - return double_collapse (edit, p); - } - } - } - for (p = edit->collapsed; p; p = p->prev) { - if (p->next) - if (p->next->start_line <= start_line) - break; /* gone past it going upward */ - if (p->start_line <= start_line) { - if (p->next) { - if (p->next->start_line > start_line) { - edit->collapsed = p; - return double_collapse (edit, p); - } - } else { - edit->collapsed = p; - return double_collapse (edit, p); - } - } - } - return 0; /* can't get here */ + return NULL; } - /* insert a collapsed at this line */ -void -collapse_insert (WEdit *edit, - const unsigned long start_line, - const unsigned long end_line, int state) +GList * +book_mark_collapse_insert (GList *list, const int start_line, const int end_line, + int state) { struct collapsed_lines *p, *q; - mc_log("collapse_insert: %ld, %ld\n", start_line, end_line); - p = collapse_find (edit, start_line); - if (p->start_line == start_line) { - /* already exists */ - } - if (p->start_line > start_line && p->end_line > end_line) { - /* incorrect region */ - } + p = g_new0 (struct collapsed_lines, 1); + p->start_line = start_line; + p->end_line = end_line; + p->state = state; - /* create list entry */ - q = g_malloc0 (sizeof (struct collapsed_lines)); - q->start_line = start_line; - q->end_line = end_line; - q->state = state; - q->next = p->next; - /* insert into list */ - q->prev = p; - if (p->next) - p->next->prev = q; - p->next = q; + GList *link, *newlink, *tmp; + /* + * Go to the last position and traverse the list backwards + * starting from the second last entry to make sure that we + * are not removing the current link. + */ + list = g_list_append (list, p); + list = g_list_last (list); + link = g_list_previous (list); + + int sl = 0; + int el = 0; + + while (link) { + newlink = g_list_previous (link); + q = (struct collapsed_lines *) link->data; + sl = q->start_line; + el = q->end_line; + if (((sl == start_line) || (el == end_line) || + (sl == end_line) || (el == start_line)) || + ((sl < start_line) && (el > start_line) && (el < end_line)) || + ((sl > start_line) && (sl < end_line) && (el > end_line))) { + g_free (link->data); + tmp = g_list_remove_link (list, link); + g_list_free_1 (link); + } + link = newlink; + } + return list; } + /* returns true if a collapsed exists at this line * return start_line, end_line if found region * */ -int collapse_query (WEdit * edit, const unsigned long line, - unsigned long *start_line, - unsigned long *end_line, - int *state) +int book_mark_collapse_query (GList * list, const int line, + int *start_line, + int *end_line, + int *state) { + GList *cl; struct collapsed_lines *p; *start_line = 0; *end_line = 0; *state = 0; - if (!edit->collapsed) - return 0; - for (p = collapse_find (edit, line); p; p = p->prev) { - if (p->start_line != line) - return 0; - *start_line = p->start_line; - *end_line = p->end_line; - *state = p->state; - return 1; + cl = book_mark_collapse_find (list, line); + if ( cl ){ + p = (struct collapsed_lines *) cl->data; + if ((p->start_line >= line) && (line <= p->end_line) ) { + *start_line = p->start_line; + *end_line = p->end_line; + *state = p->state; + return 1; + } } return 0; -} \ No newline at end of file +} + +int book_mark_get_collapse_state (GList * list, const int line) +{ + int start_line; + int end_line; + int state; + int c = 0; + +// mc_log("start_line: %ld, end_line: %ld, line: %ld [%i]\n", start_line, end_line, line, c); + c = book_mark_collapse_query (list, line, &start_line, &end_line, &state); + if ( c == 0 ) + return C_LINES_DEFAULT; + if ( line == start_line ) { + if ( state ) + return C_LINES_COLLAPSED; + else + return C_LINES_ELAPSED; + } + if ( line > start_line && line< end_line ) { + if ( state ) + return C_LINES_MIDDLE_C; + else + return C_LINES_MIDDLE_E; + } + if ( line == end_line ) { + if ( state ) + return C_LINES_MIDDLE_C; + else + return C_LINES_LAST; + } +} diff --git a/edit/edit-widget.h b/edit/edit-widget.h index 10cb749b0..778974c80 100644 --- a/edit/edit-widget.h +++ b/edit/edit-widget.h @@ -22,8 +22,6 @@ struct collapsed_lines { int start_line; /* first collpsed line number */ int end_line; /* end collapsed line number */ int state; /* 1 - collapsed; 0 - elapsed */ - struct collapsed_lines *next; - struct collapsed_lines *prev; }; struct syntax_rule { @@ -105,7 +103,7 @@ struct WEdit { long line_offsets[N_LINE_CACHES]; struct _book_mark *book_mark; - struct collapsed_lines *collapsed; + GList *collapsed; /* undo stack and pointers */ unsigned long stack_pointer; diff --git a/edit/edit.c b/edit/edit.c index 7e53c538c..0f5c99e95 100644 --- a/edit/edit.c +++ b/edit/edit.c @@ -2679,17 +2679,19 @@ edit_execute_cmd (WEdit *edit, int command, int char_for_insertion) case CK_Add_Collapse_Region: if ( edit->mark1 != edit->mark2 ) { - long upto_start = edit_count_lines (edit, edit->mark1, edit->curs1); + int upto_start = edit_count_lines (edit, edit->mark1, edit->curs1); int lines_selected = edit_count_lines (edit, edit->mark1, edit->curs1); - long start_line = edit->curs_line; + int start_line = edit->curs_line; if ( edit->curs1 > edit->mark1 ) { start_line = edit->curs_line - upto_start; } else { start_line = edit->curs_line + upto_start; } - unsigned long end_line = start_line + lines_selected; - collapse_insert (edit, start_line, end_line, 1); + unsigned int end_line = start_line + lines_selected; + mc_log("lines_selected:%ld\n", lines_selected); + book_mark_collapse_insert (edit->collapsed, start_line, end_line, 1); } + edit->force |= REDRAW_PAGE; break; case CK_Toggle_Bookmark: diff --git a/edit/edit.h b/edit/edit.h index 0506e381f..5ccfe49a1 100644 --- a/edit/edit.h +++ b/edit/edit.h @@ -24,6 +24,7 @@ #define MC_EDIT_H #include +#include "../src/global.h" #define SEARCH_DIALOG_OPTION_NO_SCANF (1 << 0) #define SEARCH_DIALOG_OPTION_NO_REGEX (1 << 1) @@ -101,6 +102,13 @@ #define TAB_SIZE option_tab_spacing #define HALF_TAB_SIZE ((int) option_tab_spacing / 2) +#define C_LINES_ELAPSED 1 /* first line elapsed region */ +#define C_LINES_COLLAPSED 2 /* first line collapsed region */ +#define C_LINES_MIDDLE_E 3 /* in middle collapsed */ +#define C_LINES_MIDDLE_C 4 /* in middle elapsed */ +#define C_LINES_LAST 5 /* last line elapsed region */ +#define C_LINES_DEFAULT 0 + /* max count stack files */ #define MAX_HISTORY_MOVETO 50 @@ -239,14 +247,15 @@ void book_mark_flush (WEdit * edit, int c); void book_mark_inc (WEdit * edit, int line); void book_mark_dec (WEdit * edit, int line); -struct collapsed_lines *collapse_find (WEdit * edit, int start_line); -void collapse_insert (WEdit *edit, - const unsigned long start_line, - const unsigned long end_line, int state); -int collapse_query (WEdit * edit, const unsigned long line, - unsigned long *start_line, - unsigned long *end_line, - int *state); + +GList * book_mark_collapse_insert (GList * list, + const int start_line, + const int end_line, int state); +int book_mark_collapse_query (GList *list, const int line, + int *start_line, + int *end_line, + int *state); +int book_mark_get_collapse_state (GList *list, const int line); int line_is_blank (WEdit *edit, long line); int edit_indent_width (WEdit *edit, long p); diff --git a/edit/editdraw.c b/edit/editdraw.c index 61680b5e2..3418ded1a 100644 --- a/edit/editdraw.c +++ b/edit/editdraw.c @@ -373,16 +373,16 @@ edit_draw_this_line (WEdit *edit, long b, long row, long start_col, g_snprintf (line_stat, 2, "*"); } switch ( collapse_state ) { - case -1: + case C_LINES_ELAPSED: line_stat[0] = '-'; break; - case 1: + case C_LINES_COLLAPSED: line_stat[0] = '+'; break; - case 2: + case C_LINES_MIDDLE_E: line_stat[0] = '|'; break; - case 3: + case C_LINES_LAST: line_stat[0] = '\\'; break; } @@ -612,29 +612,10 @@ render_edit_text (WEdit * edit, long start_row, long start_column, long end_row, while (row <= end_row) { if (key_pending (edit)) goto exit_render; - if ( !collapse_header ) { - cur_line = edit->start_line + row; - collapse_header = collapse_query (edit, cur_line, - &sline, &eline, - &collapsed); - if ( collapse_header ) { - count_collapsed_lines = sline - eline; - if ( collapsed ) { - collapse_state = -1; //collapsed "+" - } else { - collapse_state = 1; //elapsed "-" - } - } - } - if ( count_collapsed_lines > 1 ) { - count_collapsed_lines--; - collapse_state = 2; //in middle - } else if ( count_collapsed_lines == 1 ) { - count_collapsed_lines--; - collapse_state = 3; //last collapsed line - collapse_header = 0; - } - if (( !collapse_header ) || (( collapse_header ) && ( !collapsed ))) { + cur_line = edit->start_line + row; + mc_log("REDRAW_PAGE cur_line:%i\n", cur_line); + collapse_state = book_mark_get_collapse_state(edit, cur_line); + if ( collapse_state != C_LINES_MIDDLE_C ) { edit_draw_this_line (edit, b, row, start_column, end_column, collapse_state); } row++; @@ -648,33 +629,12 @@ render_edit_text (WEdit * edit, long start_row, long start_column, long end_row, long upto = curs_row - 1 <= end_row ? curs_row - 1 : end_row; row = start_row; b = edit->start_display; - collapse_state = 0; while (row <= upto) { if (key_pending (edit)) goto exit_render; - if ( !collapse_header ) { - cur_line = edit->start_line + row; - collapse_header = collapse_query (edit, cur_line, - &sline, &eline, - &collapsed); - if ( collapse_header ) { - count_collapsed_lines = sline - eline; - if ( collapsed ) { - collapse_state = -1; //collapsed "+" - } else { - collapse_state = 1; //elapsed "-" - } - } - } - if ( count_collapsed_lines > 1 ) { - count_collapsed_lines--; - collapse_state = 2; //in middle - } else if ( count_collapsed_lines == 1 ) { - count_collapsed_lines--; - collapse_state = 3; //last collapsed line - collapse_header = 0; - } - if (( !collapse_header ) || (( collapse_header ) && ( !collapsed ))) { + cur_line = edit->start_line + row; + collapse_state = book_mark_get_collapse_state(edit, cur_line); + if ( collapse_state != C_LINES_MIDDLE_C ) { edit_draw_this_line (edit, b, row, start_column, end_column, collapse_state); } @@ -688,7 +648,12 @@ render_edit_text (WEdit * edit, long start_row, long start_column, long end_row, if (curs_row >= start_row && curs_row <= end_row) { if (key_pending (edit)) goto exit_render; - edit_draw_this_line (edit, b, curs_row, start_column, end_column, 0); + cur_line = edit->start_line + curs_row; + collapse_state = book_mark_get_collapse_state(edit, cur_line); + if ( collapse_state != C_LINES_MIDDLE_C ) { + edit_draw_this_line (edit, b, curs_row, start_column, end_column, + collapse_state); + } } if (force & REDRAW_AFTER_CURSOR) { if (end_row > curs_row) { @@ -697,7 +662,11 @@ render_edit_text (WEdit * edit, long start_row, long start_column, long end_row, while (row <= end_row) { if (key_pending (edit)) goto exit_render; - edit_draw_this_line (edit, b, row, start_column, end_column, 0); + cur_line = edit->start_line + row; + collapse_state = book_mark_get_collapse_state(edit, cur_line); + if ( collapse_state != C_LINES_MIDDLE_C ) { + edit_draw_this_line (edit, b, row, start_column, end_column, collapse_state); + } row++; b = edit_move_forward (edit, b, 1, 0); } @@ -709,7 +678,11 @@ render_edit_text (WEdit * edit, long start_row, long start_column, long end_row, if (row >= start_row && row <= end_row) { if (key_pending (edit)) goto exit_render; - edit_draw_this_line (edit, b, row, start_column, end_column, 0); + cur_line = edit->start_line + row; + collapse_state = book_mark_get_collapse_state(edit, cur_line); + if ( collapse_state != C_LINES_MIDDLE_C ) { + edit_draw_this_line (edit, b, row, start_column, end_column, collapse_state); + } } } if (force & REDRAW_LINE_BELOW && row < edit->num_widget_lines - 1) { @@ -719,7 +692,11 @@ render_edit_text (WEdit * edit, long start_row, long start_column, long end_row, if (row >= start_row && row <= end_row) { if (key_pending (edit)) goto exit_render; - edit_draw_this_line (edit, b, row, start_column, end_column, 0); + cur_line = edit->start_line + row; + collapse_state = book_mark_get_collapse_state(edit, cur_line); + if ( collapse_state != C_LINES_MIDDLE_C ) { + edit_draw_this_line (edit, b, row, start_column, end_column, collapse_state); + } } } }