mawww / kakoune

mawww's experiment for a better code editor
http://kakoune.org
The Unlicense
9.96k stars 715 forks source link

[BUG] Wrong filetype for scripts with #!/usr/bin/fish shebang #4614

Open hugomg opened 2 years ago

hugomg commented 2 years ago

Version of Kakoune

Kakoune v2021.11.08-204-g459c6f58

Reproducer

Ask kakoune to edit a fish shell script that has a #!/usr/bin/fish shebang but no file extension.

Outcome

Kakoune sets the filetype option to sh.

Expectations

It should set the filetype to fish. Similarly to what would be done for a file with a .fish extension.

Additional information

On my system, file -b --mime-type produces text/x-shellscript for fish scripts, both with and without a .fish file extension. This might be related to why Kakoune identifies the wrong filetype.

One of the most noticeable effects of the wrong filetype is that Fish's end keyword is not highlighted by the sh syntax highlighting.

#!/usr/bin/fish
function hello
    echo "hello world"
end
Screwtapello commented 2 years ago

The file(1) command does detect Fish scripts, but deliberately gives them the same MIME type as any other shell script:

https://github.com/file/file/blob/e470cab2a3d0ef967399ca08df7e29402a1fb6a8/magic/Magdir/commands#L95-L96

Meanwhile, Kakoune's fish filetype plugin only checks for filenames ending in .fish:

https://github.com/mawww/kakoune/blob/459c6f589f857fa33b802ad7573f42153dd4db59/rc/filetype/fish.kak#L7-L9

It looks like file(1) doesn't try to distinguish between shell syntaxes (Bourne-style shells all get text/x-shellscript but so does tcsh), so maybe the fish filetype plugin should add a filetype=sh hook that checks the first line of the buffer for ^#!.*/fish\s and resets the filetype option to fish? Or is there a policy that the filetype option should only be automatically set once per window?

mawww commented 2 years ago

Or is there a policy that the filetype option should only be automatically set once per window?

The issue I foresee with such an approach is that it would be dependent of the load order: it would break if fish.kak was loaded first as fish.kak would update the filetype, but the hooks from sh.kak would still get called after that.