aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwxiaoguang <wxiaoguang@gmail.com>2025-03-11 21:06:59 +0800
committerGitHub <noreply@github.com>2025-03-11 21:06:59 +0800
commitf61f30153b51f2db50d96268e718a1319f5c03b2 (patch)
treeaeee1abad789b59b587d15a2d35346c2cb8db835
parent608ccc32e590b57b2147e95d6d6aca4e135929fc (diff)
downloadgitea-f61f30153b51f2db50d96268e718a1319f5c03b2.tar.gz
gitea-f61f30153b51f2db50d96268e718a1319f5c03b2.zip
Fix file icon mapping (#33855)
Use the file extension mapping from VSCode's extensions. Otherwise js/ts/vba/... files won't get correct icons.
-rw-r--r--modules/fileicon/material.go28
-rw-r--r--modules/fileicon/material_test.go2
-rw-r--r--options/fileicon/material-icon-rules.json296
-rw-r--r--tools/generate-svg-vscode-extensions.json570
-rwxr-xr-xtools/generate-svg.js21
5 files changed, 809 insertions, 108 deletions
diff --git a/modules/fileicon/material.go b/modules/fileicon/material.go
index 201cf6f455..adea625c06 100644
--- a/modules/fileicon/material.go
+++ b/modules/fileicon/material.go
@@ -21,6 +21,7 @@ type materialIconRulesData struct {
FileNames map[string]string `json:"fileNames"`
FolderNames map[string]string `json:"folderNames"`
FileExtensions map[string]string `json:"fileExtensions"`
+ LanguageIDs map[string]string `json:"languageIds"`
}
type MaterialIconProvider struct {
@@ -107,25 +108,40 @@ func (m *MaterialIconProvider) FileIcon(ctx reqctx.RequestContext, entry *git.Tr
return svg.RenderHTML("octicon-file")
}
+func (m *MaterialIconProvider) findIconNameWithLangID(s string) string {
+ if _, ok := m.svgs[s]; ok {
+ return s
+ }
+ if s, ok := m.rules.LanguageIDs[s]; ok {
+ if _, ok = m.svgs[s]; ok {
+ return s
+ }
+ }
+ return ""
+}
+
func (m *MaterialIconProvider) FindIconName(name string, isDir bool) string {
- iconsData := m.rules
fileNameLower := strings.ToLower(path.Base(name))
if isDir {
- if s, ok := iconsData.FolderNames[fileNameLower]; ok {
+ if s, ok := m.rules.FolderNames[fileNameLower]; ok {
return s
}
return "folder"
}
- if s, ok := iconsData.FileNames[fileNameLower]; ok {
- return s
+ if s, ok := m.rules.FileNames[fileNameLower]; ok {
+ if s = m.findIconNameWithLangID(s); s != "" {
+ return s
+ }
}
for i := len(fileNameLower) - 1; i >= 0; i-- {
if fileNameLower[i] == '.' {
ext := fileNameLower[i+1:]
- if s, ok := iconsData.FileExtensions[ext]; ok {
- return s
+ if s, ok := m.rules.FileExtensions[ext]; ok {
+ if s = m.findIconNameWithLangID(s); s != "" {
+ return s
+ }
}
}
}
diff --git a/modules/fileicon/material_test.go b/modules/fileicon/material_test.go
index bce316c692..f36385aaf3 100644
--- a/modules/fileicon/material_test.go
+++ b/modules/fileicon/material_test.go
@@ -21,4 +21,6 @@ func TestFindIconName(t *testing.T) {
p := fileicon.DefaultMaterialIconProvider()
assert.Equal(t, "php", p.FindIconName("foo.php", false))
assert.Equal(t, "php", p.FindIconName("foo.PHP", false))
+ assert.Equal(t, "javascript", p.FindIconName("foo.js", false))
+ assert.Equal(t, "visualstudio", p.FindIconName("foo.vba", false))
}
diff --git a/options/fileicon/material-icon-rules.json b/options/fileicon/material-icon-rules.json
index 05d56cc546..fd058c82dc 100644
--- a/options/fileicon/material-icon-rules.json
+++ b/options/fileicon/material-icon-rules.json
@@ -7038,107 +7038,201 @@
"gnu": "gnuplot",
"yaml-tmlanguage": "yaml",
"tmlanguage": "xml",
- "git": "git",
- "git-commit": "git",
- "git-rebase": "git",
- "ignore": "git",
- "github-actions-workflow": "github-actions-workflow",
- "yaml": "yaml",
- "spring-boot-properties-yaml": "yaml",
- "ansible": "yaml",
- "ansible-jinja": "yaml",
- "matlab": "matlab",
- "makefile": "settings",
- "spring-boot-properties": "settings",
+ "cljx": "clojure",
+ "clojure": "clojure",
+ "edn": "clojure",
+ "cppm": "cpp",
+ "ccm": "cpp",
+ "cxxm": "cpp",
+ "c++m": "cpp",
+ "ipp": "cpp",
+ "ixx": "cpp",
+ "tpp": "cpp",
+ "txx": "cpp",
+ "hpp.in": "cpp",
+ "h.in": "cpp",
"diff": "diff",
- "razor": "razor",
- "aspnetcorerazor": "razor",
- "python": "python",
- "javascript": "javascript",
- "typescript": "typescript",
+ "rej": "diff",
+ "fsscript": "fsharp",
+ "gitignore_global": "ignore",
+ "gitignore": "ignore",
+ "git-blame-ignore-revs": "ignore",
+ "gvy": "groovy",
+ "nf": "groovy",
"handlebars": "handlebars",
- "perl": "perl",
- "perl6": "perl",
- "haxe": "haxe",
- "hxml": "haxe",
- "puppet": "puppet",
- "elixir": "elixir",
- "livescript": "livescript",
- "erlang": "erlang",
- "julia": "julia",
- "purescript": "purescript",
- "stylus": "stylus",
- "robotframework": "robot",
- "testoutput": "visualstudio",
- "solidity": "solidity",
- "autoit": "autoit",
- "terraform": "terraform",
- "cucumber": "cucumber",
- "postcss": "postcss",
- "lang-cfml": "coldfusion",
- "haskell": "haskell",
- "ruby": "ruby",
- "php": "php",
- "hack": "hack",
- "javascriptreact": "react",
- "processing": "processing",
- "django-html": "django",
- "django-txt": "django",
+ "hjs": "handlebars",
+ "hlsli": "hlsl",
+ "fx": "hlsl",
+ "fxh": "hlsl",
+ "vsh": "hlsl",
+ "psh": "hlsl",
+ "cginc": "hlsl",
+ "compute": "hlsl",
"html": "html",
- "gdscript": "godot",
- "gdresource": "godot-assets",
- "viml": "vim",
- "prolog": "prolog",
- "pawn": "pawn",
- "reason": "reason",
- "reason_lisp": "reason",
- "doctex": "tex",
- "latex": "tex",
- "latex-expl3": "tex",
- "apex": "salesforce",
- "dockercompose": "docker",
- "shellscript": "console",
- "objective-c": "objective-c",
- "objective-cpp": "objective-cpp",
- "coffeescript": "coffee",
- "fsharp": "fsharp",
- "editorconfig": "editorconfig",
- "clojure": "clojure",
- "pip-requirements": "python-misc",
- "vue-postcss": "vue",
- "vue-html": "vue",
- "bibtex": "lib",
- "bibtex-style": "lib",
- "jupyter": "jupyter",
- "plaintext": "document",
- "powershell": "powershell",
- "rsweave": "r",
- "rust": "rust",
- "ssh_config": "lock",
- "typescriptreact": "react_ts",
- "search-result": "search",
- "rescript": "rescript",
- "twee3": "twine",
- "twee3-harlowe-3": "twine",
- "twee3-chapbook-1": "twine",
- "twee3-sugarcube-2": "twine",
- "grain": "grain",
- "lolcode": "lolcode",
- "idris": "idris",
- "text-gemini": "gemini",
- "wolfram": "wolframlanguage",
- "shaderlab": "shader",
- "cadence": "cadence",
- "stylable": "stylable",
- "capnb": "cds",
- "cds-markdown-injection": "cds",
- "concourse-pipeline-yaml": "concourse",
- "concourse-task-yaml": "concourse",
- "systemd-conf": "systemd",
- "systemd-unit-file": "systemd",
- "hosts": "hosts",
- "ahk2": "ahk2",
- "gnuplot": "gnuplot"
+ "shtml": "html",
+ "xht": "html",
+ "aspx": "html",
+ "jshtm": "html",
+ "volt": "html",
+ "rhtml": "html",
+ "directory": "properties",
+ "gitattributes": "properties",
+ "gitconfig": "properties",
+ "gitmodules": "properties",
+ "editorconfig": "properties",
+ "repo": "properties",
+ "jav": "java",
+ "js": "javascript",
+ "es6": "javascript",
+ "cjs": "javascript",
+ "pac": "javascript",
+ "bowerrc": "json",
+ "jscsrc": "json",
+ "webmanifest": "json",
+ "ts.map": "json",
+ "har": "json",
+ "jslintrc": "json",
+ "jsonld": "json",
+ "geojson": "json",
+ "vuerc": "json",
+ "eslintrc": "jsonc",
+ "eslintrc.json": "jsonc",
+ "jsfmtrc": "jsonc",
+ "jshintrc": "jsonc",
+ "hintrc": "jsonc",
+ "babelrc": "jsonc",
+ "jmd": "juliamarkdown",
+ "cls": "tex",
+ "bbx": "tex",
+ "cbx": "tex",
+ "ctx": "latex",
+ "mak": "makefile",
+ "mkd": "markdown",
+ "mdwn": "markdown",
+ "mdown": "markdown",
+ "markdn": "markdown",
+ "mdtxt": "markdown",
+ "mdtext": "markdown",
+ "workbook": "markdown",
+ "npmignore": "ignore",
+ "npmrc": "properties",
+ "m": "objective-c",
+ "mm": "objective-cpp",
+ "pod": "perl",
+ "t": "perl",
+ "psgi": "perl",
+ "rakumod": "raku",
+ "rakutest": "raku",
+ "rakudoc": "raku",
+ "nqp": "raku",
+ "p6": "raku",
+ "pl6": "raku",
+ "pm6": "raku",
+ "php": "php",
+ "php4": "php",
+ "php5": "php",
+ "phtml": "php",
+ "ctp": "php",
+ "psrc": "powershell",
+ "rpy": "python",
+ "pyw": "python",
+ "cpy": "python",
+ "gyp": "python",
+ "gypi": "python",
+ "pyi": "python",
+ "ipy": "python",
+ "pyt": "python",
+ "rhistory": "r",
+ "rprofile": "r",
+ "rt": "r",
+ "razor": "razor",
+ "rbx": "ruby",
+ "rjs": "ruby",
+ "gemspec": "ruby",
+ "rake": "ruby",
+ "ru": "ruby",
+ "podspec": "ruby",
+ "rbi": "ruby",
+ "bashrc": "shellscript",
+ "bash_aliases": "shellscript",
+ "bash_profile": "shellscript",
+ "bash_login": "shellscript",
+ "ebuild": "shellscript",
+ "eclass": "shellscript",
+ "profile": "shellscript",
+ "bash_logout": "shellscript",
+ "xprofile": "shellscript",
+ "xsession": "shellscript",
+ "xsessionrc": "shellscript",
+ "zshrc": "shellscript",
+ "zprofile": "shellscript",
+ "zlogin": "shellscript",
+ "zlogout": "shellscript",
+ "zshenv": "shellscript",
+ "zsh-theme": "shellscript",
+ "cshrc": "shellscript",
+ "tcshrc": "shellscript",
+ "yashrc": "shellscript",
+ "yash_profile": "shellscript",
+ "dsql": "sql",
+ "ts": "typescript",
+ "cts": "typescript",
+ "mts": "typescript",
+ "brs": "vb",
+ "bas": "vb",
+ "vba": "vb",
+ "ascx": "xml",
+ "atom": "xml",
+ "axml": "xml",
+ "axaml": "xml",
+ "bpmn": "xml",
+ "csl": "xml",
+ "csproj.user": "xml",
+ "dita": "xml",
+ "ditamap": "xml",
+ "ent": "xml",
+ "dtml": "xml",
+ "fxml": "xml",
+ "isml": "xml",
+ "jmx": "xml",
+ "launch": "xml",
+ "menu": "xml",
+ "nuspec": "xml",
+ "opml": "xml",
+ "owl": "xml",
+ "proj": "xml",
+ "pt": "xml",
+ "publishsettings": "xml",
+ "pubxml": "xml",
+ "pubxml.user": "xml",
+ "rdf": "xml",
+ "rng": "xml",
+ "rss": "xml",
+ "shproj": "xml",
+ "storyboard": "xml",
+ "targets": "xml",
+ "tld": "xml",
+ "tmx": "xml",
+ "vbproj": "xml",
+ "vbproj.user": "xml",
+ "wsdl": "xml",
+ "wxi": "xml",
+ "wxl": "xml",
+ "wxs": "xml",
+ "xbl": "xml",
+ "xib": "xml",
+ "xliff": "xml",
+ "xpdl": "xml",
+ "xul": "xml",
+ "xoml": "xml",
+ "yaml": "yaml",
+ "yml": "yaml",
+ "eyaml": "yaml",
+ "eyml": "yaml",
+ "cff": "yaml",
+ "yaml-tmpreferences": "yaml",
+ "yaml-tmtheme": "yaml",
+ "winget": "yaml"
},
"fileNames": {
".pug-lintrc": "pug",
@@ -9015,7 +9109,11 @@
"caddyfile": "caddy",
"pklproject": "pkl",
"pklproject.deps.json": "pkl",
- ".github/funding.yml": "github-sponsors"
+ ".github/funding.yml": "github-sponsors",
+ "language-configuration.json": "jsonc",
+ "icon-theme.json": "jsonc",
+ "color-theme.json": "jsonc",
+ "*.log.?": "log"
},
"languageIds": {
"git": "git",
diff --git a/tools/generate-svg-vscode-extensions.json b/tools/generate-svg-vscode-extensions.json
new file mode 100644
index 0000000000..b258d3f1a5
--- /dev/null
+++ b/tools/generate-svg-vscode-extensions.json
@@ -0,0 +1,570 @@
+{
+ "pkg:bat": {
+ "bat": [
+ ".bat",
+ ".cmd"
+ ]
+ },
+ "pkg:clojure": {
+ "clojure": [
+ ".clj",
+ ".cljs",
+ ".cljc",
+ ".cljx",
+ ".clojure",
+ ".edn"
+ ]
+ },
+ "pkg:coffeescript": {
+ "coffeescript": [
+ ".coffee",
+ ".cson",
+ ".iced"
+ ]
+ },
+ "pkg:configuration-editing": {
+ "jsonc": [
+ ".code-workspace",
+ "language-configuration.json",
+ "icon-theme.json",
+ "color-theme.json"
+ ],
+ "json": [
+ ".code-profile"
+ ]
+ },
+ "pkg:cpp": {
+ "c": [
+ ".c",
+ ".i"
+ ],
+ "cpp": [
+ ".cpp",
+ ".cppm",
+ ".cc",
+ ".ccm",
+ ".cxx",
+ ".cxxm",
+ ".c++",
+ ".c++m",
+ ".hpp",
+ ".hh",
+ ".hxx",
+ ".h++",
+ ".h",
+ ".ii",
+ ".ino",
+ ".inl",
+ ".ipp",
+ ".ixx",
+ ".tpp",
+ ".txx",
+ ".hpp.in",
+ ".h.in"
+ ],
+ "cuda-cpp": [
+ ".cu",
+ ".cuh"
+ ]
+ },
+ "pkg:csharp": {
+ "csharp": [
+ ".cs",
+ ".csx",
+ ".cake"
+ ]
+ },
+ "pkg:css": {
+ "css": [
+ ".css"
+ ]
+ },
+ "pkg:dart": {
+ "dart": [
+ ".dart"
+ ]
+ },
+ "pkg:diff": {
+ "diff": [
+ ".diff",
+ ".patch",
+ ".rej"
+ ]
+ },
+ "pkg:docker": {
+ "dockerfile": [
+ ".dockerfile",
+ ".containerfile"
+ ]
+ },
+ "pkg:fsharp": {
+ "fsharp": [
+ ".fs",
+ ".fsi",
+ ".fsx",
+ ".fsscript"
+ ]
+ },
+ "pkg:git-base": {
+ "ignore": [
+ ".gitignore_global",
+ ".gitignore",
+ ".git-blame-ignore-revs"
+ ]
+ },
+ "pkg:go": {
+ "go": [
+ ".go"
+ ]
+ },
+ "pkg:groovy": {
+ "groovy": [
+ ".groovy",
+ ".gvy",
+ ".gradle",
+ ".jenkinsfile",
+ ".nf"
+ ]
+ },
+ "pkg:handlebars": {
+ "handlebars": [
+ ".handlebars",
+ ".hbs",
+ ".hjs"
+ ]
+ },
+ "pkg:hlsl": {
+ "hlsl": [
+ ".hlsl",
+ ".hlsli",
+ ".fx",
+ ".fxh",
+ ".vsh",
+ ".psh",
+ ".cginc",
+ ".compute"
+ ]
+ },
+ "pkg:html": {
+ "html": [
+ ".html",
+ ".htm",
+ ".shtml",
+ ".xhtml",
+ ".xht",
+ ".mdoc",
+ ".jsp",
+ ".asp",
+ ".aspx",
+ ".jshtm",
+ ".volt",
+ ".ejs",
+ ".rhtml"
+ ]
+ },
+ "pkg:ini": {
+ "ini": [
+ ".ini"
+ ],
+ "properties": [
+ ".conf",
+ ".properties",
+ ".cfg",
+ ".directory",
+ ".gitattributes",
+ ".gitconfig",
+ ".gitmodules",
+ ".editorconfig",
+ ".repo"
+ ]
+ },
+ "pkg:java": {
+ "java": [
+ ".java",
+ ".jav"
+ ]
+ },
+ "pkg:javascript": {
+ "javascriptreact": [
+ ".jsx"
+ ],
+ "javascript": [
+ ".js",
+ ".es6",
+ ".mjs",
+ ".cjs",
+ ".pac"
+ ]
+ },
+ "pkg:json": {
+ "json": [
+ ".json",
+ ".bowerrc",
+ ".jscsrc",
+ ".webmanifest",
+ ".js.map",
+ ".css.map",
+ ".ts.map",
+ ".har",
+ ".jslintrc",
+ ".jsonld",
+ ".geojson",
+ ".ipynb",
+ ".vuerc"
+ ],
+ "jsonc": [
+ ".jsonc",
+ ".eslintrc",
+ ".eslintrc.json",
+ ".jsfmtrc",
+ ".jshintrc",
+ ".swcrc",
+ ".hintrc",
+ ".babelrc"
+ ],
+ "jsonl": [
+ ".jsonl",
+ ".ndjson"
+ ],
+ "snippets": [
+ ".code-snippets"
+ ]
+ },
+ "pkg:julia": {
+ "julia": [
+ ".jl"
+ ],
+ "juliamarkdown": [
+ ".jmd"
+ ]
+ },
+ "pkg:latex": {
+ "tex": [
+ ".sty",
+ ".cls",
+ ".bbx",
+ ".cbx"
+ ],
+ "latex": [
+ ".tex",
+ ".ltx",
+ ".ctx"
+ ],
+ "bibtex": [
+ ".bib"
+ ]
+ },
+ "pkg:less": {
+ "less": [
+ ".less"
+ ]
+ },
+ "pkg:log": {
+ "log": [
+ ".log",
+ "*.log.?"
+ ]
+ },
+ "pkg:lua": {
+ "lua": [
+ ".lua"
+ ]
+ },
+ "pkg:make": {
+ "makefile": [
+ ".mak",
+ ".mk"
+ ]
+ },
+ "pkg:markdown-basics": {
+ "markdown": [
+ ".md",
+ ".mkd",
+ ".mdwn",
+ ".mdown",
+ ".markdown",
+ ".markdn",
+ ".mdtxt",
+ ".mdtext",
+ ".workbook"
+ ]
+ },
+ "pkg:ms-vscode.js-debug": {
+ "wat": [
+ ".wat",
+ ".wasm"
+ ]
+ },
+ "pkg:npm": {
+ "ignore": [
+ ".npmignore"
+ ],
+ "properties": [
+ ".npmrc"
+ ]
+ },
+ "pkg:objective-c": {
+ "objective-c": [
+ ".m"
+ ],
+ "objective-cpp": [
+ ".mm"
+ ]
+ },
+ "pkg:perl": {
+ "perl": [
+ ".pl",
+ ".pm",
+ ".pod",
+ ".t",
+ ".PL",
+ ".psgi"
+ ],
+ "raku": [
+ ".raku",
+ ".rakumod",
+ ".rakutest",
+ ".rakudoc",
+ ".nqp",
+ ".p6",
+ ".pl6",
+ ".pm6"
+ ]
+ },
+ "pkg:php": {
+ "php": [
+ ".php",
+ ".php4",
+ ".php5",
+ ".phtml",
+ ".ctp"
+ ]
+ },
+ "pkg:powershell": {
+ "powershell": [
+ ".ps1",
+ ".psm1",
+ ".psd1",
+ ".pssc",
+ ".psrc"
+ ]
+ },
+ "pkg:pug": {
+ "jade": [
+ ".pug",
+ ".jade"
+ ]
+ },
+ "pkg:python": {
+ "python": [
+ ".py",
+ ".rpy",
+ ".pyw",
+ ".cpy",
+ ".gyp",
+ ".gypi",
+ ".pyi",
+ ".ipy",
+ ".pyt"
+ ]
+ },
+ "pkg:r": {
+ "r": [
+ ".r",
+ ".rhistory",
+ ".rprofile",
+ ".rt"
+ ]
+ },
+ "pkg:razor": {
+ "razor": [
+ ".cshtml",
+ ".razor"
+ ]
+ },
+ "pkg:restructuredtext": {
+ "restructuredtext": [
+ ".rst"
+ ]
+ },
+ "pkg:ruby": {
+ "ruby": [
+ ".rb",
+ ".rbx",
+ ".rjs",
+ ".gemspec",
+ ".rake",
+ ".ru",
+ ".erb",
+ ".podspec",
+ ".rbi"
+ ]
+ },
+ "pkg:rust": {
+ "rust": [
+ ".rs"
+ ]
+ },
+ "pkg:scss": {
+ "scss": [
+ ".scss"
+ ]
+ },
+ "pkg:search-result": {
+ "search-result": [
+ ".code-search"
+ ]
+ },
+ "pkg:shaderlab": {
+ "shaderlab": [
+ ".shader"
+ ]
+ },
+ "pkg:shellscript": {
+ "shellscript": [
+ ".sh",
+ ".bash",
+ ".bashrc",
+ ".bash_aliases",
+ ".bash_profile",
+ ".bash_login",
+ ".ebuild",
+ ".eclass",
+ ".profile",
+ ".bash_logout",
+ ".xprofile",
+ ".xsession",
+ ".xsessionrc",
+ ".Xsession",
+ ".zsh",
+ ".zshrc",
+ ".zprofile",
+ ".zlogin",
+ ".zlogout",
+ ".zshenv",
+ ".zsh-theme",
+ ".fish",
+ ".ksh",
+ ".csh",
+ ".cshrc",
+ ".tcshrc",
+ ".yashrc",
+ ".yash_profile"
+ ]
+ },
+ "pkg:sql": {
+ "sql": [
+ ".sql",
+ ".dsql"
+ ]
+ },
+ "pkg:swift": {
+ "swift": [
+ ".swift"
+ ]
+ },
+ "pkg:typescript-basics": {
+ "typescript": [
+ ".ts",
+ ".cts",
+ ".mts"
+ ],
+ "typescriptreact": [
+ ".tsx"
+ ],
+ "json": [
+ ".tsbuildinfo"
+ ]
+ },
+ "pkg:vb": {
+ "vb": [
+ ".vb",
+ ".brs",
+ ".vbs",
+ ".bas",
+ ".vba"
+ ]
+ },
+ "pkg:xml": {
+ "xml": [
+ ".xml",
+ ".xsd",
+ ".ascx",
+ ".atom",
+ ".axml",
+ ".axaml",
+ ".bpmn",
+ ".cpt",
+ ".csl",
+ ".csproj",
+ ".csproj.user",
+ ".dita",
+ ".ditamap",
+ ".dtd",
+ ".ent",
+ ".mod",
+ ".dtml",
+ ".fsproj",
+ ".fxml",
+ ".iml",
+ ".isml",
+ ".jmx",
+ ".launch",
+ ".menu",
+ ".mxml",
+ ".nuspec",
+ ".opml",
+ ".owl",
+ ".proj",
+ ".props",
+ ".pt",
+ ".publishsettings",
+ ".pubxml",
+ ".pubxml.user",
+ ".rbxlx",
+ ".rbxmx",
+ ".rdf",
+ ".rng",
+ ".rss",
+ ".shproj",
+ ".storyboard",
+ ".svg",
+ ".targets",
+ ".tld",
+ ".tmx",
+ ".vbproj",
+ ".vbproj.user",
+ ".vcxproj",
+ ".vcxproj.filters",
+ ".wsdl",
+ ".wxi",
+ ".wxl",
+ ".wxs",
+ ".xaml",
+ ".xbl",
+ ".xib",
+ ".xlf",
+ ".xliff",
+ ".xpdl",
+ ".xul",
+ ".xoml"
+ ],
+ "xsl": [
+ ".xsl",
+ ".xslt"
+ ]
+ },
+ "pkg:yaml": {
+ "yaml": [
+ ".yaml",
+ ".yml",
+ ".eyaml",
+ ".eyml",
+ ".cff",
+ ".yaml-tmlanguage",
+ ".yaml-tmpreferences",
+ ".yaml-tmtheme",
+ ".winget"
+ ]
+ }
+}
diff --git a/tools/generate-svg.js b/tools/generate-svg.js
index 7368392d01..ec04bf655e 100755
--- a/tools/generate-svg.js
+++ b/tools/generate-svg.js
@@ -63,17 +63,32 @@ async function processMaterialFileIcons() {
}
fs.writeFileSync(fileURLToPath(new URL(`../options/fileicon/material-icon-svgs.json`, import.meta.url)), JSON.stringify(svgSymbols, null, 2));
+ const vscodeExtensionsJson = await readFile(fileURLToPath(new URL(`generate-svg-vscode-extensions.json`, import.meta.url)));
+ const vscodeExtensions = JSON.parse(vscodeExtensionsJson);
const iconRulesJson = await readFile(fileURLToPath(new URL(`../node_modules/material-icon-theme/dist/material-icons.json`, import.meta.url)));
const iconRules = JSON.parse(iconRulesJson);
// The rules are from VSCode material-icon-theme, we need to adjust them to our needs
// 1. We only use lowercase filenames to match (it should be good enough for most cases and more efficient)
- // 2. We do not have a "Language ID" system: https://code.visualstudio.com/docs/languages/identifiers#_known-language-identifiers
- // * So we just treat the "Language ID" as file extension, it is not always true, but it is good enough for most cases.
+ // 2. We do not have a "Language ID" system:
+ // * https://code.visualstudio.com/docs/languages/identifiers#_known-language-identifiers
+ // * https://github.com/microsoft/vscode/tree/1.98.0/extensions
delete iconRules.iconDefinitions;
for (const [k, v] of Object.entries(iconRules.fileNames)) iconRules.fileNames[k.toLowerCase()] = v;
for (const [k, v] of Object.entries(iconRules.folderNames)) iconRules.folderNames[k.toLowerCase()] = v;
for (const [k, v] of Object.entries(iconRules.fileExtensions)) iconRules.fileExtensions[k.toLowerCase()] = v;
- for (const [k, v] of Object.entries(iconRules.languageIds)) iconRules.fileExtensions[k.toLowerCase()] = v;
+ // Use VSCode's "Language ID" mapping from its extensions
+ for (const [_, langIdExtMap] of Object.entries(vscodeExtensions)) {
+ for (const [langId, names] of Object.entries(langIdExtMap)) {
+ for (const name of names) {
+ const nameLower = name.toLowerCase();
+ if (nameLower[0] === '.') {
+ iconRules.fileExtensions[nameLower.substring(1)] ??= langId;
+ } else {
+ iconRules.fileNames[nameLower] ??= langId;
+ }
+ }
+ }
+ }
const iconRulesPretty = JSON.stringify(iconRules, null, 2);
fs.writeFileSync(fileURLToPath(new URL(`../options/fileicon/material-icon-rules.json`, import.meta.url)), iconRulesPretty);
}