runtime(vim): Improve syntax script generator for Vim Script

closes: #16331

Signed-off-by: h-east <h.east.727@gmail.com>
Signed-off-by: Doug Kearns <dougkearns@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
h-east
2024-12-29 15:14:37 +01:00
committed by Christian Brabandt
parent 3b3318b640
commit f0ab3e4e41
4 changed files with 148 additions and 107 deletions

View File

@ -1,43 +1,50 @@
VIM_SRCDIR = ../../../src
RUN_VIMPROG = $(VIM_SRCDIR)/vim -N -u NONE -i NONE -n
REVISION ?= $(shell date +%Y-%m-%dT%H:%M:%S%:z)
#
# Makefile for generate runtime/syntax/vim.vim
#
VIM_SRCDIR := ../../../src
RUN_VIMPROG := $(VIM_SRCDIR)/vim -N -u NONE -i NONE -n
TARGET := ../vim.vim
CHECK_HELP_DOC := 0
SRC = $(VIM_SRCDIR)/eval.c $(VIM_SRCDIR)/ex_cmds.h $(VIM_SRCDIR)/ex_docmd.c \
SRC := $(VIM_SRCDIR)/eval.c $(VIM_SRCDIR)/ex_cmds.h $(VIM_SRCDIR)/ex_docmd.c \
$(VIM_SRCDIR)/fileio.c $(VIM_SRCDIR)/option.c $(VIM_SRCDIR)/syntax.c
export VIM_SRCDIR
export CHECK_HELP_DOC
.PHONY: generate clean
.PHONY: generate check_doc clean
all: generate
generate: vim.vim
generate: $(TARGET)
vim.vim: vim.vim.rc update_date.vim
@echo "Generating vim.vim ..."
@cp -f vim.vim.rc ../vim.vim
@$(RUN_VIMPROG) -S update_date.vim
check_doc: CHECK_HELP_DOC := 1
check_doc: clean $(TARGET)
clean:
rm -f vim.vim.rc $(TARGET)
rm -f sanity_check.err generator.err
$(TARGET): vim.vim.rc update_date.vim
@echo "Generating $(TARGET) ..."
@cp -f vim.vim.rc $(TARGET)
@$(RUN_VIMPROG) -S update_date.vim $(TARGET)
@echo "done."
vim.vim.rc: gen_syntax_vim.vim vim.vim.base $(SRC)
@echo "Generating vim.vim.rc ..."
@rm -f sanity_check.err generator.err
@$(RUN_VIMPROG) -S gen_syntax_vim.vim
@$(RUN_VIMPROG) -S gen_syntax_vim.vim $(TARGET)
@if test -f sanity_check.err ; then \
echo ; \
echo "Sanity errors:" ; \
cat sanity_check.err ; \
exit 1 ; \
fi
@if test -f generator.err ; then \
echo ; \
echo "Generator errors:" ; \
cat generator.err ; \
echo ; \
fi
@if test -f sanity_check.err || test -f generator.err ; then \
exit 1 ; \
fi
@echo "done."
clean:
rm -f vim.vim.rc
rm -f vim.vim
rm -f sanity_check.err generator.err

View File

