vis

a vi-like editor based on Plan 9's structural regular expressions

git clone https://9o.is/git/vis.git

commit 8235595a58872cf4676707f22099c2c3f5d2fcfd
parent 31a483fea831d6ed4b5d7db1f0bc03ef5b5779fa
Author: Marc André Tanner <mat@brain-dump.org>
Date:   Mon, 28 Mar 2016 12:01:49 +0200

view: add infrastructure to iterate through cursor columns

The number of columns i.e. maximal number of cursors located on the
same line can be obtained by view_cursors_column_count.

Column addressing is zero based, valid indexes are [0, max-1].

Assuming there is a cursor on every letter:

 a
 b c
 d e f
 g h
 i

max column would be 3, and the following would iterate over the
cursors forming the second column [c, e, h]:

 for (Cursor *c = view_cursors_column(view, 1); c; c = view_cursors_column_next(c, 1))
   ...

Diffstat:
Mview.c | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mview.h | 7+++++++
2 files changed, 61 insertions(+), 0 deletions(-)

diff --git a/view.c b/view.c @@ -4,6 +4,7 @@ #include <ctype.h> #include <errno.h> #include <regex.h> +#include <limits.h> #include "vis-lua.h" #include "view.h" #include "text.h" @@ -1103,6 +1104,59 @@ int view_cursors_count(View *view) { return i; } +int view_cursors_column_count(View *view) { + Text *txt = view->text; + int cpl_max = 0, cpl = 0; /* cursors per line */ + size_t line_prev = 0; + for (Cursor *c = view->cursors; c; c = c->next) { + size_t pos = view_cursors_pos(c); + size_t line = text_lineno_by_pos(txt, pos); + if (line == line_prev) + cpl++; + else + cpl = 1; + line_prev = line; + if (cpl > cpl_max) + cpl_max = cpl; + } + return cpl_max; +} + +static Cursor *cursors_column_next(View *view, Cursor *c, int column) { + size_t line_cur = 0; + int column_cur = 0; + Text *txt = view->text; + if (c) { + size_t pos = view_cursors_pos(c); + line_cur = text_lineno_by_pos(txt, pos); + column_cur = INT_MIN; + } else { + c = view->cursors; + } + + for (; c; c = c->next) { + size_t pos = view_cursors_pos(c); + size_t line = text_lineno_by_pos(txt, pos); + if (line != line_cur) { + line_cur = line; + column_cur = 0; + } else { + column_cur++; + } + if (column == column_cur) + return c; + } + return NULL; +} + +Cursor *view_cursors_column(View *view, int column) { + return cursors_column_next(view, NULL, column); +} + +Cursor *view_cursors_column_next(Cursor *c, int column) { + return cursors_column_next(c->view, c, column); +} + bool view_cursors_multiple(View *view) { return view->cursors && view->cursors->next; } diff --git a/view.h b/view.h @@ -179,4 +179,11 @@ Filerange view_selections_get(Selection*); void view_selections_set(Selection*, Filerange*); Text *view_text(View*); +/* get number of columns, that is maximal number of cursors on a line */ +int view_cursors_column_count(View*); +/* get first cursor in zero based column */ +Cursor *view_cursors_column(View*, int column); +/* get next cursor (i.e. on another line) in zero based column */ +Cursor *view_cursors_column_next(Cursor*, int column); + #endif