sublimehq / sublime_text

Issue tracker for Sublime Text
https://www.sublimetext.com
804 stars 39 forks source link

Add option to use file type icon based on file name #6349

Open Monokai opened 5 months ago

Monokai commented 5 months ago

Problem description

Sublime Text uses file type icons based on syntax scope. This works fine for the most part, but in most projects there are files that have special meaning based on the filename or extension. For example:

You could argue that these files have correct icons now (JavaScript for next.config.js or YAML for docker-compose.yml, Plain Text for .gitignore etc.), and I've also long argued that. Fact is that these files are widely known to be conceptually different. A docker-compose.yml file is about Docker, not a random YAML file. A .gitignore file is about Git settings, not any random Plain Text file.

Currently Sublime Text doesn't offer a simple way of differentiating icons based on file name. Visual Studio Code does have this functionality. It would help if a Sublime Text icon theme could parse the file name and extension as well.

Preferred solution

Target specific file name and extension patterns to use file type icons.

Alternatives

-

Additional Information

No response

jfcherng commented 5 months ago

Since you didn't mention, the best result you can get at this moment is something like https://packagecontrol.io/packages/FileIcons. But it requires you to do some operations if you are not using a builtin theme.

Monokai commented 5 months ago

@jfcherng If I understand correctly, I have to create a sublime-syntax file for every file type in order to base the icon on a file extension. And I have to include other contexts as well in that file that the file is syntax is based on. It feels very verbose.

Is there a reason for it? I would think a simple filename-based icon targeting system would work so much simpler and easier to maintain, without having to determine how to include other contexts. VSCode does it like this:

"fileExtensions": {
    "jpg" : "_image",
    "mdx" : "_markdownx",
    "todo": "_todo",
    "woff": "_font"
},
"fileNames": {
    ".dockerignore"     : "_docker",
    ".env"              : "_env",
    "eslint.config.js"  : "_eslint",
    ".gitignore"        : "_git",
    "docker-compose.yml": "_docker"
}

Which makes sense to me. It's a system that overrides the normal scope-targeted file icons with a filename targeted mapping.

jfcherng commented 5 months ago

Is there a reason for it?

It's how ST works at this moment.

file_type_docker.tmPreferences

<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
  <dict>
    <key>scope</key>
    <string>source.dockerfile, source.yaml.docker, source.shell.docker</string>
    <key>settings</key>
    <dict>
      <key>icon</key>
      <string>file_type_docker</string> <!-- load file_type_docker.png -->
    </dict>
  </dict>
</plist>

As you can see, the icon depends on scope, which depends on syntax definition files.


Which makes sense to me. It's a system that overrides the normal scope-targeted file icons with a filename targeted mapping.

Agree. I would further ask the filename matching mechanism uses regex or at least glob.

Monokai commented 5 months ago

I'm trying to create sublime-syntax files now, to target specific file extensions. If I understand correctly, I also have to extend the original context, like this for example:

%YAML 1.2
---
name: json npm
scope: source.json.npm
hidden: true
file_extensions:
  - package-lock.json
  - package.json

contexts:
  main: 
    - include: scope:source.json
      apply_prototype: true

It seems to work. Now I'm wondering how these sublime-syntax files are loaded. Which files take precedence? How are conflicts handled?

I guess my main question is: can I just put a bunch of these sublime-syntax files in my package and trust that this will only affect the file icons? Or does it interfere with other syntax definitions or (user) overrides?

Monokai commented 5 months ago

I've added this in the latest version of Monokai Pro. I took inspiration from the definitions of A File Icon and am using a single json source to generate lots of tmPreferences and sublime-syntax files in my build step. It seems to work fine, but I'm still not sure if these syntax files that reside in my package will cause conflicts with other packages or user overrides.

deathaxe commented 5 months ago

Please avoid that. It will have potential netative side effects with A File Icons, which already creates such stubs for all sorts of files. Maybe rather just have a look at its supported filetype... and just provide png files for such icons.

When creating a .supports-a-file-icon-customization file in package root, it will then give the package's icons precedence over its own.

Monokai commented 5 months ago

But if I remove the stubs and rely on A File Icon for everything then I’m having a dependency on another package, and I’m not free to customize the stubs to support other files if I understand correctly. Or maybe I’m missing something?

What negative side effects do you think it will cause? I’ve tried running that package next to mine and it just filled in the icons I don’t already have.

deathaxe commented 5 months ago

Things may become wonky as soon as scope names and/or associated file_type_... names differ between packages. This may cause no icons to be displayed for such types.

Yes, custom icons would be displayed only if A File Icon was installed then.

I wonder, which file types you want to provide custom icons for, which are not already supported by A File Icon.

Monokai commented 5 months ago

A couple, not a lot. I can’t look it up easily now as I’m not in front of a computer. But another issue is that if I would rely on A File Icon, those icons would display in between my icon set. The whole idea of Monokai Pro is to provide a coherent whole, that includes colors of icons and their style.

All this could be avoided if file name targeting wouldn’t be tied to syntax definitions. Just a mapping of filenames and extensions to file icons really.

deathaxe commented 5 months ago

This wouldn't probably change anything if multiple packages define concurrent resources. It would just avoid those syntax stubs. But maybe raise other issues.

Assigning an extension to a new syntax currently also changes the icon accordingly, which wouldn't work with hard coded extension-icon configurations.

Well, maybe most Monokai Pro users are no A File Icon users.