diff options
author | Thomas White <taw@bitwiz.org.uk> | 2016-05-22 23:26:05 +0200 |
---|---|---|
committer | Thomas White <taw@bitwiz.org.uk> | 2016-05-22 23:26:05 +0200 |
commit | b2bc55a1d24d61f3b604ebb6d60479479b97976f (patch) | |
tree | 0e33f8daf2e944103ea7690f5d4fbc94956aad70 | |
parent | 0818526f58cbb1927733f16fe665552194fe9228 (diff) |
Merge paragraphs (needs fixing)
-rw-r--r-- | src/frame.c | 54 | ||||
-rw-r--r-- | src/frame.h | 2 | ||||
-rw-r--r-- | src/sc_editor.c | 18 | ||||
-rw-r--r-- | src/sc_parse.c | 10 | ||||
-rw-r--r-- | src/sc_parse.h | 2 |
5 files changed, 78 insertions, 8 deletions
diff --git a/src/frame.c b/src/frame.c index fb849a4..32de26e 100644 --- a/src/frame.c +++ b/src/frame.c @@ -861,6 +861,60 @@ static __attribute__((unused)) void show_para(Paragraph *p) } +void merge_paragraphs(struct frame *fr, int para) +{ + Paragraph *p1, *p2; + struct text_run *runs_new; + int i; + size_t len; + SCBlock *scblock; + + if ( para >= fr->n_paras-1 ) { + printf("Paragraph number too high to merge.\n"); + return; + } + + p1 = fr->paras[para]; + p2 = fr->paras[para+1]; + show_para(p1); + show_para(p2); + + if ( (p1->type != PARA_TYPE_TEXT) || (p2->type != PARA_TYPE_TEXT) ) { + printf("Trying to merge non-text paragraphs.\n"); + return; + } + + /* All the runs from p2 get added to p1 */ + runs_new = realloc(p1->runs, + (p1->n_runs+p2->n_runs)*sizeof(struct text_run)); + if ( runs_new == NULL ) { + fprintf(stderr, "Failed to allocate merged runs.\n"); + return; + } + p1->runs = runs_new; + + /* Take off the newline at the end of the last run */ + scblock = p1->runs[p1->n_runs-1].scblock; + len = p1->runs[p1->n_runs-1].len_bytes--; + if ( sc_block_contents(scblock)[len+1] != '\n' ) { + fprintf(stderr, "Whoops, not a newline!\n"); + } + scblock_delete_text(scblock, len+1, len+2); + + for ( i=0; i<p2->n_runs; i++ ) { + p1->runs[p1->n_runs++] = p2->runs[i]; + } + free(p2->runs); + free(p2); + show_para(p1); + + for ( i=para+1; i<fr->n_paras-1; i++ ) { + fr->paras[i] = fr->paras[i+1]; + } + fr->n_paras--; +} + + static char *s_strdup(const char *a) { if ( a == NULL ) return NULL; diff --git a/src/frame.h b/src/frame.h index 0eb562b..3f343dc 100644 --- a/src/frame.h +++ b/src/frame.h @@ -164,4 +164,6 @@ extern int get_sc_pos(struct frame *fr, int pn, size_t pos, extern void *get_para_bvp(Paragraph *para); +extern void merge_paragraphs(struct frame *fr, int para); + #endif /* FRAME_H */ diff --git a/src/sc_editor.c b/src/sc_editor.c index 37bba88..748089e 100644 --- a/src/sc_editor.c +++ b/src/sc_editor.c @@ -603,22 +603,24 @@ static void do_backspace(struct frame *fr, SCEditor *e) size_t new_pos = old_pos; int new_trail = old_trail; + double wrapw = e->cursor_frame->w - e->cursor_frame->pad_l + - e->cursor_frame->pad_r; + Paragraph *para = e->cursor_frame->paras[old_para]; cursor_moveh(e->cursor_frame, &new_para, &new_pos, &new_trail, -1); cursor_moveh(e->cursor_frame, &e->cursor_para, &e->cursor_pos, &e->cursor_trail, -1); if ( e->cursor_para != old_para ) { - /* FIXME: Implement this case */ - printf("Merge paragraphs!\n"); - return; - } + merge_paragraphs(e->cursor_frame, e->cursor_para); + wrap_paragraph(e->cursor_frame->paras[new_para], NULL, wrapw); + } else { - delete_text_in_paragraph(para, e->cursor_pos+e->cursor_trail, - old_pos+old_trail); + delete_text_in_paragraph(para, e->cursor_pos+e->cursor_trail, + old_pos+old_trail); + wrap_paragraph(para, NULL, wrapw); + } - wrap_paragraph(para, NULL, e->cursor_frame->w - e->cursor_frame->pad_l - - e->cursor_frame->pad_r); sc_editor_redraw(e); } diff --git a/src/sc_parse.c b/src/sc_parse.c index 689a31e..8bc6578 100644 --- a/src/sc_parse.c +++ b/src/sc_parse.c @@ -631,6 +631,16 @@ void sc_insert_block(SCBlock *b1, int o1, SCBlock *ins) } +void scblock_delete_text(SCBlock *b, size_t o1, size_t o2) +{ + if ( o1 >= o2 ) { + fprintf(stderr, "Backwards delete!\n"); + return; + } + memmove(b->contents+o1, b->contents+o2, o2-o1); +} + + static void delete_from_block(SCBlock *b, int o1, int o2) { if ( o1 == o2 ) return; /* nothing to delete */ diff --git a/src/sc_parse.h b/src/sc_parse.h index 1260cc0..c9150eb 100644 --- a/src/sc_parse.h +++ b/src/sc_parse.h @@ -74,4 +74,6 @@ extern void show_sc_block(const SCBlock *bl, const char *prefix); extern char *serialise_sc_block(const SCBlock *bl); extern void save_sc_block(FILE *fh, const SCBlock *bl); +extern void scblock_delete_text(SCBlock *b, size_t o1, size_t o2); + #endif /* SC_PARSE_H */ |