Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Discussion options

I write some great fish aliases and forget to use them, so I wanted something that would remind me. I asked ChatGPT to whip something up and I've been trying to get the function in a shape that I'd like. However, my biggest problem is that neither I nor it can find a way to split a string properly.

Here's the script itself:

function __tip_of_the_day --description 'Show a (fish) tip-of-the-day'
    set -l tips_file ~/.config/fish/tips.txt
    test -f $tips_file; or return

    set -l content (string collect < $tips_file)
    set --show content
    set -l tips (string split0 --no-empty -- "\n%%\n" -- $content)
    set -l count (count $tips)
    test $count -gt 0; or return
    
    set --show tips
    for i in (seq (count $tips))
        printf '--- tip %d start ---\n%s\n--- tip %d end ---\n' $i $tips[$i] $i
    end

    set -l today (date "+%Y-%m-%d")

    if not command -q sha256sum; echo "__tip_of_the_day: need sha256sum" >&2; return; end

    set -l sha (printf "%s" $today | sha1sum)
    printf "sha:  %s\n" "$sha"

    set -l hex8 (string sub --start 1 --length 8 -- "$sha")
    printf "hex8: %s\n" "$hex8"

    set -l num (math "0x$hex8")
    printf "num:  %s\n" $num

    set -l idx (math "($num % $count) + 1")
    printf "idx:  %s\n" $idx

    set -l tip "$tips[$idx]"

    set_color brcyan
    echo "# Tip of the day"
    set_color normal
    echo
    printf "%s\n" "$tip"
    echo
end

And here's the contents of $tips_file:

Use ⌃R (Ctrl-R) to search command history
and press → to accept the autosuggestion.

%%

You can edit the last command quickly:
  alt+e (open in $EDITOR)  or
  alt+↑ / alt+↓ to move through history.

%%

`fzf` pairs great with Fish:
  alias fzfcd='cd (find . -type d | fzf)'

And here's what I get when I run it today (August 31, 2025):

$content: set in local scope, unexported, with 1 elements
$content[1]: |Use ⌃R (Ctrl-R) to search command history\nand press → to accept the autosuggestion.\n\n%%\n\nYou can edit the last command quickly:\n  alt+e (open in $EDITOR)  or\n  alt+↑ / alt+↓ to move through history.\n\n%%\n\n`fzf` pairs great with Fish:\n  alias fzfcd='cd (find . -type d | fzf)'|
$tips: set in local scope, unexported, with 3 elements
$tips[1]: |\\n%%\\n|
$tips[2]: |--|
$tips[3]: |Use ⌃R (Ctrl-R) to search command history\nand press → to accept the autosuggestion.\n\n%%\n\nYou can edit the last command quickly:\n  alt+e (open in $EDITOR)  or\n  alt+↑ / alt+↓ to move through history.\n\n%%\n\n`fzf` pairs great with Fish:\n  alias fzfcd='cd (find . -type d | fzf)'|
--- tip 1 start ---
\n%%\n
--- tip 1 end ---
--- tip 2 start ---
--
--- tip 2 end ---
--- tip 3 start ---
Use ⌃R (Ctrl-R) to search command history
and press → to accept the autosuggestion.

%%

You can edit the last command quickly:
  alt+e (open in $EDITOR)  or
  alt+↑ / alt+↓ to move through history.

%%

`fzf` pairs great with Fish:
  alias fzfcd='cd (find . -type d | fzf)'
--- tip 3 end ---
sha:  59b86b658d9d1528d37ce008a993c78a885883d1  -
hex8: 59b86b65
num:  1505258341
idx:  2
# Tip of the day

--

$tips is all messed up, and reading man string isn't helping me figure out the right way. I've tried fiddling around with the definition of $tips, but it's amounting to a random walk at this point and I'm not getting anywhere. What should I be doing?

You must be logged in to vote

If you change line 7 from

set -l tips (string split0 --no-empty -- "\n%%\n" -- $content)

to

set -l tips (string split --no-empty -- \n"%%"\n $content)

it will work as you intend it to. Or at least the tips part will, I'm not entirely certain if the sha part will, as I don't actually have sha256sum on the system I'm using and couldn't test that part. I do have a sha256 and sha1, and just substituting those always returned whatever was in index 2 for me. I'm unsure if those commands are equivalent, though. I'm running it on OpenBSD, and not sure if I could get sha1sum - a quick package scan didn't turn anything up.

Three things with that line:

  1. You want to use split not split0. split0 does …

Replies: 1 comment · 1 reply

Comment options

If you change line 7 from

set -l tips (string split0 --no-empty -- "\n%%\n" -- $content)

to

set -l tips (string split --no-empty -- \n"%%"\n $content)

it will work as you intend it to. Or at least the tips part will, I'm not entirely certain if the sha part will, as I don't actually have sha256sum on the system I'm using and couldn't test that part. I do have a sha256 and sha1, and just substituting those always returned whatever was in index 2 for me. I'm unsure if those commands are equivalent, though. I'm running it on OpenBSD, and not sure if I could get sha1sum - a quick package scan didn't turn anything up.

Three things with that line:

  1. You want to use split not split0. split0 does not take a separator, it only splits on NULs (not newlines)
  2. string does not interpret backslash characters inside quotes, so you have to put the \n outside
  3. You have an extra -- in there before $content - string will consider that a string to work on in addition to $content. The -- means that is the end of the option flags and the rest are to be taken as is. The first -- is the only one you need, any other ones will just be taken as a literal --. For example, if you wrote it as string split -- --no-empty -- \n"%%"\n $content, it would
    a) Take --no-empty as the string to split on (literally, including the --)
    b) Have the string that is being split be -- \n"%%"\n $content ($content being whatever is in that variable)

You might also want to remove the blank lines before and after the %% in your tips.txt file. Those empty lines will be part of the tip. Alternatively, you can make the separator be \n\n"%%"\n\n.

You must be logged in to vote
1 reply
@adiabatic
Comment options

“put the \ns outside of the double-quoted string” was not on my bingo card. Thanks!

Answer selected by adiabatic
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
🙏
Q&A
Labels
None yet
2 participants
Morty Proxy This is a proxified and sanitized view of the page, visit original site.