epitools 0.5.7 → 0.5.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/VERSION +1 -1
 - data/epitools.gemspec +3 -3
 - data/lib/epitools/autoloads.rb +1 -0
 - data/lib/epitools/core_ext.rb +85 -33
 - data/lib/epitools/core_ext/array.rb +16 -13
 - data/lib/epitools/core_ext/enumerable.rb +27 -0
 - data/lib/epitools/hexdump.rb +47 -38
 - data/lib/epitools/iter.rb +1 -1
 - data/lib/epitools/numwords.rb +1 -1
 - data/lib/epitools/path.rb +215 -185
 - data/lib/epitools/sys.rb +25 -1
 - data/lib/epitools/term.rb +37 -31
 - data/lib/epitools/wm.rb +293 -2
 - data/spec/core_ext_spec.rb +20 -1
 - data/spec/path_spec.rb +95 -87
 - data/spec/wm_spec.rb +10 -0
 - metadata +3 -3
 
    
        data/lib/epitools/sys.rb
    CHANGED
    
    | 
         @@ -65,6 +65,7 @@ module Sys 
     | 
|
| 
       65 
65 
     | 
    
         | 
| 
       66 
66 
     | 
    
         
             
              PS_FIELD_TABLE = [
         
     | 
| 
       67 
67 
     | 
    
         
             
                [:pid,    :to_i],
         
     | 
| 
      
 68 
     | 
    
         
            +
                [:ppid,   :to_i],
         
     | 
| 
       68 
69 
     | 
    
         
             
                [:pcpu,   :to_f],
         
     | 
| 
       69 
70 
     | 
    
         
             
                [:pmem,   :to_f],
         
     | 
| 
       70 
71 
     | 
    
         
             
                [:stat,   :to_s],
         
     | 
| 
         @@ -147,6 +148,15 @@ module Sys 
     | 
|
| 
       147 
148 
     | 
    
         
             
                  super(*args)
         
     | 
| 
       148 
149 
     | 
    
         
             
                end
         
     | 
| 
       149 
150 
     | 
    
         | 
| 
      
 151 
     | 
    
         
            +
                def parent
         
     | 
| 
      
 152 
     | 
    
         
            +
                  Sys.ps(ppid).first unless ppid < 1
         
     | 
| 
      
 153 
     | 
    
         
            +
                end
         
     | 
| 
      
 154 
     | 
    
         
            +
             
     | 
| 
      
 155 
     | 
    
         
            +
                def children
         
     | 
| 
      
 156 
     | 
    
         
            +
                  @@parents ||= Sys.ps.group_by(&:ppid)
         
     | 
| 
      
 157 
     | 
    
         
            +
                  @@parents[pid]
         
     | 
| 
      
 158 
     | 
    
         
            +
                end
         
     | 
| 
      
 159 
     | 
    
         
            +
             
     | 
| 
       150 
160 
     | 
    
         
             
                #
         
     | 
| 
       151 
161 
     | 
    
         
             
                # Convert all the process information to a hash.
         
     | 
| 
       152 
162 
     | 
    
         
             
                #    
         
     | 
| 
         @@ -217,11 +227,21 @@ module Sys 
     | 
|
| 
       217 
227 
     | 
    
         | 
| 
       218 
228 
     | 
    
         
             
              #-----------------------------------------------------------------------------
         
     | 
| 
       219 
229 
     | 
    
         | 
| 
      
 230 
     | 
    
         
            +
              def self.tree
         
     | 
| 
      
 231 
     | 
    
         
            +
                tree = Sys.ps.group_by(&:ppid)
         
     | 
| 
      
 232 
     | 
    
         
            +
                Hash[tree.map do |ppid, children|
         
     | 
| 
      
 233 
     | 
    
         
            +
                  kvs = children.map { |child| [child.pid, tree.delete(child.pid)] }
         
     | 
| 
      
 234 
     | 
    
         
            +
                  [ppid, Hash[kvs]]
         
     | 
| 
      
 235 
     | 
    
         
            +
                end]
         
     | 
| 
      
 236 
     | 
    
         
            +
              end
         
     | 
| 
      
 237 
     | 
    
         
            +
             
     | 
| 
       220 
238 
     | 
    
         
             
              #
         
     | 
| 
       221 
239 
     | 
    
         
             
              # List all (or specified) processes, and return ProcessInfo objects.
         
     | 
| 
       222 
240 
     | 
    
         
             
              # (Takes an optional list of pids as arguments.) 
         
     | 
| 
       223 
241 
     | 
    
         
             
              #
         
     | 
| 
       224 
242 
     | 
    
         
             
              def self.ps(*pids)
         
     | 
| 
      
 243 
     | 
    
         
            +
                #return @@cache if @@cache
         
     | 
| 
      
 244 
     | 
    
         
            +
             
     | 
| 
       225 
245 
     | 
    
         
             
                options = PS_FIELDS.join(',')
         
     | 
| 
       226 
246 
     | 
    
         | 
| 
       227 
247 
     | 
    
         
             
                pids = pids.map(&:to_i)
         
     | 
| 
         @@ -229,7 +249,7 @@ module Sys 
     | 
|
| 
       229 
249 
     | 
    
         
             
                if pids.any?
         
     | 
| 
       230 
250 
     | 
    
         
             
                  command = "ps -p #{pids.join(',')} -o #{options}"
         
     | 
| 
       231 
251 
     | 
    
         
             
                else
         
     | 
| 
       232 
     | 
    
         
            -
                  command = "ps  
     | 
| 
      
 252 
     | 
    
         
            +
                  command = "ps awx -o #{options}"
         
     | 
| 
       233 
253 
     | 
    
         
             
                end
         
     | 
| 
       234 
254 
     | 
    
         | 
| 
       235 
255 
     | 
    
         
             
                lines = `#{command}`.lines.to_a        
         
     | 
| 
         @@ -248,6 +268,10 @@ module Sys 
     | 
|
| 
       248 
268 
     | 
    
         | 
| 
       249 
269 
     | 
    
         
             
              #-----------------------------------------------------------------------------
         
     | 
| 
       250 
270 
     | 
    
         | 
| 
      
 271 
     | 
    
         
            +
              def self.refresh
         
     | 
| 
      
 272 
     | 
    
         
            +
                @@cache = nil
         
     | 
| 
      
 273 
     | 
    
         
            +
              end
         
     | 
| 
      
 274 
     | 
    
         
            +
             
     | 
| 
       251 
275 
     | 
    
         
             
              #
         
     | 
| 
       252 
276 
     | 
    
         
             
              # Trap signals!
         
     | 
| 
       253 
277 
     | 
    
         
             
              #
         
     | 
    
        data/lib/epitools/term.rb
    CHANGED
    
    | 
         @@ -9,9 +9,9 @@ 
     | 
|
| 
       9 
9 
     | 
    
         
             
            module Term
         
     | 
| 
       10 
10 
     | 
    
         | 
| 
       11 
11 
     | 
    
         
             
              extend self
         
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
       13 
13 
     | 
    
         
             
              attr_accessor :wrap, :x, :y
         
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
       15 
15 
     | 
    
         
             
              #
         
     | 
| 
       16 
16 
     | 
    
         
             
              # Return the [width,height] of the terminal.
         
     | 
| 
       17 
17 
     | 
    
         
             
              #
         
     | 
| 
         @@ -21,37 +21,43 @@ module Term 
     | 
|
| 
       21 
21 
     | 
    
         
             
                Curses.close_screen
         
     | 
| 
       22 
22 
     | 
    
         
             
                result
         
     | 
| 
       23 
23 
     | 
    
         
             
              end
         
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
       25 
25 
     | 
    
         
             
              def width;  size[0]; end
         
     | 
| 
       26 
26 
     | 
    
         
             
              def height; size[1]; end
         
     | 
| 
       27 
27 
     | 
    
         
             
              def goto(x,y); @x, @y = x, y; end
         
     | 
| 
       28 
28 
     | 
    
         
             
              def pos; [@x, @y]; end
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
       30 
30 
     | 
    
         
             
              def color(fore, back=nil)
         
     | 
| 
       31 
31 
     | 
    
         
             
                @fore = fore
         
     | 
| 
       32 
     | 
    
         
            -
                @back = back if back 
     | 
| 
      
 32 
     | 
    
         
            +
                @back = back if back
         
     | 
| 
       33 
33 
     | 
    
         
             
              end
         
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
       35 
35 
     | 
    
         
             
              def puts(s)
         
     | 
| 
       36 
     | 
    
         
            -
                # some curses shit 
     | 
| 
      
 36 
     | 
    
         
            +
                # some curses shit
         
     | 
| 
       37 
37 
     | 
    
         
             
              end
         
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
       39 
39 
     | 
    
         
             
              class Window
         
     | 
| 
       40 
40 
     | 
    
         
             
                def initialize
         
     | 
| 
       41 
41 
     | 
    
         
             
                end
         
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
       43 
43 
     | 
    
         
             
                def scroll(dx, dy)
         
     | 
| 
       44 
44 
     | 
    
         
             
                end
         
     | 
| 
       45 
45 
     | 
    
         
             
              end
         
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
       47 
47 
     | 
    
         
             
              class Table
         
     | 
| 
       48 
48 
     | 
    
         | 
| 
      
 49 
     | 
    
         
            +
                # TODO:
         
     | 
| 
      
 50 
     | 
    
         
            +
                #
         
     | 
| 
      
 51 
     | 
    
         
            +
                # * make Table's configuration eaiser to remember by putting the formatting parameters in initialize
         
     | 
| 
      
 52 
     | 
    
         
            +
                #   eg: Table.new(elements, :sort=>:vertical).to_s
         
     | 
| 
      
 53 
     | 
    
         
            +
                #
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
       49 
55 
     | 
    
         
             
                attr_accessor :border, :columns, :padding, :strip_color, :indent
         
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
       51 
57 
     | 
    
         
             
                def self.[](data)
         
     | 
| 
       52 
58 
     | 
    
         
             
                  self.new(data)
         
     | 
| 
       53 
59 
     | 
    
         
             
                end
         
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
       55 
61 
     | 
    
         
             
                def initialize(data, options={})
         
     | 
| 
       56 
62 
     | 
    
         
             
                  @data         = data.map(&:to_s)
         
     | 
| 
       57 
63 
     | 
    
         
             
                  @strip_color = options[:ansi] || options[:colorized] || options[:colored] || options[:strip_color] || options[:strip_ansi]
         
     | 
| 
         @@ -61,24 +67,24 @@ module Term 
     | 
|
| 
       61 
67 
     | 
    
         
             
                  else
         
     | 
| 
       62 
68 
     | 
    
         
             
                    @max_size = @data.map(&:size).max
         
     | 
| 
       63 
69 
     | 
    
         
             
                  end
         
     | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
       65 
71 
     | 
    
         
             
                  @indent   = options[:indent]  || 0
         
     | 
| 
       66 
72 
     | 
    
         
             
                  @border   = options[:border]
         
     | 
| 
       67 
73 
     | 
    
         
             
                  @columns  = options[:columns]
         
     | 
| 
       68 
74 
     | 
    
         
             
                  @padding  = options[:padding] || 1
         
     | 
| 
       69 
75 
     | 
    
         
             
                end
         
     | 
| 
       70 
     | 
    
         
            -
             
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
       71 
77 
     | 
    
         
             
                def num_columns
         
     | 
| 
       72 
78 
     | 
    
         
             
                  return @columns if @columns
         
     | 
| 
       73 
79 
     | 
    
         
             
                  width, height = Term.size
         
     | 
| 
       74 
80 
     | 
    
         
             
                  width -= indent
         
     | 
| 
       75 
81 
     | 
    
         
             
                  (width-2) / (@max_size + @padding)
         
     | 
| 
       76 
82 
     | 
    
         
             
                end
         
     | 
| 
       77 
     | 
    
         
            -
             
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
       78 
84 
     | 
    
         
             
                def num_rows
         
     | 
| 
       79 
85 
     | 
    
         
             
                  (@data.size / num_columns.to_f).ceil
         
     | 
| 
       80 
86 
     | 
    
         
             
                end
         
     | 
| 
       81 
     | 
    
         
            -
             
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
       82 
88 
     | 
    
         
             
                def column_order
         
     | 
| 
       83 
89 
     | 
    
         
             
                  cols = []
         
     | 
| 
       84 
90 
     | 
    
         
             
                  @data.each_slice(num_rows) { |col| cols << col }
         
     | 
| 
         @@ -96,7 +102,7 @@ module Term 
     | 
|
| 
       96 
102 
     | 
    
         
             
                  end
         
     | 
| 
       97 
103 
     | 
    
         
             
                  rows
         
     | 
| 
       98 
104 
     | 
    
         
             
                end
         
     | 
| 
       99 
     | 
    
         
            -
             
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
       100 
106 
     | 
    
         
             
                def sliced_into(n)
         
     | 
| 
       101 
107 
     | 
    
         
             
                  elems = []
         
     | 
| 
       102 
108 
     | 
    
         
             
                  @data.each_slice(n) { |e| elems << e }
         
     | 
| 
         @@ -105,32 +111,32 @@ module Term 
     | 
|
| 
       105 
111 
     | 
    
         
             
                  end
         
     | 
| 
       106 
112 
     | 
    
         
             
                  elems
         
     | 
| 
       107 
113 
     | 
    
         
             
                end
         
     | 
| 
       108 
     | 
    
         
            -
             
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
       109 
115 
     | 
    
         
             
                def by_columns
         
     | 
| 
       110 
116 
     | 
    
         
             
                  return '' if @data.empty?
         
     | 
| 
       111 
117 
     | 
    
         
             
                  render sliced_into(num_rows).transpose
         
     | 
| 
       112 
118 
     | 
    
         
             
                end
         
     | 
| 
       113 
     | 
    
         
            -
             
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
       114 
120 
     | 
    
         
             
                def by_rows
         
     | 
| 
       115 
121 
     | 
    
         
             
                  return '' if @data.empty?
         
     | 
| 
       116 
122 
     | 
    
         
             
                  render sliced_into(num_columns)
         
     | 
| 
       117 
123 
     | 
    
         
             
                end
         
     | 
| 
       118 
     | 
    
         
            -
             
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
       119 
125 
     | 
    
         
             
                def to_s
         
     | 
| 
       120 
126 
     | 
    
         
             
                  by_rows
         
     | 
| 
       121 
127 
     | 
    
         
             
                end
         
     | 
| 
       122 
     | 
    
         
            -
             
     | 
| 
      
 128 
     | 
    
         
            +
             
     | 
| 
       123 
129 
     | 
    
         
             
                def render(rows, options={})
         
     | 
| 
       124 
130 
     | 
    
         
             
                  num_cols  = rows.first.size
         
     | 
| 
       125 
131 
     | 
    
         
             
                  result    = []
         
     | 
| 
       126 
     | 
    
         
            -
             
     | 
| 
      
 132 
     | 
    
         
            +
             
     | 
| 
       127 
133 
     | 
    
         
             
                  if @border
         
     | 
| 
       128 
134 
     | 
    
         
             
                    separator = "+#{(["-" * @max_size] * num_cols).join('+')}+"
         
     | 
| 
       129 
135 
     | 
    
         
             
                    result << separator
         
     | 
| 
       130 
     | 
    
         
            -
                  end 
     | 
| 
       131 
     | 
    
         
            -
             
     | 
| 
      
 136 
     | 
    
         
            +
                  end
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
       132 
138 
     | 
    
         
             
                  for row in rows
         
     | 
| 
       133 
     | 
    
         
            -
             
     | 
| 
      
 139 
     | 
    
         
            +
             
     | 
| 
       134 
140 
     | 
    
         
             
                    justified = row.map do |e|
         
     | 
| 
       135 
141 
     | 
    
         
             
                      if (diff = @max_size - e.strip_color.size) > 0
         
     | 
| 
       136 
142 
     | 
    
         
             
                        e = e + (" " * diff)
         
     | 
| 
         @@ -142,16 +148,16 @@ module Term 
     | 
|
| 
       142 
148 
     | 
    
         
             
                      line = "|#{justified.join('|')}|"
         
     | 
| 
       143 
149 
     | 
    
         
             
                    else
         
     | 
| 
       144 
150 
     | 
    
         
             
                      line = justified.join(' '*@padding)
         
     | 
| 
       145 
     | 
    
         
            -
                    end 
     | 
| 
       146 
     | 
    
         
            -
             
     | 
| 
      
 151 
     | 
    
         
            +
                    end
         
     | 
| 
      
 152 
     | 
    
         
            +
             
     | 
| 
       147 
153 
     | 
    
         
             
                    result << (" "*indent) + line
         
     | 
| 
       148 
154 
     | 
    
         
             
                  end
         
     | 
| 
       149 
     | 
    
         
            -
             
     | 
| 
      
 155 
     | 
    
         
            +
             
     | 
| 
       150 
156 
     | 
    
         
             
                  result << separator if @border
         
     | 
| 
       151 
     | 
    
         
            -
             
     | 
| 
      
 157 
     | 
    
         
            +
             
     | 
| 
       152 
158 
     | 
    
         
             
                  result.join("\n")
         
     | 
| 
       153 
159 
     | 
    
         
             
                end
         
     | 
| 
       154 
     | 
    
         
            -
             
     | 
| 
      
 160 
     | 
    
         
            +
             
     | 
| 
       155 
161 
     | 
    
         
             
              end
         
     | 
| 
       156 
     | 
    
         
            -
             
     | 
| 
      
 162 
     | 
    
         
            +
             
     | 
| 
       157 
163 
     | 
    
         
             
            end
         
     | 
    
        data/lib/epitools/wm.rb
    CHANGED
    
    | 
         @@ -4,10 +4,22 @@ module WM 
     | 
|
| 
       4 
4 
     | 
    
         | 
| 
       5 
5 
     | 
    
         
             
              def self.windows;           @windows    ||= Window.all; end
         
     | 
| 
       6 
6 
     | 
    
         
             
              def self.desktops;          @desktops   ||= Desktop.all; end
         
     | 
| 
       7 
     | 
    
         
            -
              def self.processes;         @processes  ||= Hash[ Sys.ps.map { | 
     | 
| 
      
 7 
     | 
    
         
            +
              def self.processes;         @processes  ||= Hash[ Sys.ps.map { |pr| [pr.pid, pr] } ] ; end
         
     | 
| 
       8 
8 
     | 
    
         
             
              def self.current_desktop;   @current    ||= desktops.find { |d| d.current? }; end
         
     | 
| 
       9 
9 
     | 
    
         
             
              def self.sticky;            @sticky     ||= windows.select { |w| w.sticky? }; end
         
     | 
| 
       10 
10 
     | 
    
         | 
| 
      
 11 
     | 
    
         
            +
              def self.window(pid)
         
     | 
| 
      
 12 
     | 
    
         
            +
                results = windows.select { |w| w.pid }
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                if results.empty?
         
     | 
| 
      
 15 
     | 
    
         
            +
                  # check the children
         
     | 
| 
      
 16 
     | 
    
         
            +
                  results = windows.select { |w| w.process.children.any? {|pr| pr.pid == pid } }
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
                
         
     | 
| 
      
 19 
     | 
    
         
            +
                results
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
       11 
23 
     | 
    
         
             
              class Desktop < TypedStruct["num:int current:bool resolution viewport desktop_geometry name"]
         
     | 
| 
       12 
24 
     | 
    
         
             
                def self.all
         
     | 
| 
       13 
25 
     | 
    
         
             
                  # 0  - DG: 1680x1050  VP: N/A  WA: 0,25 1680x974  Workspace 1
         
     | 
| 
         @@ -40,7 +52,7 @@ module WM 
     | 
|
| 
       40 
52 
     | 
    
         
             
              end
         
     | 
| 
       41 
53 
     | 
    
         | 
| 
       42 
54 
     | 
    
         | 
| 
       43 
     | 
    
         
            -
              class Window < TypedStruct[" 
     | 
| 
      
 55 
     | 
    
         
            +
              class Window < TypedStruct["window_id desktop_id:int pid:int x:int y:int w:int h:int hostname title"]
         
     | 
| 
       44 
56 
     | 
    
         | 
| 
       45 
57 
     | 
    
         
             
                def self.all
         
     | 
| 
       46 
58 
     | 
    
         
             
                  `wmctrl -lpG`.lines.map(&:strip).map { |line| Window.from_line(line) }
         
     | 
| 
         @@ -70,14 +82,293 @@ module WM 
     | 
|
| 
       70 
82 
     | 
    
         
             
                end
         
     | 
| 
       71 
83 
     | 
    
         | 
| 
       72 
84 
     | 
    
         
             
                alias_method :name, :title
         
     | 
| 
      
 85 
     | 
    
         
            +
                alias_method :addr, :window_id
         
     | 
| 
       73 
86 
     | 
    
         | 
| 
       74 
87 
     | 
    
         
             
                def process
         
     | 
| 
       75 
88 
     | 
    
         
             
                  WM.processes[pid]
         
     | 
| 
       76 
89 
     | 
    
         
             
                end
         
     | 
| 
       77 
90 
     | 
    
         | 
| 
      
 91 
     | 
    
         
            +
                def command
         
     | 
| 
      
 92 
     | 
    
         
            +
                  process.command
         
     | 
| 
      
 93 
     | 
    
         
            +
                end
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
       78 
95 
     | 
    
         
             
                def inspect
         
     | 
| 
       79 
96 
     | 
    
         
             
                  "{ ::#{name}:: [#{desktop_id}]}"
         
     | 
| 
       80 
97 
     | 
    
         
             
                end
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
                def activate!
         
     | 
| 
      
 100 
     | 
    
         
            +
                  system "wmctrl", "-i", "-a", window_id
         
     | 
| 
      
 101 
     | 
    
         
            +
                end
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
                #
         
     | 
| 
      
 104 
     | 
    
         
            +
                # string is made up of regular text, plus <>'d keypresses
         
     | 
| 
      
 105 
     | 
    
         
            +
                # eg: "Hello<Ctrl-T><Ctrl-L><Ctrl-Shift-K><Return>!!!"
         
     | 
| 
      
 106 
     | 
    
         
            +
                #
         
     | 
| 
      
 107 
     | 
    
         
            +
                def send_keys(keys)
         
     | 
| 
      
 108 
     | 
    
         
            +
                  xse(keys)
         
     | 
| 
      
 109 
     | 
    
         
            +
                end
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
                #
         
     | 
| 
      
 112 
     | 
    
         
            +
                # LATIN-1 XSendKey event names:
         
     | 
| 
      
 113 
     | 
    
         
            +
                # ------------------------------------------------------
         
     | 
| 
      
 114 
     | 
    
         
            +
                # (from /usr/include/X11/keysymdef.h, XK_LATIN1 section)
         
     | 
| 
      
 115 
     | 
    
         
            +
                #
         
     | 
| 
      
 116 
     | 
    
         
            +
                # space                         0x0020  /* U+0020 SPACE */
         
     | 
| 
      
 117 
     | 
    
         
            +
                # exclam                        0x0021  /* U+0021 EXCLAMATION MARK */
         
     | 
| 
      
 118 
     | 
    
         
            +
                # quotedbl                      0x0022  /* U+0022 QUOTATION MARK */
         
     | 
| 
      
 119 
     | 
    
         
            +
                # numbersign                    0x0023  /* U+0023 NUMBER SIGN */
         
     | 
| 
      
 120 
     | 
    
         
            +
                # dollar                        0x0024  /* U+0024 DOLLAR SIGN */
         
     | 
| 
      
 121 
     | 
    
         
            +
                # percent                       0x0025  /* U+0025 PERCENT SIGN */
         
     | 
| 
      
 122 
     | 
    
         
            +
                # ampersand                     0x0026  /* U+0026 AMPERSAND */
         
     | 
| 
      
 123 
     | 
    
         
            +
                # apostrophe                    0x0027  /* U+0027 APOSTROPHE */
         
     | 
| 
      
 124 
     | 
    
         
            +
                # quoteright                    0x0027  /* deprecated */
         
     | 
| 
      
 125 
     | 
    
         
            +
                # parenleft                     0x0028  /* U+0028 LEFT PARENTHESIS */
         
     | 
| 
      
 126 
     | 
    
         
            +
                # parenright                    0x0029  /* U+0029 RIGHT PARENTHESIS */
         
     | 
| 
      
 127 
     | 
    
         
            +
                # asterisk                      0x002a  /* U+002A ASTERISK */
         
     | 
| 
      
 128 
     | 
    
         
            +
                # plus                          0x002b  /* U+002B PLUS SIGN */
         
     | 
| 
      
 129 
     | 
    
         
            +
                # comma                         0x002c  /* U+002C COMMA */
         
     | 
| 
      
 130 
     | 
    
         
            +
                # minus                         0x002d  /* U+002D HYPHEN-MINUS */
         
     | 
| 
      
 131 
     | 
    
         
            +
                # period                        0x002e  /* U+002E FULL STOP */
         
     | 
| 
      
 132 
     | 
    
         
            +
                # slash                         0x002f  /* U+002F SOLIDUS */
         
     | 
| 
      
 133 
     | 
    
         
            +
                # 0                             0x0030  /* U+0030 DIGIT ZERO */
         
     | 
| 
      
 134 
     | 
    
         
            +
                # 1                             0x0031  /* U+0031 DIGIT ONE */
         
     | 
| 
      
 135 
     | 
    
         
            +
                # 2                             0x0032  /* U+0032 DIGIT TWO */
         
     | 
| 
      
 136 
     | 
    
         
            +
                # 3                             0x0033  /* U+0033 DIGIT THREE */
         
     | 
| 
      
 137 
     | 
    
         
            +
                # 4                             0x0034  /* U+0034 DIGIT FOUR */
         
     | 
| 
      
 138 
     | 
    
         
            +
                # 5                             0x0035  /* U+0035 DIGIT FIVE */
         
     | 
| 
      
 139 
     | 
    
         
            +
                # 6                             0x0036  /* U+0036 DIGIT SIX */
         
     | 
| 
      
 140 
     | 
    
         
            +
                # 7                             0x0037  /* U+0037 DIGIT SEVEN */
         
     | 
| 
      
 141 
     | 
    
         
            +
                # 8                             0x0038  /* U+0038 DIGIT EIGHT */
         
     | 
| 
      
 142 
     | 
    
         
            +
                # 9                             0x0039  /* U+0039 DIGIT NINE */
         
     | 
| 
      
 143 
     | 
    
         
            +
                # colon                         0x003a  /* U+003A COLON */
         
     | 
| 
      
 144 
     | 
    
         
            +
                # semicolon                     0x003b  /* U+003B SEMICOLON */
         
     | 
| 
      
 145 
     | 
    
         
            +
                # less                          0x003c  /* U+003C LESS-THAN SIGN */
         
     | 
| 
      
 146 
     | 
    
         
            +
                # equal                         0x003d  /* U+003D EQUALS SIGN */
         
     | 
| 
      
 147 
     | 
    
         
            +
                # greater                       0x003e  /* U+003E GREATER-THAN SIGN */
         
     | 
| 
      
 148 
     | 
    
         
            +
                # question                      0x003f  /* U+003F QUESTION MARK */
         
     | 
| 
      
 149 
     | 
    
         
            +
                # at                            0x0040  /* U+0040 COMMERCIAL AT */
         
     | 
| 
      
 150 
     | 
    
         
            +
                # A                             0x0041  /* U+0041 LATIN CAPITAL LETTER A */
         
     | 
| 
      
 151 
     | 
    
         
            +
                # B                             0x0042  /* U+0042 LATIN CAPITAL LETTER B */
         
     | 
| 
      
 152 
     | 
    
         
            +
                # C                             0x0043  /* U+0043 LATIN CAPITAL LETTER C */
         
     | 
| 
      
 153 
     | 
    
         
            +
                # D                             0x0044  /* U+0044 LATIN CAPITAL LETTER D */
         
     | 
| 
      
 154 
     | 
    
         
            +
                # E                             0x0045  /* U+0045 LATIN CAPITAL LETTER E */
         
     | 
| 
      
 155 
     | 
    
         
            +
                # F                             0x0046  /* U+0046 LATIN CAPITAL LETTER F */
         
     | 
| 
      
 156 
     | 
    
         
            +
                # G                             0x0047  /* U+0047 LATIN CAPITAL LETTER G */
         
     | 
| 
      
 157 
     | 
    
         
            +
                # H                             0x0048  /* U+0048 LATIN CAPITAL LETTER H */
         
     | 
| 
      
 158 
     | 
    
         
            +
                # I                             0x0049  /* U+0049 LATIN CAPITAL LETTER I */
         
     | 
| 
      
 159 
     | 
    
         
            +
                # J                             0x004a  /* U+004A LATIN CAPITAL LETTER J */
         
     | 
| 
      
 160 
     | 
    
         
            +
                # K                             0x004b  /* U+004B LATIN CAPITAL LETTER K */
         
     | 
| 
      
 161 
     | 
    
         
            +
                # L                             0x004c  /* U+004C LATIN CAPITAL LETTER L */
         
     | 
| 
      
 162 
     | 
    
         
            +
                # M                             0x004d  /* U+004D LATIN CAPITAL LETTER M */
         
     | 
| 
      
 163 
     | 
    
         
            +
                # N                             0x004e  /* U+004E LATIN CAPITAL LETTER N */
         
     | 
| 
      
 164 
     | 
    
         
            +
                # O                             0x004f  /* U+004F LATIN CAPITAL LETTER O */
         
     | 
| 
      
 165 
     | 
    
         
            +
                # P                             0x0050  /* U+0050 LATIN CAPITAL LETTER P */
         
     | 
| 
      
 166 
     | 
    
         
            +
                # Q                             0x0051  /* U+0051 LATIN CAPITAL LETTER Q */
         
     | 
| 
      
 167 
     | 
    
         
            +
                # R                             0x0052  /* U+0052 LATIN CAPITAL LETTER R */
         
     | 
| 
      
 168 
     | 
    
         
            +
                # S                             0x0053  /* U+0053 LATIN CAPITAL LETTER S */
         
     | 
| 
      
 169 
     | 
    
         
            +
                # T                             0x0054  /* U+0054 LATIN CAPITAL LETTER T */
         
     | 
| 
      
 170 
     | 
    
         
            +
                # U                             0x0055  /* U+0055 LATIN CAPITAL LETTER U */
         
     | 
| 
      
 171 
     | 
    
         
            +
                # V                             0x0056  /* U+0056 LATIN CAPITAL LETTER V */
         
     | 
| 
      
 172 
     | 
    
         
            +
                # W                             0x0057  /* U+0057 LATIN CAPITAL LETTER W */
         
     | 
| 
      
 173 
     | 
    
         
            +
                # X                             0x0058  /* U+0058 LATIN CAPITAL LETTER X */
         
     | 
| 
      
 174 
     | 
    
         
            +
                # Y                             0x0059  /* U+0059 LATIN CAPITAL LETTER Y */
         
     | 
| 
      
 175 
     | 
    
         
            +
                # Z                             0x005a  /* U+005A LATIN CAPITAL LETTER Z */
         
     | 
| 
      
 176 
     | 
    
         
            +
                # bracketleft                   0x005b  /* U+005B LEFT SQUARE BRACKET */
         
     | 
| 
      
 177 
     | 
    
         
            +
                # backslash                     0x005c  /* U+005C REVERSE SOLIDUS */
         
     | 
| 
      
 178 
     | 
    
         
            +
                # bracketright                  0x005d  /* U+005D RIGHT SQUARE BRACKET */
         
     | 
| 
      
 179 
     | 
    
         
            +
                # asciicircum                   0x005e  /* U+005E CIRCUMFLEX ACCENT */
         
     | 
| 
      
 180 
     | 
    
         
            +
                # underscore                    0x005f  /* U+005F LOW LINE */
         
     | 
| 
      
 181 
     | 
    
         
            +
                # grave                         0x0060  /* U+0060 GRAVE ACCENT */
         
     | 
| 
      
 182 
     | 
    
         
            +
                # quoteleft                     0x0060  /* deprecated */
         
     | 
| 
      
 183 
     | 
    
         
            +
                # a                             0x0061  /* U+0061 LATIN SMALL LETTER A */
         
     | 
| 
      
 184 
     | 
    
         
            +
                # b                             0x0062  /* U+0062 LATIN SMALL LETTER B */
         
     | 
| 
      
 185 
     | 
    
         
            +
                # c                             0x0063  /* U+0063 LATIN SMALL LETTER C */
         
     | 
| 
      
 186 
     | 
    
         
            +
                # d                             0x0064  /* U+0064 LATIN SMALL LETTER D */
         
     | 
| 
      
 187 
     | 
    
         
            +
                # e                             0x0065  /* U+0065 LATIN SMALL LETTER E */
         
     | 
| 
      
 188 
     | 
    
         
            +
                # f                             0x0066  /* U+0066 LATIN SMALL LETTER F */
         
     | 
| 
      
 189 
     | 
    
         
            +
                # g                             0x0067  /* U+0067 LATIN SMALL LETTER G */
         
     | 
| 
      
 190 
     | 
    
         
            +
                # h                             0x0068  /* U+0068 LATIN SMALL LETTER H */
         
     | 
| 
      
 191 
     | 
    
         
            +
                # i                             0x0069  /* U+0069 LATIN SMALL LETTER I */
         
     | 
| 
      
 192 
     | 
    
         
            +
                # j                             0x006a  /* U+006A LATIN SMALL LETTER J */
         
     | 
| 
      
 193 
     | 
    
         
            +
                # k                             0x006b  /* U+006B LATIN SMALL LETTER K */
         
     | 
| 
      
 194 
     | 
    
         
            +
                # l                             0x006c  /* U+006C LATIN SMALL LETTER L */
         
     | 
| 
      
 195 
     | 
    
         
            +
                # m                             0x006d  /* U+006D LATIN SMALL LETTER M */
         
     | 
| 
      
 196 
     | 
    
         
            +
                # n                             0x006e  /* U+006E LATIN SMALL LETTER N */
         
     | 
| 
      
 197 
     | 
    
         
            +
                # o                             0x006f  /* U+006F LATIN SMALL LETTER O */
         
     | 
| 
      
 198 
     | 
    
         
            +
                # p                             0x0070  /* U+0070 LATIN SMALL LETTER P */
         
     | 
| 
      
 199 
     | 
    
         
            +
                # q                             0x0071  /* U+0071 LATIN SMALL LETTER Q */
         
     | 
| 
      
 200 
     | 
    
         
            +
                # r                             0x0072  /* U+0072 LATIN SMALL LETTER R */
         
     | 
| 
      
 201 
     | 
    
         
            +
                # s                             0x0073  /* U+0073 LATIN SMALL LETTER S */
         
     | 
| 
      
 202 
     | 
    
         
            +
                # t                             0x0074  /* U+0074 LATIN SMALL LETTER T */
         
     | 
| 
      
 203 
     | 
    
         
            +
                # u                             0x0075  /* U+0075 LATIN SMALL LETTER U */
         
     | 
| 
      
 204 
     | 
    
         
            +
                # v                             0x0076  /* U+0076 LATIN SMALL LETTER V */
         
     | 
| 
      
 205 
     | 
    
         
            +
                # w                             0x0077  /* U+0077 LATIN SMALL LETTER W */
         
     | 
| 
      
 206 
     | 
    
         
            +
                # x                             0x0078  /* U+0078 LATIN SMALL LETTER X */
         
     | 
| 
      
 207 
     | 
    
         
            +
                # y                             0x0079  /* U+0079 LATIN SMALL LETTER Y */
         
     | 
| 
      
 208 
     | 
    
         
            +
                # z                             0x007a  /* U+007A LATIN SMALL LETTER Z */
         
     | 
| 
      
 209 
     | 
    
         
            +
                # braceleft                     0x007b  /* U+007B LEFT CURLY BRACKET */
         
     | 
| 
      
 210 
     | 
    
         
            +
                # bar                           0x007c  /* U+007C VERTICAL LINE */
         
     | 
| 
      
 211 
     | 
    
         
            +
                # braceright                    0x007d  /* U+007D RIGHT CURLY BRACKET */
         
     | 
| 
      
 212 
     | 
    
         
            +
                # asciitilde                    0x007e  /* U+007E TILDE */
         
     | 
| 
      
 213 
     | 
    
         
            +
                # nobreakspace                  0x00a0  /* U+00A0 NO-BREAK SPACE */
         
     | 
| 
      
 214 
     | 
    
         
            +
                # exclamdown                    0x00a1  /* U+00A1 INVERTED EXCLAMATION MARK */
         
     | 
| 
      
 215 
     | 
    
         
            +
                # cent                          0x00a2  /* U+00A2 CENT SIGN */
         
     | 
| 
      
 216 
     | 
    
         
            +
                # sterling                      0x00a3  /* U+00A3 POUND SIGN */
         
     | 
| 
      
 217 
     | 
    
         
            +
                # currency                      0x00a4  /* U+00A4 CURRENCY SIGN */
         
     | 
| 
      
 218 
     | 
    
         
            +
                # yen                           0x00a5  /* U+00A5 YEN SIGN */
         
     | 
| 
      
 219 
     | 
    
         
            +
                # brokenbar                     0x00a6  /* U+00A6 BROKEN BAR */
         
     | 
| 
      
 220 
     | 
    
         
            +
                # section                       0x00a7  /* U+00A7 SECTION SIGN */
         
     | 
| 
      
 221 
     | 
    
         
            +
                # diaeresis                     0x00a8  /* U+00A8 DIAERESIS */
         
     | 
| 
      
 222 
     | 
    
         
            +
                # copyright                     0x00a9  /* U+00A9 COPYRIGHT SIGN */
         
     | 
| 
      
 223 
     | 
    
         
            +
                # ordfeminine                   0x00aa  /* U+00AA FEMININE ORDINAL INDICATOR */
         
     | 
| 
      
 224 
     | 
    
         
            +
                # guillemotleft                 0x00ab  /* U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */
         
     | 
| 
      
 225 
     | 
    
         
            +
                # notsign                       0x00ac  /* U+00AC NOT SIGN */
         
     | 
| 
      
 226 
     | 
    
         
            +
                # hyphen                        0x00ad  /* U+00AD SOFT HYPHEN */
         
     | 
| 
      
 227 
     | 
    
         
            +
                # registered                    0x00ae  /* U+00AE REGISTERED SIGN */
         
     | 
| 
      
 228 
     | 
    
         
            +
                # macron                        0x00af  /* U+00AF MACRON */
         
     | 
| 
      
 229 
     | 
    
         
            +
                # degree                        0x00b0  /* U+00B0 DEGREE SIGN */
         
     | 
| 
      
 230 
     | 
    
         
            +
                # plusminus                     0x00b1  /* U+00B1 PLUS-MINUS SIGN */
         
     | 
| 
      
 231 
     | 
    
         
            +
                # twosuperior                   0x00b2  /* U+00B2 SUPERSCRIPT TWO */
         
     | 
| 
      
 232 
     | 
    
         
            +
                # threesuperior                 0x00b3  /* U+00B3 SUPERSCRIPT THREE */
         
     | 
| 
      
 233 
     | 
    
         
            +
                # acute                         0x00b4  /* U+00B4 ACUTE ACCENT */
         
     | 
| 
      
 234 
     | 
    
         
            +
                # mu                            0x00b5  /* U+00B5 MICRO SIGN */
         
     | 
| 
      
 235 
     | 
    
         
            +
                # paragraph                     0x00b6  /* U+00B6 PILCROW SIGN */
         
     | 
| 
      
 236 
     | 
    
         
            +
                # periodcentered                0x00b7  /* U+00B7 MIDDLE DOT */
         
     | 
| 
      
 237 
     | 
    
         
            +
                # cedilla                       0x00b8  /* U+00B8 CEDILLA */
         
     | 
| 
      
 238 
     | 
    
         
            +
                # onesuperior                   0x00b9  /* U+00B9 SUPERSCRIPT ONE */
         
     | 
| 
      
 239 
     | 
    
         
            +
                # masculine                     0x00ba  /* U+00BA MASCULINE ORDINAL INDICATOR */
         
     | 
| 
      
 240 
     | 
    
         
            +
                # guillemotright                0x00bb  /* U+00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */
         
     | 
| 
      
 241 
     | 
    
         
            +
                # onequarter                    0x00bc  /* U+00BC VULGAR FRACTION ONE QUARTER */
         
     | 
| 
      
 242 
     | 
    
         
            +
                # onehalf                       0x00bd  /* U+00BD VULGAR FRACTION ONE HALF */
         
     | 
| 
      
 243 
     | 
    
         
            +
                # threequarters                 0x00be  /* U+00BE VULGAR FRACTION THREE QUARTERS */
         
     | 
| 
      
 244 
     | 
    
         
            +
                # questiondown                  0x00bf  /* U+00BF INVERTED QUESTION MARK */
         
     | 
| 
      
 245 
     | 
    
         
            +
                # Agrave                        0x00c0  /* U+00C0 LATIN CAPITAL LETTER A WITH GRAVE */
         
     | 
| 
      
 246 
     | 
    
         
            +
                # Aacute                        0x00c1  /* U+00C1 LATIN CAPITAL LETTER A WITH ACUTE */
         
     | 
| 
      
 247 
     | 
    
         
            +
                # Acircumflex                   0x00c2  /* U+00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX */
         
     | 
| 
      
 248 
     | 
    
         
            +
                # Atilde                        0x00c3  /* U+00C3 LATIN CAPITAL LETTER A WITH TILDE */
         
     | 
| 
      
 249 
     | 
    
         
            +
                # Adiaeresis                    0x00c4  /* U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS */
         
     | 
| 
      
 250 
     | 
    
         
            +
                # Aring                         0x00c5  /* U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE */
         
     | 
| 
      
 251 
     | 
    
         
            +
                # AE                            0x00c6  /* U+00C6 LATIN CAPITAL LETTER AE */
         
     | 
| 
      
 252 
     | 
    
         
            +
                # Ccedilla                      0x00c7  /* U+00C7 LATIN CAPITAL LETTER C WITH CEDILLA */
         
     | 
| 
      
 253 
     | 
    
         
            +
                # Egrave                        0x00c8  /* U+00C8 LATIN CAPITAL LETTER E WITH GRAVE */
         
     | 
| 
      
 254 
     | 
    
         
            +
                # Eacute                        0x00c9  /* U+00C9 LATIN CAPITAL LETTER E WITH ACUTE */
         
     | 
| 
      
 255 
     | 
    
         
            +
                # Ecircumflex                   0x00ca  /* U+00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX */
         
     | 
| 
      
 256 
     | 
    
         
            +
                # Ediaeresis                    0x00cb  /* U+00CB LATIN CAPITAL LETTER E WITH DIAERESIS */
         
     | 
| 
      
 257 
     | 
    
         
            +
                # Igrave                        0x00cc  /* U+00CC LATIN CAPITAL LETTER I WITH GRAVE */
         
     | 
| 
      
 258 
     | 
    
         
            +
                # Iacute                        0x00cd  /* U+00CD LATIN CAPITAL LETTER I WITH ACUTE */
         
     | 
| 
      
 259 
     | 
    
         
            +
                # Icircumflex                   0x00ce  /* U+00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX */
         
     | 
| 
      
 260 
     | 
    
         
            +
                # Idiaeresis                    0x00cf  /* U+00CF LATIN CAPITAL LETTER I WITH DIAERESIS */
         
     | 
| 
      
 261 
     | 
    
         
            +
                # ETH                           0x00d0  /* U+00D0 LATIN CAPITAL LETTER ETH */
         
     | 
| 
      
 262 
     | 
    
         
            +
                # Eth                           0x00d0  /* deprecated */
         
     | 
| 
      
 263 
     | 
    
         
            +
                # Ntilde                        0x00d1  /* U+00D1 LATIN CAPITAL LETTER N WITH TILDE */
         
     | 
| 
      
 264 
     | 
    
         
            +
                # Ograve                        0x00d2  /* U+00D2 LATIN CAPITAL LETTER O WITH GRAVE */
         
     | 
| 
      
 265 
     | 
    
         
            +
                # Oacute                        0x00d3  /* U+00D3 LATIN CAPITAL LETTER O WITH ACUTE */
         
     | 
| 
      
 266 
     | 
    
         
            +
                # Ocircumflex                   0x00d4  /* U+00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX */
         
     | 
| 
      
 267 
     | 
    
         
            +
                # Otilde                        0x00d5  /* U+00D5 LATIN CAPITAL LETTER O WITH TILDE */
         
     | 
| 
      
 268 
     | 
    
         
            +
                # Odiaeresis                    0x00d6  /* U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS */
         
     | 
| 
      
 269 
     | 
    
         
            +
                # multiply                      0x00d7  /* U+00D7 MULTIPLICATION SIGN */
         
     | 
| 
      
 270 
     | 
    
         
            +
                # Oslash                        0x00d8  /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */
         
     | 
| 
      
 271 
     | 
    
         
            +
                # Ooblique                      0x00d8  /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */
         
     | 
| 
      
 272 
     | 
    
         
            +
                # Ugrave                        0x00d9  /* U+00D9 LATIN CAPITAL LETTER U WITH GRAVE */
         
     | 
| 
      
 273 
     | 
    
         
            +
                # Uacute                        0x00da  /* U+00DA LATIN CAPITAL LETTER U WITH ACUTE */
         
     | 
| 
      
 274 
     | 
    
         
            +
                # Ucircumflex                   0x00db  /* U+00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX */
         
     | 
| 
      
 275 
     | 
    
         
            +
                # Udiaeresis                    0x00dc  /* U+00DC LATIN CAPITAL LETTER U WITH DIAERESIS */
         
     | 
| 
      
 276 
     | 
    
         
            +
                # Yacute                        0x00dd  /* U+00DD LATIN CAPITAL LETTER Y WITH ACUTE */
         
     | 
| 
      
 277 
     | 
    
         
            +
                # THORN                         0x00de  /* U+00DE LATIN CAPITAL LETTER THORN */
         
     | 
| 
      
 278 
     | 
    
         
            +
                # Thorn                         0x00de  /* deprecated */
         
     | 
| 
      
 279 
     | 
    
         
            +
                # ssharp                        0x00df  /* U+00DF LATIN SMALL LETTER SHARP S */
         
     | 
| 
      
 280 
     | 
    
         
            +
                # agrave                        0x00e0  /* U+00E0 LATIN SMALL LETTER A WITH GRAVE */
         
     | 
| 
      
 281 
     | 
    
         
            +
                # aacute                        0x00e1  /* U+00E1 LATIN SMALL LETTER A WITH ACUTE */
         
     | 
| 
      
 282 
     | 
    
         
            +
                # acircumflex                   0x00e2  /* U+00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX */
         
     | 
| 
      
 283 
     | 
    
         
            +
                # atilde                        0x00e3  /* U+00E3 LATIN SMALL LETTER A WITH TILDE */
         
     | 
| 
      
 284 
     | 
    
         
            +
                # adiaeresis                    0x00e4  /* U+00E4 LATIN SMALL LETTER A WITH DIAERESIS */
         
     | 
| 
      
 285 
     | 
    
         
            +
                # aring                         0x00e5  /* U+00E5 LATIN SMALL LETTER A WITH RING ABOVE */
         
     | 
| 
      
 286 
     | 
    
         
            +
                # ae                            0x00e6  /* U+00E6 LATIN SMALL LETTER AE */
         
     | 
| 
      
 287 
     | 
    
         
            +
                # ccedilla                      0x00e7  /* U+00E7 LATIN SMALL LETTER C WITH CEDILLA */
         
     | 
| 
      
 288 
     | 
    
         
            +
                # egrave                        0x00e8  /* U+00E8 LATIN SMALL LETTER E WITH GRAVE */
         
     | 
| 
      
 289 
     | 
    
         
            +
                # eacute                        0x00e9  /* U+00E9 LATIN SMALL LETTER E WITH ACUTE */
         
     | 
| 
      
 290 
     | 
    
         
            +
                # ecircumflex                   0x00ea  /* U+00EA LATIN SMALL LETTER E WITH CIRCUMFLEX */
         
     | 
| 
      
 291 
     | 
    
         
            +
                # ediaeresis                    0x00eb  /* U+00EB LATIN SMALL LETTER E WITH DIAERESIS */
         
     | 
| 
      
 292 
     | 
    
         
            +
                # igrave                        0x00ec  /* U+00EC LATIN SMALL LETTER I WITH GRAVE */
         
     | 
| 
      
 293 
     | 
    
         
            +
                # iacute                        0x00ed  /* U+00ED LATIN SMALL LETTER I WITH ACUTE */
         
     | 
| 
      
 294 
     | 
    
         
            +
                # icircumflex                   0x00ee  /* U+00EE LATIN SMALL LETTER I WITH CIRCUMFLEX */
         
     | 
| 
      
 295 
     | 
    
         
            +
                # idiaeresis                    0x00ef  /* U+00EF LATIN SMALL LETTER I WITH DIAERESIS */
         
     | 
| 
      
 296 
     | 
    
         
            +
                # eth                           0x00f0  /* U+00F0 LATIN SMALL LETTER ETH */
         
     | 
| 
      
 297 
     | 
    
         
            +
                # ntilde                        0x00f1  /* U+00F1 LATIN SMALL LETTER N WITH TILDE */
         
     | 
| 
      
 298 
     | 
    
         
            +
                # ograve                        0x00f2  /* U+00F2 LATIN SMALL LETTER O WITH GRAVE */
         
     | 
| 
      
 299 
     | 
    
         
            +
                # oacute                        0x00f3  /* U+00F3 LATIN SMALL LETTER O WITH ACUTE */
         
     | 
| 
      
 300 
     | 
    
         
            +
                # ocircumflex                   0x00f4  /* U+00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX */
         
     | 
| 
      
 301 
     | 
    
         
            +
                # otilde                        0x00f5  /* U+00F5 LATIN SMALL LETTER O WITH TILDE */
         
     | 
| 
      
 302 
     | 
    
         
            +
                # odiaeresis                    0x00f6  /* U+00F6 LATIN SMALL LETTER O WITH DIAERESIS */
         
     | 
| 
      
 303 
     | 
    
         
            +
                # division                      0x00f7  /* U+00F7 DIVISION SIGN */
         
     | 
| 
      
 304 
     | 
    
         
            +
                # oslash                        0x00f8  /* U+00F8 LATIN SMALL LETTER O WITH STROKE */
         
     | 
| 
      
 305 
     | 
    
         
            +
                # ooblique                      0x00f8  /* U+00F8 LATIN SMALL LETTER O WITH STROKE */
         
     | 
| 
      
 306 
     | 
    
         
            +
                # ugrave                        0x00f9  /* U+00F9 LATIN SMALL LETTER U WITH GRAVE */
         
     | 
| 
      
 307 
     | 
    
         
            +
                # uacute                        0x00fa  /* U+00FA LATIN SMALL LETTER U WITH ACUTE */
         
     | 
| 
      
 308 
     | 
    
         
            +
                # ucircumflex                   0x00fb  /* U+00FB LATIN SMALL LETTER U WITH CIRCUMFLEX */
         
     | 
| 
      
 309 
     | 
    
         
            +
                # udiaeresis                    0x00fc  /* U+00FC LATIN SMALL LETTER U WITH DIAERESIS */
         
     | 
| 
      
 310 
     | 
    
         
            +
                # yacute                        0x00fd  /* U+00FD LATIN SMALL LETTER Y WITH ACUTE */
         
     | 
| 
      
 311 
     | 
    
         
            +
                # thorn                         0x00fe  /* U+00FE LATIN SMALL LETTER THORN */
         
     | 
| 
      
 312 
     | 
    
         
            +
                # ydiaeresis                    0x00ff  /* U+00FF LATIN SMALL LETTER Y WITH DIAERESIS */
         
     | 
| 
      
 313 
     | 
    
         
            +
                #
         
     | 
| 
      
 314 
     | 
    
         
            +
                def keys_to_events(keys)
         
     | 
| 
      
 315 
     | 
    
         
            +
             
     | 
| 
      
 316 
     | 
    
         
            +
                  keymap = {
         
     | 
| 
      
 317 
     | 
    
         
            +
                    "`" => "grave",
         
     | 
| 
      
 318 
     | 
    
         
            +
                    " " => "space",
         
     | 
| 
      
 319 
     | 
    
         
            +
                    "~" => "asciitilde",
         
     | 
| 
      
 320 
     | 
    
         
            +
                    "_" => "underscore",
         
     | 
| 
      
 321 
     | 
    
         
            +
                    "\[" => "Escape",
         
     | 
| 
      
 322 
     | 
    
         
            +
                    '"' => "quotedbl",
         
     | 
| 
      
 323 
     | 
    
         
            +
                  }
         
     | 
| 
      
 324 
     | 
    
         
            +
             
     | 
| 
      
 325 
     | 
    
         
            +
                  tokens = keys.scan(/(<[^>]+>|.+?)/)
         
     | 
| 
      
 326 
     | 
    
         
            +
             
     | 
| 
      
 327 
     | 
    
         
            +
                  tokens.flatten.map do |key|
         
     | 
| 
      
 328 
     | 
    
         
            +
                    mods = []
         
     | 
| 
      
 329 
     | 
    
         
            +
             
     | 
| 
      
 330 
     | 
    
         
            +
                    if key =~ /^<(.+)>$/
         
     | 
| 
      
 331 
     | 
    
         
            +
             
     | 
| 
      
 332 
     | 
    
         
            +
                      specials = $1.split("-")
         
     | 
| 
      
 333 
     | 
    
         
            +
                      key = specials.pop
         
     | 
| 
      
 334 
     | 
    
         
            +
             
     | 
| 
      
 335 
     | 
    
         
            +
                      specials.each do |special|
         
     | 
| 
      
 336 
     | 
    
         
            +
                        if special =~ /^(Ctrl|Shift|Alt)$/
         
     | 
| 
      
 337 
     | 
    
         
            +
                          mods << $1
         
     | 
| 
      
 338 
     | 
    
         
            +
                        else
         
     | 
| 
      
 339 
     | 
    
         
            +
                          raise "Error: unknown modifier #{special}"
         
     | 
| 
      
 340 
     | 
    
         
            +
                        end
         
     | 
| 
      
 341 
     | 
    
         
            +
                      end
         
     | 
| 
      
 342 
     | 
    
         
            +
             
     | 
| 
      
 343 
     | 
    
         
            +
                    end
         
     | 
| 
      
 344 
     | 
    
         
            +
             
     | 
| 
      
 345 
     | 
    
         
            +
                    mods << "Shift" if key =~ /^[A-Z\~\!\@\#\$\%\^\&\*\(\)\_\+]$/
         
     | 
| 
      
 346 
     | 
    
         
            +
             
     | 
| 
      
 347 
     | 
    
         
            +
                    if key =~ /^[A-Z0-9]$/i or key.size > 1
         
     | 
| 
      
 348 
     | 
    
         
            +
                      keyname = key
         
     | 
| 
      
 349 
     | 
    
         
            +
                    else
         
     | 
| 
      
 350 
     | 
    
         
            +
                      keyname = keymap[key] || ("0x%x" % key.ord)
         
     | 
| 
      
 351 
     | 
    
         
            +
                    end
         
     | 
| 
      
 352 
     | 
    
         
            +
             
     | 
| 
      
 353 
     | 
    
         
            +
                    "#{mods.join(" ")}<Key>#{keyname}"
         
     | 
| 
      
 354 
     | 
    
         
            +
                  end
         
     | 
| 
      
 355 
     | 
    
         
            +
                end
         
     | 
| 
      
 356 
     | 
    
         
            +
             
     | 
| 
      
 357 
     | 
    
         
            +
                def xse(keys)
         
     | 
| 
      
 358 
     | 
    
         
            +
                  temp   = Tempfile.new("xse")
         
     | 
| 
      
 359 
     | 
    
         
            +
                  events = keys_to_events(keys)
         
     | 
| 
      
 360 
     | 
    
         
            +
             
     | 
| 
      
 361 
     | 
    
         
            +
                  p events
         
     | 
| 
      
 362 
     | 
    
         
            +
                  p eventstring = events.map { |e| e + "\n" }.join("")
         
     | 
| 
      
 363 
     | 
    
         
            +
             
     | 
| 
      
 364 
     | 
    
         
            +
                  temp.write eventstring 
         
     | 
| 
      
 365 
     | 
    
         
            +
                  temp.flush
         
     | 
| 
      
 366 
     | 
    
         
            +
             
     | 
| 
      
 367 
     | 
    
         
            +
                  unless system("xse", "-window", window_id, "-file", temp.path)
         
     | 
| 
      
 368 
     | 
    
         
            +
                    raise "Error: couldn't send key commands to 'xse'. (Is xsendevents installed?)"
         
     | 
| 
      
 369 
     | 
    
         
            +
                  end
         
     | 
| 
      
 370 
     | 
    
         
            +
                end
         
     | 
| 
      
 371 
     | 
    
         
            +
             
     | 
| 
       81 
372 
     | 
    
         
             
              end
         
     | 
| 
       82 
373 
     | 
    
         | 
| 
       83 
374 
     | 
    
         
             
            end
         
     |