aboutsummaryrefslogtreecommitdiff
path: root/src/work.c
diff options
context:
space:
mode:
authorThomas Voss <mail@thomasvoss.com> 2024-11-01 21:43:01 +0100
committerThomas Voss <mail@thomasvoss.com> 2024-11-01 21:43:01 +0100
commit4f41e06880f4d9b979ec001da5046373cd867c2f (patch)
treef084ed93e8387e3fa814aa17dee80b5a263bf81b /src/work.c
parent420d354fffa1e69f050ba32d8521c6d84c4f8dd1 (diff)
Add -H
Diffstat (limited to 'src/work.c')
-rw-r--r--src/work.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/src/work.c b/src/work.c
index bf66fdb..c8a3e21 100644
--- a/src/work.c
+++ b/src/work.c
@@ -18,6 +18,7 @@
#include <macros.h>
#include <mbstring.h>
#include <pcre2.h>
+#include <rune.h>
#include <unicode/string.h>
#include "exitcodes.h"
@@ -39,6 +40,7 @@ typedef struct {
} pos_state_t;
static void compute_pos(const char8_t *p, pos_state_t *ps);
+static bool has_lbrk_p(u8view_t sv);
static bool islbrk(u8view_t g);
static int svposcmp(const void *a, const void *b);
static void write_match_to_buffer(u8view_t sv, u8view_t *hl);
@@ -375,6 +377,15 @@ write_match_to_buffer(u8view_t sv, u8view_t *hl)
array_extend_sv(buf, COL_SE);
array_push(buf, sep);
array_extend_sv(buf, COL_RS);
+
+ switch (flags.H) {
+ case HDR_ALWAYS:
+ array_push(buf, '\n');
+ break;
+ case HDR_MULTI:
+ if (has_lbrk_p(sv))
+ array_push(buf, '\n');
+ }
}
#pragma GCC diagnostic pop
@@ -453,6 +464,25 @@ compute_pos(const char8_t *p, pos_state_t *ps)
}
bool
+has_lbrk_p(u8view_t sv)
+{
+ rune ch;
+ while (ucsnext(&ch, &sv) != 0) {
+ switch (ch) {
+ case '\r': /* Not *really* a newline, but it can mess with output */
+ case '\n':
+ case '\v':
+ case '\f':
+ case 0x85:
+ case RUNE_C(0x2028):
+ case RUNE_C(0x2029):
+ return true;
+ }
+ }
+ return false;
+}
+
+bool
islbrk(u8view_t g)
{
return ucseq(g, U8("\n"))