mysh 0.3.0 → 0.4.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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +95 -28
  3. data/lib/mysh.rb +13 -39
  4. data/lib/mysh/binding_wrapper.rb +21 -0
  5. data/lib/mysh/exceptions.rb +4 -0
  6. data/lib/mysh/expression.rb +11 -4
  7. data/lib/mysh/external_ruby.rb +20 -7
  8. data/lib/mysh/globalize.rb +18 -0
  9. data/lib/mysh/handlebars.rb +0 -3
  10. data/lib/mysh/init.rb +26 -0
  11. data/lib/mysh/internal/action.rb +7 -2
  12. data/lib/mysh/internal/action_pool.rb +9 -4
  13. data/lib/mysh/internal/actions/command_line.rb +56 -0
  14. data/lib/mysh/internal/actions/command_line/debug.rb +39 -0
  15. data/lib/mysh/internal/actions/command_line/init.rb +50 -0
  16. data/lib/mysh/internal/actions/command_line/load.rb +25 -0
  17. data/lib/mysh/internal/actions/command_line/post_prompt.rb +44 -0
  18. data/lib/mysh/internal/actions/command_line/pre_prompt.rb +44 -0
  19. data/lib/mysh/internal/actions/command_line/prompt.rb +42 -0
  20. data/lib/mysh/internal/actions/command_line/quit.rb +19 -0
  21. data/lib/mysh/internal/actions/command_line/usage.rb +23 -0
  22. data/lib/mysh/internal/actions/comment.rb +20 -0
  23. data/lib/mysh/internal/actions/elapsed.rb +27 -0
  24. data/lib/mysh/internal/actions/exit.rb +2 -3
  25. data/lib/mysh/internal/actions/gls.rb +1 -1
  26. data/lib/mysh/internal/actions/help/expr.txt +6 -9
  27. data/lib/mysh/internal/actions/help/quick.txt +6 -0
  28. data/lib/mysh/internal/actions/help/sub_help.rb +1 -0
  29. data/lib/mysh/internal/actions/help/usage.txt +8 -0
  30. data/lib/mysh/internal/actions/help/vars.txt +2 -2
  31. data/lib/mysh/internal/actions/load.rb +42 -0
  32. data/lib/mysh/internal/actions/quit.rb +18 -0
  33. data/lib/mysh/internal/actions/say.rb +20 -0
  34. data/lib/mysh/internal/actions/show/env.rb +13 -11
  35. data/lib/mysh/internal/actions/type.rb +4 -3
  36. data/lib/mysh/internal/actions/vars.rb +5 -5
  37. data/lib/mysh/internal/manage.rb +1 -1
  38. data/lib/mysh/process.rb +52 -0
  39. data/lib/mysh/quick.rb +3 -1
  40. data/lib/mysh/shell_variables.rb +0 -1
  41. data/lib/mysh/sources/console.rb +44 -0
  42. data/lib/mysh/{user_input → sources}/parse.rb +1 -1
  43. data/lib/mysh/{user_input/smart_source.rb → sources/smart_auto_complete.rb} +1 -1
  44. data/lib/mysh/sources/string.rb +33 -0
  45. data/lib/mysh/user_input.rb +14 -30
  46. data/lib/mysh/version.rb +1 -1
  47. data/samples/load.rb +6 -0
  48. data/samples/script.mysh +11 -0
  49. data/samples/sleep.rb +6 -0
  50. data/samples/sleep.txt +2 -0
  51. data/tests/my_shell_tests.rb +6 -4
  52. metadata +30 -5
  53. data/lib/mysh/shell_variables/globalize.rb +0 -9
@@ -8,12 +8,11 @@ module Mysh
8
8
 
9
9
  #Execute the exit command.
10
10
  def call(_args)
11
- raise MiniReadlineEOI
11
+ raise MyshExit
12
12
  end
13
13
 
14
14
  end
15
15
 
16
16
  #Add the exit command to the library.
17
- COMMANDS.add_action(ExitCommand.new('exit', 'Exit mysh.'))
18
- COMMANDS.add_action(ExitCommand.new('quit', 'Exit mysh.'))
17
+ COMMANDS.add_action(ExitCommand.new('exit', 'Exit the current mysh level.'))
19
18
  end
