54

How can I get a list of the names of filetypes that vim currently knows about?

I want to be able to do this so that when vim doesn't automatically detect a filetype I can try some of the filetypes vim knows about that may be similar and see if they provide reasonable syntax highlighting.

I know that vimscript files dealing with filetypes are put in the ftplugin directory by convention but they don't need to be (I'm not sure, but I don't think the vimscript files in the ftplugin directory are special) so I want to just ask vim what filetypes it knows about, regardless of how it learned about them.

  • 1
    You can view a list when you try to autocomplete on :setfiletype (i.e. with Tab after a space). Not sure if it's the complete list, or how to capture it to some buffer/file. – VanLaser Dec 9 '15 at 21:07
  • 1
    Use <c-d> instead of <tab> to list completions. – Peter Rincker Dec 9 '15 at 21:50
  • Type a letter or a few to filter the list and show entries which is started with these letters. – Shamaoke Jan 15 '18 at 11:29
63

Simple Solution

Type :setfiletype (with a space afterwards), then press Ctrl-d.

See :help cmdline-completion for more on autocompletion in vim's command line.

Complicated Solution

This solution uses the 'runtimepath' option to get all available syntax directories, and then fetches a list of the vimscript files in those directories with their extensions removed. This may not be the safest way to do it, so improvements are welcome:

function! GetFiletypes()
    " Get a list of all the runtime directories by taking the value of that
    " option and splitting it using a comma as the separator.
    let rtps = split(&runtimepath, ",")
    " This will be the list of filetypes that the function returns
    let filetypes = []

    " Loop through each individual item in the list of runtime paths
    for rtp in rtps
        let syntax_dir = rtp . "/syntax"
        " Check to see if there is a syntax directory in this runtimepath.
        if (isdirectory(syntax_dir))
            " Loop through each vimscript file in the syntax directory
            for syntax_file in split(glob(syntax_dir . "/*.vim"), "\n")
                " Add this file to the filetypes list with its everything
                " except its name removed.
                call add(filetypes, fnamemodify(syntax_file, ":t:r"))
            endfor
        endif
    endfor

    " This removes any duplicates and returns the resulting list.
    " NOTE: This might not be the best way to do this, suggestions are welcome.
    return uniq(sort(filetypes))
endfunction

You can then use this function in whatever way you want, such as printing all of the values in the list. You could accomplish that like so:

for f in GetFiletypes() | echo f | endfor

Note that this probably can be compacted quite a bit, it is just like this for readability. I won't explain every function and command used here, but here are all the help pages for them:

  • :help 'runtimepath'
  • :help :let
  • :help :let-&
  • :help split()
  • :help :for
  • :help expr-.
  • :help :if
  • :help isdirectory()
  • :help glob()
  • :help fnamemodify()
  • :help add()
  • :help uniq()
  • :help sort()
  • 1
    When I type set filetype<space><c d>, it shows me a list, but html is not in the list. Java is not in the list. How do I show filetype names in the sense of filetypes that correspond to the syntax formatting configurations? – John Meyer Nov 23 '17 at 13:57
  • 6
    @JohnMeyer: I made the same mistake. The command is actually :setfiletype without the typical space between "set" and "filetype". You can find more info with :help :setfiletype and :help ftdetect. – sanscore Dec 27 '17 at 19:40
  • I've tried this, and it works! btw, I can use :setfiletype ht<Ctrl+D> to list filetype starting with ht, which filters unwanted results. :) – pimgeek Oct 17 '18 at 7:18
19

If your version of vim is recent enough (v7.4.2011+), you can ask for known filetypes with the function we can now use to help define manual autocompletion: getcompletion()

:echo getcompletion('', 'filetype')

If you want to restrict the list to filetypes starting with a 'c', you'd call

:echo getcompletion('c', 'filetype')

and so on.

Note: unlike solutions that parse the file names and directory names in $VIMRUNTIME/{syntax,filetype}/, this solution analyses 'runtimepath' as well. As far as I understand, it doesn't see new filetypes defined/registered on the fly with set ft=foobar, nor after autocommands.

3

You can also print all file types in the terminal by running the following 2 commands:

1.

cd $(vim -e -T dumb --cmd 'exe "set t_cm=\<C-M>"|echo $VIMRUNTIME|quit' | tr -d '\015')

2.

cat <(ls -1 ftplugin/*.vim) <(ls -1 syntax/*.vim) | tr '\n' '\0' | xargs -0 -n 1 basename | sort | uniq | cut -f 1 -d '.'

First command simply navigates to your vim runtime path (for me it was /usr/share/vim/vim80).

Second command lists all the file type names in the two folders where vim stores the file type definitions.

Update

Suggested improvements to the two commands by muru which offer:

cd "$(vim -Nesc '!echo $VIMRUNTIME' -c qa)"
find syntax ftplugin -iname '*.vim' -exec basename -s .vim {} + | sort -u
  • 3
    That is waaaay too complicated a pipeline. Using tr to convert newlines to null only to convert it back the very next command, process substitution when simple command grouping would do. I'd suggest something like: find syntax ftplugin -iname '*.vim' -exec basename -s .vim {} + | sort -u – muru Jan 26 '18 at 1:30
  • Nice, way more succinct. Any better solution for finding the VIMRUNTIME value from terminal as well? – Samir Alajmovic Jan 26 '18 at 8:09
  • 1
    vim -Nesc '!echo $VIMRUNTIME' -c qa, I think. – muru Jan 26 '18 at 8:18
  • 1
    Yikes. That second command is frightening. Sorry. I'm not being not nice. ;) For fun, here's a Bash alternative to muru's suggestion that uses just one external command (assuming printf is a builtin): f=({ftplugin,syntax}/*.vim) && f=(${f[@]##*/}) && printf "%s\n" "${f[@]%%.*}" | sort -u . See "Parameter Expansion" in Bash man page for explanation of the hieroglyphics. – B Layer Oct 12 '18 at 5:37
  • This will give you psuedo filetype plugins like bash, which is 'not a real filetype plugin ... and gets the effect of filetype "sh"' – jeremysprofile Jul 30 at 18:07
0

Try seeing in $VIMRUNTIME/syntax. Use :echo $VIMRUNTIME to know its value. In my computer, $VIMRUNTIME/syntax was /usr/share/vim/vim81/syntax. It has all the syntax files.

If you have a vim with gui, you can also use Syntax menu to get all the filetypes supported.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.