Skip to content

Instantly share code, notes, and snippets.

@pxsta
Last active November 21, 2025 18:10
Show Gist options
  • Select an option

  • Save pxsta/5f86092eec0d611c2770 to your computer and use it in GitHub Desktop.

Select an option

Save pxsta/5f86092eec0d611c2770 to your computer and use it in GitHub Desktop.

Revisions

  1. pxsta renamed this gist Jul 9, 2019. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  2. pxsta revised this gist Jul 9, 2019. 1 changed file with 24 additions and 0 deletions.
    24 changes: 24 additions & 0 deletions LICENSE
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,24 @@
    This is free and unencumbered software released into the public domain.

    Anyone is free to copy, modify, publish, use, compile, sell, or
    distribute this software, either in source code form or as a compiled
    binary, for any purpose, commercial or non-commercial, and by any
    means.

    In jurisdictions that recognize copyright laws, the author or authors
    of this software dedicate any and all copyright interest in the
    software to the public domain. We make this dedication for the benefit
    of the public at large and to the detriment of our heirs and
    successors. We intend this dedication to be an overt act of
    relinquishment in perpetuity of all present and future rights to this
    software under copyright law.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
    OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
    ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
    OTHER DEALINGS IN THE SOFTWARE.

    For more information, please refer to <https://unlicense.org>
  3. pxsta revised this gist Nov 21, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion tmux-highlight-text-patch-README.md
    Original file line number Diff line number Diff line change
    @@ -13,7 +13,7 @@ usage
    git clone https://github.com/tmux/tmux.git
    cd tmux
    git checkout -b v2.1 2.1
    wget https://gist.githubusercontent.com/pxsta/5f86092eec0d611c2770/raw/1f5356f30378dac50e9bd8f1194bc812fd1a88a6/tmux-highlight-text.patch
    wget https://gist.githubusercontent.com/pxsta/5f86092eec0d611c2770/raw/tmux-highlight-text.patch
    patch --dry-run -p0 < tmux-highlight-text.patch
    patch -p0 < tmux-highlight-text.patch
    sh autogen.sh
  4. pxsta revised this gist Nov 18, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion tmux-highlight-text-patch-README.md
    Original file line number Diff line number Diff line change
    @@ -35,7 +35,7 @@ set-option -g trigger-highlight "Regular Expression" "Colour" IgnoreCase
    When some text matches this regular expression, tmux highlights them.

    + `Colour` :
    Put 'Coulour[0-255]' like other *-fg options.
    Put 'coulour[0-255]' like other *-fg options.

    + `IgnoreCase ` :
    If ignorecase put 1, otherwise put 0.
  5. pxsta revised this gist Nov 17, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion tmux-highlight-text-patch-README.md
    Original file line number Diff line number Diff line change
    @@ -11,8 +11,8 @@ usage

    ```bash
    git clone https://github.com/tmux/tmux.git
    git checkout -b v2.1 2.1
    cd tmux
    git checkout -b v2.1 2.1
    wget https://gist.githubusercontent.com/pxsta/5f86092eec0d611c2770/raw/1f5356f30378dac50e9bd8f1194bc812fd1a88a6/tmux-highlight-text.patch
    patch --dry-run -p0 < tmux-highlight-text.patch
    patch -p0 < tmux-highlight-text.patch
  6. pxsta revised this gist Nov 17, 2015. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion tmux-highlight-text-patch-README.md
    Original file line number Diff line number Diff line change
    @@ -10,13 +10,15 @@ usage
    ### install ###

    ```bash
    git clone -b 2.1 https://github.com/tmux/tmux.git
    git clone https://github.com/tmux/tmux.git
    git checkout -b v2.1 2.1
    cd tmux
    wget https://gist.githubusercontent.com/pxsta/5f86092eec0d611c2770/raw/1f5356f30378dac50e9bd8f1194bc812fd1a88a6/tmux-highlight-text.patch
    patch --dry-run -p0 < tmux-highlight-text.patch
    patch -p0 < tmux-highlight-text.patch
    sh autogen.sh
    ./configure && make
    make install
    ```


  7. pxsta revised this gist Nov 17, 2015. 1 changed file with 4 additions and 1 deletion.
    5 changes: 4 additions & 1 deletion tmux-highlight-text-patch-README.md
    Original file line number Diff line number Diff line change
    @@ -2,14 +2,17 @@ tmux-highlight-text.patch
    ======================
    This patch enables tmux to highlight the text like iTerm2.
    When some text in the terminal matches the regular expression set in tmux.conf, tmux highlights them.


    ![patch gif](https://gist.githubusercontent.com/pxsta/5f86092eec0d611c2770/raw/1f5356f30378dac50e9bd8f1194bc812fd1a88a6/tmux-highlight-text.gif)

    usage
    ------
    ### install ###

    ```bash
    git clone -b 2.1 https://github.com/tmux/tmux.git
    cd tmux
    wget https://gist.githubusercontent.com/pxsta/5f86092eec0d611c2770/raw/1f5356f30378dac50e9bd8f1194bc812fd1a88a6/tmux-highlight-text.patch
    patch --dry-run -p0 < tmux-highlight-text.patch
    patch -p0 < tmux-highlight-text.patch
    sh autogen.sh
  8. pxsta revised this gist Nov 17, 2015. 2 changed files with 0 additions and 0 deletions.
    Binary file added tmux-highlight-text.gif
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
    Binary file added tmux-highlight-text.jpg
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
  9. pxsta revised this gist Nov 17, 2015. No changes.
  10. pxsta created this gist Nov 17, 2015.
    44 changes: 44 additions & 0 deletions tmux-highlight-text-patch-README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,44 @@
    tmux-highlight-text.patch
    ======================
    This patch enables tmux to highlight the text like iTerm2.
    When some text in the terminal matches the regular expression set in tmux.conf, tmux highlights them.

    usage
    ------
    ### install ###

    ```bash
    git clone -b 2.1 https://github.com/tmux/tmux.git
    cd tmux
    patch --dry-run -p0 < tmux-highlight-text.patch
    patch -p0 < tmux-highlight-text.patch
    sh autogen.sh
    ./configure && make
    ```



    ### config ###

    Write like this at the '.tmux.conf'.

    ```
    set-option -g trigger-highlight "Regular Expression" "Colour" IgnoreCase
    ```

    + `Regular Expression` :
    When some text matches this regular expression, tmux highlights them.

    + `Colour` :
    Put 'Coulour[0-255]' like other *-fg options.

    + `IgnoreCase ` :
    If ignorecase put 1, otherwise put 0.

    ### example ###

    ```
    set-option -g trigger-highlight "error|fail|fatal" colour9 1
    set-option -g trigger-highlight "note" colour96 1
    set-option -g trigger-highlight "warning" colour93 1
    ```
    266 changes: 266 additions & 0 deletions tmux-highlight-text.patch
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,266 @@
    diff --git Makefile.am Makefile.am
    index 8b39ccf..711231f 100644
    --- Makefile.am
    +++ Makefile.am
    @@ -139,6 +139,7 @@ dist_tmux_SOURCES = \
    grid-cell.c \
    grid-view.c \
    grid.c \
    + highlight.c \
    input-keys.c \
    input.c \
    job.c \
    diff --git cmd-set-option.c cmd-set-option.c
    index e0b07ed..8476fc3 100644
    --- cmd-set-option.c
    +++ cmd-set-option.c
    @@ -63,10 +63,13 @@ struct options_entry *cmd_set_option_choice(struct cmd *, struct cmd_q *,
    struct options_entry *cmd_set_option_style(struct cmd *, struct cmd_q *,
    const struct options_table_entry *, struct options *,
    const char *);
    +struct options_entry *cmd_set_highlight(struct cmd *, struct cmd_q *,
    + const struct options_table_entry *, struct options *,
    + const char *);

    const struct cmd_entry cmd_set_option_entry = {
    "set-option", "set",
    - "agoqst:uw", 1, 2,
    + "agoqst:uw", 1, 4,
    "[-agosquw] [-t target-session|target-window] option [value]",
    0,
    cmd_set_option_exec
    @@ -342,6 +345,10 @@ cmd_set_option_set(struct cmd *self, struct cmd_q *cmdq,
    case OPTIONS_TABLE_STYLE:
    o = cmd_set_option_style(self, cmdq, oe, oo, value);
    break;
    + case OPTIONS_TABLE_HIGHLIGHT:
    + o = cmd_set_highlight(self, cmdq, oe, oo, value);
    + break;
    +
    }
    if (o == NULL)
    return (-1);
    @@ -404,6 +411,25 @@ cmd_set_option_key(unused struct cmd *self, struct cmd_q *cmdq,
    return (options_set_number(oo, oe->name, key));
    }

    +/* Set a highlight option. */
    +struct options_entry *
    +cmd_set_highlight(unused struct cmd *self, struct cmd_q *cmdq,
    + const struct options_table_entry *oe, struct options *oo,
    + const char *value)
    +{
    + int fg, ignorecase;
    +
    + if (self->args->argc < 4) {
    + cmdq_error(cmdq, "bad argument count : %d", self->args->argc);
    + return (NULL);
    + }
    +
    + fg = colour_fromstring(self->args->argv[2]);
    + ignorecase = atoi(self->args->argv[3]);
    + add_highlight(value,fg, ignorecase);
    + return (options_set_number(oo,oe->name,fg));
    +}
    +
    /* Set a colour option. */
    struct options_entry *
    cmd_set_option_colour(unused struct cmd *self, struct cmd_q *cmdq,
    diff --git highlight.c highlight.c
    new file mode 100644
    index 0000000..c297833
    --- /dev/null
    +++ highlight.c
    @@ -0,0 +1,69 @@
    +#include <stdlib.h>
    +#include <string.h>
    +#include <regex.h>
    +
    +#include "tmux.h"
    +
    +struct highlightlist all_highlights = LIST_HEAD_INITIALIZER(all_highlights);
    +
    +int add_highlight(const char *regstr, int fg, int ignorecase){
    + struct highlight *tmp_highlight, *new_highlight;
    + int flags=REG_EXTENDED | REG_NEWLINE;
    +
    + LIST_FOREACH(tmp_highlight, &all_highlights, lentry) {
    + if (strcmp(tmp_highlight->regstr, regstr) == 0 && tmp_highlight->ignorecase == ignorecase) {
    + free(tmp_highlight->regstr);
    + regfree(&tmp_highlight->reg);
    + tmp_highlight->regstr = xmalloc(sizeof(char)*strlen(regstr));
    + strcpy(tmp_highlight->regstr, regstr);
    + tmp_highlight->fg = fg;
    + tmp_highlight->ignorecase = ignorecase;
    + if(tmp_highlight->ignorecase){
    + flags |= REG_ICASE;
    + }
    + if (regcomp(&tmp_highlight->reg, tmp_highlight->regstr, flags) != 0) {
    + fprintf(stderr, "regex compile failed");
    + return 1;
    + }
    + return 0;
    + }
    + }
    + new_highlight = xmalloc(sizeof(struct highlight));
    + new_highlight->regstr = xmalloc(sizeof(char)*strlen(regstr));
    + strcpy(new_highlight->regstr, regstr);
    + new_highlight->fg = fg;
    + new_highlight->ignorecase = ignorecase;
    + if (new_highlight->ignorecase) {
    + flags |= REG_ICASE;
    + }
    + if (regcomp(&new_highlight->reg, new_highlight->regstr, flags) != 0) {
    + fprintf(stderr, "regex compile failed");
    + return 1;
    + }
    +
    + LIST_INSERT_HEAD(&all_highlights, new_highlight, lentry);
    + return 0;
    +}
    +
    +struct highlight_search_result find_highlight_target(const u_char *target){
    + struct highlight *tmp_highlight;
    + struct highlight_search_result res = {.find = 0, .start = 0, .end = 0};
    + regmatch_t patternMatch;
    +
    + LIST_FOREACH(tmp_highlight, &all_highlights, lentry) {
    + if (regexec(&tmp_highlight->reg, target, 1, &patternMatch, 0) == 0){
    + regoff_t tmp_startIndex = patternMatch.rm_so;
    + regoff_t tmp_endIndex = patternMatch.rm_eo;
    + if (tmp_startIndex == -1 || tmp_endIndex == -1) {
    + continue;
    + }
    + if (res.find == 0 || tmp_startIndex < res.start) {
    + res.start = tmp_startIndex;
    + res.end = tmp_endIndex;
    + res.fg = tmp_highlight->fg;
    + }
    + res.find = 1;
    + }
    + }
    + return res;
    +}
    diff --git input.c input.c
    index ab56fc3..a45212c 100644
    --- input.c
    +++ input.c
    @@ -47,6 +47,9 @@
    * be passed to the underlying terminals.
    */

    +/* To restore the original fg after the highlighting */
    +int original_fg = -1;
    +
    /* Input parser cell. */
    struct input_cell {
    struct grid_cell cell;
    @@ -840,6 +843,9 @@ input_parse(struct window_pane *wp)
    struct evbuffer *evb = wp->event->input;
    u_char *buf;
    size_t len, off;
    + struct highlight_search_result search_res = {.find = 0};
    + size_t startIndex = 0;
    + size_t endIndex = 0;

    if (EVBUFFER_LENGTH(evb) == 0)
    return;
    @@ -869,6 +875,26 @@ input_parse(struct window_pane *wp)
    while (off < len) {
    ictx->ch = buf[off++];

    + if (off > endIndex) {
    + if (original_fg >= 0) {
    + ictx->cell.cell.fg = original_fg;
    + original_fg = -1;
    + }
    +
    + search_res = find_highlight_target((u_char*)((unsigned long)buf+endIndex));
    + if (search_res.find) {
    + startIndex = endIndex + search_res.start;
    + endIndex = endIndex + search_res.end;
    + }
    + }
    +
    + if (search_res.find && startIndex < off && off <= endIndex) {
    + if (original_fg == -1) {
    + original_fg = ictx->cell.cell.fg;
    + }
    + ictx->cell.cell.fg = search_res.fg;
    + }
    +
    /* Find the transition. */
    itr = ictx->state->transitions;
    while (itr->first != -1 && itr->last != -1) {
    diff --git options-table.c options-table.c
    index e901e24..cbb826f 100644
    --- options-table.c
    +++ options-table.c
    @@ -782,6 +782,10 @@ const struct options_table_entry window_options_table[] = {
    .type = OPTIONS_TABLE_FLAG,
    .default_num = 0
    },
    + { .name = "trigger-highlight",
    + .type = OPTIONS_TABLE_HIGHLIGHT,
    + .default_num = -1
    + },

    { .name = NULL }
    };
    diff --git tmux.h tmux.h
    index 4d19a5a..a466240 100644
    --- tmux.h
    +++ tmux.h
    @@ -29,6 +29,7 @@
    #include <stdarg.h>
    #include <stdio.h>
    #include <termios.h>
    +#include <regex.h>

    #ifdef HAVE_UTEMPTER
    #include <utempter.h>
    @@ -710,6 +711,22 @@ struct job {
    };
    LIST_HEAD(joblist, job);

    +struct highlight{
    + char *regstr;
    + regex_t reg;
    + int fg;
    + int ignorecase;
    + LIST_ENTRY(highlight) lentry;
    +};
    +
    +struct highlight_search_result{
    + int find;
    + off_t start;
    + off_t end;
    + int fg;
    +};
    +LIST_HEAD(highlightlist, highlight);
    +
    /* Screen selection. */
    struct screen_sel {
    int flag;
    @@ -1376,7 +1393,8 @@ enum options_table_type {
    OPTIONS_TABLE_ATTRIBUTES,
    OPTIONS_TABLE_FLAG,
    OPTIONS_TABLE_CHOICE,
    - OPTIONS_TABLE_STYLE
    + OPTIONS_TABLE_STYLE,
    + OPTIONS_TABLE_HIGHLIGHT
    };

    struct options_table_entry {
    @@ -1532,6 +1550,11 @@ struct job *job_run(const char *, struct session *, int,
    void job_free(struct job *);
    void job_died(struct job *, int);

    +/* highlight.c */
    +extern struct highlightlist all_highlights;
    +int add_highlight(const char *, int, int);
    +struct highlight_search_result find_highlight_target(const u_char *);
    +
    /* environ.c */
    int environ_cmp(struct environ_entry *, struct environ_entry *);
    RB_PROTOTYPE(environ, environ_entry, entry, environ_cmp);