@@ -39,7 +39,7 @@ module Mysh
39
39
  def gather_gems
40
40
  @specs = Gem.loaded_specs
41
41
  .values
42
- .select {|spec| !(spec.name.partition(@mask)[1]).empty?}
42
+ .select {|spec| spec.name[@mask]}
43
43
  .sort {|first, second| first.name <=> second.name}
44
44
  end
45
45
 
@@ -5,15 +5,12 @@ results of this evaluation are displayed.
5
5
 
6
6
  Notes:
7
7
 
8
- Lines ending with a \\ are continued on the next line. The prompt changes to
9
- mysh\\ to indicate that this is going on. The command is NOT actually processed
10
- until a line with NO trailing \\ is entered.
11
-
12
- The results of the expression are displayed using the pretty-print facility
13
- except for nil (shows as blank).
14
-
15
- Auto-complete always places any file names in quotes so they can be used as
16
- string parameters.
8
+ * Lines ending with a \ are continued on the next line. The prompt changes to
9
+ mysh\ to indicate that this is going on. The command is NOT actually
10
+ processed until a line with NO trailing \ is entered.
11
+ * The results of the expression are displayed using the pretty-print facility.
12
+ * Auto-complete always places any file names in quotes so they can be used as
13
+ string parameters.
17
14
 
18
15
  A few special methods exist:
19
16
 
@@ -15,6 +15,12 @@ Form Form Description
15
15
  ! history Display the mysh command history, or if an index is specified,
16
16
  retrieve the command with that index value.
17
17
 
18
+ # A comment.
19
+
20
+ $ A mysh variable statement. See ?$ for more info.
21
+
22
+ % Execute a command and then report the elapsed time.
23
+
18
24
  = All command lines that begin with = are evaluated as Ruby
19
25
  expressions. The results of this evaluation are displayed.
20
26
 
@@ -28,6 +28,7 @@ module Mysh
28
28
  ['env', 'Help on the show env command.', 'env.txt' ],
29
29
  ['ruby', 'Help on the show ruby command.', 'ruby.txt' ],
30
30
  ['math', 'Help on math functions.', 'math.txt' ],
31
+ ['usage', 'Help on mysh usage.', 'usage.txt' ],
31
32
  ['=', 'Help on ruby expressions.', 'expr.txt' ],
32
33
  ['quick', 'Help on quick commands.', 'quick.txt' ],
33
34
  ['gls', 'Help on gls internal mysh command.', 'gls.txt' ],
@@ -0,0 +1,8 @@
1
+ Help: mysh usage info for version: {{ Mysh::VERSION }}
2
+
3
+ Usage: mysh <args>
4
+
5
+ Where args are one or more of the following command options:
6
+
7
+ {{ Mysh::COMMAND_LINE.actions_info.format_mysh_bullets }}
8
+
@@ -19,7 +19,7 @@ As an escapement, the string $$$$ maps to a single $$.
19
19
  Some variables that are used in mysh are:
20
20
 
21
21
  $$d The current date.
22
- $$date_fmt The format for the date: "%Y-%m-%d"
22
+ $$date_fmt The format for the date: "%Y-%m-%d". ie: 2017-01-09
23
23
  $$debug Does the shell display additional debugging info (true/false)
24
24
  $$h The home folder's path
25
25
  $$post_prompt The prompt used when a line is continued with a trailing \\
@@ -28,7 +28,7 @@ $$pre_prompt A prompt string displayed before the actual command prompt.
28
28
  Delete the pre_prompt variable to disable pre-prompting.
29
29
  $$prompt The user prompt.
30
30
  $$t The current time.
31
- $$time_fmt The format for the time: "%H:%M"
31
+ $$time_fmt The format for the time: "%H:%M". ie: 20:11
32
32
  $$u The current user.
33
33
  $$w The current working directory's path.
34
34
 
