aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/frame.c54
-rw-r--r--src/frame.h2
-rw-r--r--src/sc_editor.c18
-rw-r--r--src/sc_parse.c10
-rw-r--r--src/sc_parse.h2
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 */