@ -1,14 +1,15 @@
" Vim syntax file generator
" Language: Vim script
" Maintainer: Hirohito Higashi (h_east)
" Last Change: 2024 Oct 04
" Last Change: 2024 Dec 29
let s:keepcpo= &cpo
set cpo&vim
language C
let s:log_write_dir = getcwd() . '/'
function! s:parse_vim_option(opt, missing_opt, term_out_code)
function s:parse_vim_option(opt, missing_opt, term_out_code)
try
let file_name = $VIM_SRCDIR . '/optiondefs.h'
let item = {}
@ -65,7 +66,7 @@ function! s:parse_vim_option(opt, missing_opt, term_out_code)
endtry
endfunc
function! s:append_syn_vimopt(lnum, str_info, opt_list, prefix, bool_only)
function s:append_syn_vimopt(lnum, str_info, opt_list, prefix, bool_only)
let ret_lnum = a:lnum
let str = a:str_info.start
@ -96,7 +97,7 @@ function! s:append_syn_vimopt(lnum, str_info, opt_list, prefix, bool_only)
endfunc
" ------------------------------------------------------------------------------
function! s:parse_vim_command(cmd)
function s:parse_vim_command(cmd)
try
let file_name = $VIM_SRCDIR . '/ex_cmds.h'
let item = {}
@ -131,41 +132,28 @@ function! s:parse_vim_command(cmd)
if my > 0
let omit_idx = (key =~# '\l') ? 1 : 0
for idx in range(1, strlen(lcmd[key][my]))
let spec=0
if lcmd[key][my] ==# 'ex'
let spec=1
echo "cmd name:" lcmd[key][my]
endif
let matched = 0
for pre in range(my - 1, 0, -1)
if spec
echo "pre:" pre ", my:" my
endif
if pre == my
if spec
echo "continue"
endif
continue
endif
" for weird abbreviations for delete. (See :help :d)
" And k{char} is used as mark. (See :help :k)
" Avoiding conflicts shortened command and special commands
" - weird abbreviations for delete. (See :help :d)
" - k{char} is used as mark. (See :help :k)
" - :s commsnds repeat. (See :help :substitute-repeat)
if lcmd[key][my][:idx] ==# lcmd[key][pre][:idx] ||
\ (key ==# 'd' &&
\ lcmd[key][my][:idx] =~# '^d\%[elete][lp]$')
\ || (key ==# 'k' &&
\ lcmd[key][my][:idx] =~# '^k[a-zA-Z]$')
\ || (key ==# 's' &&
\ lcmd[key][my][:idx] =~# '^s\%(c\%([^sr][^ip]\=\)\=$\|g\|i[^mlg]\=$\|I\|r[^e]\=$\)')
let matched = 1
let omit_idx = idx + 1
if spec
echo "match. break. omit_idx:" omit_idx
endif
break
endif
endfor
if !matched
if spec
echo "not match. break"
endif
break
endif
endfor
@ -185,46 +173,6 @@ function! s:parse_vim_command(cmd)
endfor
endfor
" Check exists in the help. (Usually it does not check...)
let doc_dir = './vim/runtime/doc'
if 0
for vimcmd in a:cmd
let find_ptn = '^|:' . vimcmd.name . '|\s\+'
exec "silent! vimgrep /" . find_ptn . "/gj " . doc_dir . "/index.txt"
let li = getqflist()
if empty(li)
call s:err_sanity(printf('Ex-cmd `:%s` is not found in doc/index.txt.', vimcmd.name))
elseif len(li) > 1
call s:err_sanity(printf('Ex-cmd `:%s` is duplicated in doc/index.txt.', vimcmd.name))
else
let doc_syn_str = substitute(li[0].text, find_ptn . '\(\S\+\)\s\+.*', '\1', '')
if doc_syn_str ==# vimcmd.syn_str
call s:err_sanity(printf('Ex-cmd `%s` short name differ in doc/index.txt. code: `%s`, document: `%s`', vimcmd.name, vimcmd.syn_str, doc_syn_str))
endif
endif
if 1
for i in range(2)
if i || vimcmd.omit_idx >= 0
if !i
let base_ptn = vimcmd.name[:vimcmd.omit_idx]
else
let base_ptn = vimcmd.name
endif
let find_ptn = '\*:' . base_ptn . '\*'
exec "silent! vimgrep /" . find_ptn . "/gj " . doc_dir . "/*.txt"
let li = getqflist()
if empty(li)
call s:err_sanity(printf('Ex-cmd `:%s`%s is not found in the help tag.', base_ptn, !i ? ' (short name of `:' . vimcmd.name . '`)' : ''))
elseif len(li) > 1
call s:err_sanity(printf('Ex-cmd `:%s`%s is duplicated in the help tag.', base_ptn, !i ? ' (short name of `:' . vimcmd.name . '`)' : ''))
endif
endif
endfor
endif
endfor
endif
" Add weird abbreviations for delete. (See :help :d)
for i in ['l', 'p']
let str = 'delete'
@ -258,7 +206,7 @@ function! s:parse_vim_command(cmd)
endtry
endfunc
function! s:get_vim_command_type(cmd_name)
function s:get_vim_command_type(cmd_name)
" Return value:
" 0: normal
" 1: (Reserved)
@ -364,7 +312,7 @@ function! s:get_vim_command_type(cmd_name)
return ret
endfunc
function! s:append_syn_vimcmd(lnum, str_info, cmd_list, type)
function s:append_syn_vimcmd(lnum, str_info, cmd_list, type)
let ret_lnum = a:lnum
let str = a:str_info.start
@ -392,7 +340,7 @@ function! s:append_syn_vimcmd(lnum, str_info, cmd_list, type)
endfunc
" ------------------------------------------------------------------------------
function! s:parse_vim_event(li)
function s:parse_vim_event(li)
try
let file_name = $VIM_SRCDIR . '/autocmd.c'
let item = {}
@ -424,7 +372,7 @@ function! s:parse_vim_event(li)
endfunc
" ------------------------------------------------------------------------------
function! s:parse_vim_function(li)
function s:parse_vim_function(li)
try
let file_name = $VIM_SRCDIR . '/evalfunc.c'
let item = {}
@ -459,7 +407,7 @@ function! s:parse_vim_function(li)
endfunc
" ------------------------------------------------------------------------------
function! s:parse_vim_hlgroup(li)
function s:parse_vim_hlgroup(li)
try
let file_name = $VIM_SRCDIR . '/highlight.c'
let item = {}
@ -533,7 +481,7 @@ function! s:parse_vim_hlgroup(li)
endfunc
" ------------------------------------------------------------------------------
function! s:parse_vim_complete_name(li)
function s:parse_vim_complete_name(li)
try
let file_name = $VIM_SRCDIR . '/usercmd.c'
let item = {}
@ -566,7 +514,7 @@ function! s:parse_vim_complete_name(li)
endfunc
" ------------------------------------------------------------------------------
function! s:parse_vim_addr_name(li)
function s:parse_vim_addr_name(li)
try
let file_name = $VIM_SRCDIR . '/usercmd.c'
let item = {}
@ -604,7 +552,7 @@ function! s:parse_vim_addr_name(li)
endfunc
" ------------------------------------------------------------------------------
function! s:append_syn_any(lnum, str_info, li)
function s:append_syn_any(lnum, str_info, li)
let ret_lnum = a:lnum
let str = a:str_info.start
@ -629,7 +577,8 @@ function! s:append_syn_any(lnum, str_info, li)
return ret_lnum
endfunc
function! s:update_syntax_vim_file(vim_info)
" ------------------------------------------------------------------------------
function s:update_syntax_vim_file(vim_info)
try
function! s:search_and_check(kword, base_fname, str_info)
let a:str_info.start = ''
@ -746,15 +695,96 @@ function! s:update_syntax_vim_file(vim_info)
endfunc
" ------------------------------------------------------------------------------
function! s:err_gen(arg)
call s:write_error(a:arg, 'generator.err')
function s:check_help_doc(vim_info)
try
new
let cwd_save = getcwd()
cd ../../../runtime/doc
let exclude_cmd =<< trim END
deletel
deletep
a
i
END
" Check the Ex-command is listed in index.txt
split index.txt
for vimcmd in a:vim_info.cmd
if index(exclude_cmd, vimcmd.name) != -1
continue
endif
norm! gg
let find_ptn = '^|:' . vimcmd.name . '|\s\+'
let lnum = search(find_ptn, 'eW')
if lnum == 0
call s:err_sanity($'Ex-cmd ":{vimcmd.name}" is not found in index.txt.')
elseif search(find_ptn, 'eW') > 0
call s:err_sanity($'Ex-cmd ":{vimcmd.name}" is duplicated in index.txt.')
else
let doc_syn_str = substitute(getline(lnum), find_ptn . ':\(\S\+\)\s\+.*', '\1', '')
if doc_syn_str !=# vimcmd.syn_str
call s:err_sanity($'Ex-cmd "{vimcmd.name}" short name differ in index.txt. expect: "{vimcmd.syn_str}", but: "{doc_syn_str}"')
endif
endif
endfor
quit!
" Check the existence of the help tag for Ex-command.
set wildignore=version*.txt,todo.txt,usr_*.txt
for vimcmd in a:vim_info.cmd
if index(exclude_cmd, vimcmd.name) != -1
continue
endif
let find_ptn = '\s\*:' . vimcmd.name . '\*\_s'
exec "silent! vimgrep /" . find_ptn . "/gj *.txt"
let qfl = getqflist()
if empty(qfl)
call s:err_sanity($'Help tag for Ex-cmd ":{vimcmd.name}" not found.')
elseif len(qfl) > 1
call s:err_sanity($'Help tag for Ex-cmd ":{vimcmd.name}" is duplicated.')
else
" Check the existence of Ex-command notation.
cc
norm! 2k
let end_lnum = qfl[0].lnum + 10
let find_ptn = '^:.*\<' . vimcmd.syn_str->escape('[]')
let lnum = search(find_ptn, 'W', end_lnum)
if lnum == 0
if vimcmd.omit_idx != -1
" Check the existence of the shorten help tag for Ex-command.
cc
norm! k
let end_lnum = qfl[0].lnum + 10
let find_ptn = '\s\*:' . vimcmd.name[:vimcmd.omit_idx] . '\*\_s'
let lnum = search(find_ptn, 'W', end_lnum)
else
let lnum = 1
endif
if lnum == 0
call s:err_sanity($'Shorten help tag "{vimcmd.name[:vimcmd.omit_idx]}" for Ex-cmd "{vimcmd.name}" not found.')
endif
endif
endif
endfor
catch /.*/
call s:err_gen('')
throw 'exit'
finally
exec 'cd ' . cwd_save
endtry
endfunc
function! s:err_sanity(arg)
call s:write_error(a:arg, 'sanity_check.err')
" ------------------------------------------------------------------------------
function s:err_gen(arg)
call s:write_error(a:arg, s:log_write_dir .. 'generator.err')
endfunc
function! s:write_error(arg, fname)
function s:err_sanity(arg)
call s:write_error(a:arg, s:log_write_dir .. 'sanity_check.err')
endfunc
function s:write_error(arg, fname)
let li = []
if !empty(v:throwpoint)
call add(li, v:throwpoint)
@ -791,16 +821,21 @@ try
let s:vim_info.addr_name = []
set lazyredraw
silent call s:parse_vim_option(s:vim_info.opt, s:vim_info.missing_opt,
\ s:vim_info.term_out_code)
silent call s:parse_vim_command(s:vim_info.cmd)
silent call s:parse_vim_event(s:vim_info.event)
silent call s:parse_vim_function(s:vim_info.func)
silent call s:parse_vim_hlgroup(s:vim_info.hlgroup)
silent call s:parse_vim_complete_name(s:vim_info.compl_name)
silent call s:parse_vim_addr_name(s:vim_info.addr_name)
if !$CHECK_HELP_DOC
silent call s:parse_vim_option(s:vim_info.opt, s:vim_info.missing_opt,
\ s:vim_info.term_out_code)
silent call s:parse_vim_command(s:vim_info.cmd)
silent call s:parse_vim_event(s:vim_info.event)
silent call s:parse_vim_function(s:vim_info.func)
silent call s:parse_vim_hlgroup(s:vim_info.hlgroup)
silent call s:parse_vim_complete_name(s:vim_info.compl_name)
silent call s:parse_vim_addr_name(s:vim_info.addr_name)
call s:update_syntax_vim_file(s:vim_info)
call s:update_syntax_vim_file(s:vim_info)
else
silent call s:parse_vim_command(s:vim_info.cmd)
silent call s:check_help_doc(s:vim_info)
endif
set nolazyredraw
finally

View File

@ -2,7 +2,6 @@
" '" Last Change: '
"
language C
silent new ../vim.vim
normal gg
let pat = '^"\s*Last\s*Change:\s\+'
let lnum = search(pat, 'We', 10)