#!/usr/bin/ruby

require 'tins/xt'
include Tins::GO
require 'utils'
include Utils
require 'tempfile'

def usage
  puts <<-EOT
Usage: #{File.basename($0)} [OPTS] [PATHS]

PATHS are the directory and file paths that are opened in the vim.

Options are

  -w             open a buffer in vim and wait until it is deleted
  -s             read files and files:linenumbers from stdin and open them
  -m             make intermediate non existing directories to file
  -g [m|c|d|o|g] open modified/cached/deleted/other/(next git commit) files
  -c COMMAND     send ex command to the current running editor
  -C COMMAND     send visual command to the current running editor
  -p DURATION    pause for this many seconds to wait for vim's reaction
  -S SERVER      specify the server for this edit command
  -l             list current vim servers
  -h             display this help

Version is #{File.basename($0)} #{Utils::VERSION}.
  EOT
  exit 1
end

$opt = go 'p:S:c:g:wsmlh'
$opt[?h] and usage

config = Utils::ConfigFile.new
config.configure_from_paths

editor = Editor.new do |c|
  c.wait           = $opt[?w]
  c.pause_duration = ($opt[?p] || 1).to_i
  s = $opt[?S] and c.servername = s
  c.mkdir = $opt[?m]
end

if $opt[?l]
  puts editor.serverlist
  exit 0
elsif $opt[?s]
  begin
    until STDIN.eof?
      line = STDIN.gets
      line = line.sub(/.*?([^:\s]+:)/, '\1')
      editor.edit(line)
    end
  rescue Interrupt
    exit 1
  end
  exit 0
elsif command = $opt[?c]
  editor.edit_remote_send "\e:#{command}\n"
elsif command = $opt[?C]
  editor.edit_remote_send command
end

argv = ARGV.dup
if argv.empty?
  unless STDIN.tty?
    file = File.new(File.join(Dir.tmpdir, "edit_tmp.#$$"), 'w')
    until STDIN.eof?
      buffer = STDIN.read(8192)
      file.write buffer
    end
    file.close
    argv << file.path
  end
end
case git_files_arg = $opt[?g]
when ?g
  argv.concat `git diff HEAD --name-only`.lines.map(&:chomp).uniq
when /\A[mcdo]\z/
  argv.concat `git ls-files -#{git_files_arg}`.lines.map(&:chomp).uniq
end
if argv.empty?
  editor.start
else
  if editor.file_linenumber?(argv.first)
    editor.wait = argv.size > 1
    for current_file in argv
      STDOUT.puts "Edit #{current_file}"
      editor.edit current_file
    end
  else
    editor.edit(*argv)
  end
end
exit 0