coolline 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.
@@ -1,15 +1,20 @@
1
1
  require 'io/console'
2
2
 
3
3
  class Coolline
4
- if ENV["XDG_CONFIG_HOME"]
5
- ConfigDir = ENV["XDG_CONFIG_HOME"]
6
- ConfigFile = File.join(ConfigDir, "coolline.rb")
4
+ if config_home = ENV["XDG_CONFIG_HOME"] and !config_home.empty?
5
+ ConfigDir = File.join(config_home, "coolline")
7
6
  else
8
- ConfigDir = ENV["HOME"]
9
- ConfigFile = File.join(ConfigDir, ".coolline.rb")
7
+ ConfigDir = File.join(ENV["HOME"], ".config", "coolline")
10
8
  end
11
9
 
12
- HistoryFile = File.join(ConfigDir, ".coolline-history")
10
+ if cache_home = ENV["XDG_CACHE_HOME"] and !cache_home.empty?
11
+ CacheDir = File.join(cache_home, "coolline")
12
+ else
13
+ CacheDir = File.join(ENV["HOME"], ".cache", "coolline")
14
+ end
15
+
16
+ ConfigFile = File.join(ConfigDir, "coolline.rb")
17
+ HistoryFile = File.join(CacheDir, "history")
13
18
 
14
19
  NullFile = if defined? File::NULL
15
20
  File::NULL
@@ -17,7 +22,7 @@ class Coolline
17
22
  "/dev/null"
18
23
  end
19
24
 
