aboutsummaryrefslogtreecommitdiff
path: root/text.c
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2015-01-24 18:36:23 +0100
committerMarc André Tanner <mat@brain-dump.org>2015-02-03 13:38:31 +0100
commit52927a1b6509953063eaee51aef3b8d1ea28629d (patch)
treefee8d2bb3a08b847c099270d924310b8cf92bf0b /text.c
parentc6910b03fbc8b7978369900dc571d758de3ef844 (diff)
downloadvis-52927a1b6509953063eaee51aef3b8d1ea28629d.tar.gz
vis-52927a1b6509953063eaee51aef3b8d1ea28629d.tar.xz
Fix :nnn where nnn > maximal number of lines
Diffstat (limited to 'text.c')
-rw-r--r--text.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/text.c b/text.c
index 71d21c4..cd85734 100644
--- a/text.c
+++ b/text.c
@@ -154,7 +154,7 @@ static void action_push(Action **stack, Action *action);
static Action *action_pop(Action **stack);
/* logical line counting cache */
static void lineno_cache_invalidate(LineCache *cache);
-static size_t lines_skip_forward(Text *txt, size_t pos, size_t lines);
+static size_t lines_skip_forward(Text *txt, size_t pos, size_t lines, size_t *lines_skiped);
static size_t lines_count(Text *txt, size_t pos, size_t len);
/* allocate a new buffer of MAX(size, BUFFER_SIZE) bytes */
@@ -1070,7 +1070,8 @@ static size_t lines_count(Text *txt, size_t pos, size_t len) {
}
/* skip n lines forward and return position afterwards */
-static size_t lines_skip_forward(Text *txt, size_t pos, size_t lines) {
+static size_t lines_skip_forward(Text *txt, size_t pos, size_t lines, size_t *lines_skipped) {
+ size_t lines_old = lines;
text_iterate(txt, it, pos) {
const char *start = it.text;
while (lines > 0 && start < it.end) {
@@ -1088,6 +1089,7 @@ static size_t lines_skip_forward(Text *txt, size_t pos, size_t lines) {
if (lines == 0)
break;
}
+ *lines_skipped = lines_old - lines;
return pos;
}
@@ -1097,11 +1099,13 @@ static void lineno_cache_invalidate(LineCache *cache) {
}
size_t text_pos_by_lineno(Text *txt, size_t lineno) {
+ size_t lines_skipped;
LineCache *cache = &txt->lines;
if (lineno <= 1)
return 0;
if (lineno > cache->lineno) {
- cache->pos = lines_skip_forward(txt, cache->pos, lineno - cache->lineno);
+ cache->pos = lines_skip_forward(txt, cache->pos, lineno - cache->lineno, &lines_skipped);
+ cache->lineno += lines_skipped;
} else if (lineno < cache->lineno) {
#if 0
// TODO does it make sense to scan memory backwards here?
@@ -1110,9 +1114,9 @@ size_t text_pos_by_lineno(Text *txt, size_t lineno) {
lines_skip_backward(txt, cache->pos, diff);
} else
#endif
- cache->pos = lines_skip_forward(txt, 0, lineno - 1);
+ cache->pos = lines_skip_forward(txt, 0, lineno - 1, &lines_skipped);
+ cache->lineno = lines_skipped + 1;
}
- cache->lineno = lineno;
return cache->pos;
}