mayl 0.1.0 → 0.2.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.
@@ -2,6 +2,17 @@ module Mayl
2
2
  # Public: The Commands module is a namespace for all the commands that Mayl
3
3
  # uses.
4
4
  module Commands
5
+ def self.autocomplete(line, env)
6
+ key = line.split.first || ''
7
+
8
+ # Try to get namespaces or keys
9
+ keys = env.autocomplete(key)
10
+ return keys if keys.any?
11
+
12
+ # If not, autocomplete commands
13
+ opts = constants.map(&:to_s).map(&:downcase)
14
+ opts.grep(/^#{Regexp.escape(key)}/)
15
+ end
5
16
  end
6
17
  end
7
18
 
@@ -14,6 +14,7 @@ module Mayl
14
14
  # path - the path to cd in
15
15
  def initialize(env, path)
16
16
  @env = env
17
+ path = path.split('.').reject(&:empty?).compact.join('.') if path =~ /\w/
17
18
  @path = path
18
19
  end
19
20
 
@@ -29,6 +30,8 @@ module Mayl
29
30
  when "."
30
31
  @env.namespace = ""
31
32
  else
33
+ check_namespace!
34
+
32
35
  if @env.namespace.empty?
33
36
  @env.namespace = @path
34
37
  else
@@ -37,6 +40,19 @@ module Mayl
37
40
  end
38
41
  nil
39
42
  end
43
+
44
+ # Public: Checks that you're not trying to enter a leaf.
45
+ #
46
+ # Raises an ArgumentError if you are.
47
+ def check_namespace!
48
+ namespace = [@env.namespace, @path].reject(&:empty?).join('.')
49
+ matches = @env.peek(namespace).compact
50
+
51
+ if matches.empty?
52
+ key = @path.split('.').last
53
+ raise ArgumentError, "Can't cd to #{key} -- it's a leaf"
54
+ end
55
+ end
40
56
  end
41
57
  end
42
58
  end
@@ -19,9 +19,7 @@ module Mayl
19
19
  #
20
20
  # Returns nil.
21
21
  def execute
22
- locales.map { |locale|
23
- locale.peek(@env.namespace)
24
- }.flatten.uniq.each do |option|
22
+ @env.peek.each do |option|
25
23
  print "#{option} "
26
24
  end
27
25
  nil
@@ -6,6 +6,25 @@ module Mayl
6
6
  attr_accessor :last_value
7
7
  attr_accessor :namespace
8
8
 
9
+ # Public: Autocompletes a key looking at the current namespace and
10
+ # their contents.
11
+ #
12
+ # key - the partial key to consult in the namespace.
13
+ #
14
+ # Returns an Array of results.
15
+ def autocomplete(key)
16
+ peek.grep(/^#{Regexp.escape(key)}/)
17
+ end
18
+
19
+ # Public: Returns the keys inside a namespace, by default ours.
20
+ #
21
+ # namespace - the namespace to peek in. It's ours by default.
22
+ #
23
+ # Returns an Array of results.
24
+ def peek(namespace=self.namespace)
25
+ locales.map { |locale| locale.peek(namespace) }.flatten.uniq
26
+ end
27
+
9
28
  # Public: Initializes a new Env loading the locales from a path.
10
29
  def initialize(path)
11
30
  @locales = Loader.load(path)
@@ -1,3 +1,5 @@
1
+ require "readline"
2
+
1
3
  module Mayl
2
4
  # Public: The class responsible for reading user input, interpreting it and
3
5
  # executing associated commands.
@@ -18,19 +20,31 @@ module Mayl
18
20
  # Returns nothing.
19
21
  def start
20
22
  locales = @env.locales.map(&:name)
23
+ stty_save = `stty -g`.chomp
21
24
  prompt = "> "
22
25
  puts "Detected locales: #{locales.join(', ')}"
23
- while (print prompt; input = $stdin.gets)
24
- begin
25
- value = @parser.parse(input.chomp).execute
26
- @env.last_value = value
27
- @env.commit
28
- prompt = [@env.namespace, '> '].reject(&:empty?).join ' '
29
- rescue => e
30
- print "Error: #{e.message}"
31
- ensure
32
- print "\n"
26
+
27
+ env = @env
28
+ Readline.completion_proc = proc { |s| Commands.autocomplete(s, env) }
29
+ Readline.completion_append_character = ''
30
+ # Readline.completer_word_break_characters = 23.chr
31
+
32
+ begin
33
+ while input = Readline.readline(prompt, true)
34
+ begin
35
+ value = @parser.parse(input.chomp).execute
36
+ @env.last_value = value
37
+ @env.commit
38
+ prompt = [@env.namespace, '> '].reject(&:empty?).join ' '
39
+ rescue => e
40
+ print "Error: #{e.message}"
41
+ ensure
42
+ print "\n"
43
+ end
33
44
  end
45
+ rescue Interrupt
46
+ system("stty", stty_save)
47
+ exit
34
48
  end
35
49
  end
36
50
  end
@@ -1,4 +1,4 @@
1
1
  module Mayl
2
2
  # The version of the Mayl gem.
3
- VERSION = "0.1.0"
3
+ VERSION = "0.2.0"
4
4
  end
@@ -12,21 +12,30 @@ module Mayl
12
12
 
13
13
  it 'enters a directory' do
14
14
  @command = Cd.new @env, 'post.attributes'
15
+ @command.stubs(:check_namespace!)
15
16
  @command.execute
16
17
  @env.namespace.must_equal 'activerecord.models.post.attributes'
17
18
  end
18
19
 
19
20
  it 'goes down one level' do
20
21
  @command = Cd.new @env, '..'
22
+ @command.stubs(:check_namespace!)
21
23
  @command.execute
22
24
  @env.namespace.must_equal 'activerecord'
23
25
  end
24
26
 
25
27
  it 'goes to the root level' do
26
28
  @command = Cd.new @env, '.'
29
+ @command.stubs(:check_namespace!)
27
30
  @command.execute
28
31
  @env.namespace.must_equal ''
29
32
  end
33
+
34
+ it 'does not enter leaves' do
35
+ @env.stubs(:peek).returns []
36
+ @command = Cd.new @env, 'activerecord.models.post'
37
+ proc { @command.execute }.must_raise ArgumentError
38
+ end
30
39
  end
31
40
  end
32
41
  end
@@ -11,8 +11,7 @@ module Mayl
11
11
  end
12
12
 
13
13
  it 'prints the current keys inside the namespace' do
14
- @locales.first.expects(:peek).with('activerecord').returns ['models']
15
- @locales.last.expects(:peek).with('activerecord').returns ['attributes', 'models']
14
+ @env.expects(:peek).returns ['models', 'attributes']
16
15
 
17
16
  @command.expects(:print).with('models ')
18
17
  @command.expects(:print).with('attributes ')
@@ -3,7 +3,7 @@ require 'test_helper'
3
3
  module Mayl
4
4
  describe Env do
5
5
  before do
6
- @locales = [stub, stub]
6
+ @locales = [stub(peek: [:baz]), stub(peek: [:bar])]
7
7
  Loader.expects(:load).with('my/path').returns @locales
8
8
  @env = Mayl::Env.new('my/path')
9
9
  end
@@ -19,6 +19,14 @@ module Mayl
19
19
 
20
20
  @env.commit
21
21
  end
22
+
23
+ it 'peeks in the locales' do
24
+ @env.peek.must_equal [:baz, :bar]
25
+ end
26
+
27
+ it 'autocompletes from a key' do
28
+ @env.autocomplete('ba').must_equal [:baz, :bar]
29
+ end
22
30
  end
23
31
  end
24
32
 
@@ -12,7 +12,7 @@ module Mayl
12
12
  @baz = stub
13
13
  @baz.expects(:execute)
14
14
 
15
- $stdin.expects(:gets).times(3).returns("foo bar\n", "baz lol\n", nil)
15
+ Readline.expects(:readline).times(3).returns("foo bar\n", "baz lol\n", nil)
16
16
 
17
17
  @repl.parser.expects(:parse).with('foo bar').returns @foo
18
18
  @repl.parser.expects(:parse).with('baz lol').returns @baz
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mayl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-17 00:00:00.000000000 Z
12
+ date: 2012-04-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: yard