Created
March 14, 2012 08:48
-
-
Save a-square/2035172 to your computer and use it in GitHub Desktop.
Vimfix is a ruby script made to help port vim color schemes to xterm-256color terminals
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/ruby | |
class Array | |
# classic implementation using the left fold | |
# from StackOverflow | |
def min_index | |
champ = self.each_with_index.inject([1000, 0]) do |c, (v, i)| | |
cv = c[0]; ci = c[1]; | |
if v <= cv | |
[v, i] | |
else | |
[cv, ci] | |
end | |
end | |
champ[1] | |
end | |
end | |
class Rgb | |
attr_accessor :r, :g, :b | |
def initialize(r, g, b) | |
raise "Color components must be subtractible, 'r' is #{r.class}" unless r.respond_to? :- | |
raise "Color components must be subtractible, 'g' is #{g.class}" unless g.respond_to? :- | |
raise "Color components must be subtractible, 'b' is #{b.class}" unless b.respond_to? :- | |
@r = r; @g = g; @b = b | |
end | |
def self.from_s(string) | |
rgb = Rgb.from_hash(string) | |
return rgb unless rgb.nil? | |
rgb = Rgb.from_name(string) | |
return rgb # even if nil | |
end | |
def self.from_hash(hash) | |
hash.match(/#([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2})/) do |match| | |
return Rgb.new(match[1].hex, match[2].hex, match[3].hex) | |
end | |
nil | |
end | |
def self.from_name(name) | |
@@name2rgb.has_key?(name.downcase) ? @@name2rgb[name.downcase] : nil | |
end | |
def -(rgb) | |
raise "Must subtract an Rgb from an Rgb" unless rgb.instance_of? Rgb | |
Rgb.new(self.r - rgb.r, self.g - rgb.g, self.b - rgb.b) | |
end | |
# source: StackOverflow | |
# uses absolute values so that it could be used | |
# as a norm (not Euclidean, though) | |
def luma | |
0.2126 * @r.abs + 0.7152 * @g.abs + 0.0722 * @b.abs | |
end | |
def to_256 | |
# we add 16 to account for not using the standard colors | |
@@cterm2rgb.map { |x| (x - self).luma }.min_index + 16 | |
end | |
############################################# | |
# initialize the conversion table | |
############################################# | |
# initialize the array for the cterm => rgb conversion | |
@@cterm2rgb = Array.new | |
=begin | |
# removed to prevent 16 (remappable) colors from creeping in | |
@@cterm2rgb = [Rgb.from_hash('#000000'), | |
Rgb.from_hash('#800000'), | |
Rgb.from_hash('#008000'), | |
Rgb.from_hash('#808000'), | |
Rgb.from_hash('#000080'), | |
Rgb.from_hash('#800080'), | |
Rgb.from_hash('#008080'), | |
Rgb.from_hash('#c0c0c0'), | |
Rgb.from_hash('#808080'), | |
Rgb.from_hash('#ff0000'), | |
Rgb.from_hash('#00ff00'), | |
Rgb.from_hash('#ffff00'), | |
Rgb.from_hash('#0000ff'), | |
Rgb.from_hash('#ff00ff'), | |
Rgb.from_hash('#00ffff'), | |
Rgb.from_hash('#ffffff')] | |
=end | |
intensities = [0x00, 0x5f, 0x87, 0xaf, 0xdf, 0xff] | |
intensities.each do |r| | |
intensities.each do |g| | |
intensities.each do |b| | |
@@cterm2rgb << Rgb.new(r, g, b) | |
end | |
end | |
end | |
0.upto(23).each do |shade| | |
i = 0x08 + 10 * shade | |
@@cterm2rgb << Rgb.new(i, i, i) | |
end | |
# test output | |
# @@cterm2rgb.each_with_index { |x, i| puts i.to_s + ' ' + x.to_256.to_s } | |
############################################# | |
# initialize the X11 color names table | |
############################################# | |
@@name2rgb = Hash.new | |
File.open("/etc/X11/rgb.txt") do |file| | |
file.lines do |line| | |
# goes like r g b name | |
line.match(/\s*(\d+)\s*(\d+)\s*(\d+)\s*(\S+)/) do |match| | |
@@name2rgb[match[4].downcase] = Rgb.new(match[1].to_i, match[2].to_i, match[3].to_i) | |
end | |
end | |
end | |
end | |
# Reads vim color scheme from stdin, translates all rgb colors into their | |
# 256color counterparts, and outputs the fixed strings containing these numbers | |
# to stdout while also changing 'gui' => 'cterm'. | |
# | |
# Use it to quickly obtain cterm colors and them splice them back into the | |
# color scheme manually | |
$stdin.lines do |line| | |
result = line.gsub(/gui(\w*)=(#[[:digit:]]{6}|\S+)/) do |match| | |
parsed = Rgb.from_s($2) | |
out = parsed.nil? ? $2 : parsed.to_256 | |
"cterm#{$1}=#{out}" | |
end | |
# print only the lines that were changed | |
puts result.chomp unless result == line | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment