oh-my-fish/plugins/msg/msg.fish
Jorge Bucaran c76ce97d03 Add ability to escape -s and -n options using a backslash.
Add notes in comments about escaping.
2015-01-09 14:10:02 +09:00

165 lines
5.0 KiB
Fish

# __ _ ___ ___ _
# / ' \(_-</ _ `/
# /_/_/_/___/\_, /
# /___/ v0.1.0
# NAME
# msg - technicolor message printer
#
# SYNOPSIS
# msg [-sn] [@<fg:bg> | style]<text>[style]
#
# OPTIONS
# -s
# Do not separate arguments with spaces.
# -n
# Do not output a newline at the end of the message.
#
# STYLES
# _text_ Bold
# __text__ Underline
# ___text___ Bold and Underline
# `$variable` Apply @<styles> to $variables
# /directory/ Directories
# [url] Links
# \n Line Break
# \t Tab Space
#
# @<fg:bg> fg=bg=RGB|RRGGBB|name|random
# RGB value can be any three to six hex digit or color name.
# e.g, @0fb, @tomato, @random, @error, @ok.
#
# NOTES
# Escape style separators or options prepending a \ to the
# string if inside quotes `msg "\-s"` or a \\ backslash in
# order to escape the backslash itself when outside quotes.
#
# AUTHORS
# Jorge Bucaran <jbucaran@me.com>
#
# v. 0.1.0
#/
# Global `msg` default color and styles.
set --global msg_color_fg FFFFFF
set --global msg_color_bg normal
set --global msg_style_url 00FF00 $msg_color_bg -u
set --global msg_style_dir FFA500 $msg_color_bg -u
set --global msg_color_err FF0000
set --global msg_color_ok 00FA9A
function msg -d "Technicolor printer."
# Default " " whitespace between strings, skip with -s.
set -l ws " "
# Default \n newline after message, skip with -n.
set -l ln \n
switch (count $argv)
case 0
# Nothing to print here.
return 0
case \*
switch $argv[1]
# Options must appear joined and without spaces: -sn or -ns
case -s\* -n\*
# To use options at least a second parameter will be required.
if [ (count $argv) -gt 1 ]
# Use -s to not add spaces between words.
if msg.util.str.has "s" $argv[1]
set ws ""
end
# Use -n to not add a newline at the end of the message.
if msg.util.str.has "n" $argv[1]
set ln ""
end
# We are done with options, get rid of first item.
set argv $argv[2..-1]
else
return 0
end
end
end
# Print flow is get next style token, set style, get anything else, print
# and use the reset. set_color normal makes sure to reset both colors and
# bold / underline styles.
set -l reset (set_color normal)(set_color $msg_color_fg)
# Foreground and background color carried from previous @style token.
# These variables are set and reset via msg.util.set.color
set -l fg $msg_color_fg
set -l bg $msg_color_bg
for token in $argv
switch $token
# Parse style tokens:
# _txt_, __txt__, ___txt___, @color `$var`, /dir/, [url]
case ___\*___\* __\*__\* _\*_\* \[\*\]\* \/\*\/\* `\*`\*
set -l left _ # Begin of style
set -l right _ # End of style
set -l color $fg $bg -o
switch $token
case ___\*___\* __\*__\* _\*_\*
if msg.util.str.has __ $token
set color[3] -u
set left __
if msg.util.str.has ___ $token
set color[3] -uo
set left ___
end
end
case \[\*\]\*
set color $msg_style_url
set left [ ]
set right ]
case \/\*\/\*
set color $msg_style_dir
set left \/
set right \/
case `\*`\*
set color $fg $bg
set left `
set right `
end
# Extract text between left and right separators.
echo -n (msg.util.set.color $color)(msg.util.str.get $left $token)$reset
# Extract string after separator from the right.
echo -n (printf $token | sed "s/^.*\\$right\(.*\)/\1/")$ws
# Parse @fg:bg style tokens.
case @\*
set fg (printf $token | cut -c 2-) # @fg[:bg] → fg[:bg]
set bg (printf $fg | cut -d: -f 2) # fg:bg → fg|bg
set fg (printf $fg | cut -d: -f 1) # fg:bg → fg
# Do not let bg=fg have the same color unless the user wants to.
if [ $bg = $fg ]
if not msg.util.str.has : $token
set bg $msg_color_bg
end
end
# Make color string into valid RRGGBB hex format code.
set fg (msg.util.get.color $fg)
set bg (msg.util.get.color $bg)
# Everything else, print tokens, whitespace, etc.
case \*
set -l blank $ws
switch $token
# Do not print whitespace after the following characters.
case $argv[-1] \n\* \t\* \r
set blank ""
end
switch $token
# Escape -s -n options and style separators \\[text] \\/text/
case \\\[\* \\\/\* \\\_\* \\\-s \\\-n
set token (printf $token | sed "s/^\\\//")
end
echo -en (msg.util.set.color)$token$reset$blank
end
end
echo -en $ln
end