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.

  • 3
    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
    Commented Dec 9, 2015 at 21:07
  • 1
    Use <c-d> instead of <tab> to list completions. Commented Dec 9, 2015 at 21:50
  • Type a letter or a few to filter the list and show entries which is started with these letters.
    – Shamaoke
    Commented Jan 15, 2018 at 11:29

4 Answers 4


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"))

    " 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))

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()
  • 2
    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
    Commented Nov 23, 2017 at 13:57
  • 8
    @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
    Commented Dec 27, 2017 at 19:40
  • 1
    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
    Commented Oct 17, 2018 at 7:18
  • Even pre-completion() the double loop is a bit complex as we have globpath(&rtp, 'syntax/**/*.vim'). With the new object syntax the same code becomes: echo globpath(&rtp, 'syntax/**/*.vim', 0, 1)->map({ _, v -> v->fnamemodify(':t:r')})->sort()->uniq(). But then the ftplugin directory also needs to be analysed, and the specific {filetype}_whatever.vim pattern needs to be taken into acount as well. Commented Oct 19, 2022 at 13:23

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,ftplugin}/, 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.


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


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


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.


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
    Commented Jan 26, 2018 at 1:30
  • Nice, way more succinct. Any better solution for finding the VIMRUNTIME value from terminal as well? Commented Jan 26, 2018 at 8:09
  • 1
    vim -Nesc '!echo $VIMRUNTIME' -c qa, I think.
    – muru
    Commented Jan 26, 2018 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
    Commented Oct 12, 2018 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"' Commented Jul 30, 2019 at 18:07

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 and acknowledge you have read our privacy policy.

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