Eshu

 view release on metacpan or  search on metacpan

include/eshu_bash.h  view on Meta::CPAN

			}
		}

		/* ── blank line: preserve, no indent change ── */
		if (is_blank) {
			if (eol < end) eshu_buf_putc(&out, '\n');
			p = (eol < end) ? eol + 1 : eol;
			lineno++;
			continue;
		}

		/* ── scan line for depth deltas ── */
		delta = eshu_bash_scan_line(&ctx, content, content_len);

		/* ── apply pre-delta, clamp depth ── */
		ctx.depth += delta.pre;
		if (ctx.depth < 0) ctx.depth = 0;

		/* ── emit (only if in range) ── */
		if (eshu_in_range(cfg, lineno)) {
			eshu_emit_indent(&out, ctx.depth, cfg);
		} else {
			/* out-of-range: preserve original leading whitespace */
			eshu_buf_write(&out, line_start, (size_t)(content - line_start));
		}

		/* emit trimmed content */
		eshu_buf_write_trimmed(&out, content, (int)(eol - content));
		if (eol < end) eshu_buf_putc(&out, '\n');

		/* ── apply post-delta ── */
		ctx.depth += delta.post;
		if (ctx.depth < 0) ctx.depth = 0;

		p = (eol < end) ? eol + 1 : eol;
		lineno++;
	}

	eshu_buf_putc(&out, '\0');
	*out_len = out.len - 1;
	return out.data;
}


#include "eshu_hl_util.h"

/* ══════════════════════════════════════════════════════════════════
 *  Bash keyword and builtin lists
 * ══════════════════════════════════════════════════════════════════ */

static const char * const eshu_hl_bash_kw[] = {
    "break", "case", "continue", "do", "done", "elif", "else",
    "esac", "eval", "exit", "export", "false", "fi", "for",
    "function", "if", "in", "local", "readonly", "return",
    "select", "set", "shift", "source", "then", "trap",
    "true", "typeset", "unset", "until", "while",
    NULL
};

static const char * const eshu_hl_bash_bi[] = {
    "alias", "awk", "basename", "cat", "cd", "chmod", "chown",
    "cp", "cut", "date", "declare", "dirname", "echo", "exec",
    "find", "getopts", "grep", "head", "kill", "ln", "ls",
    "mkdir", "mktemp", "mv", "printf", "pwd", "read", "rm",
    "rmdir", "sed", "sleep", "sort", "tail", "test", "touch",
    "tr", "uniq", "wc", "xargs",
    NULL
};

/* ══════════════════════════════════════════════════════════════════
 *  Bash highlighter
 * ══════════════════════════════════════════════════════════════════ */

static char *eshu_highlight_bash(const char *src, size_t src_len, size_t *out_len) {
    eshu_buf_t  out;
    const char *p     = src;
    const char *end   = src + src_len;
    const char *plain = p;
    int         at_bol = 1;

    eshu_buf_init(&out, src_len * 2 + 64);

#define BASH_SPAN(cls, ts, te) do { \
    eshu_hl_flush(&out, plain, (ts)); \
    eshu_hl_span(&out, (cls), (ts), (te)); \
    p = (te); plain = p; \
} while(0)

    while (p < end) {
        char c = *p;

        /* comment: # to EOL */
        if (c == '#') {
            const char *ts = p;
            while (p < end && *p != '\n') p++;
            BASH_SPAN("esh-c", ts, p);
            at_bol = 0;
            continue;
        }

        /* heredoc start: <<[-] — highlight operator, body emitted as plain later */
        if (c == '<' && p + 1 < end && *(p + 1) == '<') {
            const char *ts = p;
            p += 2;
            if (p < end && *p == '-') p++;
            /* consume optional quote and tag name */
            char qc = 0;
            if (p < end && (*p == '\'' || *p == '"' || *p == '`')) qc = *p++;
            while (p < end && *p != '\n' && *p != '\r' &&
                   (qc ? *p != qc : (isalnum((unsigned char)*p) || *p == '_')))
                p++;
            if (qc && p < end && *p == qc) p++;
            BASH_SPAN("esh-h", ts, p);
            at_bol = 0;
            continue;
        }

        /* $'...' ANSI-C quoted string */
        if (c == '$' && p + 1 < end && *(p + 1) == '\'') {
            const char *ts = p;
            p += 2;



( run in 1.358 second using v1.01-cache-2.11-cpan-92ad3014f07 )