Module: Imaginator
Defined Under Namespace
Classes: Image
Instance Method Summary collapse
-
#cell_size ⇒ Object
- cell width px, cell height px
-
(Floats).
- #image_tooling? ⇒ Boolean
- #iterm_images? ⇒ Boolean
- #iterm_print_image(data:, r: nil, c: nil, io: $stdout) ⇒ Object
- #kitty_images? ⇒ Boolean
- #kitty_print_image(data:, r: nil, c: nil, io: $stdout) ⇒ Object
- #print_image ⇒ Object
- #term_features ⇒ Object
- #term_image_protocol ⇒ Object
- #term_seq(seq, end_marker) ⇒ Object
Instance Method Details
#cell_size ⇒ Object
- cell width px, cell height px
-
(Floats)
86 87 88 89 90 91 92 93 94 |
# File 'lib/imsg-grep/images/imaginator.rb', line 86 def cell_size # [cell width px, cell height px] (Floats) @cell_size ||= case when iterm = term_seq("\e]1337;ReportCellSize\e\\", ?\a)[/ReportCellSize=(.*)\e/, 1] iterm.split(?;).map{ Float it }.then{ |h, w, s| s ||= 1; [w*s, h*s] } # multiply by retina scale factor when csi16t = term_seq("\e[16t", ?t)[/\e\[6;(\d+;\d+)t/, 1] # ghostty csi16t.split(?;).map{ Float it }.reverse # else calc from TIOCGWINSZ or CSI14/18t, but this is enough for iterm, ghostty end end |
#image_tooling? ⇒ Boolean
106 |
# File 'lib/imsg-grep/images/imaginator.rb', line 106 def image_tooling? = !!(EXTENSION_AVAILABLE && term_image_protocol && cell_size) |
#iterm_images? ⇒ Boolean
83 |
# File 'lib/imsg-grep/images/imaginator.rb', line 83 def iterm_images? = @iterm_images ||= term_features&.include?(?F) |
#iterm_print_image(data:, r: nil, c: nil, io: $stdout) ⇒ Object
108 109 110 111 112 113 114 115 116 117 |
# File 'lib/imsg-grep/images/imaginator.rb', line 108 def iterm_print_image data:, r:nil, c:nil, io:$stdout head = "\e]1337;" io << head << "MultipartFile=inline=1;preserveAspectRatio=1" io << ";width=" << c if c io << ";height=" << r if r io << ?\a data = [data].pack("m0") (0...data.size).step(200).each{ io << head << "FilePart=" << data[it, 200] << ?\a } io << head << "FileEnd" << ?\a end |
#kitty_images? ⇒ Boolean
84 |
# File 'lib/imsg-grep/images/imaginator.rb', line 84 def kitty_images? = @kitty_images ||= term_seq("\e_Gi=31,s=1,v=1,a=q,t=d,f=24;AAAA\e\\", "\e\\") == "\e_Gi=31;OK\e\\" |
#kitty_print_image(data:, r: nil, c: nil, io: $stdout) ⇒ Object
119 120 121 122 123 124 |
# File 'lib/imsg-grep/images/imaginator.rb', line 119 def kitty_print_image data:, r:nil, c:nil, io:$stdout io << "\e_Gf=100,a=T,t=d" io << ",c=" << c if c io << ",r=" << r if r io << ?; << [data].pack("m0") << "\e\\" end |
#print_image ⇒ Object
126 127 128 129 130 131 132 |
# File 'lib/imsg-grep/images/imaginator.rb', line 126 def print_image(...) return unless image_tooling? case term_image_protocol when :iterm then iterm_print_image(...) when :kitty then kitty_print_image(...) end end |
#term_features ⇒ Object
82 |
# File 'lib/imsg-grep/images/imaginator.rb', line 82 def term_features = @term_features ||= (term_seq("\e]1337;Capabilities\e\\", ?\a) =~ /Capabilities=([A-Za-z0-9]*)/ and $1.scan(/[A-Z][a-z]?\d*/)) |
#term_image_protocol ⇒ Object
96 97 98 99 100 101 102 103 104 |
# File 'lib/imsg-grep/images/imaginator.rb', line 96 def term_image_protocol return @term_image_protocol unless @term_image_protocol.nil? @term_image_protocol = case when ENV["TERM_PROGRAM"] == "Apple_Terminal" then false # it echoes back the kitty query and I don't wanna figure out how not to when iterm_images? then :iterm # has to go before kitty as iterm responds ok to kitty query but can't render them when kitty_images? then :kitty # you're a kitty! yes you are! and you're sitting there! hi, kitty! else false end end |
#term_seq(seq, end_marker) ⇒ Object
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/imsg-grep/images/imaginator.rb', line 64 def term_seq(seq, end_marker) t = ->{ Process.clock_gettime Process::CLOCK_MONOTONIC } buf = "" IO.console.raw do |tty| tty << seq tty.flush timeout = t.() + 0.1 loop do buf << tty.read_nonblock(1) break if buf.end_with? end_marker rescue IO::WaitReadable break if t.() > timeout IO.select([tty], nil, nil, 0.01) end end buf end |