@@ -0,0 +1,42 @@
1
+ # coding: utf-8
2
+
3
+ #* mysh/internal/actions/load.rb -- The mysh load command.
4
+ module Mysh
5
+
6
+ #* mysh/internal/actions/load.rb -- The mysh load command.
7
+ class LoadCommand < Action
8
+
9
+ #Execute the load command.
10
+ #<br>Endemic Code Smells
11
+ #* :reek:TooManyStatements
12
+ def call(args)
13
+ file_name = args.shift
14
+
15
+ if file_name
16
+ file_ext, @exec_binding = File.extname(file_name), binding
17
+
18
+ if file_ext == '.mysh'
19
+ Mysh.process_file(file_name)
20
+ :internal
21
+ elsif file_ext == '.txt'
22
+ show_handlebar_file(file_name, self)
23
+ :internal
24
+ elsif ["", ".rb"].include?(file_ext)
25
+ load file_name
26
+ :internal
27
+ else
28
+ fail "Error: Unknown file type: #{file_name.inspect}"
29
+ end
30
+
31
+ else
32
+ fail "Error: A load file must be specified."
33
+ end
34
+
35
+ end
36
+
37
+ end
38
+
39
+ #Add the load command to the library.
40
+ desc = 'Load a ruby program, mysh script, or text file into the mysh environment.'
41
+ COMMANDS.add_action(LoadCommand.new('load file', desc))
42
+ end
@@ -0,0 +1,18 @@
1
+ # coding: utf-8
2
+
3
+ #* mysh/internal/actions/quit.rb -- The mysh internal quit command.
4
+ module Mysh
5
+
6
+ #* mysh/internal/actions/quit.rb -- The mysh internal quit command.
7
+ class QuitCommand < Action
8
+
9
+ #Execute the quit command.
10
+ def call(_args)
11
+ exit
12
+ end
13
+
14
+ end
15
+
16
+ #Add the quit command to the library.
17
+ COMMANDS.add_action(QuitCommand.new('quit', 'Quit out of the mysh.'))
18
+ end
@@ -0,0 +1,20 @@
1
+ # coding: utf-8
2
+
3
+ #* mysh/internal/actions/say.rb -- A mysh internal say command.
4
+ module Mysh
5
+
6
+ #* mysh/internal/actions/say.rb -- A mysh internal say command.
7
+ class SayCommand < Action
8
+
9
+ #Say something!
10
+ def call(args)
11
+ puts args.join(' ')
12
+ :internal
13
+ end
14
+
15
+ end
16
+
17
+ #Add says to the library.
18
+ desc = 'Display the text in the command arguments.'
19
+ COMMANDS.add_action(SayCommand.new('say <stuff>', desc))
20
+ end
@@ -19,17 +19,19 @@ module Mysh
19
19
  #<br>Endemic Code Smells
20
20
  #* :reek:UtilityFunction
21
21
  def info
22
- [["user", ENV['USER']],
23
- ["home", ENV['HOME']],
24
- ["name", $PROGRAM_NAME.decorate],
25
- ["shell", ENV['SHELL'] || ENV['ComSpec']],
26
- ["host", ENV['HOSTNAME'] || ENV['COMPUTERNAME']],
27
- ["os", ENV['OS']],
28
- ["platform", MiniReadline::TERM_PLATFORM],
29
- ["java", MiniReadline::TERM_JAVA != nil],
30
- ["term", ENV['TERM']],
31
- ["disp", ENV['DISPLAY']],
32
- ["edit", ENV['EDITOR']]]
22
+ [["version", Mysh::VERSION],
23
+ ["init file", $mysh_init_file],
24
+ ["user", ENV['USER']],
25
+ ["home", ENV['HOME']],
26
+ ["name", $PROGRAM_NAME.decorate],
27
+ ["os shell", ENV['SHELL'] || ENV['ComSpec']],
28
+ ["host", ENV['HOSTNAME'] || ENV['COMPUTERNAME']],
29
+ ["os", ENV['OS']],
30
+ ["platform", MiniReadline::TERM_PLATFORM],
31
+ ["java?", MiniReadline::TERM_JAVA != nil],
32
+ ["term", ENV['TERM']],
33
+ ["disp", ENV['DISPLAY']],
34
+ ["edit", ENV['EDITOR']]]
33
35
  end