20
- AnsiCode = %r{(\e\[\??\d+(?:;\d+)?\w)}
25
+ AnsiCode = %r{(\e\[\??\d+(?:[;\d]*)\w)}
21
26
 
22
27
  # @return [Hash] All the defaults settings
23
28
  Settings = {
@@ -29,6 +34,7 @@ class Coolline
29
34
  Handler.new(?\C-a, &:beginning_of_line),
30
35
  Handler.new(?\C-e, &:end_of_line),
31
36
  Handler.new(?\C-k, &:kill_line),
37
+ Handler.new(?\C-u, &:clear_line),
32
38
  Handler.new(?\C-f, &:forward_char),
33
39
  Handler.new(?\C-b, &:backward_char),
34
40
  Handler.new(?\C-d, &:kill_current_char_or_leave),
@@ -38,6 +44,7 @@ class Coolline
38
44
  Handler.new(?\C-n, &:next_history_line),
39
45
  Handler.new(?\C-p, &:previous_history_line),
40
46
  Handler.new(?\C-r, &:interactive_search),
47
+ Handler.new(?\C-l, &:clear_screen),
41
48
  Handler.new(?\t, &:complete),
42
49
  Handler.new(?\C-a..?\C-z) {},
43
50
 
@@ -46,14 +53,21 @@ class Coolline
46
53
  Handler.new("\ef", &:forward_word),
47
54
  Handler.new("\e[A", &:previous_history_line),
48
55
  Handler.new("\e[B", &:next_history_line),
56
+ Handler.new("\e[3~", &:kill_current_char),
49
57
  Handler.new("\e[5~", &:previous_history_line),
50
58
  Handler.new("\e[6~", &:next_history_line),
59
+ Handler.new("\e[7~", &:beginning_of_line),
60
+ Handler.new("\e[8~", &:end_of_line),
51
61
  Handler.new("\e[C", &:forward_char),
52
62
  Handler.new("\e[D", &:backward_char),
63
+ Handler.new("\e[F", &:end_of_line),
64
+ Handler.new("\e[H", &:beginning_of_line),
53
65
  Handler.new("\et", &:transpose_words),
54
66
  Handler.new("\ec", &:capitalize_word),
55
67
  Handler.new("\eu", &:uppercase_word),
56
68
  Handler.new("\el", &:lowercase_word),
69
+ Handler.new("\e<", &:first_history_line),
70
+ Handler.new("\e>", &:last_history_line),
57
71
 
58
72
  Handler.new(/\e.+/) {},
59
73
  ],
@@ -84,6 +98,15 @@ class Coolline
84
98
  load_config! unless @config_loaded
85
99
  end
86
100
 
101
+ # Binds a key to a block. This key binding will have precedence over already
102
+ # defined key bindings.
103
+ #
104
+ # @param [String] key Key code sent by the terminal
105
+ # @yieldparam [Coolline] cool Coolline instance to use
106
+ def self.bind(key, &action)
107
+ Coolline::Settings[:handlers].unshift Coolline::Handler.new(key, &action)
108
+ end
109
+
87
110
  # Creates a new cool line.
88
111
  #
89
112
  # @yieldparam [Coolline] self
@@ -227,6 +250,8 @@ class Coolline
227
250
  @history[-1] = @line if @history.size != 0
228
251
  @history.index = @history.size
229
252
 
253
+ @history.save_line
254
+
230
255
  @line + "\n"
231
256
  end
232
257
 
@@ -240,6 +265,12 @@ class Coolline
240
265
  @output.print(*objs)
241
266
  end
242
267
 
268
+ # Closes the History object. Should be called when you're done with a Coolline
269
+ # instance.
270
+ def close
271
+ @history.close
272
+ end
273
+
243
274
  # Selects the previous line in history (if any)
244
275
  def previous_history_line
245
276
  if @history.index >= 0
@@ -251,6 +282,15 @@ class Coolline
251
282
  end_of_line
252
283
  end
253
284
 
285
+ # Selects the first line of history
286
+ def first_history_line
287
+ @history.index = 0
288
+ @line.replace @history[0]
289
+
290
+ @history_moved = true
291
+ end_of_line
292
+ end
293
+
254
294
  # Selects the next line in history (if any).
255
295
  #
256
296
  # When on the last line, this method replaces the current line with an empty
@@ -269,6 +309,15 @@ class Coolline
269
309
  end_of_line
270
310
  end
271
311
 
312
+ # Selects the last line of history
313
+ def last_history_line
314
+ @history.index = @history.size - 2
315
+ @line.replace @history[@history.index]
316
+
317
+ @history_moved = true
318
+ end_of_line
319
+ end
320
+
272
321
  # Prompts the user to search for a line
273
322
  def interactive_search
274
323
  found_index = @history.index
@@ -349,6 +398,11 @@ class Coolline
349
398
  (string =~ AnsiCode) == 0
350
399
  end
351
400
 
401
+ def clear_screen
402
+ print "\e[2J" # clear
403
+ print "\e[0;0H" # goto 0, 0
404
+ end
405
+
352
406
  private
353
407
  def transform(line)
354
408
  @transform_proc.call(line)
@@ -128,6 +128,12 @@ class Coolline
128
128
  line[pos..-1] = ""
129
129
  end
130
130
 
131
+ # Removes all the characters in the line
132
+ def clear_line
133
+ line.clear
134
+ self.pos = 0
135
+ end
136
+
131
137
  # Swaps the previous character with the current one
132
138
  def transpose_chars
133
139
  if line.size >= 2
@@ -5,7 +5,7 @@ class Coolline
5
5
  attr_accessor :index
6
6
 
7
7
  def initialize(filename, max_size = 5000)
8
- @io = File.open(filename, 'a+')
8
+ @io = open_file(filename)
9
9
  @max_size = max_size
10
10
 
11
11
  @lines = []
@@ -17,7 +17,7 @@ class Coolline
17
17
 
18
18
  def reopen(filename)
19
19
  close
20
- @io = File.open(filename, 'a+')
20
+ @io = open_file(filename)
21
21
 
22
22
  load_lines
23
23
  end
@@ -42,9 +42,6 @@ class Coolline
42
42
  end
43
43
 
44
44
  def <<(el)
45
- @io.puts el
46
- @io.flush
47
-
48
45
  @lines << el.dup
49
46
  @lines.delete_at(0) if @lines.size > @max_size
50
47
 
@@ -63,6 +60,11 @@ class Coolline
63
60
  @lines[id] = val
64
61
  end
65
62
 
63
+ def save_line
64
+ @io.puts self[-1]
65
+ @io.flush
66
+ end
67
+
66
68
  def size
67
69
  @lines.size
68
70
  end
@@ -70,6 +72,7 @@ class Coolline
70
72
  attr_accessor :max_size
71
73
 
72
74
  private
75
+
73
76
  def load_lines
74
77
  line_count = @io.count
75
78
  @io.rewind
@@ -83,5 +86,25 @@ class Coolline
83
86
  end
84
87
  end
85
88
  end
89
+
90
+ def open_file(filename)
91
+ dirname = File.dirname(filename)
92
+
93
+ if !Dir.exist?(dirname)
94
+ create_path(dirname)
95
+ end
96
+
97
+ File.open(filename, "a+")
98
+ end
99
+
100
+ def create_path(path)
101
+ dir = File.dirname(path)
102
+
103
+ if !Dir.exist? dir
104
+ create_path(dir)
105
+ end
106
+
107
+ Dir.mkdir(path, 0700)
108
+ end
86
109
  end
87
110
  end
@@ -1,3 +1,3 @@
1
1
  class Coolline
2
- Version = "0.2.0"
2
+ Version = "0.3.0"
3
3
  end
data/repl.rb CHANGED
@@ -4,6 +4,10 @@ require 'coolline'
4
4
  require 'coderay'
5
5
  require 'pp'
6
6
 
7
+ Coolline.bind "\C-z" do |c|
8
+ puts c.object_id
9
+ end
10
+
7
11
  cool = Coolline.new do |c|
8
12
  c.transform_proc = proc do
9
13
  CodeRay.scan(c.line, :ruby).term
@@ -20,8 +24,12 @@ end
20
24
 
21
25
  loop do
22
26
  line = cool.readline
23
- obj = eval(line)
27
+ break if line == "exit\n"
28
+
29
+ obj = eval(line)
24
30
 
25
31
  print "=> "
26
32
  pp obj
27
33
  end
34
+
35
+ cool.close
@@ -0,0 +1,17 @@
1
+ require File.expand_path("helpers.rb", File.dirname(__FILE__))
2
+
3
+ context "a user uses colors for live code highlighting" do
4
+ setup do
5
+ Coolline.new
6
+ end
7
+
8
+ context "stripping 8-color ANSI codes" do
9
+ asserts(:strip_ansi_codes, "\033[42mLove\033[0m").equals "Love"
10
+ asserts(:strip_ansi_codes, "\e[42mLove\e[0m").equals "Love"
11
+ end
12
+
13
+ context "stripping non 8-color ANSI codes" do
14
+ asserts(:strip_ansi_codes, "\033[38;5;232mHate\033[0m").equals "Hate"
15
+ asserts(:strip_ansi_codes, "\e[38;5;232mHate\e[0m").equals "Hate"
16
+ end
17
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: coolline
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-03 00:00:00.000000000 Z
12
+ date: 2012-07-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: riot
16
- requirement: &12993820 !ruby/object:Gem::Requirement
16
+ requirement: &18648680 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,7 +21,7 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *12993820
24
+ version_requirements: *18648680
25
25
  description: ! 'A readline-like library that allows to change how the input
26
26
 
27
27
  is displayed.
@@ -40,6 +40,7 @@ files:
40
40
  - lib/coolline.rb
41
41
  - test/helpers.rb
42
42
  - test/editor_test.rb
43
+ - test/coolline_test.rb
43
44
  - test/run_all.rb
44
45
  - test/history_test.rb
45
46
  - repl.rb