Sublime Forum

Build 3103 Creating new files assumed file extension can not be changed

#1

When creating files it is impossible to change the assumed extension. I am okay with the idea of determining the file extension and appending it like “untitled.haml” but changing the name to “untitled.sass” doesn’t stick.

In fact naming a file that was incorrectly determined to be a haml file “untitled.sass” will create a file named “untitled.sass.haml”.

So having to create a file and then immediately rename it is not good. And my watchman script that does some task that I would rather not describe is now broken.

0 Likes

Sublime text editor will not save as python script file
#2

When entering the file name, make sure that either “any file type” is selected or the type which uses the extension you want to add. This is usually inferred from the syntax definition of the current buffer you want to “save as”.

The different extension is most likely added by the OS’s file chooser dialog.

0 Likes

#3

This is particularly frustrating when I just want to save something as “.jsx”, but it’s always forced into “.jsx.js”, because of some sort of syntax default extension nonsense (even though the JS syntax I have supports multiple extensions?), causing an immediate linter error because it’s now got the wrong extension.

I feel like this wasn’t always the case in ST, and has changed either in a later release of ST or a later release of macOS?

0 Likes

#4

What JSX package are you using? Also, what do you mean that ‘it’s always forced into “.jsx.js”’?

0 Likes

#5

I’m a bit hazy on the full details at the moment, but on different OS’s the behaviour of the file save dialog box is different. I’ve looked at this in the past and it seemed like it was the OS at fault, or Sublime behaving the way the OS would, because the behaviour is different across different platforms.

Specifically some platforms will add the extension if you omit it and some don’t, and some will force the extension they think it should be while some will accept whatever you provide.

So on MacOS if the dialog thinks it should be a .js file, then bob becomes bob.js, but bob.jsx becomes bob.jsx.js.

0 Likes

#6

I can’t reproduce the issue when specifying another file extension. “foo” becomes “foo.js” but “bar.jsx” stays “bar.jsx”.

0 Likes

#7

It might be specific to only some versions of MacOS perhaps? I just ran a quick test across my Windows 7 machine, my Linux Slackware machine and my MacBook running 10.10.5, all running build 3157.

In the test I had a window split into two groups, with an unsaved plain text file on the left and an unsaved JavaScript file on the right. I ran two tests; what happens if you enter the filename test, and what happens if you enter the filename test.ext.

I ended up with this table (please excuse the crudity of the model; I didn’t have time to build it to scale or to paint it ;)):

                    No Extension   | Add Extension
--------------------------------------------------------------
| Windows Plain |  test is test    | test.ext is test.ext    |
| Windows JS    |  test is test    | test.ext is test.ext    |
| Linux Plain   |  test is test    | test.ext is test.ext    |
| Linux JS      |  test is test    | test.ext is test.ext    |
| MacOS Plain   |  test is test    | test.ext is test.ext    |
| MacOS JS      |  test is test.js | test.ext is test.ext.js |
--------------------------------------------------------------

The first thing to note is that my Linux machine and the MacBook both offered a default filename with an appropriate extension on it (either untitiled or untitled.js, depending) while Windows just opened the dialog with an empty filename field. In both cases the filename was pre-selected to allow you to just enter in a filename and hit enter.

Across Windows and Linux both, whatever filename was ultimately in the filename field was the one that was used, so in the case of Linux if I override its default choice of a .js extension, it went with what I gave it.

Conversely, on MacOS, the plain text file with no pre-entered extension saved as whatever filename I gave it, but the JavaScript file always had a .js extension forced onto the end, even if I manually erased it and put something else in its place (including nothing at all).

The fact that the behaviour is different across the different OS’s makes me think that Sublime is just deferring to whatever the common dialog of the platform would do, or that if it has the ability to control it that it’s specifically working the way that it is to match some platform specification, the way that it moves the Preferences and About menu items on MacOS to be under the Sublime Text menu entry, for example.

It should be noted that at least in my case neither the Linux file save dialog box (using XFCE as my WM) nor the MacOS save box has any field for file type, which is probably why it pre-populates a filename with extension into the file box by default for you.

I wouldn’t be completely shocked if (some versions of) MacOS do this on purpose to ensure that you don’t accidentally save a file with an extension other than the one that the application you’re using knows how to open, though.

1 Like

Why no extension when I save new file?
#8

It looks like this has to do with the list of file extensions for the syntax definition you’re using. After removing all non-core JavaScript packages and saving a new file using the core JavaScript syntax as “xyzzy.jsx”, it asked me to confirm the file extension. When I did, it saved it exactly as I specified. However, saving a JavaScript view as “xyzzy.ext” resulted in “xyzzy.ext.js”.

When I reenabled JS Custom, the problem went away. When I saved a file as “xyzzy.jsx”, it worked immediately with no confirmation.

I haven’t quite pinned down the logic.

0 Likes

#9

Ah yeah, I think there are related or semi-related issues on the tracker regarding something like that, possibly to do with how it uses the first listed extension as the default? I think it was either an issue like that or an issue similar to the one reported here about the extension being forced where I looked at this originally, but it’s been a while.

0 Likes

#10

Presumably the Ja Custom syntax supplies jsx as an extension it understands, which means the file save dialog doesn’t add (the first) extension as a compatible one has been provided.

0 Likes

#11

It does. What confuses me is that if @vdh is editing JSX files, then presumably he would be using a third-party package that understands JSX syntax, and to my knowledge all of the popular ones list .jsx as a file extension.

0 Likes

#12

I’ve experienced this issue with both my current syntax plugin, JS Custom, as well as the older babel-sublime syntax that I had before that.

I’ve been using the “JS Custom - React” syntax, which the plugin generates into ~/Library/Application Support/Sublime Text 3/Packages/User/JS Custom/Syntaxes/React.sublime-syntax, the start of which looks like this:

%YAML 1.2
---
name: JS Custom - React
file_extensions:
  - js
  - jsx
first_line_match: ^#!\s*/.*\b(node|js)\b
scope: source.js

As confirmed above, if left on the Plain Text syntax, it will allow any extension, but after the syntax is selected it will always force a .js extension on the file.

I just now tested an edit to the React.sublime-syntax file and swapped the positions of jsx and js, and it indeed forces the first listed extension. So I guess that (sort of) solves the immediate issue for me, but it’s still a bad behaviour when a syntax supports multiple extensions.

0 Likes

#13

While I’m not sure how to solve the underlying problem, you can solve it cleanly for JS Custom by editing your user configuration. In the command palette, select “Preferences: JS Custom”. Then, copy the default settings (on the left) to your user settings (on the right). Then, under configurationsReactfile_extensions, swap "js" and "jsx". This will put jsx first on the list. Example:

{
    "defaults": {
        "comma_operator": false,
        "custom_tagged_literals": false,
        "es_decorators": true,
        "flow_types": false,
        "jsx": false,
    },

    "configurations": {
        "Default": {},
        "React": {
            "file_extensions": [ "jsx", "js" ],
            "flow_types": true,
            "jsx": true,
        }
    },

    "auto_build": true,
    "jsx_close_tag": true
}

When you save your changes, the React syntax will automatically be recompiled.

Editing the compiled syntax file directly is not recommended, because your changes will be overwritten if the syntax is recompiled, such as after an update or if you make any other changes. If there isn’t an existing configuration option that does what you want, please post an issue; because all syntax extensions are optional, there’s a fairly low bar for adding a new one.

1 Like