termdump 0.2.0 → 0.3.0
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.
- checksums.yaml +4 -4
- data/README.md +47 -4
- data/etc/_termdump +1 -1
- data/etc/termdump +1 -0
- data/etc/termdump.1.md +2 -0
- data/lib/termdump/command.rb +6 -1
- data/lib/termdump/main.rb +40 -24
- data/lib/termdump/session.rb +16 -11
- data/lib/termdump/terminal/base/base.rb +11 -1
- data/lib/termdump/terminal/base/terminal_helper.rb +3 -0
- data/lib/termdump/terminal/gnome_terminal.rb +3 -3
- data/lib/termdump/terminal/guake.rb +2 -2
- data/lib/termdump/terminal/konsole.rb +31 -0
- data/lib/termdump/terminal/terminator.rb +16 -14
- data/lib/termdump/terminal/tilda.rb +68 -0
- data/lib/termdump/terminal/urxvt.rb +42 -0
- data/lib/termdump/terminal/xterm.rb +2 -1
- data/lib/termdump/version.rb +1 -1
- data/test/test_main.rb +45 -5
- data/test/test_session.rb +3 -2
- data/test/test_tilda.rb +21 -0
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: adc894662dfd676e61a1a1685fe6a7c850b360f0
|
4
|
+
data.tar.gz: 9e5ab976f6b7b451caf65f044fffc1e6c2fed588
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 73ee5f4c7e9f8c9feb1851bb0d02b307313277908ffb85a57e83cacecfadfab444670bcff5a2d55a87aeed5094eaa476b063a5c694c984a52d1deca44874c332
|
7
|
+
data.tar.gz: 5c5a485e9372294db2777b1aea8ae9133d6e113b07c7c54175fbe0ed36a779273b6339b065dfbd66261bd067aeb5a73e110927aad292dbd84bb18e7bc0230d46
|
data/README.md
CHANGED
@@ -28,6 +28,7 @@ $ termdump -i
|
|
28
28
|
|
29
29
|
```shell
|
30
30
|
$ termdump -s mydailywork
|
31
|
+
Enter a new session name:
|
31
32
|
# or `termdump -s mydailywork --exclude`
|
32
33
|
# if you want to exclude the pty running this command
|
33
34
|
```
|
@@ -38,29 +39,71 @@ $ termdump -s mydailywork
|
|
38
39
|
$ termdump mydailywork
|
39
40
|
```
|
40
41
|
|
42
|
+
or
|
43
|
+
|
44
|
+
```shell
|
45
|
+
$ termdump
|
46
|
+
order: session name ctime atime
|
47
|
+
[0]: scutmall 2015-07-01 17:07:37 2015-07-25 11:59:42
|
48
|
+
[1]: mydailywork 2015-07-19 11:05:52 2015-07-25 11:22:03
|
49
|
+
[2]: termdump 2015-06-30 10:58:20 2015-07-25 11:21:46
|
50
|
+
Select one session to load:1
|
51
|
+
```
|
52
|
+
|
41
53
|
### edit a session
|
42
54
|
|
43
55
|
```shell
|
44
56
|
$ termdump -e mydailywork
|
45
57
|
```
|
46
58
|
|
59
|
+
or
|
60
|
+
|
61
|
+
```shell
|
62
|
+
$ termdump -e
|
63
|
+
order: session name ctime atime
|
64
|
+
[0]: scutmall 2015-07-01 17:07:37 2015-07-25 11:59:42
|
65
|
+
[1]: mydailywork 2015-07-19 11:05:52 2015-07-25 11:22:03
|
66
|
+
[2]: termdump 2015-06-30 10:58:20 2015-07-25 11:21:46
|
67
|
+
Select one session to edit:1
|
68
|
+
```
|
69
|
+
|
47
70
|
### delete a session
|
48
71
|
|
49
72
|
```shell
|
50
73
|
$ termdump -d mydailywork
|
51
74
|
```
|
52
75
|
|
76
|
+
or
|
77
|
+
|
78
|
+
```shell
|
79
|
+
$ termdump -d
|
80
|
+
order: session name ctime atime
|
81
|
+
[0]: scutmall 2015-07-01 17:07:37 2015-07-25 11:59:42
|
82
|
+
[1]: mydailywork 2015-07-19 11:05:52 2015-07-25 11:22:03
|
83
|
+
[2]: termdump 2015-06-30 10:58:20 2015-07-25 11:21:46
|
84
|
+
Select one session to delete:1
|
85
|
+
```
|
86
|
+
|
87
|
+
### list all session
|
88
|
+
|
89
|
+
```shell
|
90
|
+
$ termdump -l
|
91
|
+
# equal to run `termdump`
|
92
|
+
```
|
93
|
+
|
53
94
|
Read more in [session syntax and examples](sessions.md) and [configure](configure.md).
|
54
95
|
|
55
96
|
## Supported terminal
|
56
97
|
|
57
98
|
- [x] gnome-terminal
|
58
|
-
- [x] terminator
|
59
|
-
- [x] xterm
|
60
99
|
- [x] guake
|
61
|
-
- [
|
62
|
-
- [
|
100
|
+
- [x] konsole
|
101
|
+
- [x] terminator
|
102
|
+
- [x] tilda
|
103
|
+
- [x] urxvt
|
63
104
|
- [ ] xfce4-terminal
|
105
|
+
- [x] xterm
|
106
|
+
- [ ] yakuake
|
64
107
|
|
65
108
|
If you want to support Terminal X, you can write a terminal file under
|
66
109
|
https://github.com/spacewander/termdump/tree/master/lib/termdump/terminal and then send me a pr.
|
data/etc/_termdump
CHANGED
data/etc/termdump
CHANGED
data/etc/termdump.1.md
CHANGED
@@ -38,6 +38,8 @@ Dump your (pseudo)terminal session and replay it. You can use it to bootstrap da
|
|
38
38
|
|
39
39
|
If you run `termdump` with a session name only, it will replay the session.
|
40
40
|
|
41
|
+
*session* can be a session file(currently in yml format) in `~/.config/termdump/session`, or in the current working directory, or an absolute path to the session file.
|
42
|
+
|
41
43
|
# SAVE OPTIONS
|
42
44
|
|
43
45
|
--stdout
|
data/lib/termdump/command.rb
CHANGED
@@ -40,7 +40,12 @@ module TermDump
|
|
40
40
|
puts VERSION
|
41
41
|
exit 0
|
42
42
|
end
|
43
|
-
|
43
|
+
begin
|
44
|
+
opts.parse! args
|
45
|
+
rescue OptionParser::InvalidOption
|
46
|
+
puts opts.help
|
47
|
+
exit 1
|
48
|
+
end
|
44
49
|
|
45
50
|
# :load is the default action if no option given
|
46
51
|
if @args.action == :load
|
data/lib/termdump/main.rb
CHANGED
@@ -12,6 +12,7 @@ module TermDump
|
|
12
12
|
BASE_DIR = "#{Dir.home}/.config/termdump/" # only for posix file system
|
13
13
|
@@session_dir = BASE_DIR + "session"
|
14
14
|
@@config_file = BASE_DIR + "config.yml"
|
15
|
+
@@session_extname = '.yml'
|
15
16
|
|
16
17
|
def initialize
|
17
18
|
@config = read_configure
|
@@ -27,7 +28,7 @@ module TermDump
|
|
27
28
|
|
28
29
|
# initialize configure and session directory interactively
|
29
30
|
def init
|
30
|
-
if Dir.exist?(
|
31
|
+
if Dir.exist?(@@config_file)
|
31
32
|
return puts "The configure has been initialized yet"
|
32
33
|
end
|
33
34
|
dir = File.dirname(File.realpath(__FILE__)) # for ruby > 2.0.0, use __dir__
|
@@ -44,11 +45,12 @@ module TermDump
|
|
44
45
|
print "Will create #{@@config_file} and #{@@session_dir}, go on?[Y/N] "
|
45
46
|
answer = $stdin.gets.chomp
|
46
47
|
return if answer == 'N' || answer == 'n'
|
47
|
-
FileUtils.mkpath @@session_dir
|
48
48
|
configure = {
|
49
49
|
'terminal' => support_term[choice]
|
50
50
|
}
|
51
|
+
FileUtils.mkpath(BASE_DIR) unless Dir.exist?(BASE_DIR)
|
51
52
|
IO.write @@config_file, YAML.dump(configure)
|
53
|
+
FileUtils.mkdir(@@session_dir) unless Dir.exist?(@@session_dir)
|
52
54
|
puts "Ok, the configure is initialized now. Happy coding!"
|
53
55
|
return
|
54
56
|
end
|
@@ -216,12 +218,28 @@ module TermDump
|
|
216
218
|
yml_tree.to_yaml
|
217
219
|
end
|
218
220
|
|
221
|
+
# If name is an absolute path(with or without session extname),
|
222
|
+
# check if the session exists;
|
223
|
+
# otherwises search session file first in current path and then in session_dir
|
224
|
+
#
|
219
225
|
# return a Hash with two symbols:
|
220
226
|
# :exist => is session already existed
|
221
227
|
# :name => the absolute path of session
|
222
228
|
def search_session name
|
223
|
-
|
224
|
-
|
229
|
+
if File.extname(name) != @@session_extname
|
230
|
+
name = name + @@session_extname
|
231
|
+
end
|
232
|
+
|
233
|
+
status = {:exist => File.exist?(name), :name => name}
|
234
|
+
if !status[:exist] && Pathname.new(name).relative?
|
235
|
+
session_name = File.join(Dir.pwd, name)
|
236
|
+
status = {:exist => File.exist?(session_name), :name => session_name}
|
237
|
+
unless status[:exist]
|
238
|
+
session_name = File.join(@@session_dir, name)
|
239
|
+
status = {:exist => File.exist?(session_name), :name => session_name}
|
240
|
+
end
|
241
|
+
end
|
242
|
+
status
|
225
243
|
end
|
226
244
|
|
227
245
|
# save yml format string to a yml file in @@session_dir
|
@@ -252,18 +270,22 @@ module TermDump
|
|
252
270
|
|
253
271
|
def list list_action
|
254
272
|
begin
|
255
|
-
Dir.
|
256
|
-
sessions
|
273
|
+
sessions = Dir.glob("#{@@session_dir}/*#{@@session_extname}")
|
274
|
+
sessions += Dir.glob("#{Dir.pwd}/*#{@@session_extname}")
|
257
275
|
if sessions.empty?
|
258
276
|
puts "No session exists in #{@@session_dir}"
|
259
277
|
else
|
260
|
-
puts "order:\tsession name\tctime
|
278
|
+
puts "order:\tsession name\tctime atime"
|
261
279
|
sessions.sort!{|x, y| File.atime(y) <=> File.atime(x) }
|
262
280
|
sessions.each_with_index do |f, i|
|
263
|
-
|
264
|
-
|
265
|
-
f.
|
266
|
-
|
281
|
+
# equal to yy-MM-dd hh:mm:ss
|
282
|
+
cdate = File.ctime(f).strftime('%F %T')
|
283
|
+
adate = File.atime(f).strftime('%F %T')
|
284
|
+
is_pwd = f.start_with?(Dir.pwd)
|
285
|
+
# remain the path in sessions absolute
|
286
|
+
f = File.basename(f, @@session_extname)
|
287
|
+
f = "[pwd]#{f}" if is_pwd
|
288
|
+
printf("[%d]: %15s\t%s\t%s\n", i, f, cdate, adate)
|
267
289
|
end
|
268
290
|
|
269
291
|
get_input_order = proc do |action, &handler|
|
@@ -294,7 +316,7 @@ module TermDump
|
|
294
316
|
status = search_session name
|
295
317
|
return puts "#{status[:name]} not found" unless status[:exist]
|
296
318
|
File.delete status[:name]
|
297
|
-
puts "Delete session '#{name}' successfully"
|
319
|
+
puts "Delete session '#{status[:name]}' successfully"
|
298
320
|
end
|
299
321
|
|
300
322
|
def edit_session name
|
@@ -305,9 +327,12 @@ module TermDump
|
|
305
327
|
exec ENV['EDITOR'], status[:name]
|
306
328
|
end
|
307
329
|
|
330
|
+
# load the process tree from yml format string, and replay it
|
308
331
|
def load_session name
|
309
|
-
|
310
|
-
|
332
|
+
status = search_session name
|
333
|
+
return puts "#{status[:name]} not found" unless status[:exist]
|
334
|
+
ptree = YAML.load(IO.read(status[:name]))
|
335
|
+
if ptree.is_a?(Hash) && ptree != {}
|
311
336
|
begin
|
312
337
|
ptree = check ptree
|
313
338
|
rescue SessionSyntaxError => e
|
@@ -315,17 +340,8 @@ module TermDump
|
|
315
340
|
exit 1
|
316
341
|
end
|
317
342
|
Session.new(@config).replay(ptree)
|
318
|
-
end
|
319
|
-
end
|
320
|
-
|
321
|
-
# load the process tree from yml format string
|
322
|
-
def load_file name
|
323
|
-
status = search_session name
|
324
|
-
unless status[:exist]
|
325
|
-
puts "#{status[:name]} not found"
|
326
|
-
{}
|
327
343
|
else
|
328
|
-
|
344
|
+
raise SessionSyntaxError.new("yml format error")
|
329
345
|
end
|
330
346
|
end
|
331
347
|
|
data/lib/termdump/session.rb
CHANGED
@@ -9,23 +9,28 @@ module TermDump
|
|
9
9
|
# * new_vsplit: The key sequence used to open a new vsplit
|
10
10
|
# * new_hsplit: The key sequence used to open a new hsplit
|
11
11
|
def initialize config={}
|
12
|
-
if config.has_key?('terminal')
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
12
|
+
if config.nil? || !config.has_key?('terminal')
|
13
|
+
raise ArgumentError.new(
|
14
|
+
"You need to set 'terminal' in the configure file")
|
15
|
+
end
|
16
|
+
begin
|
17
|
+
terminal = config['terminal']
|
18
|
+
require_relative "terminal/#{terminal}"
|
19
|
+
rescue LoadError
|
20
|
+
puts "Load with terminal #{terminal} error:"
|
21
|
+
puts "Not support #{terminal} yet!"
|
22
|
+
exit 0
|
23
23
|
end
|
24
|
+
|
24
25
|
@terminal = Terminal.new(config)
|
25
26
|
@node_queue = []
|
26
27
|
@support_split = Terminal.public_method_defined?(:vsplit) &&
|
27
28
|
Terminal.public_method_defined?(:hsplit)
|
28
29
|
@support_tab = Terminal.public_method_defined?(:tab)
|
30
|
+
|
31
|
+
if config.has_key?('delay') && config['delay'] == config['delay'].to_i
|
32
|
+
@terminal.delay = config['delay']
|
33
|
+
end
|
29
34
|
end
|
30
35
|
|
31
36
|
def replay task
|
@@ -4,10 +4,13 @@ module TermDump
|
|
4
4
|
class BasicTerminal
|
5
5
|
include TerminalHelper
|
6
6
|
|
7
|
+
attr_writer :delay
|
7
8
|
def initialize config
|
8
9
|
@user_defined_config = config
|
9
10
|
@config = {}
|
10
11
|
@default_config = {}
|
12
|
+
|
13
|
+
@delay = 0.5 # delay for 0.5 second
|
11
14
|
end
|
12
15
|
|
13
16
|
# Get user defined value/configure value/default value with a configure item.
|
@@ -15,7 +18,14 @@ module TermDump
|
|
15
18
|
def configure configure_key
|
16
19
|
@user_defined_config.fetch(configure_key) {|key_in_config|
|
17
20
|
@config.fetch(key_in_config) {|default_key|
|
18
|
-
@default_config.fetch(default_key)
|
21
|
+
@default_config.fetch(default_key)
|
22
|
+
}
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
# wait until shell/terminal launched, so that we can do something in them
|
27
|
+
def wait_for_launching
|
28
|
+
sleep @delay
|
19
29
|
end
|
20
30
|
|
21
31
|
# run command in current window
|
@@ -8,6 +8,7 @@ module TermDump
|
|
8
8
|
# case 1 : [A-Z] => [a-z]
|
9
9
|
# case 2 : <Primary> => Ctrl
|
10
10
|
# case 3 : [0-9] [a-z] UpDownLeftRight F[0-12] Return space... => not changed
|
11
|
+
# case 4 : <Control> => Ctrl
|
11
12
|
# For example,
|
12
13
|
# '<Primary><Shift>A' => 'Ctrl+Shift+a'
|
13
14
|
# '<Alt>space' => 'Alt+space'
|
@@ -18,6 +19,8 @@ module TermDump
|
|
18
19
|
key.downcase
|
19
20
|
elsif key == 'Primary'
|
20
21
|
'Ctrl'
|
22
|
+
elsif key == 'Control'
|
23
|
+
'Ctrl'
|
21
24
|
else
|
22
25
|
key
|
23
26
|
end
|
@@ -4,7 +4,7 @@ module TermDump
|
|
4
4
|
# This Terminal class is for [gnome-terminal](https://wiki.gnome.org/Apps/Terminal)
|
5
5
|
class Terminal < BasicTerminal
|
6
6
|
def initialize config
|
7
|
-
|
7
|
+
super config
|
8
8
|
@keybindings = '/apps/gnome-terminal/keybindings'
|
9
9
|
@config = {
|
10
10
|
'new_window' => get_configure_key('new_window'),
|
@@ -24,13 +24,13 @@ module TermDump
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def exec cwd, cmd
|
27
|
-
|
27
|
+
wait_for_launching
|
28
28
|
`xdotool getactivewindow type #{escape("cd #{cwd}\n")}`
|
29
29
|
`xdotool getactivewindow type #{escape("#{cmd}\n")}` unless cmd.nil?
|
30
30
|
end
|
31
31
|
|
32
32
|
def window name, cwd, cmd
|
33
|
-
# `getactivewindow key` not work on gnome-terminal
|
33
|
+
# `getactivewindow key` not work on gnome-terminal
|
34
34
|
`xdotool key #{configure 'new_window'}`
|
35
35
|
exec cwd, cmd
|
36
36
|
end
|
@@ -5,8 +5,8 @@ module TermDump
|
|
5
5
|
# See `man guake`
|
6
6
|
class Terminal < BasicTerminal
|
7
7
|
def initialize config
|
8
|
-
|
9
|
-
@keybindings = '/apps/guake/keybindings'
|
8
|
+
super config
|
9
|
+
@keybindings = '/apps/guake/keybindings/local'
|
10
10
|
@config = {
|
11
11
|
'new_tab' => get_configure_key('new_tab')
|
12
12
|
}
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require_relative 'base/base'
|
2
|
+
|
3
|
+
module TermDump
|
4
|
+
# This Terminal class is for
|
5
|
+
# [konsole](https://konsole.kde.org/)
|
6
|
+
# See https://docs.kde.org/stable5/en/applications/konsole/index.html
|
7
|
+
class Terminal < BasicTerminal
|
8
|
+
def initialize config
|
9
|
+
super config
|
10
|
+
end
|
11
|
+
|
12
|
+
def exec cwd, cmd
|
13
|
+
wait_for_launching
|
14
|
+
`xdotool getactivewindow type #{escape("cd #{cwd}\n")}`
|
15
|
+
`xdotool getactivewindow type #{escape("#{cmd}\n")}` unless cmd.nil?
|
16
|
+
end
|
17
|
+
|
18
|
+
def window name, cwd, cmd
|
19
|
+
`konsole --workdir #{escape cwd}`
|
20
|
+
wait_for_launching
|
21
|
+
`xdotool getactivewindow type #{escape("#{cmd}\n")}` unless cmd.nil?
|
22
|
+
end
|
23
|
+
|
24
|
+
def tab name, cwd, cmd
|
25
|
+
`konsole --workdir #{escape cwd} --new-tab`
|
26
|
+
wait_for_launching
|
27
|
+
`xdotool getactivewindow type #{escape("#{cmd}\n")}` unless cmd.nil?
|
28
|
+
end
|
29
|
+
# konsoe's split is not real. It just make another duplicate session.
|
30
|
+
end
|
31
|
+
end
|
@@ -5,7 +5,7 @@ module TermDump
|
|
5
5
|
# See `man terminator` and `man termintor_config`
|
6
6
|
class Terminal < BasicTerminal
|
7
7
|
def initialize config
|
8
|
-
|
8
|
+
super config
|
9
9
|
# the config file will be ~/.config/terminator/config,
|
10
10
|
# but it may be overridden with $XDG_CONFIG_HOME
|
11
11
|
# (in which case it will be $XDG_CONFIG_HOME/terminator/config)
|
@@ -17,8 +17,6 @@ module TermDump
|
|
17
17
|
if File.exist?(configure)
|
18
18
|
lines = IO.readlines(configure)
|
19
19
|
@config = parse_configure lines
|
20
|
-
else
|
21
|
-
@config = {}
|
22
20
|
end
|
23
21
|
@default_config = {
|
24
22
|
'new_window' => 'ctrl+shift+i',
|
@@ -28,7 +26,7 @@ module TermDump
|
|
28
26
|
}
|
29
27
|
end
|
30
28
|
|
31
|
-
CONFIGURE_KEY_MAPPER = {
|
29
|
+
@@CONFIGURE_KEY_MAPPER = {
|
32
30
|
'new_tab' => 'new_tab',
|
33
31
|
'split_vert' => 'new_vsplit',
|
34
32
|
'split_horiz' => 'new_hsplit',
|
@@ -38,7 +36,8 @@ module TermDump
|
|
38
36
|
#
|
39
37
|
# The configure format of terminator:
|
40
38
|
#[keybindings]
|
41
|
-
# full_screen = <Ctrl><Shift>F11
|
39
|
+
# full_screen = <Ctrl><Shift>F11 # ...
|
40
|
+
# # ...
|
42
41
|
#
|
43
42
|
# We only care about the keybindings.
|
44
43
|
def parse_configure lines
|
@@ -50,23 +49,26 @@ module TermDump
|
|
50
49
|
if line.start_with?('[') || line == ''
|
51
50
|
in_keybindings = false
|
52
51
|
else
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
52
|
+
unless line.start_with?('#')
|
53
|
+
key, value = line.split('=', 2)
|
54
|
+
key.strip!
|
55
|
+
first, _, third = value.rpartition('#')
|
56
|
+
value = (first != "" ? first.strip : third.strip)
|
57
|
+
key = @@CONFIGURE_KEY_MAPPER[key]
|
58
|
+
unless key.nil? || value == ''
|
59
|
+
config[key] = convert_key_sequence(value)
|
60
|
+
end
|
60
61
|
end
|
61
62
|
end
|
62
|
-
|
63
|
+
|
64
|
+
end # end in keybindings
|
63
65
|
in_keybindings = true if line == '[keybindings]'
|
64
66
|
end
|
65
67
|
config
|
66
68
|
end
|
67
69
|
|
68
70
|
def exec cwd, cmd
|
69
|
-
|
71
|
+
wait_for_launching
|
70
72
|
`xdotool getactivewindow type #{escape("cd #{cwd}\n")}`
|
71
73
|
`xdotool getactivewindow type #{escape("#{cmd}\n")}` unless cmd.nil?
|
72
74
|
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require_relative 'base/base'
|
2
|
+
|
3
|
+
module TermDump
|
4
|
+
# This Terminal class is for [tilda](https://github.com/lanoxx/tilda)
|
5
|
+
# See `man tilda` and <https://github.com/lanoxx/tilda>
|
6
|
+
class Terminal < BasicTerminal
|
7
|
+
def initialize config
|
8
|
+
super config
|
9
|
+
|
10
|
+
# FIXME Could not detect the order of current tilda window,
|
11
|
+
# so guess it to be the first one
|
12
|
+
#
|
13
|
+
# Each tilda window with order x can be toggled by Fx, for example,
|
14
|
+
# the first one is toggled by F1; and use config_(x-1) as its configure.
|
15
|
+
configure = "#{Dir.home}/.config/tilda/config_0"
|
16
|
+
if File.exist?(configure)
|
17
|
+
lines = IO.readlines(configure)
|
18
|
+
@config = parse_configure lines
|
19
|
+
end
|
20
|
+
|
21
|
+
@default_config = {
|
22
|
+
'new_window' => 'F1',
|
23
|
+
'new_tab' => 'ctrl+shift+t'
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
@@CONFIGURE_KEY_MAPPER = {
|
28
|
+
'addtab_key' => 'new_tab',
|
29
|
+
'key' => 'new_window'
|
30
|
+
}
|
31
|
+
|
32
|
+
def parse_configure lines
|
33
|
+
config = {}
|
34
|
+
lines.each do |line|
|
35
|
+
line.lstrip!
|
36
|
+
unless line.start_with?('#')
|
37
|
+
key, value = line.split('=', 2)
|
38
|
+
key.strip!
|
39
|
+
key = @@CONFIGURE_KEY_MAPPER[key]
|
40
|
+
value = value.match('\A\s*"(.*?)"')
|
41
|
+
unless key.nil? || value.nil?
|
42
|
+
config[key] = convert_key_sequence(value[1])
|
43
|
+
end # need to handle key
|
44
|
+
end # not a comment line
|
45
|
+
end
|
46
|
+
config
|
47
|
+
end
|
48
|
+
|
49
|
+
# Each tilda's window is toggled by different key binding,
|
50
|
+
# For example, first tilda window is toggled by F1, second one by F2, ...
|
51
|
+
# To keep simple, treat window as tab
|
52
|
+
def window name, cwd, cmd
|
53
|
+
tab name, cwd, cmd
|
54
|
+
end
|
55
|
+
|
56
|
+
def tab name, cwd, cmd
|
57
|
+
# `getactivewindow key` not work on tilda
|
58
|
+
`xdotool key #{configure 'new_tab'}`
|
59
|
+
exec cwd, cmd
|
60
|
+
end
|
61
|
+
|
62
|
+
def exec cwd, cmd
|
63
|
+
wait_for_launching
|
64
|
+
`xdotool getactivewindow type #{escape("cd #{cwd}\n")}`
|
65
|
+
`xdotool getactivewindow type #{escape("#{cmd}\n")}` unless cmd.nil?
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require_relative 'base/base'
|
2
|
+
|
3
|
+
module TermDump
|
4
|
+
# This Terminal class is for
|
5
|
+
# [urxvt](http://software.schmorp.de/pkg/rxvt-unicode.html)
|
6
|
+
# See `man urxvt` and `man 7 urxvt`
|
7
|
+
class Terminal < BasicTerminal
|
8
|
+
def initialize config
|
9
|
+
super config
|
10
|
+
# urxvt's configure is written with perl. It is too difficult to get the
|
11
|
+
# binding key value. So here we pass the responsibility of setting key binding
|
12
|
+
# to the users.
|
13
|
+
@default_config = {
|
14
|
+
# there is no default new_window key binding in urxvt
|
15
|
+
'new_window' => nil,
|
16
|
+
'new_tab' => 'shift+Down', # it should be 'Down' not 'down'
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
def exec cwd, cmd
|
21
|
+
wait_for_launching
|
22
|
+
`xdotool getactivewindow type #{escape("cd #{cwd}\n")}`
|
23
|
+
`xdotool getactivewindow type #{escape("#{cmd}\n")}` unless cmd.nil?
|
24
|
+
end
|
25
|
+
|
26
|
+
def window name, cwd, cmd
|
27
|
+
if configure 'new_window'
|
28
|
+
`xdotool getactivewindow key #{configure 'new_window'}`
|
29
|
+
else
|
30
|
+
`xdotool getactivewindow type 'urxvt &\n'`
|
31
|
+
wait_for_launching
|
32
|
+
end
|
33
|
+
exec cwd, cmd
|
34
|
+
end
|
35
|
+
|
36
|
+
def tab name, cwd, cmd
|
37
|
+
# use `urxvt -pe tabbed` to enable tab support
|
38
|
+
`xdotool getactivewindow key #{configure 'new_tab'}`
|
39
|
+
exec cwd, cmd
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -5,10 +5,11 @@ module TermDump
|
|
5
5
|
# See `man xterm`
|
6
6
|
class Terminal < BasicTerminal
|
7
7
|
def initialize config
|
8
|
+
super config
|
8
9
|
end
|
9
10
|
|
10
11
|
def exec cwd, cmd
|
11
|
-
|
12
|
+
wait_for_launching
|
12
13
|
`xdotool getactivewindow type #{escape("cd #{cwd}\n")}`
|
13
14
|
`xdotool getactivewindow type #{escape("#{cmd}\n")}` unless cmd.nil?
|
14
15
|
end
|
data/lib/termdump/version.rb
CHANGED
data/test/test_main.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'minitest/autorun'
|
2
|
+
require 'tempfile'
|
2
3
|
require 'yaml'
|
3
4
|
|
4
5
|
require 'termdump/main'
|
@@ -21,6 +22,7 @@ class TestMain < MiniTest::Test
|
|
21
22
|
Dir.rmdir("tmp") if Dir.exist?("tmp")
|
22
23
|
Dir.mkdir "tmp"
|
23
24
|
path = File.join Dir.pwd, "tmp"
|
25
|
+
old_path = TermDump::Main.class_variable_get :@@session_dir
|
24
26
|
TermDump::Main.class_variable_set :@@session_dir, path
|
25
27
|
status = @main.search_session 'nonexistent'
|
26
28
|
assert_equal File.join(path, 'nonexistent.yml'), status[:name]
|
@@ -37,16 +39,54 @@ class TestMain < MiniTest::Test
|
|
37
39
|
assert_equal 3, Dir.entries(path).size
|
38
40
|
status = @main.search_session 'termdump'
|
39
41
|
assert_equal true, status[:exist]
|
42
|
+
assert_equal true, File.size(status[:name]) > 0
|
40
43
|
# edit_session can't be tested automatically
|
41
|
-
|
42
|
-
assert_equal true, res.is_a?(Hash)
|
43
|
-
|
44
|
-
task = @main.check res # the output of res may be modified
|
45
|
-
assert_equal true, task.is_a?(Hash)
|
44
|
+
# so is load_session
|
46
45
|
|
47
46
|
@main.delete_session 'termdump'
|
48
47
|
assert_equal 2, Dir.entries(path).size
|
48
|
+
# "tmp" should be empty
|
49
49
|
Dir.rmdir "tmp"
|
50
|
+
TermDump::Main.class_variable_set :@@session_dir, old_path
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_search_session_with_or_without_extname
|
54
|
+
name = "test"
|
55
|
+
status = @main.search_session name
|
56
|
+
session_dir = TermDump::Main.class_variable_get :@@session_dir
|
57
|
+
session_extname = TermDump::Main.class_variable_get :@@session_extname
|
58
|
+
assert_equal File.join(session_dir, name + session_extname), status[:name]
|
59
|
+
if File.exist?(status[:name])
|
60
|
+
assert_equal true, status[:exist]
|
61
|
+
else
|
62
|
+
assert_equal false, status[:exist]
|
63
|
+
end
|
64
|
+
|
65
|
+
# with or without extname is ok
|
66
|
+
name += session_extname
|
67
|
+
status = @main.search_session name
|
68
|
+
assert_equal File.join(session_dir, name), status[:name]
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_search_session
|
72
|
+
session_extname = TermDump::Main.class_variable_get :@@session_extname
|
73
|
+
Tempfile.open(['test', session_extname], Dir.pwd) do |tmp|
|
74
|
+
# with absolute path
|
75
|
+
status = @main.search_session tmp.path
|
76
|
+
assert_equal true, status[:exist]
|
77
|
+
# with relative path in pwd
|
78
|
+
status = @main.search_session File.basename(tmp.path)
|
79
|
+
assert_equal true, status[:exist]
|
80
|
+
end
|
81
|
+
|
82
|
+
session_dir = TermDump::Main.class_variable_get(:@@session_dir)
|
83
|
+
if Dir.exist?(session_dir)
|
84
|
+
Tempfile.open(['test', session_extname], session_dir) do |tmp|
|
85
|
+
status = @main.search_session File.basename(tmp.path)
|
86
|
+
# with relative path in pwd
|
87
|
+
assert_equal true, status[:exist]
|
88
|
+
end
|
89
|
+
end
|
50
90
|
end
|
51
91
|
|
52
92
|
def test_path
|
data/test/test_session.rb
CHANGED
@@ -4,7 +4,7 @@ require 'termdump/session'
|
|
4
4
|
|
5
5
|
class TestSession < MiniTest::Test
|
6
6
|
def setup
|
7
|
-
@session = TermDump::Session.new
|
7
|
+
@session = TermDump::Session.new({'terminal' => 'base/mock'})
|
8
8
|
end
|
9
9
|
|
10
10
|
def inject_node_queue actions
|
@@ -107,6 +107,7 @@ class TestSession < MiniTest::Test
|
|
107
107
|
[:tab, 'tab', 'some', 'rm -rf /'],
|
108
108
|
[:vsplit, 'vsplit', 'any', 'ls'],
|
109
109
|
[:hsplit, 'hsplit', 'else']
|
110
|
-
]
|
110
|
+
].flatten!
|
111
|
+
assert_equal expected, done_actions
|
111
112
|
end
|
112
113
|
end
|
data/test/test_tilda.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
|
3
|
+
require 'termdump/terminal/tilda'
|
4
|
+
|
5
|
+
class TestTerminator < MiniTest::Test
|
6
|
+
@@term = TermDump::Terminal.new({})
|
7
|
+
|
8
|
+
def test_parse_configure
|
9
|
+
lines = [
|
10
|
+
'addtab_key = "<Primary><Shift>x"',
|
11
|
+
'#fullscreen_key = "F11"',
|
12
|
+
]
|
13
|
+
config = @@term.parse_configure lines
|
14
|
+
assert_equal 'Ctrl+Shift+x', config['new_tab']
|
15
|
+
|
16
|
+
lines = ['addtab_key="<Control>x" # "x"']
|
17
|
+
config = @@term.parse_configure lines
|
18
|
+
assert_equal 'Ctrl+x', config['new_tab']
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: termdump
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- spacewander
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-09-05 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: termdump is a tool which can dump your pty session and replay it
|
14
14
|
email:
|
@@ -39,7 +39,10 @@ files:
|
|
39
39
|
- lib/termdump/terminal/base/terminal_helper.rb
|
40
40
|
- lib/termdump/terminal/gnome_terminal.rb
|
41
41
|
- lib/termdump/terminal/guake.rb
|
42
|
+
- lib/termdump/terminal/konsole.rb
|
42
43
|
- lib/termdump/terminal/terminator.rb
|
44
|
+
- lib/termdump/terminal/tilda.rb
|
45
|
+
- lib/termdump/terminal/urxvt.rb
|
43
46
|
- lib/termdump/terminal/xterm.rb
|
44
47
|
- lib/termdump/version.rb
|
45
48
|
- test/run_cmd.sh
|
@@ -49,6 +52,7 @@ files:
|
|
49
52
|
- test/test_main.rb
|
50
53
|
- test/test_session.rb
|
51
54
|
- test/test_terminator.rb
|
55
|
+
- test/test_tilda.rb
|
52
56
|
homepage: https://github.com/spacewander/termdump
|
53
57
|
licenses:
|
54
58
|
- MIT
|
@@ -80,6 +84,7 @@ summary: Dump your (pseudo)terminal session and replay it
|
|
80
84
|
test_files:
|
81
85
|
- test/test_session.rb
|
82
86
|
- test/run_cmd.sh
|
87
|
+
- test/test_tilda.rb
|
83
88
|
- test/test_main.rb
|
84
89
|
- test/test_command.rb
|
85
90
|
- test/test_basic_terminal.rb
|