vis
a vi-like editor based on Plan 9's structural regular expressions
git clone https://9o.is/git/vis.git
commit f240bd06720ebdf896e6219b66c58cce5ee33fdf parent 2f3bde2e9c1e324dcf3ace4e4afa065380aa646b Author: Marc André Tanner <mat@brain-dump.org> Date: Sun, 7 Feb 2016 13:19:01 +0100 text-object: introduce text_object_number Diffstat:
| M | text-objects.c | | | 25 | +++++++++++++++++++++++++ |
| M | text-objects.h | | | 2 | ++ |
2 files changed, 27 insertions(+), 0 deletions(-)
diff --git a/text-objects.c b/text-objects.c @@ -13,6 +13,8 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include <errno.h> +#include <stdlib.h> #include <string.h> #include <ctype.h> #include "text-motions.h" @@ -300,6 +302,29 @@ Filerange text_object_range(Text *txt, size_t pos, int (*isboundary)(int)) { return text_range_new(start, it.pos); } +static int is_number(int c) { + return !(c == '-' || c == 'x' || c == 'X' || + ('0' <= c && c <= '9') || + ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F')); +} + +Filerange text_object_number(Text *txt, size_t pos) { + char *buf, *err = NULL; + Filerange r = text_object_range(txt, pos, is_number); + if (!text_range_valid(&r)) + return r; + if (!(buf = text_bytes_alloc0(txt, r.start, text_range_size(&r)))) + return text_range_empty(); + errno = 0; + strtoll(buf, &err, 0); + if (errno || err == buf) + r = text_range_empty(); + else + r.end = r.start + (err - buf); + free(buf); + return r; +} + Filerange text_range_linewise(Text *txt, Filerange *rin) { Filerange rout = *rin; rout.start = text_line_begin(txt, rin->start); diff --git a/text-objects.h b/text-objects.h @@ -45,6 +45,8 @@ Filerange text_object_single_quote(Text*, size_t pos); Filerange text_object_backtick(Text*, size_t pos); /* text object delimited by arbitrary chars for which isboundary returns non-zero */ Filerange text_object_range(Text*, size_t pos, int (*isboundary)(int)); +/* a number in either decimal, hex or octal format */ +Filerange text_object_number(Text*, size_t pos); /* extend a range to cover whole lines */ Filerange text_range_linewise(Text*, Filerange*);