Skip to content

Commit

Permalink
view: add infrastructure for delayed cursor destruction
Browse files Browse the repository at this point in the history
At least one cursor (referred to as primary or main cursor) has always
to exist. In the sam command language implementation we might want to
dispose a cursor even if it is the primary one before later commands
will create different ones (e.g. `:x/pattern/ { i/>>>/ a/<<</ }`).

This commit introduces view_cursors_dispose_force. If called on
the last remaining cursor, its selection is cleared and it is marked for
destruction as soon as a new cursor is created. view_cursor_disposed
returns the cursor marked for deletion (if any) and clears the descruction
flag.
  • Loading branch information
martanne committed Jan 13, 2017
1 parent 0f35467 commit 0539640
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 2 deletions.
25 changes: 23 additions & 2 deletions view.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ struct View {
Line *lastline; /* last currently used line, always <= bottomline */
Line *bottomline; /* bottom of view, might be unused if lastline < bottomline */
Cursor *cursor; /* main cursor, always placed within the visible viewport */
Cursor *cursor_dead;/* main cursor which was disposed, will be removed when another cursor is created */
int cursor_count; /* how many cursors do currently exist */
Line *line; /* used while drawing view content, line where next char will be drawn */
int col; /* used while drawing view content, column where next char will be drawn */
Expand Down Expand Up @@ -972,7 +973,8 @@ static Cursor *cursors_new(View *view, size_t pos, bool force) {
view->cursors = c;
}
view->cursor = c;
view->cursor_count++;;
view->cursor_count++;
view_cursors_dispose(view->cursor_dead);
view_cursors_to(c, pos);
return c;
err:
Expand Down Expand Up @@ -1067,13 +1069,15 @@ static void view_cursors_free(Cursor *c) {
c->view->cursors = c->next;
if (c->view->cursor == c)
c->view->cursor = c->next ? c->next : c->prev;
if (c->view->cursor_dead == c)
c->view->cursor_dead = NULL;
c->view->cursor_count--;
free(c);
}

bool view_cursors_dispose(Cursor *c) {
if (!c)
return false;
return true;
View *view = c->view;
if (!view->cursors || !view->cursors->next)
return false;
Expand All @@ -1083,6 +1087,23 @@ bool view_cursors_dispose(Cursor *c) {
return true;
}

bool view_cursors_dispose_force(Cursor *c) {
if (view_cursors_dispose(c))
return true;
View *view = c->view;
if (view->cursor_dead)
return false;
view_cursors_selection_clear(c);
view->cursor_dead = c;
return true;
}

Cursor *view_cursor_disposed(View *view) {
Cursor *c = view->cursor_dead;
view->cursor_dead = NULL;
return c;
}

Cursor *view_cursors(View *view) {
view->cursor_generation++;
return view->cursors;
Expand Down
7 changes: 7 additions & 0 deletions view.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,13 @@ bool view_cursors_multiple(View*);
/* dispose an existing cursor with its associated selection (if any),
* not applicaple for the last existing cursor */
bool view_cursors_dispose(Cursor*);
/* if called for the last existing cursor its selection is destroyed
* and the cursor is marked for destruction and will be disposed as
* soon as a new cursor is created. */
bool view_cursors_dispose_force(Cursor*);
/* if the primary cursor was marked for destruction (by means of
* view_cursors_dispose_force) return it and clear descruction flag */
Cursor *view_cursor_disposed(View*);
/* only keep the main cursor, release all others together with their
* selections (if any) */
void view_cursors_clear(View*);
Expand Down

0 comments on commit 0539640

Please sign in to comment.