patch 9.0.1797: Vimball/Visual Basic filetype detection conflict

Problem:  Vimball/Visual Basic filetype detection conflict
Solution: runtime(vb): Improve Vimball and Visual Basic detection logic

Only run Vimball Archiver's BufEnter autocommand on Vimball archives.
Fixes #2694.

closes: #12899

Signed-off-by: Christian Brabandt <cb@256bit.org>
Co-authored-by: Doug Kearns <dougkearns@gmail.com>
diff --git a/runtime/autoload/dist/ft.vim b/runtime/autoload/dist/ft.vim
index bc21257..6c15c29 100644
--- a/runtime/autoload/dist/ft.vim
+++ b/runtime/autoload/dist/ft.vim
@@ -62,7 +62,7 @@
   endif
 enddef
 
-var ft_visual_basic_content = '\cVB_Name\|Begin VB\.\(Form\|MDIForm\|UserControl\)'
+var ft_visual_basic_content = '\c^\s*\%(Attribute\s\+VB_Name\|Begin\s\+\%(VB\.\|{\%(\x\+-\)\+\x\+}\)\)'
 
 # See FTfrm() for Visual Basic form file detection
 export def FTbas()
@@ -146,11 +146,13 @@
     return
   endif
 
-  if getline(1) =~ '^\v%(\%|\\)'
+  var line1 = getline(1)
+
+  if line1 =~ '^\v%(\%|\\)'
     setf tex
-  elseif getline(1)[0] == '#' && getline(1) =~ 'rexx'
+  elseif line1[0] == '#' && line1 =~ 'rexx'
     setf rexx
-  elseif getline(1) == 'VERSION 1.0 CLASS'
+  elseif line1 == 'VERSION 1.0 CLASS'
     setf vb
   else
     setf st
@@ -324,6 +326,11 @@
     return
   endif
 
+  if getline(1) == "VERSION 5.00"
+    setf vb
+    return
+  endif
+
   var lines = getline(1, min([line("$"), 5]))
 
   if match(lines, ft_visual_basic_content) > -1
@@ -1197,5 +1204,13 @@
   setf v
 enddef
 
+export def FTvba()
+  if getline(1) =~ '^["#] Vimball Archiver'
+    setf vim
+  else
+    setf vb
+  endif
+enddef
+
 # Uncomment this line to check for compilation errors early
 # defcompile
diff --git a/runtime/filetype.vim b/runtime/filetype.vim
index a434503..9dc4811 100644
--- a/runtime/filetype.vim
+++ b/runtime/filetype.vim
@@ -209,9 +209,6 @@
 " Bass
 au BufNewFile,BufRead *.bass			setf bass
 
-" Visual Basic Script (close to Visual Basic) or Visual Basic .NET
-au BufNewFile,BufRead *.vb,*.vbs,*.dsm,*.ctl	setf vb
-
 " IBasic file (similar to QBasic)
 au BufNewFile,BufRead *.iba,*.ibi		setf ibasic
 
@@ -2376,7 +2373,7 @@
 au BufNewFile,BufRead *.hdl,*.vhd,*.vhdl,*.vbe,*.vst,*.vho  setf vhdl
 
 " Vim script
-au BufNewFile,BufRead *.vim,*.vba,.exrc,_exrc	setf vim
+au BufNewFile,BufRead *.vim,.exrc,_exrc		setf vim
 
 " Viminfo file
 au BufNewFile,BufRead .viminfo,_viminfo		setf viminfo
@@ -2389,10 +2386,31 @@
 	\   setf virata |
 	\ endif
 
-" Visual Basic (also uses *.bas) or FORM
+" Visual Basic (see also *.bas *.cls)
+
+" Visual Basic or FORM
 au BufNewFile,BufRead *.frm			call dist#ft#FTfrm()
 
