theme-check 0.6.0 → 0.8.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.
- checksums.yaml +4 -4
- data/.github/workflows/theme-check.yml +11 -3
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +29 -0
- data/Gemfile +5 -5
- data/LICENSE.md +2 -0
- data/README.md +1 -0
- data/RELEASING.md +10 -3
- data/Rakefile +6 -0
- data/config/default.yml +3 -0
- data/dev.yml +1 -1
- data/docs/checks/remote_asset.md +82 -0
- data/exe/theme-check +1 -1
- data/lib/theme_check.rb +1 -0
- data/lib/theme_check/check.rb +1 -1
- data/lib/theme_check/checks/asset_size_css.rb +1 -1
- data/lib/theme_check/checks/asset_size_javascript.rb +1 -1
- data/lib/theme_check/checks/img_width_and_height.rb +2 -2
- data/lib/theme_check/checks/matching_translations.rb +1 -1
- data/lib/theme_check/checks/parser_blocking_javascript.rb +1 -1
- data/lib/theme_check/checks/remote_asset.rb +99 -0
- data/lib/theme_check/checks/translation_key_exists.rb +1 -4
- data/lib/theme_check/checks/undefined_object.rb +1 -1
- data/lib/theme_check/checks/valid_html_translation.rb +1 -1
- data/lib/theme_check/cli.rb +101 -57
- data/lib/theme_check/config.rb +6 -2
- data/lib/theme_check/disabled_checks.rb +2 -2
- data/lib/theme_check/in_memory_storage.rb +13 -16
- data/lib/theme_check/language_server/completion_engine.rb +2 -2
- data/lib/theme_check/language_server/completion_providers/filter_completion_provider.rb +1 -1
- data/lib/theme_check/language_server/completion_providers/object_completion_provider.rb +1 -1
- data/lib/theme_check/language_server/completion_providers/render_snippet_completion_provider.rb +1 -1
- data/lib/theme_check/language_server/completion_providers/tag_completion_provider.rb +2 -2
- data/lib/theme_check/language_server/constants.rb +2 -2
- data/lib/theme_check/language_server/document_link_engine.rb +4 -3
- data/lib/theme_check/language_server/handler.rb +29 -21
- data/lib/theme_check/language_server/server.rb +1 -2
- data/lib/theme_check/node.rb +1 -2
- data/lib/theme_check/offense.rb +3 -1
- data/lib/theme_check/packager.rb +1 -1
- data/lib/theme_check/parsing_helpers.rb +1 -1
- data/lib/theme_check/releaser.rb +39 -0
- data/lib/theme_check/shopify_liquid/deprecated_filter.rb +6 -8
- data/lib/theme_check/shopify_liquid/filter.rb +3 -5
- data/lib/theme_check/shopify_liquid/object.rb +2 -6
- data/lib/theme_check/shopify_liquid/tag.rb +1 -3
- data/lib/theme_check/storage.rb +3 -3
- data/lib/theme_check/string_helpers.rb +47 -0
- data/lib/theme_check/tags.rb +1 -2
- data/lib/theme_check/theme.rb +1 -1
- data/lib/theme_check/version.rb +1 -1
- data/packaging/homebrew/theme_check.base.rb +1 -1
- data/theme-check.gemspec +3 -2
- metadata +9 -19
data/lib/theme_check/cli.rb
CHANGED
|
@@ -1,80 +1,104 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
require "optparse"
|
|
3
|
+
|
|
2
4
|
module ThemeCheck
|
|
3
5
|
class Cli
|
|
4
6
|
class Abort < StandardError; end
|
|
5
7
|
|
|
6
|
-
|
|
7
|
-
Usage: theme-check [options] /path/to/your/theme
|
|
8
|
+
attr_accessor :path
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
-v, --version Print Theme Check version
|
|
10
|
+
def initialize
|
|
11
|
+
@path = "."
|
|
12
|
+
@command = :check
|
|
13
|
+
@only_categories = []
|
|
14
|
+
@exclude_categories = []
|
|
15
|
+
@auto_correct = false
|
|
16
|
+
@config_path = nil
|
|
17
|
+
end
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
def option_parser(parser = OptionParser.new, help: true)
|
|
20
|
+
return @option_parser if defined?(@option_parser)
|
|
21
|
+
@option_parser = parser
|
|
22
|
+
@option_parser.banner = "Usage: theme-check [options] [/path/to/your/theme]"
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
@option_parser.separator("")
|
|
25
|
+
@option_parser.separator("Basic Options:")
|
|
26
|
+
@option_parser.on(
|
|
27
|
+
"-C", "--config PATH",
|
|
28
|
+
"Use the config provided, overriding .theme-check.yml if present"
|
|
29
|
+
) { |path| @config_path = path }
|
|
30
|
+
@option_parser.on(
|
|
31
|
+
"-c", "--category CATEGORY",
|
|
32
|
+
"Only run this category of checks"
|
|
33
|
+
) { |category| @only_categories << category.to_sym }
|
|
34
|
+
@option_parser.on(
|
|
35
|
+
"-x", "--exclude-category CATEGORY",
|
|
36
|
+
"Exclude this category of checks"
|
|
37
|
+
) { |category| @exclude_categories << category.to_sym }
|
|
38
|
+
@option_parser.on(
|
|
39
|
+
"-a", "--auto-correct",
|
|
40
|
+
"Automatically fix offenses"
|
|
41
|
+
) { @auto_correct = true }
|
|
25
42
|
|
|
26
|
-
|
|
27
|
-
@
|
|
43
|
+
@option_parser.separator("")
|
|
44
|
+
@option_parser.separator("Miscellaneous:")
|
|
45
|
+
@option_parser.on(
|
|
46
|
+
"--init",
|
|
47
|
+
"Generate a .theme-check.yml file"
|
|
48
|
+
) { @command = :init }
|
|
49
|
+
@option_parser.on(
|
|
50
|
+
"--print",
|
|
51
|
+
"Output active config to STDOUT"
|
|
52
|
+
) { @command = :print }
|
|
53
|
+
@option_parser.on(
|
|
54
|
+
"-h", "--help",
|
|
55
|
+
"Show this. Hi!"
|
|
56
|
+
) { @command = :help } if help
|
|
57
|
+
@option_parser.on(
|
|
58
|
+
"-l", "--list",
|
|
59
|
+
"List enabled checks"
|
|
60
|
+
) { @command = :list }
|
|
61
|
+
@option_parser.on(
|
|
62
|
+
"-v", "--version",
|
|
63
|
+
"Print Theme Check version"
|
|
64
|
+
) { @command = :version }
|
|
28
65
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
when "--version", "-v"
|
|
41
|
-
command = :version
|
|
42
|
-
when "--config", "-C"
|
|
43
|
-
config_path = Pathname.new(args.shift)
|
|
44
|
-
when "--category", "-c"
|
|
45
|
-
only_categories << args.shift.to_sym
|
|
46
|
-
when "--exclude-category", "-x"
|
|
47
|
-
exclude_categories << args.shift.to_sym
|
|
48
|
-
when "--list", "-l"
|
|
49
|
-
command = :list
|
|
50
|
-
when "--auto-correct", "-a"
|
|
51
|
-
auto_correct = true
|
|
52
|
-
when "--init"
|
|
53
|
-
command = :init
|
|
54
|
-
else
|
|
55
|
-
@path = arg
|
|
56
|
-
end
|
|
57
|
-
end
|
|
66
|
+
@option_parser.separator("")
|
|
67
|
+
@option_parser.separator(<<~EOS)
|
|
68
|
+
Description:
|
|
69
|
+
Theme Check helps you follow Shopify Themes & Liquid best practices by analyzing the
|
|
70
|
+
Liquid & JSON inside your theme.
|
|
71
|
+
|
|
72
|
+
You can configure checks in the .theme-check.yml file of your theme root directory.
|
|
73
|
+
EOS
|
|
74
|
+
|
|
75
|
+
@option_parser
|
|
76
|
+
end
|
|
58
77
|
|
|
59
|
-
|
|
60
|
-
|
|
78
|
+
def parse(argv)
|
|
79
|
+
@path = option_parser.parse(argv).first || "."
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def run!
|
|
83
|
+
unless [:version, :init, :help].include?(@command)
|
|
84
|
+
@config = if @config_path
|
|
61
85
|
ThemeCheck::Config.new(
|
|
62
86
|
root: @path,
|
|
63
|
-
configuration: ThemeCheck::Config.load_file(config_path)
|
|
87
|
+
configuration: ThemeCheck::Config.load_file(@config_path)
|
|
64
88
|
)
|
|
65
89
|
else
|
|
66
90
|
ThemeCheck::Config.from_path(@path)
|
|
67
91
|
end
|
|
68
|
-
@config.only_categories = only_categories
|
|
69
|
-
@config.exclude_categories = exclude_categories
|
|
70
|
-
@config.auto_correct = auto_correct
|
|
92
|
+
@config.only_categories = @only_categories
|
|
93
|
+
@config.exclude_categories = @exclude_categories
|
|
94
|
+
@config.auto_correct = @auto_correct
|
|
71
95
|
end
|
|
72
96
|
|
|
73
|
-
send(command)
|
|
97
|
+
send(@command)
|
|
74
98
|
end
|
|
75
99
|
|
|
76
|
-
def run
|
|
77
|
-
run
|
|
100
|
+
def run
|
|
101
|
+
run!
|
|
78
102
|
rescue Abort => e
|
|
79
103
|
if e.message.empty?
|
|
80
104
|
exit(1)
|
|
@@ -83,6 +107,18 @@ module ThemeCheck
|
|
|
83
107
|
end
|
|
84
108
|
end
|
|
85
109
|
|
|
110
|
+
def self.parse_and_run!(argv)
|
|
111
|
+
cli = new
|
|
112
|
+
cli.parse(argv)
|
|
113
|
+
cli.run!
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def self.parse_and_run(argv)
|
|
117
|
+
cli = new
|
|
118
|
+
cli.parse(argv)
|
|
119
|
+
cli.run
|
|
120
|
+
end
|
|
121
|
+
|
|
86
122
|
def list
|
|
87
123
|
puts @config.enabled_checks
|
|
88
124
|
end
|
|
@@ -102,12 +138,20 @@ module ThemeCheck
|
|
|
102
138
|
end
|
|
103
139
|
end
|
|
104
140
|
|
|
141
|
+
def print
|
|
142
|
+
puts YAML.dump(@config.to_h)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def help
|
|
146
|
+
puts option_parser.to_s
|
|
147
|
+
end
|
|
148
|
+
|
|
105
149
|
def check
|
|
106
150
|
puts "Checking #{@config.root} ..."
|
|
107
151
|
storage = ThemeCheck::FileSystemStorage.new(@config.root, ignored_patterns: @config.ignored_patterns)
|
|
108
152
|
theme = ThemeCheck::Theme.new(storage)
|
|
109
153
|
if theme.all.empty?
|
|
110
|
-
raise Abort, "No templates found
|
|
154
|
+
raise Abort, "No templates found."
|
|
111
155
|
end
|
|
112
156
|
analyzer = ThemeCheck::Analyzer.new(theme, @config.enabled_checks, @config.auto_correct)
|
|
113
157
|
analyzer.analyze_theme
|
data/lib/theme_check/config.rb
CHANGED
|
@@ -91,7 +91,11 @@ module ThemeCheck
|
|
|
91
91
|
|
|
92
92
|
options_for_check = options.transform_keys(&:to_sym)
|
|
93
93
|
options_for_check.delete(:enabled)
|
|
94
|
-
check =
|
|
94
|
+
check = if options_for_check.empty?
|
|
95
|
+
check_class.new
|
|
96
|
+
else
|
|
97
|
+
check_class.new(**options_for_check)
|
|
98
|
+
end
|
|
95
99
|
check.options = options_for_check
|
|
96
100
|
check
|
|
97
101
|
end.compact
|
|
@@ -104,7 +108,7 @@ module ThemeCheck
|
|
|
104
108
|
private
|
|
105
109
|
|
|
106
110
|
def check_name?(name)
|
|
107
|
-
name.start_with?(/[A-Z]/)
|
|
111
|
+
name.to_s.start_with?(/[A-Z]/)
|
|
108
112
|
end
|
|
109
113
|
|
|
110
114
|
def validate_configuration(configuration, default_configuration = self.class.default, parent_keys = [])
|
|
@@ -61,11 +61,11 @@ module ThemeCheck
|
|
|
61
61
|
end
|
|
62
62
|
|
|
63
63
|
def start_disabling?(text)
|
|
64
|
-
text.strip.
|
|
64
|
+
text.strip.start_with?(DISABLE_START)
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
def stop_disabling?(text)
|
|
68
|
-
text.strip.
|
|
68
|
+
text.strip.start_with?(DISABLE_END)
|
|
69
69
|
end
|
|
70
70
|
|
|
71
71
|
# Return a list of checks from a theme-check-disable comment
|
|
@@ -6,32 +6,25 @@
|
|
|
6
6
|
# as a big hash already, leave it like that and save yourself some IO.
|
|
7
7
|
module ThemeCheck
|
|
8
8
|
class InMemoryStorage < Storage
|
|
9
|
-
def initialize(files = {}, root =
|
|
9
|
+
def initialize(files = {}, root = "/dev/null")
|
|
10
10
|
@files = files
|
|
11
|
-
@root = root
|
|
11
|
+
@root = Pathname.new(root)
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
def path(
|
|
15
|
-
|
|
16
|
-
name
|
|
14
|
+
def path(relative_path)
|
|
15
|
+
@root.join(relative_path)
|
|
17
16
|
end
|
|
18
17
|
|
|
19
|
-
def relative_path
|
|
20
|
-
|
|
21
|
-
return path.relative_path_from(@root).to_s unless path.relative? || @root.nil?
|
|
22
|
-
name
|
|
18
|
+
def read(relative_path)
|
|
19
|
+
@files[relative_path]
|
|
23
20
|
end
|
|
24
21
|
|
|
25
|
-
def
|
|
26
|
-
@files[relative_path
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def write(name, content)
|
|
30
|
-
@files[relative_path(name)] = content
|
|
22
|
+
def write(relative_path, content)
|
|
23
|
+
@files[relative_path] = content
|
|
31
24
|
end
|
|
32
25
|
|
|
33
26
|
def files
|
|
34
|
-
@
|
|
27
|
+
@files.keys
|
|
35
28
|
end
|
|
36
29
|
|
|
37
30
|
def directories
|
|
@@ -41,5 +34,9 @@ module ThemeCheck
|
|
|
41
34
|
.map(&:to_s)
|
|
42
35
|
.uniq
|
|
43
36
|
end
|
|
37
|
+
|
|
38
|
+
def relative_path(absolute_path)
|
|
39
|
+
Pathname.new(absolute_path).relative_path_from(@root).to_s
|
|
40
|
+
end
|
|
44
41
|
end
|
|
45
42
|
end
|
|
@@ -10,8 +10,8 @@ module ThemeCheck
|
|
|
10
10
|
@providers = CompletionProvider.all.map { |x| x.new(storage) }
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
def completions(
|
|
14
|
-
buffer = @storage.read(
|
|
13
|
+
def completions(relative_path, line, col)
|
|
14
|
+
buffer = @storage.read(relative_path)
|
|
15
15
|
cursor = from_line_column_to_index(buffer, line, col)
|
|
16
16
|
token = find_token(buffer, cursor)
|
|
17
17
|
return [] if token.nil?
|
|
@@ -8,7 +8,7 @@ module ThemeCheck
|
|
|
8
8
|
def completions(content, cursor)
|
|
9
9
|
return [] unless can_complete?(content, cursor)
|
|
10
10
|
available_labels
|
|
11
|
-
.select { |w| w.
|
|
11
|
+
.select { |w| w.start_with?(partial(content, cursor)) }
|
|
12
12
|
.map { |filter| filter_to_completion(filter) }
|
|
13
13
|
end
|
|
14
14
|
|
|
@@ -7,7 +7,7 @@ module ThemeCheck
|
|
|
7
7
|
return [] unless can_complete?(content, cursor)
|
|
8
8
|
partial = first_word(content) || ''
|
|
9
9
|
ShopifyLiquid::Object.labels
|
|
10
|
-
.select { |w| w.
|
|
10
|
+
.select { |w| w.start_with?(partial) }
|
|
11
11
|
.map { |object| object_to_completion(object) }
|
|
12
12
|
end
|
|
13
13
|
|
|
@@ -7,12 +7,12 @@ module ThemeCheck
|
|
|
7
7
|
return [] unless can_complete?(content, cursor)
|
|
8
8
|
partial = first_word(content) || ''
|
|
9
9
|
ShopifyLiquid::Tag.labels
|
|
10
|
-
.select { |w| w.
|
|
10
|
+
.select { |w| w.start_with?(partial) }
|
|
11
11
|
.map { |tag| tag_to_completion(tag) }
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def can_complete?(content, cursor)
|
|
15
|
-
content.
|
|
15
|
+
content.start_with?(Liquid::TagStart) && (
|
|
16
16
|
cursor_on_first_word?(content, cursor) ||
|
|
17
17
|
cursor_on_start_content?(content, cursor, Liquid::TagStart)
|
|
18
18
|
)
|
|
@@ -10,8 +10,9 @@ module ThemeCheck
|
|
|
10
10
|
@storage = storage
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
def document_links(
|
|
14
|
-
buffer = @storage.read(
|
|
13
|
+
def document_links(relative_path)
|
|
14
|
+
buffer = @storage.read(relative_path)
|
|
15
|
+
return [] unless buffer
|
|
15
16
|
matches(buffer, PARTIAL_RENDER).map do |match|
|
|
16
17
|
start_line, start_character = from_index_to_line_column(
|
|
17
18
|
buffer,
|
|
@@ -40,7 +41,7 @@ module ThemeCheck
|
|
|
40
41
|
end
|
|
41
42
|
|
|
42
43
|
def link(partial)
|
|
43
|
-
|
|
44
|
+
"file://#{@storage.path('snippets/' + partial + '.liquid')}"
|
|
44
45
|
end
|
|
45
46
|
end
|
|
46
47
|
end
|
|
@@ -42,19 +42,19 @@ module ThemeCheck
|
|
|
42
42
|
alias_method :on_shutdown, :on_exit
|
|
43
43
|
|
|
44
44
|
def on_text_document_did_change(_id, params)
|
|
45
|
-
|
|
46
|
-
@storage.write(
|
|
45
|
+
relative_path = relative_path_from_text_document_uri(params)
|
|
46
|
+
@storage.write(relative_path, content_changes_text(params))
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
def on_text_document_did_close(_id, params)
|
|
50
|
-
|
|
51
|
-
@storage.write(
|
|
50
|
+
relative_path = relative_path_from_text_document_uri(params)
|
|
51
|
+
@storage.write(relative_path, "")
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
def on_text_document_did_open(_id, params)
|
|
55
|
-
|
|
56
|
-
@storage.write(
|
|
57
|
-
analyze_and_send_offenses(
|
|
55
|
+
relative_path = relative_path_from_text_document_uri(params)
|
|
56
|
+
@storage.write(relative_path, text_document_text(params))
|
|
57
|
+
analyze_and_send_offenses(text_document_uri(params))
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
def on_text_document_did_save(_id, params)
|
|
@@ -62,27 +62,27 @@ module ThemeCheck
|
|
|
62
62
|
end
|
|
63
63
|
|
|
64
64
|
def on_text_document_document_link(id, params)
|
|
65
|
-
|
|
65
|
+
relative_path = relative_path_from_text_document_uri(params)
|
|
66
66
|
send_response(
|
|
67
67
|
id: id,
|
|
68
|
-
result: document_links(
|
|
68
|
+
result: document_links(relative_path)
|
|
69
69
|
)
|
|
70
70
|
end
|
|
71
71
|
|
|
72
72
|
def on_text_document_completion(id, params)
|
|
73
|
-
|
|
73
|
+
relative_path = relative_path_from_text_document_uri(params)
|
|
74
74
|
line = params.dig('position', 'line')
|
|
75
75
|
col = params.dig('position', 'character')
|
|
76
76
|
send_response(
|
|
77
77
|
id: id,
|
|
78
|
-
result: completions(
|
|
78
|
+
result: completions(relative_path, line, col)
|
|
79
79
|
)
|
|
80
80
|
end
|
|
81
81
|
|
|
82
82
|
private
|
|
83
83
|
|
|
84
84
|
def in_memory_storage(root)
|
|
85
|
-
config =
|
|
85
|
+
config = config_for_path(root)
|
|
86
86
|
|
|
87
87
|
# Make a real FS to get the files from the snippets folder
|
|
88
88
|
fs = ThemeCheck::FileSystemStorage.new(
|
|
@@ -95,13 +95,17 @@ module ThemeCheck
|
|
|
95
95
|
.map { |fn| [fn, ""] }
|
|
96
96
|
.to_h
|
|
97
97
|
|
|
98
|
-
InMemoryStorage.new(files, root)
|
|
98
|
+
InMemoryStorage.new(files, config.root)
|
|
99
99
|
end
|
|
100
100
|
|
|
101
101
|
def text_document_uri(params)
|
|
102
102
|
params.dig('textDocument', 'uri').sub('file://', '')
|
|
103
103
|
end
|
|
104
104
|
|
|
105
|
+
def relative_path_from_text_document_uri(params)
|
|
106
|
+
@storage.relative_path(text_document_uri(params))
|
|
107
|
+
end
|
|
108
|
+
|
|
105
109
|
def text_document_text(params)
|
|
106
110
|
params.dig('textDocument', 'text')
|
|
107
111
|
end
|
|
@@ -110,9 +114,13 @@ module ThemeCheck
|
|
|
110
114
|
params.dig('contentChanges', 0, 'text')
|
|
111
115
|
end
|
|
112
116
|
|
|
113
|
-
def
|
|
114
|
-
root = ThemeCheck::Config.find(
|
|
115
|
-
|
|
117
|
+
def config_for_path(path)
|
|
118
|
+
root = ThemeCheck::Config.find(path) || @root_path
|
|
119
|
+
ThemeCheck::Config.from_path(root)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def analyze_and_send_offenses(absolute_path)
|
|
123
|
+
config = config_for_path(absolute_path)
|
|
116
124
|
storage = ThemeCheck::FileSystemStorage.new(
|
|
117
125
|
config.root,
|
|
118
126
|
ignored_patterns: config.ignored_patterns
|
|
@@ -131,12 +139,12 @@ module ThemeCheck
|
|
|
131
139
|
analyzer.offenses
|
|
132
140
|
end
|
|
133
141
|
|
|
134
|
-
def completions(
|
|
135
|
-
@completion_engine.completions(
|
|
142
|
+
def completions(relative_path, line, col)
|
|
143
|
+
@completion_engine.completions(relative_path, line, col)
|
|
136
144
|
end
|
|
137
145
|
|
|
138
|
-
def document_links(
|
|
139
|
-
@document_link_engine.document_links(
|
|
146
|
+
def document_links(relative_path)
|
|
147
|
+
@document_link_engine.document_links(relative_path)
|
|
140
148
|
end
|
|
141
149
|
|
|
142
150
|
def send_diagnostics(offenses)
|
|
@@ -162,7 +170,7 @@ module ThemeCheck
|
|
|
162
170
|
send_response(
|
|
163
171
|
method: 'textDocument/publishDiagnostics',
|
|
164
172
|
params: {
|
|
165
|
-
uri: "file
|
|
173
|
+
uri: "file://#{path}",
|
|
166
174
|
diagnostics: offenses.map { |offense| offense_to_diagnostic(offense) },
|
|
167
175
|
},
|
|
168
176
|
)
|