# External program with regex highlighting

**URL:** <https://discuss.kakoune.com/t/external-program-with-regex-highlighting/2435>\
**Category:** Uncategorized\
**Created:** [March 14, 2024, 3:28pm UTC](https://discuss.kakoune.com/t/external-program-with-regex-highlighting/2435 "2024-03-14T15:28:30Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![gypaetus](https://discuss.kakoune.com/letter_avatar_proxy/v4/letter/g/839c29/32.png) [@gypaetus](https://discuss.kakoune.com/u/gypaetus)\
**Post date:** [March 14, 2024, 3:28pm UTC](https://discuss.kakoune.com/t/external-program-with-regex-highlighting/2435/1 "2024-03-14T15:28:30Z")

</div>

I would like to run an external program on a regex highlight to determine the face of the match but could not figure out how to do it. For instance if the file contains dates in a certain format, I would like to run an external command with `date +%u $date` to determine the day of the week and highlight each of them with different colors.

---

<div class="post-metadata">

**Author:** ![cipharius](https://discuss.kakoune.com/user_avatar/discuss.kakoune.com/cipharius/32/184_2.png) [@cipharius](https://discuss.kakoune.com/u/cipharius)\
**Post date:** [March 14, 2024, 8:09pm UTC](https://discuss.kakoune.com/t/external-program-with-regex-highlighting/2435/2 "2024-03-14T20:09:20Z")

</div>

You should be able to do fine with shell expansion. For example:

```auto
:add-highlighter -override buffer/date-highlight regex %sh{date +%u date_value} 0:red

```

The override option is there so that you can invoke this command again to update which dates are highlighted. For multiple, different highlights you’d give them different name.

The `date_value` placeholder can either be manually written or you could define a kakoune option where you set it’s value, then you could access it with shell variable `$kak_opt_optionName`.

---

<div class="post-metadata">

**Author:** ![gypaetus](https://discuss.kakoune.com/letter_avatar_proxy/v4/letter/g/839c29/32.png) [@gypaetus](https://discuss.kakoune.com/u/gypaetus)\
**Post date:** [March 15, 2024, 8:26am UTC](https://discuss.kakoune.com/t/external-program-with-regex-highlighting/2435/3 "2024-03-15T08:26:51Z")

</div>

Sorry I did not explain clearly the problem I tried to solve. If a text file contains dates  
in the following format:

```auto
2024-01-01
2024-01-02

```

I would like to match them with a regex and then run an external command on each of these matches.

```auto
date +%u -d 2024-01-01
date +%u -d 2024-01-02

```

to determine the day of the week from 1 (Monday) to 7 (Sunday) for each date. Then I would  
like to use a different color for each day using a list defining 7 colors (red, green, yellow, …). This could be done with a shell script but I do not know how to interface the regex match in the highlighter with an external command in this way.

---

<div class="post-metadata">

**Author:** ![Screwtapello](https://discuss.kakoune.com/user_avatar/discuss.kakoune.com/screwtapello/32/12_2.png) [@Screwtapello](https://discuss.kakoune.com/u/Screwtapello)\
**Post date:** [March 16, 2024, 12:25pm UTC](https://discuss.kakoune.com/t/external-program-with-regex-highlighting/2435/4 "2024-03-16T12:25:30Z")

</div>

At a very high level, what you’ll need to do is:

- create seven “faces” (see `:set-face` and `:doc faces`), one for each day of the week, to describe how a date representing that day should be displayed
- create a `range-specs` option (see `:declare-option` and `:doc options types`), which will associate portions of the buffer with one of those faces
- add a `ranges` highlighter (see `:add-highlighter` and `:doc highlighters specs-highlighters`) that tells Kakoune to interpret the payload of each item in the `range-specs` option as a face to be applied to the text in the given range
- use a `NormalIdle` hook (or similar) to invoke your code after each time the buffer is modified
- in that hook:
  - initialise the option to an empty value
  - select all the dates with a regex (probably using `:execute-keys` to do a `%s...` operation)
  - for each selection (see `:evaluate-commands -itersel`), add an item to the option (`:set-option -add`) that uses the range of the current selection (`%val{selection_desc}`) and runs the `date` command on the contents of the selection (`%sh{ date +%u -d $kak_selection }`)

That’s kind of expensive, because it involves shelling out for every regex match. It might be possible to do something more efficient handling all of the dates at once, but it would also be more complex.

---

<div class="post-metadata">

**Author:** ![gypaetus](https://discuss.kakoune.com/letter_avatar_proxy/v4/letter/g/839c29/32.png) [@gypaetus](https://discuss.kakoune.com/u/gypaetus)\
**Post date:** [March 18, 2024, 10:12am UTC](https://discuss.kakoune.com/t/external-program-with-regex-highlighting/2435/5 "2024-03-18T10:12:14Z")

</div>

Excellent! Thank you very much.
