vis
a vi-like editor based on Plan 9's structural regular expressions
git clone https://9o.is/git/vis.git
commit 9226e82939c9e425a96347f3ae159a655d063a5e parent db92f344d23fa4daa43da5d849a9aa11d12c544a Author: Marc André Tanner <mat@brain-dump.org> Date: Sat, 25 Oct 2014 15:18:23 +0200 Support partial writes Diffstat:
| M | text.c | | | 29 | ++++++++++++++++++++--------- |
| M | text.h | | | 1 | + |
| M | vis.c | | | 2 | +- |
3 files changed, 22 insertions(+), 10 deletions(-)
diff --git a/text.c b/text.c @@ -664,26 +664,37 @@ err: } ssize_t text_write(Text *txt, int fd) { - ssize_t len = 0; - text_iterate(txt, it, 0) { - size_t plen = it.end - it.start, poff = 0; - while (plen > 0) { - ssize_t res = write(fd, it.start + poff, plen); + Filerange r = (Filerange){ .start = 0, .end = text_size(txt) }; + return text_range_write(txt, &r, fd); +} + +ssize_t text_range_write(Text *txt, Filerange *range, int fd) { + size_t size = range->end - range->start; + size_t rem = size; + for (Iterator it = text_iterator_get(txt, range->start); + rem > 0 && text_iterator_valid(&it); + text_iterator_next(&it)) { + size_t prem = it.end - it.text, poff = 0; + if (prem > rem) + prem = rem; + while (prem > 0) { + ssize_t res = write(fd, it.text + poff, prem); if (res < 0) { if (errno == EAGAIN || errno == EINTR) continue; return -1; } if (res == 0) - break; + goto out; poff += res; - plen -= res; + prem -= res; + rem -= res; } - len += plen; } +out: txt->saved_action = txt->undo; text_snapshot(txt); - return len; + return size - rem; } /* load the given file as starting point for further editing operations. diff --git a/text.h b/text.h @@ -87,6 +87,7 @@ bool text_newlines_crnl(Text*); bool text_save(Text*, const char *file); bool text_range_save(Text*, Filerange*, const char *file); ssize_t text_write(Text*, int fd); +ssize_t text_range_write(Text*, Filerange*, int fd); void text_free(Text*); typedef struct Regex Regex; diff --git a/vis.c b/vis.c @@ -1416,7 +1416,7 @@ static bool cmd_write(Filerange *range, const char *argv[]) { argv[1] = text_filename_get(text); if (!argv[1]) { if (text_fd_get(text) == STDIN_FILENO) - return text_write(text, STDOUT_FILENO) >= 0; + return text_range_write(text, range, STDOUT_FILENO) >= 0; editor_info_show(vis, "Filename expected"); return false; }