Skip to content

Commit f61f301

Browse files
authoredMar 11, 2025··
Fix file icon mapping (#33855)
Use the file extension mapping from VSCode's extensions. Otherwise js/ts/vba/... files won't get correct icons.
1 parent 608ccc3 commit f61f301

File tree

5 files changed

+809
-108
lines changed

5 files changed

+809
-108
lines changed
 

‎modules/fileicon/material.go

+22-6
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ type materialIconRulesData struct {
2121
FileNames map[string]string `json:"fileNames"`
2222
FolderNames map[string]string `json:"folderNames"`
2323
FileExtensions map[string]string `json:"fileExtensions"`
24+
LanguageIDs map[string]string `json:"languageIds"`
2425
}
2526

2627
type MaterialIconProvider struct {
@@ -107,25 +108,40 @@ func (m *MaterialIconProvider) FileIcon(ctx reqctx.RequestContext, entry *git.Tr
107108
return svg.RenderHTML("octicon-file")
108109
}
109110

111+
func (m *MaterialIconProvider) findIconNameWithLangID(s string) string {
112+
if _, ok := m.svgs[s]; ok {
113+
return s
114+
}
115+
if s, ok := m.rules.LanguageIDs[s]; ok {
116+
if _, ok = m.svgs[s]; ok {
117+
return s
118+
}
119+
}
120+
return ""
121+
}
122+
110123
func (m *MaterialIconProvider) FindIconName(name string, isDir bool) string {
111-
iconsData := m.rules
112124
fileNameLower := strings.ToLower(path.Base(name))
113125
if isDir {
114-
if s, ok := iconsData.FolderNames[fileNameLower]; ok {
126+
if s, ok := m.rules.FolderNames[fileNameLower]; ok {
115127
return s
116128
}
117129
return "folder"
118130
}
119131

120-
if s, ok := iconsData.FileNames[fileNameLower]; ok {
121-
return s
132+
if s, ok := m.rules.FileNames[fileNameLower]; ok {
133+
if s = m.findIconNameWithLangID(s); s != "" {
134+
return s
135+
}
122136
}
123137

124138
for i := len(fileNameLower) - 1; i >= 0; i-- {
125139
if fileNameLower[i] == '.' {
126140
ext := fileNameLower[i+1:]
127-
if s, ok := iconsData.FileExtensions[ext]; ok {
128-
return s
141+
if s, ok := m.rules.FileExtensions[ext]; ok {
142+
if s = m.findIconNameWithLangID(s); s != "" {
143+
return s
144+
}
129145
}
130146
}
131147
}

‎modules/fileicon/material_test.go

+2
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,6 @@ func TestFindIconName(t *testing.T) {
2121
p := fileicon.DefaultMaterialIconProvider()
2222
assert.Equal(t, "php", p.FindIconName("foo.php", false))
2323
assert.Equal(t, "php", p.FindIconName("foo.PHP", false))
24+
assert.Equal(t, "javascript", p.FindIconName("foo.js", false))
25+
assert.Equal(t, "visualstudio", p.FindIconName("foo.vba", false))
2426
}

‎options/fileicon/material-icon-rules.json

+197-99
Original file line numberDiff line numberDiff line change
@@ -7038,107 +7038,201 @@
70387038
"gnu": "gnuplot",
70397039
"yaml-tmlanguage": "yaml",
70407040
"tmlanguage": "xml",
7041-
"git": "git",
7042-
"git-commit": "git",
7043-
"git-rebase": "git",
7044-
"ignore": "git",
7045-
"github-actions-workflow": "github-actions-workflow",
7046-
"yaml": "yaml",
7047-
"spring-boot-properties-yaml": "yaml",
7048-
"ansible": "yaml",
7049-
"ansible-jinja": "yaml",
7050-
"matlab": "matlab",
7051-
"makefile": "settings",
7052-
"spring-boot-properties": "settings",
7041+
"cljx": "clojure",
7042+
"clojure": "clojure",
7043+
"edn": "clojure",
7044+
"cppm": "cpp",
7045+
"ccm": "cpp",
7046+
"cxxm": "cpp",
7047+
"c++m": "cpp",
7048+
"ipp": "cpp",
7049+
"ixx": "cpp",
7050+
"tpp": "cpp",
7051+
"txx": "cpp",
7052+
"hpp.in": "cpp",
7053+
"h.in": "cpp",
70537054
"diff": "diff",
7054-
"razor": "razor",
7055-
"aspnetcorerazor": "razor",
7056-
"python": "python",
7057-
"javascript": "javascript",
7058-
"typescript": "typescript",
7055+
"rej": "diff",
7056+
"fsscript": "fsharp",
7057+
"gitignore_global": "ignore",
7058+
"gitignore": "ignore",
7059+
"git-blame-ignore-revs": "ignore",
7060+
"gvy": "groovy",
7061+
"nf": "groovy",
70597062
"handlebars": "handlebars",
7060-
"perl": "perl",
7061-
"perl6": "perl",
7062-
"haxe": "haxe",
7063-
"hxml": "haxe",
7064-
"puppet": "puppet",
7065-
"elixir": "elixir",
7066-
"livescript": "livescript",
7067-
"erlang": "erlang",
7068-
"julia": "julia",
7069-
"purescript": "purescript",
7070-
"stylus": "stylus",
7071-
"robotframework": "robot",
7072-
"testoutput": "visualstudio",
7073-
"solidity": "solidity",
7074-
"autoit": "autoit",
7075-
"terraform": "terraform",
7076-
"cucumber": "cucumber",
7077-
"postcss": "postcss",
7078-
"lang-cfml": "coldfusion",
7079-
"haskell": "haskell",
7080-
"ruby": "ruby",
7081-
"php": "php",
7082-
"hack": "hack",
7083-
"javascriptreact": "react",
7084-
"processing": "processing",
7085-
"django-html": "django",
7086-
"django-txt": "django",
7063+
"hjs": "handlebars",
7064+
"hlsli": "hlsl",
7065+
"fx": "hlsl",
7066+
"fxh": "hlsl",
7067+
"vsh": "hlsl",
7068+
"psh": "hlsl",
7069+
"cginc": "hlsl",
7070+
"compute": "hlsl",
70877071
"html": "html",
7088-
"gdscript": "godot",
7089-
"gdresource": "godot-assets",
7090-
"viml": "vim",
7091-
"prolog": "prolog",
7092-
"pawn": "pawn",
7093-
"reason": "reason",
7094-
"reason_lisp": "reason",
7095-
"doctex": "tex",
7096-
"latex": "tex",
7097-
"latex-expl3": "tex",
7098-
"apex": "salesforce",
7099-
"dockercompose": "docker",
7100-
"shellscript": "console",
7101-
"objective-c": "objective-c",
7102-
"objective-cpp": "objective-cpp",
7103-
"coffeescript": "coffee",
7104-
"fsharp": "fsharp",
7105-
"editorconfig": "editorconfig",
7106-
"clojure": "clojure",
7107-
"pip-requirements": "python-misc",
7108-
"vue-postcss": "vue",
7109-
"vue-html": "vue",
7110-
"bibtex": "lib",
7111-
"bibtex-style": "lib",
7112-
"jupyter": "jupyter",
7113-
"plaintext": "document",
7114-
"powershell": "powershell",
7115-
"rsweave": "r",
7116-
"rust": "rust",
7117-
"ssh_config": "lock",
7118-
"typescriptreact": "react_ts",
7119-
"search-result": "search",
7120-
"rescript": "rescript",
7121-
"twee3": "twine",
7122-
"twee3-harlowe-3": "twine",
7123-
"twee3-chapbook-1": "twine",
7124-
"twee3-sugarcube-2": "twine",
7125-
"grain": "grain",
7126-
"lolcode": "lolcode",
7127-
"idris": "idris",
7128-
"text-gemini": "gemini",
7129-
"wolfram": "wolframlanguage",
7130-
"shaderlab": "shader",
7131-
"cadence": "cadence",
7132-
"stylable": "stylable",
7133-
"capnb": "cds",
7134-
"cds-markdown-injection": "cds",
7135-
"concourse-pipeline-yaml": "concourse",
7136-
"concourse-task-yaml": "concourse",
7137-
"systemd-conf": "systemd",
7138-
"systemd-unit-file": "systemd",
7139-
"hosts": "hosts",
7140-
"ahk2": "ahk2",
7141-
"gnuplot": "gnuplot"
7072+
"shtml": "html",
7073+
"xht": "html",
7074+
"aspx": "html",
7075+
"jshtm": "html",
7076+
"volt": "html",
7077+
"rhtml": "html",
7078+
"directory": "properties",
7079+
"gitattributes": "properties",
7080+
"gitconfig": "properties",
7081+
"gitmodules": "properties",
7082+
"editorconfig": "properties",
7083+
"repo": "properties",
7084+
"jav": "java",
7085+
"js": "javascript",
7086+
"es6": "javascript",
7087+
"cjs": "javascript",
7088+
"pac": "javascript",
7089+
"bowerrc": "json",
7090+
"jscsrc": "json",
7091+
"webmanifest": "json",
7092+
"ts.map": "json",
7093+
"har": "json",
7094+
"jslintrc": "json",
7095+
"jsonld": "json",
7096+
"geojson": "json",
7097+
"vuerc": "json",
7098+
"eslintrc": "jsonc",
7099+
"eslintrc.json": "jsonc",
7100+
"jsfmtrc": "jsonc",
7101+
"jshintrc": "jsonc",
7102+
"hintrc": "jsonc",
7103+
"babelrc": "jsonc",
7104+
"jmd": "juliamarkdown",
7105+
"cls": "tex",
7106+
"bbx": "tex",
7107+
"cbx": "tex",
7108+
"ctx": "latex",
7109+
"mak": "makefile",
7110+
"mkd": "markdown",
7111+
"mdwn": "markdown",
7112+
"mdown": "markdown",
7113+
"markdn": "markdown",
7114+
"mdtxt": "markdown",
7115+
"mdtext": "markdown",
7116+
"workbook": "markdown",
7117+
"npmignore": "ignore",
7118+
"npmrc": "properties",
7119+
"m": "objective-c",
7120+
"mm": "objective-cpp",
7121+
"pod": "perl",
7122+
"t": "perl",
7123+
"psgi": "perl",
7124+
"rakumod": "raku",
7125+
"rakutest": "raku",
7126+
"rakudoc": "raku",
7127+
"nqp": "raku",
7128+
"p6": "raku",
7129+
"pl6": "raku",
7130+
"pm6": "raku",
7131+
"php": "php",
7132+
"php4": "php",
7133+
"php5": "php",
7134+
"phtml": "php",
7135+
"ctp": "php",
7136+
"psrc": "powershell",
7137+
"rpy": "python",
7138+
"pyw": "python",
7139+
"cpy": "python",
7140+
"gyp": "python",
7141+
"gypi": "python",
7142+
"pyi": "python",
7143+
"ipy": "python",
7144+
"pyt": "python",
7145+
"rhistory": "r",
7146+
"rprofile": "r",
7147+
"rt": "r",
7148+
"razor": "razor",
7149+
"rbx": "ruby",
7150+
"rjs": "ruby",
7151+
"gemspec": "ruby",
7152+
"rake": "ruby",
7153+
"ru": "ruby",
7154+
"podspec": "ruby",
7155+
"rbi": "ruby",
7156+
"bashrc": "shellscript",
7157+
"bash_aliases": "shellscript",
7158+
"bash_profile": "shellscript",
7159+
"bash_login": "shellscript",
7160+
"ebuild": "shellscript",
7161+
"eclass": "shellscript",
7162+
"profile": "shellscript",
7163+
"bash_logout": "shellscript",
7164+
"xprofile": "shellscript",
7165+
"xsession": "shellscript",
7166+
"xsessionrc": "shellscript",
7167+
"zshrc": "shellscript",
7168+
"zprofile": "shellscript",
7169+
"zlogin": "shellscript",
7170+
"zlogout": "shellscript",
7171+
"zshenv": "shellscript",
7172+
"zsh-theme": "shellscript",
7173+
"cshrc": "shellscript",
7174+
"tcshrc": "shellscript",
7175+
"yashrc": "shellscript",
7176+
"yash_profile": "shellscript",
7177+
"dsql": "sql",
7178+
"ts": "typescript",
7179+
"cts": "typescript",
7180+
"mts": "typescript",
7181+
"brs": "vb",
7182+
"bas": "vb",
7183+
"vba": "vb",
7184+
"ascx": "xml",
7185+
"atom": "xml",
7186+
"axml": "xml",
7187+
"axaml": "xml",
7188+
"bpmn": "xml",
7189+
"csl": "xml",
7190+
"csproj.user": "xml",
7191+
"dita": "xml",
7192+
"ditamap": "xml",
7193+
"ent": "xml",
7194+
"dtml": "xml",
7195+
"fxml": "xml",
7196+
"isml": "xml",
7197+
"jmx": "xml",
7198+
"launch": "xml",
7199+
"menu": "xml",
7200+
"nuspec": "xml",
7201+
"opml": "xml",
7202+
"owl": "xml",
7203+
"proj": "xml",
7204+
"pt": "xml",
7205+
"publishsettings": "xml",
7206+
"pubxml": "xml",
7207+
"pubxml.user": "xml",
7208+
"rdf": "xml",
7209+
"rng": "xml",
7210+
"rss": "xml",
7211+
"shproj": "xml",
7212+
"storyboard": "xml",
7213+
"targets": "xml",
7214+
"tld": "xml",
7215+
"tmx": "xml",
7216+
"vbproj": "xml",
7217+
"vbproj.user": "xml",
7218+
"wsdl": "xml",
7219+
"wxi": "xml",
7220+
"wxl": "xml",
7221+
"wxs": "xml",
7222+
"xbl": "xml",
7223+
"xib": "xml",
7224+
"xliff": "xml",
7225+
"xpdl": "xml",
7226+
"xul": "xml",
7227+
"xoml": "xml",
7228+
"yaml": "yaml",
7229+
"yml": "yaml",
7230+
"eyaml": "yaml",
7231+
"eyml": "yaml",
7232+
"cff": "yaml",
7233+
"yaml-tmpreferences": "yaml",
7234+
"yaml-tmtheme": "yaml",
7235+
"winget": "yaml"
71427236
},
71437237
"fileNames": {
71447238
".pug-lintrc": "pug",
@@ -9015,7 +9109,11 @@
90159109
"caddyfile": "caddy",
90169110
"pklproject": "pkl",
90179111
"pklproject.deps.json": "pkl",
9018-
".github/funding.yml": "github-sponsors"
9112+
".github/funding.yml": "github-sponsors",
9113+
"language-configuration.json": "jsonc",
9114+
"icon-theme.json": "jsonc",
9115+
"color-theme.json": "jsonc",
9116+
"*.log.?": "log"
90199117
},
90209118
"languageIds": {
90219119
"git": "git",
+570
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,570 @@
1+
{
2+
"pkg:bat": {
3+
"bat": [
4+
".bat",
5+
".cmd"
6+
]
7+
},
8+
"pkg:clojure": {
9+
"clojure": [
10+
".clj",
11+
".cljs",
12+
".cljc",
13+
".cljx",
14+
".clojure",
15+
".edn"
16+
]
17+
},
18+
"pkg:coffeescript": {
19+
"coffeescript": [
20+
".coffee",
21+
".cson",
22+
".iced"
23+
]
24+
},
25+
"pkg:configuration-editing": {
26+
"jsonc": [
27+
".code-workspace",
28+
"language-configuration.json",
29+
"icon-theme.json",
30+
"color-theme.json"
31+
],
32+
"json": [
33+
".code-profile"
34+
]
35+
},
36+
"pkg:cpp": {
37+
"c": [
38+
".c",
39+
".i"
40+
],
41+
"cpp": [
42+
".cpp",
43+
".cppm",
44+
".cc",
45+
".ccm",
46+
".cxx",
47+
".cxxm",
48+
".c++",
49+
".c++m",
50+
".hpp",
51+
".hh",
52+
".hxx",
53+
".h++",
54+
".h",
55+
".ii",
56+
".ino",
57+
".inl",
58+
".ipp",
59+
".ixx",
60+
".tpp",
61+
".txx",
62+
".hpp.in",
63+
".h.in"
64+
],
65+
"cuda-cpp": [
66+
".cu",
67+
".cuh"
68+
]
69+
},
70+
"pkg:csharp": {
71+
"csharp": [
72+
".cs",
73+
".csx",
74+
".cake"
75+
]
76+
},
77+
"pkg:css": {
78+
"css": [
79+
".css"
80+
]
81+
},
82+
"pkg:dart": {
83+
"dart": [
84+
".dart"
85+
]
86+
},
87+
"pkg:diff": {
88+
"diff": [
89+
".diff",
90+
".patch",
91+
".rej"
92+
]
93+
},
94+
"pkg:docker": {
95+
"dockerfile": [
96+
".dockerfile",
97+
".containerfile"
98+
]
99+
},
100+
"pkg:fsharp": {
101+
"fsharp": [
102+
".fs",
103+
".fsi",
104+
".fsx",
105+
".fsscript"
106+
]
107+
},
108+
"pkg:git-base": {
109+
"ignore": [
110+
".gitignore_global",
111+
".gitignore",
112+
".git-blame-ignore-revs"
113+
]
114+
},
115+
"pkg:go": {
116+
"go": [
117+
".go"
118+
]
119+
},
120+
"pkg:groovy": {
121+
"groovy": [
122+
".groovy",
123+
".gvy",
124+
".gradle",
125+
".jenkinsfile",
126+
".nf"
127+
]
128+
},
129+
"pkg:handlebars": {
130+
"handlebars": [
131+
".handlebars",
132+
".hbs",
133+
".hjs"
134+
]
135+
},
136+
"pkg:hlsl": {
137+
"hlsl": [
138+
".hlsl",
139+
".hlsli",
140+
".fx",
141+
".fxh",
142+
".vsh",
143+
".psh",
144+
".cginc",
145+
".compute"
146+
]
147+
},
148+
"pkg:html": {
149+
"html": [
150+
".html",
151+
".htm",
152+
".shtml",
153+
".xhtml",
154+
".xht",
155+
".mdoc",
156+
".jsp",
157+
".asp",
158+
".aspx",
159+
".jshtm",
160+
".volt",
161+
".ejs",
162+
".rhtml"
163+
]
164+
},
165+
"pkg:ini": {
166+
"ini": [
167+
".ini"
168+
],
169+
"properties": [
170+
".conf",
171+
".properties",
172+
".cfg",
173+
".directory",
174+
".gitattributes",
175+
".gitconfig",
176+
".gitmodules",
177+
".editorconfig",
178+
".repo"
179+
]
180+
},
181+
"pkg:java": {
182+
"java": [
183+
".java",
184+
".jav"
185+
]
186+
},
187+
"pkg:javascript": {
188+
"javascriptreact": [
189+
".jsx"
190+
],
191+
"javascript": [
192+
".js",
193+
".es6",
194+
".mjs",
195+
".cjs",
196+
".pac"
197+
]
198+
},
199+
"pkg:json": {
200+
"json": [
201+
".json",
202+
".bowerrc",
203+
".jscsrc",
204+
".webmanifest",
205+
".js.map",
206+
".css.map",
207+
".ts.map",
208+
".har",
209+
".jslintrc",
210+
".jsonld",
211+
".geojson",
212+
".ipynb",
213+
".vuerc"
214+
],
215+
"jsonc": [
216+
".jsonc",
217+
".eslintrc",
218+
".eslintrc.json",
219+
".jsfmtrc",
220+
".jshintrc",
221+
".swcrc",
222+
".hintrc",
223+
".babelrc"
224+
],
225+
"jsonl": [
226+
".jsonl",
227+
".ndjson"
228+
],
229+
"snippets": [
230+
".code-snippets"
231+
]
232+
},
233+
"pkg:julia": {
234+
"julia": [
235+
".jl"
236+
],
237+
"juliamarkdown": [
238+
".jmd"
239+
]
240+
},
241+
"pkg:latex": {
242+
"tex": [
243+
".sty",
244+
".cls",
245+
".bbx",
246+
".cbx"
247+
],
248+
"latex": [
249+
".tex",
250+
".ltx",
251+
".ctx"
252+
],
253+
"bibtex": [
254+
".bib"
255+
]
256+
},
257+
"pkg:less": {
258+
"less": [
259+
".less"
260+
]
261+
},
262+
"pkg:log": {
263+
"log": [
264+
".log",
265+
"*.log.?"
266+
]
267+
},
268+
"pkg:lua": {
269+
"lua": [
270+
".lua"
271+
]
272+
},
273+
"pkg:make": {
274+
"makefile": [
275+
".mak",
276+
".mk"
277+
]
278+
},
279+
"pkg:markdown-basics": {
280+
"markdown": [
281+
".md",
282+
".mkd",
283+
".mdwn",
284+
".mdown",
285+
".markdown",
286+
".markdn",
287+
".mdtxt",
288+
".mdtext",
289+
".workbook"
290+
]
291+
},
292+
"pkg:ms-vscode.js-debug": {
293+
"wat": [
294+
".wat",
295+
".wasm"
296+
]
297+
},
298+
"pkg:npm": {
299+
"ignore": [
300+
".npmignore"
301+
],
302+
"properties": [
303+
".npmrc"
304+
]
305+
},
306+
"pkg:objective-c": {
307+
"objective-c": [
308+
".m"
309+
],
310+
"objective-cpp": [
311+
".mm"
312+
]
313+
},
314+
"pkg:perl": {
315+
"perl": [
316+
".pl",
317+
".pm",
318+
".pod",
319+
".t",
320+
".PL",
321+
".psgi"
322+
],
323+
"raku": [
324+
".raku",
325+
".rakumod",
326+
".rakutest",
327+
".rakudoc",
328+
".nqp",
329+
".p6",
330+
".pl6",
331+
".pm6"
332+
]
333+
},
334+
"pkg:php": {
335+
"php": [
336+
".php",
337+
".php4",
338+
".php5",
339+
".phtml",
340+
".ctp"
341+
]
342+
},
343+
"pkg:powershell": {
344+
"powershell": [
345+
".ps1",
346+
".psm1",
347+
".psd1",
348+
".pssc",
349+
".psrc"
350+
]
351+
},
352+
"pkg:pug": {
353+
"jade": [
354+
".pug",
355+
".jade"
356+
]
357+
},
358+
"pkg:python": {
359+
"python": [
360+
".py",
361+
".rpy",
362+
".pyw",
363+
".cpy",
364+
".gyp",
365+
".gypi",
366+
".pyi",
367+
".ipy",
368+
".pyt"
369+
]
370+
},
371+
"pkg:r": {
372+
"r": [
373+
".r",
374+
".rhistory",
375+
".rprofile",
376+
".rt"
377+
]
378+
},
379+
"pkg:razor": {
380+
"razor": [
381+
".cshtml",
382+
".razor"
383+
]
384+
},
385+
"pkg:restructuredtext": {
386+
"restructuredtext": [
387+
".rst"
388+
]
389+
},
390+
"pkg:ruby": {
391+
"ruby": [
392+
".rb",
393+
".rbx",
394+
".rjs",
395+
".gemspec",
396+
".rake",
397+
".ru",
398+
".erb",
399+
".podspec",
400+
".rbi"
401+
]
402+
},
403+
"pkg:rust": {
404+
"rust": [
405+
".rs"
406+
]
407+
},
408+
"pkg:scss": {
409+
"scss": [
410+
".scss"
411+
]
412+
},
413+
"pkg:search-result": {
414+
"search-result": [
415+
".code-search"
416+
]
417+
},
418+
"pkg:shaderlab": {
419+
"shaderlab": [
420+
".shader"
421+
]
422+
},
423+
"pkg:shellscript": {
424+
"shellscript": [
425+
".sh",
426+
".bash",
427+
".bashrc",
428+
".bash_aliases",
429+
".bash_profile",
430+
".bash_login",
431+
".ebuild",
432+
".eclass",
433+
".profile",
434+
".bash_logout",
435+
".xprofile",
436+
".xsession",
437+
".xsessionrc",
438+
".Xsession",
439+
".zsh",
440+
".zshrc",
441+
".zprofile",
442+
".zlogin",
443+
".zlogout",
444+
".zshenv",
445+
".zsh-theme",
446+
".fish",
447+
".ksh",
448+
".csh",
449+
".cshrc",
450+
".tcshrc",
451+
".yashrc",
452+
".yash_profile"
453+
]
454+
},
455+
"pkg:sql": {
456+
"sql": [
457+
".sql",
458+
".dsql"
459+
]
460+
},
461+
"pkg:swift": {
462+
"swift": [
463+
".swift"
464+
]
465+
},
466+
"pkg:typescript-basics": {
467+
"typescript": [
468+
".ts",
469+
".cts",
470+
".mts"
471+
],
472+
"typescriptreact": [
473+
".tsx"
474+
],
475+
"json": [
476+
".tsbuildinfo"
477+
]
478+
},
479+
"pkg:vb": {
480+
"vb": [
481+
".vb",
482+
".brs",
483+
".vbs",
484+
".bas",
485+
".vba"
486+
]
487+
},
488+
"pkg:xml": {
489+
"xml": [
490+
".xml",
491+
".xsd",
492+
".ascx",
493+
".atom",
494+
".axml",
495+
".axaml",
496+
".bpmn",
497+
".cpt",
498+
".csl",
499+
".csproj",
500+
".csproj.user",
501+
".dita",
502+
".ditamap",
503+
".dtd",
504+
".ent",
505+
".mod",
506+
".dtml",
507+
".fsproj",
508+
".fxml",
509+
".iml",
510+
".isml",
511+
".jmx",
512+
".launch",
513+
".menu",
514+
".mxml",
515+
".nuspec",
516+
".opml",
517+
".owl",
518+
".proj",
519+
".props",
520+
".pt",
521+
".publishsettings",
522+
".pubxml",
523+
".pubxml.user",
524+
".rbxlx",
525+
".rbxmx",
526+
".rdf",
527+
".rng",
528+
".rss",
529+
".shproj",
530+
".storyboard",
531+
".svg",
532+
".targets",
533+
".tld",
534+
".tmx",
535+
".vbproj",
536+
".vbproj.user",
537+
".vcxproj",
538+
".vcxproj.filters",
539+
".wsdl",
540+
".wxi",
541+
".wxl",
542+
".wxs",
543+
".xaml",
544+
".xbl",
545+
".xib",
546+
".xlf",
547+
".xliff",
548+
".xpdl",
549+
".xul",
550+
".xoml"
551+
],
552+
"xsl": [
553+
".xsl",
554+
".xslt"
555+
]
556+
},
557+
"pkg:yaml": {
558+
"yaml": [
559+
".yaml",
560+
".yml",
561+
".eyaml",
562+
".eyml",
563+
".cff",
564+
".yaml-tmlanguage",
565+
".yaml-tmpreferences",
566+
".yaml-tmtheme",
567+
".winget"
568+
]
569+
}
570+
}

‎tools/generate-svg.js

+18-3
Original file line numberDiff line numberDiff line change
@@ -63,17 +63,32 @@ async function processMaterialFileIcons() {
6363
}
6464
fs.writeFileSync(fileURLToPath(new URL(`../options/fileicon/material-icon-svgs.json`, import.meta.url)), JSON.stringify(svgSymbols, null, 2));
6565

66+
const vscodeExtensionsJson = await readFile(fileURLToPath(new URL(`generate-svg-vscode-extensions.json`, import.meta.url)));
67+
const vscodeExtensions = JSON.parse(vscodeExtensionsJson);
6668
const iconRulesJson = await readFile(fileURLToPath(new URL(`../node_modules/material-icon-theme/dist/material-icons.json`, import.meta.url)));
6769
const iconRules = JSON.parse(iconRulesJson);
6870
// The rules are from VSCode material-icon-theme, we need to adjust them to our needs
6971
// 1. We only use lowercase filenames to match (it should be good enough for most cases and more efficient)
70-
// 2. We do not have a "Language ID" system: https://code.visualstudio.com/docs/languages/identifiers#_known-language-identifiers
71-
// * So we just treat the "Language ID" as file extension, it is not always true, but it is good enough for most cases.
72+
// 2. We do not have a "Language ID" system:
73+
// * https://code.visualstudio.com/docs/languages/identifiers#_known-language-identifiers
74+
// * https://github.com/microsoft/vscode/tree/1.98.0/extensions
7275
delete iconRules.iconDefinitions;
7376
for (const [k, v] of Object.entries(iconRules.fileNames)) iconRules.fileNames[k.toLowerCase()] = v;
7477
for (const [k, v] of Object.entries(iconRules.folderNames)) iconRules.folderNames[k.toLowerCase()] = v;
7578
for (const [k, v] of Object.entries(iconRules.fileExtensions)) iconRules.fileExtensions[k.toLowerCase()] = v;
76-
for (const [k, v] of Object.entries(iconRules.languageIds)) iconRules.fileExtensions[k.toLowerCase()] = v;
79+
// Use VSCode's "Language ID" mapping from its extensions
80+
for (const [_, langIdExtMap] of Object.entries(vscodeExtensions)) {
81+
for (const [langId, names] of Object.entries(langIdExtMap)) {
82+
for (const name of names) {
83+
const nameLower = name.toLowerCase();
84+
if (nameLower[0] === '.') {
85+
iconRules.fileExtensions[nameLower.substring(1)] ??= langId;
86+
} else {
87+
iconRules.fileNames[nameLower] ??= langId;
88+
}
89+
}
90+
}
91+
}
7792
const iconRulesPretty = JSON.stringify(iconRules, null, 2);
7893
fs.writeFileSync(fileURLToPath(new URL(`../options/fileicon/material-icon-rules.json`, import.meta.url)), iconRulesPretty);
7994
}

0 commit comments

Comments
 (0)
Please sign in to comment.