-" SaxBasic is close to Visual Basic
+" Visual Basic
+" user control, ActiveX document form, active designer, property page
+au BufNewFile,BufRead *.ctl,*.dob,*.dsr,*.pag	setf vb
+
+" Visual Basic or Vimball Archiver
+au BufNewFile,BufRead *.vba			call dist#ft#FTvba()
+
+" Visual Basic Project
+au BufNewFile,BufRead *.vbp			setf dosini
+
+" VBScript (close to Visual Basic)
+au BufNewFile,BufRead *.vbs			setf vb
+
+" Visual Basic .NET (close to Visual Basic)
+au BufNewFile,BufRead *.vb			setf vb
+
+" Visual Studio Macro
+au BufNewFile,BufRead *.dsm			setf vb
+
+" SaxBasic (close to Visual Basic)
 au BufNewFile,BufRead *.sba			setf vb
 
 " Vgrindefs file
diff --git a/runtime/plugin/vimballPlugin.vim b/runtime/plugin/vimballPlugin.vim
index d7473a0..cd14efa 100644
--- a/runtime/plugin/vimballPlugin.vim
+++ b/runtime/plugin/vimballPlugin.vim
@@ -28,10 +28,16 @@
 com! -nargs=* -complete=dir  RmVimball						call vimball#SaveSettings()|call vimball#RmVimball(<f-args>)|call vimball#RestoreSettings()
 augroup Vimball
  au!
- au BufEnter  *.vba,*.vba.gz,*.vba.bz2,*.vba.zip,*.vba.xz	setlocal bt=nofile fmr=[[[,]]] fdm=marker|if &ff != 'unix'|setlocal ma ff=unix noma|endif|if line('$') > 1|call vimball#ShowMesg(0,"Source this file to extract it! (:so %)")|endif
+ au BufEnter  *.vba,*.vba.gz,*.vba.bz2,*.vba.zip,*.vba.xz
+	   \ if getline(1) =~ '^" Vimball Archiver' |
+	   \  setlocal bt=nofile fmr=[[[,]]] fdm=marker|if &ff != 'unix'|setlocal ma ff=unix noma|endif|if line('$') > 1|call vimball#ShowMesg(0, "Source this file to extract it! (:so %)")|endif |
+	   \ endif
  au SourceCmd *.vba.gz,*.vba.bz2,*.vba.zip,*.vba.xz			let s:origfile=expand("%")|if expand("%")!=expand("<afile>") | exe "1sp" fnameescape(expand("<afile>"))|endif|call vimball#Decompress(expand("<amatch>"))|so %|if s:origfile!=expand("<afile>")|close|endif
  au SourceCmd *.vba											if expand("%")!=expand("<afile>") | exe "1sp" fnameescape(expand("<afile>"))|call vimball#Vimball(1)|close|else|call vimball#Vimball(1)|endif
- au BufEnter  *.vmb,*.vmb.gz,*.vmb.bz2,*.vmb.zip,*.vmb.xz	setlocal bt=nofile fmr=[[[,]]] fdm=marker|if &ff != 'unix'|setlocal ma ff=unix noma|endif|if line('$') > 1|call vimball#ShowMesg(0,"Source this file to extract it! (:so %)")|endif
+ au BufEnter  *.vmb,*.vmb.gz,*.vmb.bz2,*.vmb.zip,*.vmb.xz
+	   \ if getline(1) =~ '^" Vimball Archiver' |
+	   \  setlocal bt=nofile fmr=[[[,]]] fdm=marker|if &ff != 'unix'|setlocal ma ff=unix noma|endif|if line('$') > 1|call vimball#ShowMesg(0,"Source this file to extract it! (:so %)")|endif |
+	   \ endif
  au SourceCmd *.vmb.gz,*.vmb.bz2,*.vmb.zip,*.vmb.xz			let s:origfile=expand("%")|if expand("%")!=expand("<afile>") | exe "1sp" fnameescape(expand("<afile>"))|endif|call vimball#Decompress(expand("<amatch>"))|so %|if s:origfile!=expand("<afile>")|close|endif
  au SourceCmd *.vmb											if expand("%")!=expand("<afile>") | exe "1sp" fnameescape(expand("<afile>"))|call vimball#Vimball(1)|close|else|call vimball#Vimball(1)|endif
 augroup END
@@ -41,3 +47,5 @@
 " vim: fdm=marker
 let &cpo= s:keepcpo
 unlet s:keepcpo
+
+" vim: ts=4: