epitools 0.5.7 → 0.5.8
Sign up to get free protection for your applications and to get access to all the features.
- 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
|