File type detection in vim without a valid file extension

I am looking for a way to determine file type in vim and set syntax highlighting based on file type. The only catch is that I cannot use the file extension to determine the type of file.

This is my scenario: I use vimdiff or gvimdiff as a P4DIFF tool that shows the changes between the files in my local copy and the perforce servers. Perforce seems to list the files from the perforce server in the / tmp directory and uses the PID for the file name, for example:

 /tmp/tmp.24673.23 

This was for the C ++ source file.

The most common file types that I see in the perforce repository are C / C ++ source and header files, Makefile scripts, python scripts, perl scripts, ruby โ€‹โ€‹scripts, and tcl scripts.

  • I studied the use of modeline , but most of the sources in our tree do not have this information embedded in the file.

  • This post mentions a possible approach to finding and identifying a magic pattern. I could not find any consistent magical scheme with which I could get a high level of success.

  • I tried using the binary file in my linux window to find out what results I would get. It seems to well identify C / C ++ sources, but does not work for Make files and even python scripts (which do not have hashbang)

Itโ€™s good that among the two files that are compared, the file is to the right of my local copy and, therefore, has the correct file name with the extension, so the syntax highlighting is turned on correctly for the file on the right.

Can this be used to set syntax highlighting for the file displayed on the left?

Any alternative solutions to this problem are also welcome.

+6
source share
2 answers

It was an interesting puzzle. :)

 aug SmartDiffType au! au VimEnter * :if &diff && len(&ft) | call setwinvar(2/winnr(),'&ft',&ft) | elseif &diff | let &ft=getwinvar(2/winnr(),'&ft') | endif aug END 

Notes:

  • From the 4 lines above, you only need the au VimEnter line, but as a rule, it is recommended that you place the autocommands into some autocommand group with reset ( au! ) At the top.
  • Autocommand on VimEnter , because otherwise diff or windows would not be configured correctly yet
  • vimdiff can be run with the old file to the right or left of the split, so we consider both cases.
  • 2/winnr() - a mathematical trick to translate between 1 and 2 (2/2 = 1, 2/1 = 2)
+6
source

Assuming you opened only 2 splits, and the split on the left is your local file, you can do the following

 :windo let &ft = getwinvar(1, '&ft') 

This will set the filetype value to the window value of the upper left window for all windows.

For more help see:

 :h :windo :h 'ft' :h getwinvar( 
+3
source

All Articles