Module: Lydown::CLI::REPL

Defined in:
lib/lydown/cli/repl.rb

Constant Summary collapse

HISTORY_FN =
File.expand_path('~/.lydown_history')
HELP =
<<EOF
    
    pwd                 Print working directory
    cd <path>           Change working directory
    ls [<path>]         Show lydown files in working directory

    cat <file>          Show content of file
    cat <file>:<line>   Show content of file at specified line, or range of
                        lines, e.g. cat flute1:13, or cat flute1:25-27

    edit <file>         Edit file using vim
    edit <file>:<line>  Edit file using vim, place cursor at specified line
    
    score               Compile & open score
    midi                Compile & open MIDI file
    <part>              Compile & open part
    
    To exit press ctrl-C
EOF

Class Method Summary collapse

Class Method Details

.compile(opts) ⇒ Object



220
221
222
223
224
225
226
227
228
229
230
# File 'lib/lydown/cli/repl.rb', line 220

def compile(opts)
  Lydown::CLI::Support.detect_work_directory(opts)
  Lydown::CLI::Support.detect_filename(opts)

  prev_handler = trap("INT") do
    puts
  end
  Lydown::CLI::Compiler.process(opts)
ensure
  trap("INT", prev_handler)
end

.handle_cat(args) ⇒ Object



161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/lydown/cli/repl.rb', line 161

def handle_cat(args)
  if args =~ /^([^\s:]+):?(\d+)?\-?(\d+)?$/
    fn = $1
    line_start = $2
    line_end = $3
    
    if line_start
      if line_end
        line_range = (line_start.to_i - 1)..(line_end.to_i - 1)
      else
        line_range = (line_start.to_i - 1)..(line_start.to_i - 1)
      end
    else
      line_range = nil
    end
      
    return unless fn = validate_filename(fn)
    
    content = IO.read(fn)
    unless line_range
      puts content
    else
      puts content.lines[line_range].join
    end
  end
end

.handle_cd(args) ⇒ Object



109
110
111
112
113
114
115
# File 'lib/lydown/cli/repl.rb', line 109

def handle_cd(args)
  path = File.expand_path(args)
  FileUtils.cd(path)
  update_proofing_watcher(path)
rescue => e
  puts e.message
end

.handle_default(args) ⇒ Object



202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
# File 'lib/lydown/cli/repl.rb', line 202

def handle_default(args)
  opts = {}
  
  args.split(',').map(&:strip).each do |a|
    if File.file?(a) || File.file?("#{a}.ld")
      opts = {path: '.', parts: [a], mode: :part, open_target: true, repl: true}
    elsif File.directory?(a)
      opts = {path: '.', movements: [a], mode: :score, open_target: true, repl: true}
    else
      raise LydownError, "Invalid path specified - #{a}"
    end
    $stderr.puts "Processing #{a}..."
    compile(opts)
  end
rescue => e
  # do nothing
end

.handle_edit(args) ⇒ Object



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/lydown/cli/repl.rb', line 121

def handle_edit(args)
  if args =~ /(.*):(\d+)$/
    fn = $1; line = $2
  else
    fn = args; line = nil
  end
  
  return unless fn = validate_filename(fn)

  if line
    system "vim +#{line} #{fn} -c 'normal zz'"
  else
    system "vim #{fn}"
  end
end

.handle_git(args) ⇒ Object



117
118
119
# File 'lib/lydown/cli/repl.rb', line 117

def handle_git(args)
  puts `git #{args}`
end

.handle_help(args) ⇒ Object



101
102
103
# File 'lib/lydown/cli/repl.rb', line 101

def handle_help(args)
  puts HELP; puts
end

.handle_ls(args) ⇒ Object



157
158
159
# File 'lib/lydown/cli/repl.rb', line 157

def handle_ls(args)
  system 'ls'
end

.handle_midi(args) ⇒ Object



194
195
196
197
198
199
200
# File 'lib/lydown/cli/repl.rb', line 194

def handle_midi(args)
  opts = {path: '.', open_target: true, mode: :score, format: :midi, 
    repl: true
  }
  $stderr.puts "Processing MIDI..."
  compile(opts)
end

.handle_pwd(args) ⇒ Object



105
106
107
# File 'lib/lydown/cli/repl.rb', line 105

def handle_pwd(args)
  puts FileUtils.pwd
end

.handle_score(args) ⇒ Object



188
189
190
191
192
# File 'lib/lydown/cli/repl.rb', line 188

def handle_score(args)
  opts = {path: '.', open_target: true, mode: :score, repl: true}
  $stderr.puts "Processing score..."
  compile(opts)
end

.load_historyObject



47
48
49
50
51
52
# File 'lib/lydown/cli/repl.rb', line 47

def load_history
  IO.read(HISTORY_FN).lines.each do |l|
    Readline::HISTORY << l.chomp
  end
rescue
end

.maintain_clean_history(line) ⇒ Object



39
40
41
42
43
# File 'lib/lydown/cli/repl.rb', line 39

def maintain_clean_history(line)
  if line =~ /^\s*$/ or Readline::HISTORY.to_a[-2] == line
    Readline::HISTORY.pop
  end
end

.process(line) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/lydown/cli/repl.rb', line 68

def process(line)
  if line =~ /^([a-z]+)\s?(.*)$/
    cmd = $1
    args = $2
    cmd_method = :"handle_#{cmd}"
    if respond_to?(cmd_method)
      send(cmd_method, args)
    else
      handle_default(line)
    end
  end
end

.promptObject



64
65
66
# File 'lib/lydown/cli/repl.rb', line 64

def prompt
  "#{File.basename(FileUtils.pwd)}"
end

.runObject



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/lydown/cli/repl.rb', line 8

def run
  require 'lydown/version'
  puts "Lydown version #{Lydown::VERSION}"
  
  lilypond_version = Lydown::Lilypond.detect_lilypond_version(true)
  if lilypond_version
    puts "Lilypond version #{lilypond_version}"
  end

  require 'lydown'
  
  orig_dir = FileUtils.pwd
  
  trap("INT") do
    Lydown::CLI::Proofing.unwatch # stop file watcher for proofing
    save_history
    puts
    FileUtils.cd(orig_dir)
    exit(0)
  end
  
  load_history
  
  update_proofing_watcher(orig_dir)
  
  while line = Readline.readline(prompt, true).chomp
    maintain_clean_history(line)
    process(line)
  end
end

.save_historyObject



54
55
56
57
58
59
60
61
62
# File 'lib/lydown/cli/repl.rb', line 54

def save_history
  File.open(HISTORY_FN, 'w+') do |f|
    Readline::HISTORY.to_a.each do |l|
      f.puts l
    end
  end
rescue => e
  puts "Failed to save history: #{e.message}"
end

.update_proofing_watcher(path) ⇒ Object



148
149
150
151
152
153
154
155
# File 'lib/lydown/cli/repl.rb', line 148

def update_proofing_watcher(path)
  opts = {path: path, proof_mode: true, open_target: true, 
    no_progress_bar: true, silent: true, repl: true}
  Lydown::CLI::Support.detect_work_directory(opts)
  Lydown::CLI::Support.detect_filename(opts)
  
  Lydown::CLI::Proofing.watch(opts)
end

.validate_filename(fn) ⇒ Object



137
138
139
140
141
142
143
144
145
146
# File 'lib/lydown/cli/repl.rb', line 137

def validate_filename(fn)
  unless File.file?(fn)
    fn += '.ld'
    unless File.file?(fn)
      puts "File not found"
      return nil
    end
  end
  fn
end