34
36
 
35
37
  #Get the path.
@@ -15,13 +15,14 @@ module Mysh
15
15
  if file_name
16
16
  show_handlebar_file(file_name, self)
17
17
  else
18
- puts "Error: A text file must be specified."
18
+ fail "A text file must be specified."
19
19
  end
20
20
  end
21
21
 
22
22
  end
23
23
 
24
24
  #Add the type command to the library.
25
- desc = 'Display a text file with optional embedded handlebars.'
26
- COMMANDS.add_action(TypeCommand.new('type', desc))
25
+ desc = 'Display a text file with support for optional embedded ' +
26
+ 'handlebars and mysh variables.'
27
+ COMMANDS.add_action(TypeCommand.new('type file', desc))
27
28
  end
@@ -23,7 +23,7 @@ module Mysh
23
23
  match = VAR_EXP.match(str.chomp)
24
24
  @name, @equals, @value = match[:name], match[:equals], match[:value]
25
25
  do_command
26
- true
26
+ :internal
27
27
  end
28
28
 
29
29
  #Do the actual work here.
@@ -43,10 +43,10 @@ module Mysh
43
43
 
44
44
  #Display all variables neatly.
45
45
  def show_all_values
46
- puts MNV.keys
47
- .sort
48
- .map {|sym| ["$" + sym.to_s, MNV.get_source(sym)]}
49
- .format_mysh_bullets
46
+ puts (MNV.keys - ['$'.to_sym])
47
+ .sort
48
+ .map {|sym| ["$" + sym.to_s, MNV.get_source(sym)]}
49
+ .format_mysh_bullets
50
50
  end
51
51
 
52
52
  end
@@ -8,7 +8,7 @@ module Mysh
8
8
 
9
9
  #Parse a command string for use by commands.
10
10
  def self.parse_command(str)
11
- result = Mysh.parse_args(str.chomp)
11
+ result = parse_args(str.chomp)
12
12
 
13
13
  [COMMANDS[result.shift], result]
14
14
  end
@@ -0,0 +1,52 @@
1
+ # coding: utf-8
2
+
3
+ #* mysh/process.rb -- The mysh command processors.
4
+ module Mysh
5
+
6
+ #Process from the console.
7
+ def self.process_console
8
+ process_source(Console.new)
9
+ end
10
+
11
+ #Process from a string.
12
+ def self.process_string(str)
13
+ process_source(StringSource.new(str))
14
+ end
15
+
16
+ #Process from a file.
17
+ def self.process_file(name)
18
+ process_source(StringSource.new(IO.read(name)))
19
+ end
20
+
21
+ #Process commands from a source.
22
+ def self.process_source(source)
23
+ until source.eoi? do
24
+ execute_a_command(get_command(source))
25
+ end
26
+ rescue MyshExit
27
+ end
28
+
29
+ #Execute a single line of input and handle exceptions.
30
+ def self.execute_a_command(str)
31
+ try_execute_command(str)
32
+
33
+ rescue Interrupt, StandardError, ScriptError => err
34
+ puts "Error #{err.class}: #{err}"
35
+ puts err.backtrace if MNV[:debug]
36
+ end
37
+
38
+ #Try to execute a single line of input. Does not handle exceptions.
39
+ def self.try_execute_command(input)
40
+ unless input.start_with?("$")
41
+ input = input.preprocess
42
+ end
43
+
44
+ puts "=> #{input}" if MNV[:debug]
45
+
46
+ try_execute_quick_command(input) ||
47
+ try_execute_internal_command(input) ||
48
+ try_execute_external_ruby(input) ||
49
+ (system(input) ? :system : :error)
50
+ end
51
+
52
+ end
data/lib/mysh/quick.rb CHANGED
@@ -7,10 +7,12 @@ module Mysh
7
7
  QUICK = Hash.new(lambda {|_str| false})
8
8
 
9
9
  QUICK['!'] = lambda {|str| HISTORY_COMMAND.quick_parse_and_call(str) }
10
+ QUICK['#'] = lambda {|str| MYSH_COMMENT.call(str) }
11
+ QUICK['$'] = lambda {|str| VARS_COMMAND.call(str) }
12
+ QUICK['%'] = lambda {|str| TIMED_COMMAND.call(str) }
10
13
  QUICK['='] = lambda {|str| $mysh_exec_host.execute(str) }
11
14
  QUICK['?'] = lambda {|str| HELP_COMMAND.quick_parse_and_call(str) }
12
15
  QUICK['@'] = lambda {|str| SHOW_COMMAND.quick_parse_and_call(str) }
13
- QUICK['$'] = lambda {|str| VARS_COMMAND.call(str) }
14
16
 
15
17
  #Try to execute the string as a quick command.
16
18
  def self.try_execute_quick_command(str)
@@ -2,7 +2,6 @@
2
2
 
3
3
  require_relative 'shell_variables/shell_variable_store'
4
4
  require_relative 'shell_variables/shell_variable_keeper'
5
- require_relative 'shell_variables/globalize'
6
5
  require_relative 'shell_variables/evaluate'
7
6
 
8
7
  #* mysh/shell_variables.rb -- Adds support for mysh scripting variables.
@@ -0,0 +1,44 @@
1
+ # coding: utf-8
2
+
3
+ #* mysh/sources/console.rb -- The mysh console command source.
4
+ module Mysh
5
+
6
+ #A wrapper for the mysh console terminal.
7
+ class Console
8
+
9
+ #Setup the console wrapper.
10
+ def initialize
11
+ @eoi = false
12
+ end
13
+
14
+ #Get the initial line of command input.
15
+ def get_command
16
+ puts MNV[:pre_prompt] if MNV.key?(:pre_prompt)
17
+ get(prompt: MNV[:prompt] + '>')
18
+ end
19
+
20
+ #Get additional lines of continued commands.
21
+ def get_command_extra(str)
22
+ get(prompt: MNV[:post_prompt] + '\\', prefix: str[0])
23
+ end
24
+
25
+ #Have we reached the end of input?
26
+ def eoi?
27
+ @eoi
28
+ end
29
+
30
+ private
31
+
32
+ #Get some actual user input!
33
+ def get(parms={})
34
+ result = (input = Mysh.input).readline(parms)
35
+ input.instance_options[:initial] = ""
36
+ result
37
+ rescue MiniReadlineEOI
38
+ @eoi = true
39
+ "\n"
40
+ end
41
+
42
+ end
43
+
44
+ end
@@ -1,6 +1,6 @@
1
1
  # coding: utf-8
2
2
 
3
- #* mysh/user_input/parse.rb -- mysh general parser.
3
+ #* mysh/sources/parse.rb -- mysh general parser.
4
4
  module Mysh
5
5
 
6
6
  #Parse a string into components.
@@ -1,6 +1,6 @@
1
1
  # coding: utf-8
2
2
 
3
- #* mysh/user_input/smart_source.rb - An adaptive source for auto-complete.
3
+ #* mysh/sources/smart_auto_complete.rb - An adaptive source for auto-complete.
4
4
  module Mysh
5
5
 
6
6
  #* array_source.rb - An array as the source for auto-complete.
@@ -0,0 +1,33 @@
1
+ # coding: utf-8
2
+
3
+ #* mysh/sources/string.rb -- The mysh string command source.
4
+ module Mysh
5
+
6
+ #A wrapper for a string with mysh commands.
7
+ class StringSource
8
+
9
+ #Setup the string source.
10
+ def initialize(str)
11
+ @eoi = false
12
+ @read_pt = str.lines.each
13
+ end
14
+
15
+ #Get the initial line of command input.
16
+ def get_command(_str="")
17
+ @read_pt.next
18
+ rescue StopIteration
19
+ @eoi = true
20
+ "\n"
21
+ end
22
+
23
+ #Set up an alias as these two are identical.
24
+ alias :get_command_extra :get_command
25
+
26
+ #Have we reached the end of input?
27
+ def eoi?
28
+ @eoi
29
+ end
30
+
31
+ end
32
+
33
+ end