aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/frame.c72
-rw-r--r--src/frame.h4
-rw-r--r--src/sc_editor.c10
3 files changed, 78 insertions, 8 deletions
diff --git a/src/frame.c b/src/frame.c
index 3c9dd34..136ff0f 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -945,14 +945,20 @@ void delete_text_from_frame(struct frame *fr, struct edit_pos p1, struct edit_po
double wrapw)
{
int i;
+ size_t del = 0;
sort_positions(&p1, &p2);
+ printf("para %i offs %ld\n", p1.para, p1.pos);
+ printf("para %i offs %li\n", p2.para, p2.pos);
+
for ( i=p1.para; i<=p2.para; i++ ) {
size_t start;
ssize_t finis;
+ printf("para %i\n", i);
+
Paragraph *para = fr->paras[i];
if ( i == p1.para ) {
@@ -968,31 +974,44 @@ void delete_text_from_frame(struct frame *fr, struct edit_pos p1, struct edit_po
}
if ( (start == 0) && (finis == -1) ) {
+ printf("deleting para %i\n", i);
delete_paragraph(fr, i);
p2.para--;
i--;
} else {
- delete_text_in_paragraph(para, start, finis);
+ printf("deleting from %ld to %ld\n", start, finis);
+ del += delete_text_in_paragraph(para, start, finis);
wrap_paragraph(para, NULL, wrapw, 0, 0);
}
}
+
+ /* Update offsets for all subsequent paragraphs, but only if they're
+ * from the same SCBlock */
+ printf("fixing offsets from para %i by %i\n", p1.para, del);
+ fix_scblock_offsets(fr, p1, del);
}
/* offs2 negative means "to end" */
-void delete_text_in_paragraph(Paragraph *para, size_t offs1, ssize_t offs2)
+size_t delete_text_in_paragraph(Paragraph *para, size_t offs1, ssize_t offs2)
{
int nrun1, nrun2, nrun;
int i;
size_t scblock_offs1, scblock_offs2;
+ size_t sum_del = 0;
/* Find which run we are in */
nrun1 = which_run(para, offs1);
- nrun2 = which_run(para, offs2);
+ if ( offs2 < 0 ) {
+ /* Delete to end */
+ nrun2 = para->n_runs-1;
+ } else {
+ nrun2 = which_run(para, offs2);
+ }
if ( (nrun1 == para->n_runs) || (nrun2 == para->n_runs) ) {
fprintf(stderr, "Couldn't find run to delete from.\n");
- return;
+ return 0;
}
for ( nrun=nrun1; nrun<=nrun2; nrun++ ) {
@@ -1008,7 +1027,11 @@ void delete_text_in_paragraph(Paragraph *para, size_t offs1, ssize_t offs2)
}
ds = offs1 - run->para_offs_bytes;
- de = offs2 - run->para_offs_bytes;
+ if ( offs2 < 0 ) {
+ de = run->len_bytes;
+ } else {
+ de = offs2 - run->para_offs_bytes;
+ }
if ( ds < 0 ) ds = 0;
if ( de > run->len_bytes ) {
de = run->len_bytes;
@@ -1020,6 +1043,8 @@ void delete_text_in_paragraph(Paragraph *para, size_t offs1, ssize_t offs2)
/* Delete from the corresponding SC block */
scblock_offs1 = ds + run->scblock_offs_bytes;
scblock_offs2 = de + run->scblock_offs_bytes;
+ sum_del += scblock_offs2 - scblock_offs1;
+ printf("del %i %i\n", scblock_offs1, scblock_offs2);
scblock_delete_text(run->scblock, scblock_offs1, scblock_offs2);
/* Fix up the offsets of the subsequent text runs */
@@ -1034,6 +1059,43 @@ void delete_text_in_paragraph(Paragraph *para, size_t offs1, ssize_t offs2)
offs2 -= del_len;
}
+
+ return sum_del;
+}
+
+
+void fix_scblock_offsets(struct frame *fr, struct edit_pos pos, size_t del)
+{
+ int i;
+ int nrun;
+ size_t offs;
+ SCBlock *scblock;
+
+ offs = pos_trail_to_offset(fr->paras[pos.para], pos.pos, pos.trail);
+ nrun = which_run(fr->paras[pos.para], offs);
+
+ if ( nrun == fr->paras[pos.para]->n_runs ) {
+ fprintf(stderr, "Couldn't find new start\n");
+ return;
+ }
+
+ /* We will update the offsets of any runs which match this block */
+ scblock = fr->paras[pos.para]->runs[nrun].scblock;
+
+ for ( i=pos.para+1; i<fr->n_paras; i++ ) {
+
+ int j;
+ Paragraph *para;
+
+ para = fr->paras[i];
+
+ if ( para->type != PARA_TYPE_TEXT ) continue;
+
+ for ( j=0; j<para->n_runs; j++ ) {
+ if ( para->runs[j].scblock != scblock) return;
+ para->runs[j].scblock_offs_bytes -= del;
+ }
+ }
}
diff --git a/src/frame.h b/src/frame.h
index 0386a51..8e2ffe3 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -181,7 +181,9 @@ extern void insert_text_in_paragraph(Paragraph *para, size_t offs,
extern void delete_text_from_frame(struct frame *fr, struct edit_pos p1, struct edit_pos p2,
double wrap_w);
-extern void delete_text_in_paragraph(Paragraph *para, size_t offs1, ssize_t offs2);
+extern size_t delete_text_in_paragraph(Paragraph *para, size_t offs0, ssize_t offs2);
+
+extern void fix_scblock_offsets(struct frame *fr, struct edit_pos pos, size_t del);
extern SCBlock *split_paragraph(struct frame *fr, int pn, size_t pos,
PangoContext *pc);
diff --git a/src/sc_editor.c b/src/sc_editor.c
index aabb84a..db0f11d 100644
--- a/src/sc_editor.c
+++ b/src/sc_editor.c
@@ -720,7 +720,6 @@ static void do_backspace(struct frame *fr, SCEditor *e)
if ( e->sel_active ) {
/* Delete the selected block */
- printf("delete block\n");
delete_text_from_frame(e->cursor_frame, e->sel_start, e->sel_end, wrapw);
/* Cursor goes at start of deletion */
@@ -753,15 +752,22 @@ static void do_backspace(struct frame *fr, SCEditor *e)
} else {
+ size_t del;
size_t offs_new, offs_old;
+ struct edit_pos pos;
offs_new = pos_trail_to_offset(para, e->cursor_pos,
e->cursor_trail);
offs_old = pos_trail_to_offset(para, old_pos, old_trail);
- delete_text_in_paragraph(para, offs_new, offs_old);
+ del = delete_text_in_paragraph(para, offs_new, offs_old);
+ pos.para = new_para;
+ pos.pos = new_pos;
+ pos.trail = new_trail;
+ fix_scblock_offsets(fr, pos, 1);
wrap_paragraph(para, NULL, wrapw, 0, 0);
+
}
}