Skip to content

Instantly share code, notes, and snippets.

@ttscoff
Created July 1, 2022 15:26
Embed
What would you like to do?
Get the current ANSI color sequence at the point a string ends
#!/usr/bin/env ruby
# frozen_string_literal: true
# String color helpers
class ::String
ESCAPE_REGEX = /(?<=\[)(?:(?:(?:[349]|10)[0-9]|[0-9])?;?)+(?=m)/.freeze
# Get the calculated ANSI color at the end of the string
#
# If you want to inject a colored string into another
# string on the console, you want the color to return to
# what it was before the inserted string when the inserted
# string ends. This gets you that previous color.
#
# @return ANSI escape sequence to match previous color
#
def last_color_code
m = scan(ESCAPE_REGEX)
em = ['0']
fg, bg, rgbf, rgbb = nil
m.each do |c|
case c
when '0'
em = ['0']
fg, bg, rgbf, rgbb = nil
when /^[34]8/
case c
when /^3/
fg = nil
rgbf = c
when /^4/
bg = nil
rgbb = c
end
else
c.split(/;/).each do |i|
x = i.to_i
if x <= 9
em << x
elsif x >= 30 && x <= 39
rgbf = nil
fg = x
elsif x >= 40 && x <= 49
rgbb = nil
bg = x
elsif x >= 90 && x <= 97
rgbf = nil
fg = x
elsif x >= 100 && x <= 107
rgbb = nil
bg = x
end
end
end
end
escape = "\e[#{em.join(';')}m"
escape += "\e[#{rgbb}m" if rgbb
escape += "\e[#{rgbf}m" if rgbf
escape + "\e[#{[fg, bg].delete_if(&:nil?).join(';')}m"
end
end
str = "\e[1;31;47mHe\e[38;2;144;10;38mllo\e[4mThereHowAre"
puts "#{str} \e[0m\e[0;31;43m\e[7mHIGHLIGHT #{str.last_color_code}RESET"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment