Module: MilkTea::CLI::CommandSnapshot

Included in:
MilkTea::CLI
Defined in:
lib/milk_tea/tooling/cli/commands/snapshot.rb

Instance Method Summary collapse

Instance Method Details

#snapshot_commandObject



6
7
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/milk_tea/tooling/cli/commands/snapshot.rb', line 6

def snapshot_command
  input_path = nil
  theme_path = nil
  output_path = nil
  textmate_only = false

  until @argv.empty?
    arg = @argv.first
    case arg
    when "--theme", "-t"
      @argv.shift
      theme_path = @argv.shift
      unless theme_path
        @err.puts("snapshot: missing value for --theme")
        return 1
      end
    when "--output", "-o"
      @argv.shift
      output_path = @argv.shift
      unless output_path
        @err.puts("snapshot: missing value for --output")
        return 1
      end
    when "--textmate-only"
      @argv.shift
      textmate_only = true
    else
      if arg.start_with?("-")
        @err.puts("snapshot: unknown option #{arg}")
        return 1
      end
      unless input_path
        input_path = @argv.shift
      else
        @err.puts("snapshot: unexpected argument #{@argv.shift}")
        return 1
      end
    end
  end

  unless input_path
    @err.puts("snapshot: missing source file path")
    print_usage(@err)
    return 1
  end

  unless File.file?(input_path)
    @err.puts("snapshot: source file not found: #{input_path}")
    return 1
  end

  input_path = File.expand_path(input_path)
  theme_path = File.expand_path(theme_path) if theme_path
  output_path = File.expand_path(output_path) if output_path

  if theme_path && !File.file?(theme_path)
    @err.puts("snapshot: theme file not found: #{theme_path}")
    return 1
  end

  snapshot_script = MilkTea.root.join("bindings/vscode/scripts/snapshot.js").to_s
  unless File.file?(snapshot_script)
    @err.puts("snapshot: internal script not found at #{snapshot_script}")
    return 1
  end

  args = ["node", snapshot_script, input_path]
  args.push("-t", theme_path) if theme_path
  args.push("-o", output_path) if output_path

  semantic_result = nil
  unless textmate_only
    begin
      semantic_result = MilkTea::LSP::Server.semantic_tokens_for_path(input_path)
    rescue => e
      @err.puts("snapshot: semantic analysis skipped: #{e.message}")
    end
  end

  if semantic_result && semantic_result[:entries] && !semantic_result[:entries].empty?
    source = File.read(input_path)
    lines = source.split("\n", -1)
    semantic_result[:entries].each do |entry|
      byte_start = entry[:startChar]
      byte_len = entry[:length]
      line_text = lines[entry[:line]]
      unless line_text && byte_start && byte_len
        entry[:startChar] = 0
        entry[:length] = 0
        next
      end
      char_start = line_text.byteslice(0, byte_start).length
      char_length = line_text.byteslice(byte_start, byte_len).length
      char_length = line_text.length - char_start if char_start + char_length > line_text.length
      entry[:startChar] = char_start
      entry[:length] = char_length
    end

    temp = Tempfile.new(["mt_semantic", ".json"])
    temp.write(JSON.generate(semantic_result[:entries]))
    temp.close
    args.push("-s", temp.path)
    system(*args)
    temp.unlink
  else
    system(*args)
  end
  $?.success? ? 0 : 1
end