vim-config/unmanaged-vim-plug/txtfmt/syntax/txtfmt.vim

2263 lines
81 KiB
VimL
Executable File

" Txtfmt: Set of Vim plugins (syntax, ftplugin, plugin) for creating and
" displaying formatted text with Vim.
" File: This is the txtfmt syntax file
" Creation: 2004 Nov 06
" Last Change: 2010 Sep 04
" Maintainer: Brett Pershing Stahlman <brettstahlman@comcast.net>
" License: This file is placed in the public domain.
" Let the common code know whether this is syntax file or ftplugin
let s:script_name = 'syntax'
" Constants <<<
" >>>
" Common Configuration <<<
" Note: No point in having the modeline and/or global options processed by
" both the syntax and ftplugin files.
" IMPORTANT: Everything inside the "Common Configuration" fold should be
" identical between the syntax and ftplugin files. Keep in sync as changes are
" made...
if !exists('b:txtfmt_did_common_config')
let b:txtfmt_did_common_config = 1
" Ensure that the code within plugin/txtfmt.vim will be executed when the
" file is sourced.
let b:txtfmt_do_common_config = 1
" TODO - Should we ensure that warning occurs for missing file?
runtime plugin/txtfmt.vim
" Make sure the common config doesn't run again
unlet b:txtfmt_do_common_config
endif
" >>>
" Config <<<
" Needed only for syntax file
" Note: Performed after the Common Configuration, which sets the 'escape'
" option, needed when defining syntax
" Function: s:Do_config() <<<
" Purpose: Do configuration required only for syntax file.
" Assumption: Common config has already been performed, so that needed options
" have been set.
fu! s:Do_config()
" Nothing to do here now that skip def is defined in Define_syntax
" TODO...
endfu
" >>>
call s:Do_config()
" >>>
" Function: s:Winrestcmd() <<<
" Purpose: Works just like Vim's winrestcmd, which was added in Vim 6.3,
" (and therefore, is not something I want to rely upon). Returns a
" string that can be :execute'd to restore the current window layout,
" assuming exactly the same set of windows exist when the string is
" exe'd.
" Note: winrestcmd() format looks like this:
" 1resize <height1>|vert 1resize <width1>| ... Nresize <heightN>|vert Nresize <widthN>|
" Note how the final element is terminated by a vertical bar.
" Testing: Verified for non-trivial window layout that winrestcmd() and
" this function return the same string.
fu! s:Winrestcmd()
let i = 1
let N = winnr('$')
let cmd = ''
while i <= N
let cmd = cmd . i . 'resize ' . winheight(i) . '|vert ' . i . 'resize ' . winwidth(i) . '|'
let i = i + 1
endwhile
return cmd
endfu
" >>>
" Function: s:Create_scratch_buffer() <<<
" Purpose: Create an empty scratch buffer in the current window, hiding
" the current buffer.
" Assumption: The hidden buffer will be restored by a call to
" s:Cleanup_scratch_buffer() later.
" Vim Idiosyncrasy: Special care must be taken when the current window
" contains an empty, [No Name] buffer; in that case, :hide enew will, by
" default, reuse that buffer for the newly created one (discarding any
" existing buf-local variables). This is problematic, since we need to
" return to the original buffer when we're finished with the scratch
" buffer. Note that in some cases, Txtfmt options may already have been
" stored to buf-local variables in the empty, [No Name] buffer before
" this function is called.
" Solution: Bram suggested adding a blank line to the original buffer to
" ensure it isn't reused. The blank line can be removed in the
" s:Cleanup_scratch_buffer() function.
" Note: Before this function was added, the scratch buffer was created
" in a new window. The problem with that approach was that it fails when
" there's no room to create another window.
fu! s:Create_scratch_buffer()
" See whether the current buffer is an empty, unnamed buffer that
" will be discarded by the :hide enew below.
if line('$') == 1 && col('$') == 1 && bufname('%') == ''
" Current buffer is an empty, unnamed buffer
" To prevent its being discarded by :hide enew, add a blank
" line, which we'll remove in the associated cleanup function
" Make sure the buffer is modifiable, taking care to save and restore
" current setting.
let modifiable_save = &l:modifiable
setlocal modifiable
call append(1, '')
let &l:modifiable = modifiable_save
let s:Added_blank_line_to_empty_buffer = 1
endif
" Create the scratch buffer
hide enew
set buftype=nofile
set bufhidden=wipe
set noswapfile
" The following setlocal is necessary to prevent E21 in the event that
" 'nomodifiable' is set globally.
setlocal modifiable
endfu
" >>>
" Function: s:Cleanup_scratch_buffer() <<<
" Purpose: Wipe out the scratch buffer in the current window, restoring
" the buffer it supplanted.
" Assumption: s:Create_scratch_buffer() was called to create the scratch
" buffer in the current window.
fu! s:Cleanup_scratch_buffer()
" Return to the buffer that was current when the associated create
" function was called
" Note: The scratch buffer 'bufhidden' option will ensure that it's
" bwipe'd
buffer #
if exists('s:Added_blank_line_to_empty_buffer')
unlet s:Added_blank_line_to_empty_buffer
" Get rid of the blank line we added in the associated create
" function.
" Note: Make sure the buffer is modifiable, taking care to save and
" restore current setting.
let modifiable_save = &l:modifiable
setlocal modifiable
undo
let &l:modifiable = modifiable_save
endif
endfu
" >>>
" Function: s:Is_match_offset_char_based() <<<
" Purpose: Return nonzero if and only if the this version of Vim treats match
" offsets as character offsets.
" Assumption: Current encoding is multi-byte
fu! s:Is_match_offset_char_based()
let s = "AB" . nr2char(0x100) . 'C'
" Set lazyredraw to ensure user never sees the buffer we create
let lazyredraw_save = &lazyredraw
set lazyredraw
" Create a scratch buffer in the current window
call s:Create_scratch_buffer()
" Put the test string at the head of the new scratch buffer
call setline(1, s)
" Create syntax region that will include the last character on the line if
" and only if this Vim treats match offsets as char offsets
syn match Tf_Test /AB/me=e+2,he=e+2
" Is the last char in the Tf_Test syntax group?
if synIDattr(synID(line("."), col("$") - 1, 1), "name") == 'Tf_Test'
let off_is_char = 1
else
let off_is_char = 0
endif
" Clean up the scratch buffer, returning to the previous buffer
call s:Cleanup_scratch_buffer()
" Restore old lazyredraw setting
if !lazyredraw_save
set nolazyredraw
endif
" Return true if and only if offsets are char-based
return off_is_char
endfu
" >>>
" Function: s:Get_bytes_per_token() <<<
" Purpose: Return the number of bytes used to encode the first Txtfmt token,
" warning user if this number is different from the number of bytes used to
" encode the last.
" Assumption: # of bytes per token will never decrease as character codes
" increase
fu! s:Get_bytes_per_token()
let num_bytes = strlen(nr2char(b:txtfmt_clr_first_tok))
" Make sure first and last token comprise the same number of bytes,
" and warn user if not...
if num_bytes != strlen(nr2char(b:txtfmt_fmt_last_tok))
" Note: Txtfmt highlighting will probably be incorrect, but there's
" not much we can do about it other than warn user...
echohl WarningMsg
echomsg "Warning! The 'tokrange' setting you have chosen may not work correctly"
echomsg "because not all tokens within the range are encoded with the same number"
echomsg "of bytes. If fmt/clr regions do not display correctly, you should either"
echomsg "choose a different 'tokrange', or apply the multi-byte patch included with"
echomsg "the plugin."
echohl Comment
echomsg " :help txtfmt-choosing-token-range"
echohl MoreMsg
echomsg "Hit any key to continue..."
echohl None
call getchar()
endif
" Return # of bytes used by first token
return num_bytes
endfu
" >>>
" Function: s:Define_syntax() <<<
fu! s:Define_syntax()
" Define a convenience flag that indicates whether background colors are
" in effect
let bgc_enabled = b:txtfmt_cfg_bgcolor && b:txtfmt_cfg_numbgcolors > 0
let clr_enabled = b:txtfmt_cfg_numfgcolors > 0
" cui (color uniqueness index) will contain a different index for each
" color configuration (and will be empty string in the unlikely event that
" both numfgcolors and numbgcolors are 0 - i.e., no colors used)
" Note: This strategy is necessary because Vim's highlight groups are not
" buffer-specific, but there is a buffer-specific version of txtfmtColor{}
let cui = b:txtfmt_color_uniq_idx
" Concealment group <<<
" Create a concealment highlight group, to which others can link
" The Ignore group is a preferred group, defined in distributed
" syncolor.vim
" IMPORTANT NOTE: Some of the distributed colorschemes DO NOT hide text in
" the Ignore group. I disagree with this practice, and have posted to the
" Vim list on the subject, but the situation is unlikely to change...
" Fortunately, there is a workaround that always works for the GUI,and
" sometimes works for a cterm.
" Workaround: *Attempt* to define fg=bg. This will always work for the
" GUI, and will work for a cterm if the colorscheme has defined ctermbg
" for the Normal group. If the attempt fails, simply link to Ignore group,
" which may or may not hide text.
if has('gui_running')
hi Tf_conceal guifg=bg
else
let v:errmsg = ""
silent! hi Tf_conceal ctermfg=bg
if v:errmsg != ""
" Link to Ignore and put suggestions in help file for users of
" colorschemes that don't hide Ignore'd text.
hi link Tf_conceal Ignore
endif
endif
" Check for existence of 'conceal' patch (and desire on part of user to
" use it)
if b:txtfmt_cfg_conceal
" Note: 'conceallevel' and 'concealcursor' are window-local
setl conceallevel=3
let &l:concealcursor = b:txtfmt_cfg_concealcursor
let concealends = ' concealends'
let conceal = ' conceal'
else
let concealends = ''
let conceal = ''
endif
" >>>
" Define match offset that corresponds to a single txtfmt token <<<
" Note: This is required because of a Vim bug: as of Vim 7.1, syntax match
" offsets are always treated as byte offsets, though the documentation
" suggests offsets are char-based. There is a patch floating around,
" however, which fixes this; also, Vim 7.2 *may* fix it; thus, it's not
" safe to assume anything about whether the running Vim uses byte or char
" offsets. If necessary, Is_match_offset_char_based will find out.
" Note: Eventually, the if and first elseif can be combined, but for now,
" I want to set b:txtfmt_dbg_syn_off as a debug var, in case any users
" experience problems...
if b:txtfmt_cfg_enc_class == '1'
let tok_off = 1
" Nonexistence of b:txtfmt_dbg_syn_off indicates
" Is_match_offset_char_based wasn't run
unlet! b:txtfmt_dbg_syn_off
silent elseif s:Is_match_offset_char_based()
let tok_off = 1
let b:txtfmt_dbg_syn_off = 'char'
else
" Offsets are measured in bytes; hence, we need to determine how many
" bytes per token
let tok_off = s:Get_bytes_per_token()
let b:txtfmt_dbg_syn_off = 'byte'
endif
" >>>
" 'containedin' list (option dependent) <<<
if b:txtfmt_cfg_nested
" Ensure that txtfmt top-level item can be contained by a non-txtfmt
" syntax group (e.g. C-language comment).
" TODO - Perhaps put inner_esc groups into a cluster.
if b:txtfmt_cfg_escape != 'none'
let containedin_def = ' containedin=ALLBUT,@Tf'.cui.'_all,Tf_def_tok'
\.',Tf_outer_esc,Tf_any_stok_inner_esc'
\.(clr_enabled ? ',Tf_clr_etok_inner_esc' : '')
\.(bgc_enabled ? ',Tf_bgc_etok_inner_esc' : '').',Tf_fmt_etok_inner_esc'
else
let containedin_def = ' containedin=ALLBUT,@Tf'.cui.'_all,Tf_def_tok'
endif
else
let containedin_def = ''
endif
" >>>
" Define special default token group <<<
" This group ensures that 'no clr', 'no bgc', and 'no fmt' tokens at top
" level (including those that end a clr only, bgc only, or fmt only group)
" will be concealed.
" Order note: This region is defined here to ensure that it has a lower
" priority than any of the other txtfmt regions that can be begun by a
" default token.
exe 'syn match Tf_def_tok /['.b:txtfmt_re_any_etok_atom.']/ contained'.conceal
hi link Tf_def_tok Tf_conceal
" >>>
" Choose cterm or gui versions of color and format assignments
if has('gui_running')
let eq_clr = ' guifg='
let eq_bgc = ' guibg='
let eq_fmt = ' gui='
else
let eq_clr = ' ctermfg='
let eq_bgc = ' ctermbg='
let eq_fmt = ' cterm='
endif
" NOTES TO PRESERVE
" TODO - Decide whether the inner_esc regions obviate the need for the
" skip-def. (I don't think so...)
" UNDER CONSTRUCTION
" Create background-color specific concealment groups
" Note: Use cui to ensure that different buffers could have different sets
" of background colors in effect
" Loop over active colors only (with the aid of index indirection array)
let pi = 1
while pi <= (b:txtfmt_cfg_bgcolor ? b:txtfmt_cfg_numbgcolors : 0)
let i = b:txtfmt_cfg_bgcolor{pi}
exe 'hi Tf'.cui.'_conceal_'.i.' '.eq_bgc.b:txtfmt_bgc{i}.eq_clr.b:txtfmt_bgc{i}
let pi = pi + 1
endwhile
" Create vars to facilitate switching between normal (toplevel)
" concealment group and background-color-specific groups
let matchgroup_top_def = ' matchgroup=Tf_conceal'
let matchgroup_def = matchgroup_top_def
" Important Note: The following line may be executed on the Vim command
" line to regenerate the code within the BEGIN...<<< / END...>>> markers.
" The script generating the code is a perl script appended to the end of
" this file: specifically, between the `#!perl' and the __END__ marker.
" :0/BEGIN AUTOGENERATED CODE BLOCK <\{3}/;/END AUTOGENERATED CODE BLOCK >\{3}/d|exe '.-1r !perl -x %'|exe "norm '["
" BEGIN AUTOGENERATED CODE BLOCK <<<
" Last update: Sun Sep 27 16:16:52 2009
"============= BEGIN NON-INDENTING BLOCK =============
if clr_enabled
"===
"*** clr
"===
if b:txtfmt_cfg_escape != 'none'
let contains_clr=
\' contains='
\.'Tf_any_stok_inner_esc,'
\.'Tf_clr_etok_inner_esc'
if b:txtfmt_cfg_escape == 'bslash'
let skip_clr = ' skip=/\\./'
else
let skip_clr = ' skip=/\(.\)\1/'
endif
else
let contains_clr = ''
let skip_clr = ''
endif
let end_clr =
\' end=/['
\.b:txtfmt_re_any_stok_atom
\.b:txtfmt_re_clr_etok_atom
\.']/me=e-'.tok_off
let r1_clr =
\skip_clr
\.contains_clr
\.end_clr
\.containedin_def
let start_clr =
\' start=/['
\.(bgc_enabled ? b:txtfmt_re_bgc_etok_atom : '').b:txtfmt_re_fmt_etok_atom
\.']/'
let r2_clr =
\skip_clr
\.contains_clr
\.start_clr
\.end_clr
\.' contained'
"============= BEGIN NON-INDENTING BLOCK =============
if bgc_enabled
"===
"*** clr-bgc
"===
if b:txtfmt_cfg_escape != 'none'
let contains_clrbgc=
\' contains='
\.'Tf_any_stok_inner_esc,'
\.'Tf_clr_etok_inner_esc,'
\.'Tf_bgc_etok_inner_esc'
if b:txtfmt_cfg_escape == 'bslash'
let skip_clrbgc = ' skip=/\\./'
else
let skip_clrbgc = ' skip=/\(.\)\1/'
endif
else
let contains_clrbgc = ''
let skip_clrbgc = ''
endif
let end_clrbgc =
\' end=/['
\.b:txtfmt_re_any_stok_atom
\.b:txtfmt_re_clr_etok_atom
\.b:txtfmt_re_bgc_etok_atom
\.']/me=e-'.tok_off
let r1_clrbgc =
\skip_clrbgc
\.contains_clrbgc
\.end_clrbgc
\.' contained'
let start_clrbgc =
\' start=/['
\.b:txtfmt_re_fmt_etok_atom
\.']/'
let r2_clrbgc =
\skip_clrbgc
\.contains_clrbgc
\.start_clrbgc
\.end_clrbgc
\.' contained'
"===
"*** clr-bgc-fmt
"===
if b:txtfmt_cfg_escape != 'none'
let contains_clrbgcfmt=
\' contains='
\.'Tf_any_stok_inner_esc,'
\.'Tf_clr_etok_inner_esc,'
\.'Tf_bgc_etok_inner_esc,'
\.'Tf_fmt_etok_inner_esc'
if b:txtfmt_cfg_escape == 'bslash'
let skip_clrbgcfmt = ' skip=/\\./'
else
let skip_clrbgcfmt = ' skip=/\(.\)\1/'
endif
else
let contains_clrbgcfmt = ''
let skip_clrbgcfmt = ''
endif
let end_clrbgcfmt =
\' end=/['
\.b:txtfmt_re_any_stok_atom
\.b:txtfmt_re_clr_etok_atom
\.b:txtfmt_re_bgc_etok_atom
\.b:txtfmt_re_fmt_etok_atom
\.']/me=e-'.tok_off
let r1_clrbgcfmt =
\skip_clrbgcfmt
\.contains_clrbgcfmt
\.end_clrbgcfmt
\.' contained'
" Revert to toplevel (no background color) matchgroup
endif " bgc_enabled
"============= END NON-INDENTING BLOCK =============
"===
"*** clr-fmt
"===
if b:txtfmt_cfg_escape != 'none'
let contains_clrfmt=
\' contains='
\.'Tf_any_stok_inner_esc,'
\.'Tf_clr_etok_inner_esc,'
\.'Tf_fmt_etok_inner_esc'
if b:txtfmt_cfg_escape == 'bslash'
let skip_clrfmt = ' skip=/\\./'
else
let skip_clrfmt = ' skip=/\(.\)\1/'
endif
else
let contains_clrfmt = ''
let skip_clrfmt = ''
endif
let end_clrfmt =
\' end=/['
\.b:txtfmt_re_any_stok_atom
\.b:txtfmt_re_clr_etok_atom
\.b:txtfmt_re_fmt_etok_atom
\.']/me=e-'.tok_off
let r1_clrfmt =
\skip_clrfmt
\.contains_clrfmt
\.end_clrfmt
\.' contained'
" Define the r2 region vars if and only if at least one of the
" region types whose end token could begin this region is active
"============= BEGIN NON-INDENTING BLOCK =============
if bgc_enabled
let start_clrfmt =
\' start=/['
\.b:txtfmt_re_bgc_etok_atom
\.']/'
let r2_clrfmt =
\skip_clrfmt
\.contains_clrfmt
\.start_clrfmt
\.end_clrfmt
\.' contained'
endif " bgc_enabled
"============= END NON-INDENTING BLOCK =============
"============= BEGIN NON-INDENTING BLOCK =============
if bgc_enabled
"===
"*** clr-fmt-bgc
"===
if b:txtfmt_cfg_escape != 'none'
let contains_clrfmtbgc=
\' contains='
\.'Tf_any_stok_inner_esc,'
\.'Tf_clr_etok_inner_esc,'
\.'Tf_fmt_etok_inner_esc,'
\.'Tf_bgc_etok_inner_esc'
if b:txtfmt_cfg_escape == 'bslash'
let skip_clrfmtbgc = ' skip=/\\./'
else
let skip_clrfmtbgc = ' skip=/\(.\)\1/'
endif
else
let contains_clrfmtbgc = ''
let skip_clrfmtbgc = ''
endif
let end_clrfmtbgc =
\' end=/['
\.b:txtfmt_re_any_stok_atom
\.b:txtfmt_re_clr_etok_atom
\.b:txtfmt_re_fmt_etok_atom
\.b:txtfmt_re_bgc_etok_atom
\.']/me=e-'.tok_off
let r1_clrfmtbgc =
\skip_clrfmtbgc
\.contains_clrfmtbgc
\.end_clrfmtbgc
\.' contained'
" Revert to toplevel (no background color) matchgroup
endif " bgc_enabled
"============= END NON-INDENTING BLOCK =============
endif " clr_enabled
"============= END NON-INDENTING BLOCK =============
"============= BEGIN NON-INDENTING BLOCK =============
if bgc_enabled
"===
"*** bgc
"===
if b:txtfmt_cfg_escape != 'none'
let contains_bgc=
\' contains='
\.'Tf_any_stok_inner_esc,'
\.'Tf_bgc_etok_inner_esc'
if b:txtfmt_cfg_escape == 'bslash'
let skip_bgc = ' skip=/\\./'
else
let skip_bgc = ' skip=/\(.\)\1/'
endif
else
let contains_bgc = ''
let skip_bgc = ''
endif
let end_bgc =
\' end=/['
\.b:txtfmt_re_any_stok_atom
\.b:txtfmt_re_bgc_etok_atom
\.']/me=e-'.tok_off
let r1_bgc =
\skip_bgc
\.contains_bgc
\.end_bgc
\.containedin_def
let start_bgc =
\' start=/['
\.(clr_enabled ? b:txtfmt_re_clr_etok_atom : '').b:txtfmt_re_fmt_etok_atom
\.']/'
let r2_bgc =
\skip_bgc
\.contains_bgc
\.start_bgc
\.end_bgc
\.' contained'
"============= BEGIN NON-INDENTING BLOCK =============
if clr_enabled
"===
"*** bgc-clr
"===
if b:txtfmt_cfg_escape != 'none'
let contains_bgcclr=
\' contains='
\.'Tf_any_stok_inner_esc,'
\.'Tf_bgc_etok_inner_esc,'
\.'Tf_clr_etok_inner_esc'
if b:txtfmt_cfg_escape == 'bslash'
let skip_bgcclr = ' skip=/\\./'
else
let skip_bgcclr = ' skip=/\(.\)\1/'
endif
else
let contains_bgcclr = ''
let skip_bgcclr = ''
endif
let end_bgcclr =
\' end=/['
\.b:txtfmt_re_any_stok_atom
\.b:txtfmt_re_bgc_etok_atom
\.b:txtfmt_re_clr_etok_atom
\.']/me=e-'.tok_off
let r1_bgcclr =
\skip_bgcclr
\.contains_bgcclr
\.end_bgcclr
\.' contained'
let start_bgcclr =
\' start=/['
\.b:txtfmt_re_fmt_etok_atom
\.']/'
let r2_bgcclr =
\skip_bgcclr
\.contains_bgcclr
\.start_bgcclr
\.end_bgcclr
\.' contained'
"===
"*** bgc-clr-fmt
"===
if b:txtfmt_cfg_escape != 'none'
let contains_bgcclrfmt=
\' contains='
\.'Tf_any_stok_inner_esc,'
\.'Tf_bgc_etok_inner_esc,'
\.'Tf_clr_etok_inner_esc,'
\.'Tf_fmt_etok_inner_esc'
if b:txtfmt_cfg_escape == 'bslash'
let skip_bgcclrfmt = ' skip=/\\./'
else
let skip_bgcclrfmt = ' skip=/\(.\)\1/'
endif
else
let contains_bgcclrfmt = ''
let skip_bgcclrfmt = ''
endif
let end_bgcclrfmt =
\' end=/['
\.b:txtfmt_re_any_stok_atom
\.b:txtfmt_re_bgc_etok_atom
\.b:txtfmt_re_clr_etok_atom
\.b:txtfmt_re_fmt_etok_atom
\.']/me=e-'.tok_off
let r1_bgcclrfmt =
\skip_bgcclrfmt
\.contains_bgcclrfmt
\.end_bgcclrfmt
\.' contained'
endif " clr_enabled
"============= END NON-INDENTING BLOCK =============
"===
"*** bgc-fmt
"===
if b:txtfmt_cfg_escape != 'none'
let contains_bgcfmt=
\' contains='
\.'Tf_any_stok_inner_esc,'
\.'Tf_bgc_etok_inner_esc,'
\.'Tf_fmt_etok_inner_esc'
if b:txtfmt_cfg_escape == 'bslash'
let skip_bgcfmt = ' skip=/\\./'
else
let skip_bgcfmt = ' skip=/\(.\)\1/'
endif
else
let contains_bgcfmt = ''
let skip_bgcfmt = ''
endif
let end_bgcfmt =
\' end=/['
\.b:txtfmt_re_any_stok_atom
\.b:txtfmt_re_bgc_etok_atom
\.b:txtfmt_re_fmt_etok_atom
\.']/me=e-'.tok_off
let r1_bgcfmt =
\skip_bgcfmt
\.contains_bgcfmt
\.end_bgcfmt
\.' contained'
" Define the r2 region vars if and only if at least one of the
" region types whose end token could begin this region is active
"============= BEGIN NON-INDENTING BLOCK =============
if clr_enabled
let start_bgcfmt =
\' start=/['
\.b:txtfmt_re_clr_etok_atom
\.']/'
let r2_bgcfmt =
\skip_bgcfmt
\.contains_bgcfmt
\.start_bgcfmt
\.end_bgcfmt
\.' contained'
endif " clr_enabled
"============= END NON-INDENTING BLOCK =============
"============= BEGIN NON-INDENTING BLOCK =============
if clr_enabled
"===
"*** bgc-fmt-clr
"===
if b:txtfmt_cfg_escape != 'none'
let contains_bgcfmtclr=
\' contains='
\.'Tf_any_stok_inner_esc,'
\.'Tf_bgc_etok_inner_esc,'
\.'Tf_fmt_etok_inner_esc,'
\.'Tf_clr_etok_inner_esc'
if b:txtfmt_cfg_escape == 'bslash'
let skip_bgcfmtclr = ' skip=/\\./'
else
let skip_bgcfmtclr = ' skip=/\(.\)\1/'
endif
else
let contains_bgcfmtclr = ''
let skip_bgcfmtclr = ''
endif
let end_bgcfmtclr =
\' end=/['
\.b:txtfmt_re_any_stok_atom
\.b:txtfmt_re_bgc_etok_atom
\.b:txtfmt_re_fmt_etok_atom
\.b:txtfmt_re_clr_etok_atom
\.']/me=e-'.tok_off
let r1_bgcfmtclr =
\skip_bgcfmtclr
\.contains_bgcfmtclr
\.end_bgcfmtclr
\.' contained'
endif " clr_enabled
"============= END NON-INDENTING BLOCK =============
" Revert to toplevel (no background color) matchgroup
endif " bgc_enabled
"============= END NON-INDENTING BLOCK =============
"===
"*** fmt
"===
if b:txtfmt_cfg_escape != 'none'
let contains_fmt=
\' contains='
\.'Tf_any_stok_inner_esc,'
\.'Tf_fmt_etok_inner_esc'
if b:txtfmt_cfg_escape == 'bslash'
let skip_fmt = ' skip=/\\./'
else
let skip_fmt = ' skip=/\(.\)\1/'
endif
else
let contains_fmt = ''
let skip_fmt = ''
endif
let end_fmt =
\' end=/['
\.b:txtfmt_re_any_stok_atom
\.b:txtfmt_re_fmt_etok_atom
\.']/me=e-'.tok_off
let r1_fmt =
\skip_fmt
\.contains_fmt
\.end_fmt
\.containedin_def
" Define the r2 region vars if and only if at least one of the
" region types whose end token could begin this region is active
"============= BEGIN NON-INDENTING BLOCK =============
if clr_enabled || bgc_enabled
let start_fmt =
\' start=/['
\.(clr_enabled ? b:txtfmt_re_clr_etok_atom : '').(bgc_enabled ? b:txtfmt_re_bgc_etok_atom : '')
\.']/'
let r2_fmt =
\skip_fmt
\.contains_fmt
\.start_fmt
\.end_fmt
\.' contained'
endif " clr_enabled || bgc_enabled
"============= END NON-INDENTING BLOCK =============
"============= BEGIN NON-INDENTING BLOCK =============
if clr_enabled
"===
"*** fmt-clr
"===
if b:txtfmt_cfg_escape != 'none'
let contains_fmtclr=
\' contains='
\.'Tf_any_stok_inner_esc,'
\.'Tf_fmt_etok_inner_esc,'
\.'Tf_clr_etok_inner_esc'
if b:txtfmt_cfg_escape == 'bslash'
let skip_fmtclr = ' skip=/\\./'
else
let skip_fmtclr = ' skip=/\(.\)\1/'
endif
else
let contains_fmtclr = ''
let skip_fmtclr = ''
endif
let end_fmtclr =
\' end=/['
\.b:txtfmt_re_any_stok_atom
\.b:txtfmt_re_fmt_etok_atom
\.b:txtfmt_re_clr_etok_atom
\.']/me=e-'.tok_off
let r1_fmtclr =
\skip_fmtclr
\.contains_fmtclr
\.end_fmtclr
\.' contained'
" Define the r2 region vars if and only if at least one of the
" region types whose end token could begin this region is active
"============= BEGIN NON-INDENTING BLOCK =============
if bgc_enabled
let start_fmtclr =
\' start=/['
\.b:txtfmt_re_bgc_etok_atom
\.']/'
let r2_fmtclr =
\skip_fmtclr
\.contains_fmtclr
\.start_fmtclr
\.end_fmtclr
\.' contained'
endif " bgc_enabled
"============= END NON-INDENTING BLOCK =============
"============= BEGIN NON-INDENTING BLOCK =============
if bgc_enabled
"===
"*** fmt-clr-bgc
"===
if b:txtfmt_cfg_escape != 'none'
let contains_fmtclrbgc=
\' contains='
\.'Tf_any_stok_inner_esc,'
\.'Tf_fmt_etok_inner_esc,'
\.'Tf_clr_etok_inner_esc,'
\.'Tf_bgc_etok_inner_esc'
if b:txtfmt_cfg_escape == 'bslash'
let skip_fmtclrbgc = ' skip=/\\./'
else
let skip_fmtclrbgc = ' skip=/\(.\)\1/'
endif
else
let contains_fmtclrbgc = ''
let skip_fmtclrbgc = ''
endif
let end_fmtclrbgc =
\' end=/['
\.b:txtfmt_re_any_stok_atom
\.b:txtfmt_re_fmt_etok_atom
\.b:txtfmt_re_clr_etok_atom
\.b:txtfmt_re_bgc_etok_atom
\.']/me=e-'.tok_off
let r1_fmtclrbgc =
\skip_fmtclrbgc
\.contains_fmtclrbgc
\.end_fmtclrbgc
\.' contained'
" Revert to toplevel (no background color) matchgroup
endif " bgc_enabled
"============= END NON-INDENTING BLOCK =============
endif " clr_enabled
"============= END NON-INDENTING BLOCK =============
"============= BEGIN NON-INDENTING BLOCK =============
if bgc_enabled
"===
"*** fmt-bgc
"===
if b:txtfmt_cfg_escape != 'none'
let contains_fmtbgc=
\' contains='
\.'Tf_any_stok_inner_esc,'
\.'Tf_fmt_etok_inner_esc,'
\.'Tf_bgc_etok_inner_esc'
if b:txtfmt_cfg_escape == 'bslash'
let skip_fmtbgc = ' skip=/\\./'
else
let skip_fmtbgc = ' skip=/\(.\)\1/'
endif
else
let contains_fmtbgc = ''
let skip_fmtbgc = ''
endif
let end_fmtbgc =
\' end=/['
\.b:txtfmt_re_any_stok_atom
\.b:txtfmt_re_fmt_etok_atom
\.b:txtfmt_re_bgc_etok_atom
\.']/me=e-'.tok_off
let r1_fmtbgc =
\skip_fmtbgc
\.contains_fmtbgc
\.end_fmtbgc
\.' contained'
" Define the r2 region vars if and only if at least one of the
" region types whose end token could begin this region is active
"============= BEGIN NON-INDENTING BLOCK =============
if clr_enabled
let start_fmtbgc =
\' start=/['
\.b:txtfmt_re_clr_etok_atom
\.']/'
let r2_fmtbgc =
\skip_fmtbgc
\.contains_fmtbgc
\.start_fmtbgc
\.end_fmtbgc
\.' contained'
endif " clr_enabled
"============= END NON-INDENTING BLOCK =============
"============= BEGIN NON-INDENTING BLOCK =============
if clr_enabled
"===
"*** fmt-bgc-clr
"===
if b:txtfmt_cfg_escape != 'none'
let contains_fmtbgcclr=
\' contains='
\.'Tf_any_stok_inner_esc,'
\.'Tf_fmt_etok_inner_esc,'
\.'Tf_bgc_etok_inner_esc,'
\.'Tf_clr_etok_inner_esc'
if b:txtfmt_cfg_escape == 'bslash'
let skip_fmtbgcclr = ' skip=/\\./'
else
let skip_fmtbgcclr = ' skip=/\(.\)\1/'
endif
else
let contains_fmtbgcclr = ''
let skip_fmtbgcclr = ''
endif
let end_fmtbgcclr =
\' end=/['
\.b:txtfmt_re_any_stok_atom
\.b:txtfmt_re_fmt_etok_atom
\.b:txtfmt_re_bgc_etok_atom
\.b:txtfmt_re_clr_etok_atom
\.']/me=e-'.tok_off
let r1_fmtbgcclr =
\skip_fmtbgcclr
\.contains_fmtbgcclr
\.end_fmtbgcclr
\.' contained'
endif " clr_enabled
"============= END NON-INDENTING BLOCK =============
" Revert to toplevel (no background color) matchgroup
endif " bgc_enabled
"============= END NON-INDENTING BLOCK =============
"============= BEGIN NON-INDENTING BLOCK =============
if clr_enabled
"===
"*** Loop over clr levels
"===
let ip = 1
while ip <= b:txtfmt_cfg_numfgcolors
let i = b:txtfmt_cfg_fgcolor{ip}
let chi = nr2char(b:txtfmt_clr_first_tok + i)
" Add to appropriate clusters
exe 'syn cluster Tf'.cui.'_all add=Tf'.cui.'_clr_'.i
exe 'syn cluster Tf'.cui.'_clr_all add=Tf'.cui.'_clr_'.i
" Cache the nextgroup clause
let ng = ' nextgroup=@Tf'.cui.'_clr_all'.(bgc_enabled ? ',@Tf'.cui.'_clrbgc_'.i.'_all' : '').',@Tf'.cui.'_clrfmt_'.i.'_all,Tf_def_tok'
" Define region that is begun by a start token
exe 'syn region Tf'.cui.'_clr_'.i.matchgroup_def
\.' start=/'.chi.'/'.r1_clr.ng.concealends
" Define region that is begun by an end token
" (when permitted by a nextgroup)
exe 'syn region Tf'.cui.'_clr_'.i.'_rtd'.matchgroup_def
\.r2_clr.ng.concealends
" Define highlighting for this region
" Note: cterm= MUST come after ctermfg= to ensure that bold attribute is
" handled correctly in a cterm.
" :help cterm-colors
exe 'hi Tf'.cui.'_clr_'.i
\.eq_clr.b:txtfmt_clr{i}
" Link rtd to non-rtd group
exe 'hi link Tf'.cui.'_clr_'.i.'_rtd Tf'.cui.'_clr_'.i
"============= BEGIN NON-INDENTING BLOCK =============
if bgc_enabled
"===
"*** Loop over clr-bgc levels
"===
let jp = 1
while jp <= b:txtfmt_cfg_numbgcolors
let j = b:txtfmt_cfg_bgcolor{jp}
let chj = nr2char(b:txtfmt_bgc_first_tok + j)
" Add to appropriate clusters
exe 'syn cluster Tf'.cui.'_all add=Tf'.cui.'_clrbgc_'.i.'_'.j
exe 'syn cluster Tf'.cui.'_clrbgc_'.i.'_all add=Tf'.cui.'_clrbgc_'.i.'_'.j
" Ensure that this and higher order regions use bgc-specific concealment group
let matchgroup_def = ' matchgroup=Tf'.cui.'_conceal_'.j
" Cache the nextgroup clause
let ng = ' nextgroup=Tf'.cui.'_bgc_'.j.'_rtd,Tf'.cui.'_clr_'.i.'_rtd,@Tf'.cui.'_bgcclr_'.j.'_all,@Tf'.cui.'_clrbgc_'.i.'_all,@Tf'.cui.'_clrbgcfmt_'.i.'_'.j.'_all'
" Define region that is begun by a start token
exe 'syn region Tf'.cui.'_clrbgc_'.i.'_'.j.matchgroup_def
\.' start=/'.chj.'/'.r1_clrbgc.ng.concealends
" Define region that is begun by an end token
" (when permitted by a nextgroup)
exe 'syn region Tf'.cui.'_clrbgc_'.i.'_'.j.'_rtd'.matchgroup_def
\.r2_clrbgc.ng.concealends
" Define highlighting for this region
" Note: cterm= MUST come after ctermfg= to ensure that bold attribute is
" handled correctly in a cterm.
" :help cterm-colors
exe 'hi Tf'.cui.'_clrbgc_'.i.'_'.j
\.eq_clr.b:txtfmt_clr{i}.eq_bgc.b:txtfmt_bgc{j}
" Link rtd to non-rtd group
exe 'hi link Tf'.cui.'_clrbgc_'.i.'_'.j.'_rtd Tf'.cui.'_clrbgc_'.i.'_'.j
"===
"*** Loop over clr-bgc-fmt levels
"===
let k = 1
while k <= b:txtfmt_num_formats - 1
let chk = nr2char(b:txtfmt_fmt_first_tok + k)
" Add to appropriate clusters
exe 'syn cluster Tf'.cui.'_all add=Tf'.cui.'_clrbgcfmt_'.i.'_'.j.'_'.k
exe 'syn cluster Tf'.cui.'_clrbgcfmt_'.i.'_'.j.'_all add=Tf'.cui.'_clrbgcfmt_'.i.'_'.j.'_'.k
" Define region that is begun by a start token
exe 'syn region Tf'.cui.'_clrbgcfmt_'.i.'_'.j.'_'.k.matchgroup_def
\.' start=/'.chk.'/'.r1_clrbgcfmt.' nextgroup=Tf'.cui.'_bgcfmt_'.j.'_'.k.'_rtd,Tf'.cui.'_clrfmt_'.i.'_'.k.'_rtd,Tf'.cui.'_clrbgc_'.i.'_'.j.'_rtd,@Tf'.cui.'_bgcfmtclr_'.j.'_'.k.'_all,@Tf'.cui.'_clrfmtbgc_'.i.'_'.k.'_all,@Tf'.cui.'_clrbgcfmt_'.i.'_'.j.'_all'.concealends
" Define highlighting for this region
" Note: cterm= MUST come after ctermfg= to ensure that bold attribute is
" handled correctly in a cterm.
" :help cterm-colors
exe 'hi Tf'.cui.'_clrbgcfmt_'.i.'_'.j.'_'.k
\.eq_clr.b:txtfmt_clr{i}.eq_bgc.b:txtfmt_bgc{j}.eq_fmt.b:txtfmt_fmt{k}
let k = k + 1
endwhile
let jp = jp + 1
endwhile
" Revert to toplevel (no background color) matchgroup
let matchgroup_def = matchgroup_top_def
endif " bgc_enabled
"============= END NON-INDENTING BLOCK =============
"===
"*** Loop over clr-fmt levels
"===
let j = 1
while j <= b:txtfmt_num_formats - 1
let chj = nr2char(b:txtfmt_fmt_first_tok + j)
" Add to appropriate clusters
exe 'syn cluster Tf'.cui.'_all add=Tf'.cui.'_clrfmt_'.i.'_'.j
exe 'syn cluster Tf'.cui.'_clrfmt_'.i.'_all add=Tf'.cui.'_clrfmt_'.i.'_'.j
" Cache the nextgroup clause
let ng = ' nextgroup=Tf'.cui.'_fmt_'.j.'_rtd,Tf'.cui.'_clr_'.i.'_rtd,@Tf'.cui.'_fmtclr_'.j.'_all,@Tf'.cui.'_clrfmt_'.i.'_all'.(bgc_enabled ? ',@Tf'.cui.'_clrfmtbgc_'.i.'_'.j.'_all' : '')
" Define region that is begun by a start token
exe 'syn region Tf'.cui.'_clrfmt_'.i.'_'.j.matchgroup_def
\.' start=/'.chj.'/'.r1_clrfmt.ng.concealends
" Define the following region if and only if at least one of the
" region types whose end token could begin this region is active
"============= BEGIN NON-INDENTING BLOCK =============
if bgc_enabled
" Define region that is begun by an end token
" (when permitted by a nextgroup)
exe 'syn region Tf'.cui.'_clrfmt_'.i.'_'.j.'_rtd'.matchgroup_def
\.r2_clrfmt.ng.concealends
endif " bgc_enabled
"============= END NON-INDENTING BLOCK =============
" Define highlighting for this region
" Note: cterm= MUST come after ctermfg= to ensure that bold attribute is
" handled correctly in a cterm.
" :help cterm-colors
exe 'hi Tf'.cui.'_clrfmt_'.i.'_'.j
\.eq_clr.b:txtfmt_clr{i}.eq_fmt.b:txtfmt_fmt{j}
" Link rtd to non-rtd group
exe 'hi link Tf'.cui.'_clrfmt_'.i.'_'.j.'_rtd Tf'.cui.'_clrfmt_'.i.'_'.j
"============= BEGIN NON-INDENTING BLOCK =============
if bgc_enabled
"===
"*** Loop over clr-fmt-bgc levels
"===
let kp = 1
while kp <= b:txtfmt_cfg_numbgcolors
let k = b:txtfmt_cfg_bgcolor{kp}
let chk = nr2char(b:txtfmt_bgc_first_tok + k)
" Add to appropriate clusters
exe 'syn cluster Tf'.cui.'_all add=Tf'.cui.'_clrfmtbgc_'.i.'_'.j.'_'.k
exe 'syn cluster Tf'.cui.'_clrfmtbgc_'.i.'_'.j.'_all add=Tf'.cui.'_clrfmtbgc_'.i.'_'.j.'_'.k
" Ensure that this and higher order regions use bgc-specific concealment group
let matchgroup_def = ' matchgroup=Tf'.cui.'_conceal_'.k
" Define region that is begun by a start token
exe 'syn region Tf'.cui.'_clrfmtbgc_'.i.'_'.j.'_'.k.matchgroup_def
\.' start=/'.chk.'/'.r1_clrfmtbgc.' nextgroup=Tf'.cui.'_fmtbgc_'.j.'_'.k.'_rtd,Tf'.cui.'_clrbgc_'.i.'_'.k.'_rtd,Tf'.cui.'_clrfmt_'.i.'_'.j.'_rtd,@Tf'.cui.'_fmtbgcclr_'.j.'_'.k.'_all,@Tf'.cui.'_clrbgcfmt_'.i.'_'.k.'_all,@Tf'.cui.'_clrfmtbgc_'.i.'_'.j.'_all'.concealends
" Define highlighting for this region
" Note: cterm= MUST come after ctermfg= to ensure that bold attribute is
" handled correctly in a cterm.
" :help cterm-colors
exe 'hi Tf'.cui.'_clrfmtbgc_'.i.'_'.j.'_'.k
\.eq_clr.b:txtfmt_clr{i}.eq_bgc.b:txtfmt_bgc{k}.eq_fmt.b:txtfmt_fmt{j}
let kp = kp + 1
endwhile
" Revert to toplevel (no background color) matchgroup
let matchgroup_def = matchgroup_top_def
endif " bgc_enabled
"============= END NON-INDENTING BLOCK =============
let j = j + 1
endwhile
let ip = ip + 1
endwhile
endif " clr_enabled
"============= END NON-INDENTING BLOCK =============
"============= BEGIN NON-INDENTING BLOCK =============
if bgc_enabled
"===
"*** Loop over bgc levels
"===
let ip = 1
while ip <= b:txtfmt_cfg_numbgcolors
let i = b:txtfmt_cfg_bgcolor{ip}
let chi = nr2char(b:txtfmt_bgc_first_tok + i)
" Add to appropriate clusters
exe 'syn cluster Tf'.cui.'_all add=Tf'.cui.'_bgc_'.i
exe 'syn cluster Tf'.cui.'_bgc_all add=Tf'.cui.'_bgc_'.i
" Ensure that this and higher order regions use bgc-specific concealment group
let matchgroup_def = ' matchgroup=Tf'.cui.'_conceal_'.i
" Cache the nextgroup clause
let ng = ' nextgroup=@Tf'.cui.'_bgc_all'.(clr_enabled ? ',@Tf'.cui.'_bgcclr_'.i.'_all' : '').',@Tf'.cui.'_bgcfmt_'.i.'_all,Tf_def_tok'
" Define region that is begun by a start token
exe 'syn region Tf'.cui.'_bgc_'.i.matchgroup_def
\.' start=/'.chi.'/'.r1_bgc.ng.concealends
" Define region that is begun by an end token
" (when permitted by a nextgroup)
exe 'syn region Tf'.cui.'_bgc_'.i.'_rtd'.matchgroup_def
\.r2_bgc.ng.concealends
" Define highlighting for this region
" Note: cterm= MUST come after ctermfg= to ensure that bold attribute is
" handled correctly in a cterm.
" :help cterm-colors
exe 'hi Tf'.cui.'_bgc_'.i
\.eq_bgc.b:txtfmt_bgc{i}
" Link rtd to non-rtd group
exe 'hi link Tf'.cui.'_bgc_'.i.'_rtd Tf'.cui.'_bgc_'.i
"============= BEGIN NON-INDENTING BLOCK =============
if clr_enabled
"===
"*** Loop over bgc-clr levels
"===
let jp = 1
while jp <= b:txtfmt_cfg_numfgcolors
let j = b:txtfmt_cfg_fgcolor{jp}
let chj = nr2char(b:txtfmt_clr_first_tok + j)
" Add to appropriate clusters
exe 'syn cluster Tf'.cui.'_all add=Tf'.cui.'_bgcclr_'.i.'_'.j
exe 'syn cluster Tf'.cui.'_bgcclr_'.i.'_all add=Tf'.cui.'_bgcclr_'.i.'_'.j
" Cache the nextgroup clause
let ng = ' nextgroup=Tf'.cui.'_clr_'.j.'_rtd,Tf'.cui.'_bgc_'.i.'_rtd,@Tf'.cui.'_clrbgc_'.j.'_all,@Tf'.cui.'_bgcclr_'.i.'_all,@Tf'.cui.'_bgcclrfmt_'.i.'_'.j.'_all'
" Define region that is begun by a start token
exe 'syn region Tf'.cui.'_bgcclr_'.i.'_'.j.matchgroup_def
\.' start=/'.chj.'/'.r1_bgcclr.ng.concealends
" Define region that is begun by an end token
" (when permitted by a nextgroup)
exe 'syn region Tf'.cui.'_bgcclr_'.i.'_'.j.'_rtd'.matchgroup_def
\.r2_bgcclr.ng.concealends
" Define highlighting for this region
" Note: cterm= MUST come after ctermfg= to ensure that bold attribute is
" handled correctly in a cterm.
" :help cterm-colors
exe 'hi Tf'.cui.'_bgcclr_'.i.'_'.j
\.eq_clr.b:txtfmt_clr{j}.eq_bgc.b:txtfmt_bgc{i}
" Link rtd to non-rtd group
exe 'hi link Tf'.cui.'_bgcclr_'.i.'_'.j.'_rtd Tf'.cui.'_bgcclr_'.i.'_'.j
"===
"*** Loop over bgc-clr-fmt levels
"===
let k = 1
while k <= b:txtfmt_num_formats - 1
let chk = nr2char(b:txtfmt_fmt_first_tok + k)
" Add to appropriate clusters
exe 'syn cluster Tf'.cui.'_all add=Tf'.cui.'_bgcclrfmt_'.i.'_'.j.'_'.k
exe 'syn cluster Tf'.cui.'_bgcclrfmt_'.i.'_'.j.'_all add=Tf'.cui.'_bgcclrfmt_'.i.'_'.j.'_'.k
" Define region that is begun by a start token
exe 'syn region Tf'.cui.'_bgcclrfmt_'.i.'_'.j.'_'.k.matchgroup_def
\.' start=/'.chk.'/'.r1_bgcclrfmt.' nextgroup=Tf'.cui.'_clrfmt_'.j.'_'.k.'_rtd,Tf'.cui.'_bgcfmt_'.i.'_'.k.'_rtd,Tf'.cui.'_bgcclr_'.i.'_'.j.'_rtd,@Tf'.cui.'_clrfmtbgc_'.j.'_'.k.'_all,@Tf'.cui.'_bgcfmtclr_'.i.'_'.k.'_all,@Tf'.cui.'_bgcclrfmt_'.i.'_'.j.'_all'.concealends
" Define highlighting for this region
" Note: cterm= MUST come after ctermfg= to ensure that bold attribute is
" handled correctly in a cterm.
" :help cterm-colors
exe 'hi Tf'.cui.'_bgcclrfmt_'.i.'_'.j.'_'.k
\.eq_clr.b:txtfmt_clr{j}.eq_bgc.b:txtfmt_bgc{i}.eq_fmt.b:txtfmt_fmt{k}
let k = k + 1
endwhile
let jp = jp + 1
endwhile
endif " clr_enabled
"============= END NON-INDENTING BLOCK =============
"===
"*** Loop over bgc-fmt levels
"===
let j = 1
while j <= b:txtfmt_num_formats - 1
let chj = nr2char(b:txtfmt_fmt_first_tok + j)
" Add to appropriate clusters
exe 'syn cluster Tf'.cui.'_all add=Tf'.cui.'_bgcfmt_'.i.'_'.j
exe 'syn cluster Tf'.cui.'_bgcfmt_'.i.'_all add=Tf'.cui.'_bgcfmt_'.i.'_'.j
" Cache the nextgroup clause
let ng = ' nextgroup=Tf'.cui.'_fmt_'.j.'_rtd,Tf'.cui.'_bgc_'.i.'_rtd,@Tf'.cui.'_fmtbgc_'.j.'_all,@Tf'.cui.'_bgcfmt_'.i.'_all'.(clr_enabled ? ',@Tf'.cui.'_bgcfmtclr_'.i.'_'.j.'_all' : '')
" Define region that is begun by a start token
exe 'syn region Tf'.cui.'_bgcfmt_'.i.'_'.j.matchgroup_def
\.' start=/'.chj.'/'.r1_bgcfmt.ng.concealends
" Define the following region if and only if at least one of the
" region types whose end token could begin this region is active
"============= BEGIN NON-INDENTING BLOCK =============
if clr_enabled
" Define region that is begun by an end token
" (when permitted by a nextgroup)
exe 'syn region Tf'.cui.'_bgcfmt_'.i.'_'.j.'_rtd'.matchgroup_def
\.r2_bgcfmt.ng.concealends
endif " clr_enabled
"============= END NON-INDENTING BLOCK =============
" Define highlighting for this region
" Note: cterm= MUST come after ctermfg= to ensure that bold attribute is
" handled correctly in a cterm.
" :help cterm-colors
exe 'hi Tf'.cui.'_bgcfmt_'.i.'_'.j
\.eq_bgc.b:txtfmt_bgc{i}.eq_fmt.b:txtfmt_fmt{j}
" Link rtd to non-rtd group
exe 'hi link Tf'.cui.'_bgcfmt_'.i.'_'.j.'_rtd Tf'.cui.'_bgcfmt_'.i.'_'.j
"============= BEGIN NON-INDENTING BLOCK =============
if clr_enabled
"===
"*** Loop over bgc-fmt-clr levels
"===
let kp = 1
while kp <= b:txtfmt_cfg_numfgcolors
let k = b:txtfmt_cfg_fgcolor{kp}
let chk = nr2char(b:txtfmt_clr_first_tok + k)
" Add to appropriate clusters
exe 'syn cluster Tf'.cui.'_all add=Tf'.cui.'_bgcfmtclr_'.i.'_'.j.'_'.k
exe 'syn cluster Tf'.cui.'_bgcfmtclr_'.i.'_'.j.'_all add=Tf'.cui.'_bgcfmtclr_'.i.'_'.j.'_'.k
" Define region that is begun by a start token
exe 'syn region Tf'.cui.'_bgcfmtclr_'.i.'_'.j.'_'.k.matchgroup_def
\.' start=/'.chk.'/'.r1_bgcfmtclr.' nextgroup=Tf'.cui.'_fmtclr_'.j.'_'.k.'_rtd,Tf'.cui.'_bgcclr_'.i.'_'.k.'_rtd,Tf'.cui.'_bgcfmt_'.i.'_'.j.'_rtd,@Tf'.cui.'_fmtclrbgc_'.j.'_'.k.'_all,@Tf'.cui.'_bgcclrfmt_'.i.'_'.k.'_all,@Tf'.cui.'_bgcfmtclr_'.i.'_'.j.'_all'.concealends
" Define highlighting for this region
" Note: cterm= MUST come after ctermfg= to ensure that bold attribute is
" handled correctly in a cterm.
" :help cterm-colors
exe 'hi Tf'.cui.'_bgcfmtclr_'.i.'_'.j.'_'.k
\.eq_clr.b:txtfmt_clr{k}.eq_bgc.b:txtfmt_bgc{i}.eq_fmt.b:txtfmt_fmt{j}
let kp = kp + 1
endwhile
endif " clr_enabled
"============= END NON-INDENTING BLOCK =============
let j = j + 1
endwhile
let ip = ip + 1
endwhile
" Revert to toplevel (no background color) matchgroup
let matchgroup_def = matchgroup_top_def
endif " bgc_enabled
"============= END NON-INDENTING BLOCK =============
"===
"*** Loop over fmt levels
"===
let i = 1
while i <= b:txtfmt_num_formats - 1
let chi = nr2char(b:txtfmt_fmt_first_tok + i)
" Add to appropriate clusters
exe 'syn cluster Tf'.cui.'_all add=Tf'.cui.'_fmt_'.i
exe 'syn cluster Tf'.cui.'_fmt_all add=Tf'.cui.'_fmt_'.i
" Cache the nextgroup clause
let ng = ' nextgroup=@Tf'.cui.'_fmt_all'.(clr_enabled ? ',@Tf'.cui.'_fmtclr_'.i.'_all' : '').(bgc_enabled ? ',@Tf'.cui.'_fmtbgc_'.i.'_all' : '').',Tf_def_tok'
" Define region that is begun by a start token
exe 'syn region Tf'.cui.'_fmt_'.i.matchgroup_def
\.' start=/'.chi.'/'.r1_fmt.ng.concealends
" Define the following region if and only if at least one of the
" region types whose end token could begin this region is active
"============= BEGIN NON-INDENTING BLOCK =============
if clr_enabled || bgc_enabled
" Define region that is begun by an end token
" (when permitted by a nextgroup)
exe 'syn region Tf'.cui.'_fmt_'.i.'_rtd'.matchgroup_def
\.r2_fmt.ng.concealends
endif " clr_enabled || bgc_enabled
"============= END NON-INDENTING BLOCK =============
" Define highlighting for this region
" Note: cterm= MUST come after ctermfg= to ensure that bold attribute is
" handled correctly in a cterm.
" :help cterm-colors
exe 'hi Tf'.cui.'_fmt_'.i
\.eq_fmt.b:txtfmt_fmt{i}
" Link rtd to non-rtd group
exe 'hi link Tf'.cui.'_fmt_'.i.'_rtd Tf'.cui.'_fmt_'.i
"============= BEGIN NON-INDENTING BLOCK =============
if clr_enabled
"===
"*** Loop over fmt-clr levels
"===
let jp = 1
while jp <= b:txtfmt_cfg_numfgcolors
let j = b:txtfmt_cfg_fgcolor{jp}
let chj = nr2char(b:txtfmt_clr_first_tok + j)
" Add to appropriate clusters
exe 'syn cluster Tf'.cui.'_all add=Tf'.cui.'_fmtclr_'.i.'_'.j
exe 'syn cluster Tf'.cui.'_fmtclr_'.i.'_all add=Tf'.cui.'_fmtclr_'.i.'_'.j
" Cache the nextgroup clause
let ng = ' nextgroup=Tf'.cui.'_clr_'.j.'_rtd,Tf'.cui.'_fmt_'.i.'_rtd,@Tf'.cui.'_clrfmt_'.j.'_all,@Tf'.cui.'_fmtclr_'.i.'_all'.(bgc_enabled ? ',@Tf'.cui.'_fmtclrbgc_'.i.'_'.j.'_all' : '')
" Define region that is begun by a start token
exe 'syn region Tf'.cui.'_fmtclr_'.i.'_'.j.matchgroup_def
\.' start=/'.chj.'/'.r1_fmtclr.ng.concealends
" Define the following region if and only if at least one of the
" region types whose end token could begin this region is active
"============= BEGIN NON-INDENTING BLOCK =============
if bgc_enabled
" Define region that is begun by an end token
" (when permitted by a nextgroup)
exe 'syn region Tf'.cui.'_fmtclr_'.i.'_'.j.'_rtd'.matchgroup_def
\.r2_fmtclr.ng.concealends
endif " bgc_enabled
"============= END NON-INDENTING BLOCK =============
" Define highlighting for this region
" Note: cterm= MUST come after ctermfg= to ensure that bold attribute is
" handled correctly in a cterm.
" :help cterm-colors
exe 'hi Tf'.cui.'_fmtclr_'.i.'_'.j
\.eq_clr.b:txtfmt_clr{j}.eq_fmt.b:txtfmt_fmt{i}
" Link rtd to non-rtd group
exe 'hi link Tf'.cui.'_fmtclr_'.i.'_'.j.'_rtd Tf'.cui.'_fmtclr_'.i.'_'.j
"============= BEGIN NON-INDENTING BLOCK =============
if bgc_enabled
"===
"*** Loop over fmt-clr-bgc levels
"===
let kp = 1
while kp <= b:txtfmt_cfg_numbgcolors
let k = b:txtfmt_cfg_bgcolor{kp}
let chk = nr2char(b:txtfmt_bgc_first_tok + k)
" Add to appropriate clusters
exe 'syn cluster Tf'.cui.'_all add=Tf'.cui.'_fmtclrbgc_'.i.'_'.j.'_'.k
exe 'syn cluster Tf'.cui.'_fmtclrbgc_'.i.'_'.j.'_all add=Tf'.cui.'_fmtclrbgc_'.i.'_'.j.'_'.k
" Ensure that this and higher order regions use bgc-specific concealment group
let matchgroup_def = ' matchgroup=Tf'.cui.'_conceal_'.k
" Define region that is begun by a start token
exe 'syn region Tf'.cui.'_fmtclrbgc_'.i.'_'.j.'_'.k.matchgroup_def
\.' start=/'.chk.'/'.r1_fmtclrbgc.' nextgroup=Tf'.cui.'_clrbgc_'.j.'_'.k.'_rtd,Tf'.cui.'_fmtbgc_'.i.'_'.k.'_rtd,Tf'.cui.'_fmtclr_'.i.'_'.j.'_rtd,@Tf'.cui.'_clrbgcfmt_'.j.'_'.k.'_all,@Tf'.cui.'_fmtbgcclr_'.i.'_'.k.'_all,@Tf'.cui.'_fmtclrbgc_'.i.'_'.j.'_all'.concealends
" Define highlighting for this region
" Note: cterm= MUST come after ctermfg= to ensure that bold attribute is
" handled correctly in a cterm.
" :help cterm-colors
exe 'hi Tf'.cui.'_fmtclrbgc_'.i.'_'.j.'_'.k
\.eq_clr.b:txtfmt_clr{j}.eq_bgc.b:txtfmt_bgc{k}.eq_fmt.b:txtfmt_fmt{i}
let kp = kp + 1
endwhile
" Revert to toplevel (no background color) matchgroup
let matchgroup_def = matchgroup_top_def
endif " bgc_enabled
"============= END NON-INDENTING BLOCK =============
let jp = jp + 1
endwhile
endif " clr_enabled
"============= END NON-INDENTING BLOCK =============
"============= BEGIN NON-INDENTING BLOCK =============
if bgc_enabled
"===
"*** Loop over fmt-bgc levels
"===
let jp = 1
while jp <= b:txtfmt_cfg_numbgcolors
let j = b:txtfmt_cfg_bgcolor{jp}
let chj = nr2char(b:txtfmt_bgc_first_tok + j)
" Add to appropriate clusters
exe 'syn cluster Tf'.cui.'_all add=Tf'.cui.'_fmtbgc_'.i.'_'.j
exe 'syn cluster Tf'.cui.'_fmtbgc_'.i.'_all add=Tf'.cui.'_fmtbgc_'.i.'_'.j
" Ensure that this and higher order regions use bgc-specific concealment group
let matchgroup_def = ' matchgroup=Tf'.cui.'_conceal_'.j
" Cache the nextgroup clause
let ng = ' nextgroup=Tf'.cui.'_bgc_'.j.'_rtd,Tf'.cui.'_fmt_'.i.'_rtd,@Tf'.cui.'_bgcfmt_'.j.'_all,@Tf'.cui.'_fmtbgc_'.i.'_all'.(clr_enabled ? ',@Tf'.cui.'_fmtbgcclr_'.i.'_'.j.'_all' : '')
" Define region that is begun by a start token
exe 'syn region Tf'.cui.'_fmtbgc_'.i.'_'.j.matchgroup_def
\.' start=/'.chj.'/'.r1_fmtbgc.ng.concealends
" Define the following region if and only if at least one of the
" region types whose end token could begin this region is active
"============= BEGIN NON-INDENTING BLOCK =============
if clr_enabled
" Define region that is begun by an end token
" (when permitted by a nextgroup)
exe 'syn region Tf'.cui.'_fmtbgc_'.i.'_'.j.'_rtd'.matchgroup_def
\.r2_fmtbgc.ng.concealends
endif " clr_enabled
"============= END NON-INDENTING BLOCK =============
" Define highlighting for this region
" Note: cterm= MUST come after ctermfg= to ensure that bold attribute is
" handled correctly in a cterm.
" :help cterm-colors
exe 'hi Tf'.cui.'_fmtbgc_'.i.'_'.j
\.eq_bgc.b:txtfmt_bgc{j}.eq_fmt.b:txtfmt_fmt{i}
" Link rtd to non-rtd group
exe 'hi link Tf'.cui.'_fmtbgc_'.i.'_'.j.'_rtd Tf'.cui.'_fmtbgc_'.i.'_'.j
"============= BEGIN NON-INDENTING BLOCK =============
if clr_enabled
"===
"*** Loop over fmt-bgc-clr levels
"===
let kp = 1
while kp <= b:txtfmt_cfg_numfgcolors
let k = b:txtfmt_cfg_fgcolor{kp}
let chk = nr2char(b:txtfmt_clr_first_tok + k)
" Add to appropriate clusters
exe 'syn cluster Tf'.cui.'_all add=Tf'.cui.'_fmtbgcclr_'.i.'_'.j.'_'.k
exe 'syn cluster Tf'.cui.'_fmtbgcclr_'.i.'_'.j.'_all add=Tf'.cui.'_fmtbgcclr_'.i.'_'.j.'_'.k
" Define region that is begun by a start token
exe 'syn region Tf'.cui.'_fmtbgcclr_'.i.'_'.j.'_'.k.matchgroup_def
\.' start=/'.chk.'/'.r1_fmtbgcclr.' nextgroup=Tf'.cui.'_bgcclr_'.j.'_'.k.'_rtd,Tf'.cui.'_fmtclr_'.i.'_'.k.'_rtd,Tf'.cui.'_fmtbgc_'.i.'_'.j.'_rtd,@Tf'.cui.'_bgcclrfmt_'.j.'_'.k.'_all,@Tf'.cui.'_fmtclrbgc_'.i.'_'.k.'_all,@Tf'.cui.'_fmtbgcclr_'.i.'_'.j.'_all'.concealends
" Define highlighting for this region
" Note: cterm= MUST come after ctermfg= to ensure that bold attribute is
" handled correctly in a cterm.
" :help cterm-colors
exe 'hi Tf'.cui.'_fmtbgcclr_'.i.'_'.j.'_'.k
\.eq_clr.b:txtfmt_clr{k}.eq_bgc.b:txtfmt_bgc{j}.eq_fmt.b:txtfmt_fmt{i}
let kp = kp + 1
endwhile
endif " clr_enabled
"============= END NON-INDENTING BLOCK =============
let jp = jp + 1
endwhile
" Revert to toplevel (no background color) matchgroup
let matchgroup_def = matchgroup_top_def
endif " bgc_enabled
"============= END NON-INDENTING BLOCK =============
let i = i + 1
endwhile
" END AUTOGENERATED CODE BLOCK >>>
" Handle escape/escapee token pairs both inside and outside of fmt/clr
" regions.
" Important Note: These groups must be defined after the fmt/clr regions,
" since they must take precedence over them.
" Objectives:
" -Conceal the escape token
" -Prevent escaped or escaping tokens from beginning a region
" -Prevent escaped or escaping tokens from ending a region
" Note: Must take into account the txtfmt 'escape' option
" Also note: Must take into account the size in bytes of the escape char
" if this Vim treats offsets as byte offsets
" TODO_BG: Guard against reliance upon _bgc_ vars when they wouldn't have
" been defined.
if b:txtfmt_cfg_escape == 'bslash' || b:txtfmt_cfg_escape == 'self'
if b:txtfmt_cfg_escape == 'self'
let re_outer_esc_pair = '\(['.b:txtfmt_re_any_stok_atom.']\)\1'
let re_any_stok_esc_pair = '\(['.b:txtfmt_re_any_stok_atom.']\)\1'
let re_fmt_etok_esc_pair = '\(['.b:txtfmt_re_fmt_etok_atom.']\)\1'
if bgc_enabled
let re_bgc_etok_esc_pair = '\(['.b:txtfmt_re_bgc_etok_atom.']\)\1'
endif
if clr_enabled
let re_clr_etok_esc_pair = '\(['.b:txtfmt_re_clr_etok_atom.']\)\1'
endif
" Escape char is same number of bytes as a token
let esc_off = tok_off
elseif b:txtfmt_cfg_escape == 'bslash'
let re_outer_esc_pair = '\\\%(\\\%(\\*['.b:txtfmt_re_any_stok_atom.']\)\@=\|['.b:txtfmt_re_any_stok_atom.']\)'
let re_any_stok_esc_pair = '\\\%(\\\%(\\*['.b:txtfmt_re_any_stok_atom.']\)\@=\|['.b:txtfmt_re_any_stok_atom.']\)'
let re_fmt_etok_esc_pair = '\\\%(\\\%(\\*['.b:txtfmt_re_fmt_etok_atom.']\)\@=\|['.b:txtfmt_re_fmt_etok_atom.']\)'
if bgc_enabled
let re_bgc_etok_esc_pair = '\\\%(\\\%(\\*['.b:txtfmt_re_bgc_etok_atom.']\)\@=\|['.b:txtfmt_re_bgc_etok_atom.']\)'
endif
if clr_enabled
let re_clr_etok_esc_pair = '\\\%(\\\%(\\*['.b:txtfmt_re_clr_etok_atom.']\)\@=\|['.b:txtfmt_re_clr_etok_atom.']\)'
endif
" Escape char is single byte
let esc_off = 1
endif
" The following group prevents escaping or escaped token from starting
" a region, and causes the escaping token to be hidden
exe 'syn match Tf_outer_esc /'.re_outer_esc_pair.'/he=s+'.esc_off.containedin_def.conceal
" The following group allows escaping tokens to be hidden within a fmt/clr
" region.
exe 'syn match Tf_any_stok_inner_esc /'.re_any_stok_esc_pair.'/he=s+'.esc_off.' contains=NONE'
\.' contained'.conceal
exe 'syn match Tf_fmt_etok_inner_esc /'.re_fmt_etok_esc_pair.'/he=s+'.esc_off.' contains=NONE'
\.' contained'.conceal
if bgc_enabled
exe 'syn match Tf_bgc_etok_inner_esc /'.re_bgc_etok_esc_pair.'/he=s+'.esc_off.' contains=NONE'
\.' contained'.conceal
endif
if clr_enabled
exe 'syn match Tf_clr_etok_inner_esc /'.re_clr_etok_esc_pair.'/he=s+'.esc_off.' contains=NONE'
\.' contained'.conceal
endif
" Define highlighting for the outer and inner escape tokens
hi link Tf_outer_esc Tf_conceal
hi link Tf_any_stok_inner_esc Tf_conceal
hi link Tf_fmt_etok_inner_esc Tf_conceal
if bgc_enabled
hi link Tf_bgc_etok_inner_esc Tf_conceal
endif
if clr_enabled
hi link Tf_clr_etok_inner_esc Tf_conceal
endif
endif
endfu " >>>
" Function: s:Define_syntax_syncing() <<<
fu! s:Define_syntax_syncing()
" Configure syncing based upon syncmethod and (if applicable) synclines
" options. (Note that 'sync' is the only option visible to user. It is
" decoded into the two more convenient options by Do_config_common ->
" Set_syncing.)
if b:txtfmt_cfg_syncmethod == 'fromstart'
syn sync fromstart
elseif b:txtfmt_cfg_syncmethod == 'minlines'
exe 'syn sync minlines='.b:txtfmt_cfg_synclines
endif
" TODO - Get rid of the function code after the following return prior to
" release.
return
" SYNTAX SYNCHRONIZATION using regions correctly but with a flaw <<<
" NOTE: This is the most promising method other than 'minlines'. The only
" problem is, there's no good way to handle the case of txtfmt regions
" intermixed with other types of regions. Note that a problem exists both
" for the nested and nonested cases:
" 'nested' problem scenario: We synchronize to a nested txtfmt region.
" When the nested txtfmt region ends, the containing region is not
" resumed. (If we had used 'minlines', the presumption is we would have
" gone back far enough to parse the containing region.)
" 'nonested' problem scenario: We incorrectly synchronize to a nested
" txtfmt region because, not knowing anything about the non-txtfmt region
" definitions, we have no way of knowing when we are within one.
" TODO - If I decide to dust this off and use it, I need to look at the
" handling of <no_fmt> and <no_clr> regions.
if 0
" IMPORTANT NOTE: This should probably just be removed, but if it's ever
" used, [] need to be wrapped around the tok atoms.
" 'skip' pattern (option dependent) <<<
if b:txtfmt_cfg_escape != 'none'
" Make sure tokens that are part of an escape sequence cannot end a
" region.
if b:txtfmt_cfg_escape == 'bslash'
" TODO - Decide on allowing newlines as tokens (\_. or . ?)
let skip_def = ' skip=/\\./'
elseif b:txtfmt_cfg_escape == 'self'
let skip_def = ' skip=/\('.b:txtfmt_re_any_tok_atom.'\)\1/'
else
let skip_def = ''
endif
else
let skip_def = ''
endif
" >>>
" 'contains' list (option dependent) <<<
" Note: I'm intentionally keeping this out of the 'if' for skip_def to
" keep the logic compartmentalized.
if b:txtfmt_cfg_escape != 'none'
" Permit txtfmt regions to contain specially highlighted pairs of
" escape-escapee tokens.
let contains_def = ' contains=Tf_inner_esc'
else
let contains_def = ''
endif
" >>>
" 'containedin' list (option dependent) <<<
if b:txtfmt_cfg_nested
" Ensure that txtfmt top-level item can be contained by a non-txtfmt
" syntax group (e.g. C-language comment).
if b:txtfmt_cfg_escape != 'none'
let containedin_def = ' containedin=ALLBUT,@Tf_all,Tf_outer_esc,Tf_inner_esc'
else
let containedin_def = ' containedin=ALLBUT,@Tf_all'
endif
else
let containedin_def = ''
endif
" >>>
" Loop over the clr only regions <<<
let i = 1
let ch = nr2char(b:txtfmt_clr_first_tok + 1)
while i < b:txtfmt_num_colors
" clr{i} region (top level) <<<
" Add to appropriate clusters
exe 'syn cluster Tf_all add=Tf_clr_'.i
exe 'syn cluster Tf_clr_all add=Tf_clr_'.i
" Define nextgroup, which is common to all definitions of this group
let nextgroup_def = ' nextgroup=@Tf_clrfmt_'.i.'_all,@Tf_clr_all'
" Define a clr region that is not contained and is introduced by a clr
" token. This one can match at top level. If txtfmt 'nested' option is
" set, it can also match within non-txtfmt regions.
" Order note: This definition *must* occur prior to the combined
" fmtclr regions that begin with this fmt token.
exe 'syn region Tf_clr_'.i.' matchgroup=Ignore start=/'.ch.'/'
\.skip_def
\.' end=/'.b:txtfmt_re_any_tok_atom.'/me=e-1 '
\.nextgroup_def
\.contains_def
\.containedin_def
" Define a 'contained' clr region that is introduced by the 'no fmt'
" token when permitted by a 'nextgroup'
exe 'syn region Tf_clr_'.i.' matchgroup=Ignore'
\.' start=/'.nr2char(b:txtfmt_fmt_first_tok).'/'
\.skip_def
\.' end=/'.b:txtfmt_re_any_tok_atom.'/me=e-1 '
\.nextgroup_def
\.contains_def
\.' contains=Tfsm_clr_'.i
\.' contained'
exe 'syn sync match Tfsm_clr_'.i.' contained grouphere Tf_clr_'.i.' /./'
" >>>
" Update for next iteration
let i = i + 1
let ch = nr2char(b:txtfmt_clr_first_tok + i)
endwhile
" >>>
" Loop over the fmt only regions <<<
let i = 1
let ch = nr2char(b:txtfmt_fmt_first_tok + 1)
while i < b:txtfmt_num_formats
" fmt{i} region (top level) <<<
" Add to appropriate clusters
exe 'syn cluster Tf_all add=Tf_fmt_'.i
exe 'syn cluster Tf_fmt_all add=Tf_fmt_'.i
" Define nextgroup, which is common to all definitions of this group
let nextgroup_def = ' nextgroup=@Tf_fmtclr_'.i.'_all,@Tf_fmt_all'
" Define a fmt region that is not contained and is introduced by a fmt
" token. This one can match at top level. If txtfmt 'nested' option is
" set, it can also match within non-txtfmt regions.
" Order note: This definition *must* occur prior to the combined
" clrfmt regions that begin with this fmt token.
exe 'syn region Tf_fmt_'.i.' matchgroup=Ignore start=/'.ch.'/'
\.skip_def
\.' end=/'.b:txtfmt_re_any_tok_atom.'/me=e-1 '
\.nextgroup_def
\.contains_def
\.containedin_def
" Define a 'contained' fmt region that is introduced by the 'no clr'
" token when permitted by a 'nextgroup'
exe 'syn region Tf_fmt_'.i.' matchgroup=Ignore'
\.' start=/'.nr2char(b:txtfmt_clr_first_tok).'/'
\.skip_def
\.' end=/'.b:txtfmt_re_any_tok_atom.'/me=e-1'
\.nextgroup_def
\.contains_def
\.' contained'
\.' contains=Tfsm_fmt_'.i
exe 'syn sync match Tfsm_fmt_'.i.' contained grouphere Tf_fmt_'.i.' /./'
" >>>
" Update for next iteration
let i = i + 1
let ch = nr2char(b:txtfmt_fmt_first_tok + i)
endwhile
" >>>
" Loop over the clrfmt regions <<<
let i = 1
while i < b:txtfmt_num_colors
" clr{i} -- fmt{j} <<<
let j = 1
let ch = nr2char(b:txtfmt_fmt_first_tok + 1)
while j < b:txtfmt_num_formats
" Add to appropriate clusters
exe 'syn cluster Tf_all add=Tf_clrfmt_'.i.'_'.j
exe 'syn cluster Tf_clrfmt_'.i.'_all add=Tf_clrfmt_'.i.'_'.j
let nextgroup_def =
\' nextgroup=@Tf_clr_'.i.',@Tf_fmt_'.j.',@Tf_clrfmt_'.i.'_all,@Tf_fmtclr_'.j.'_all'
exe 'syn region Tf_clrfmt_'.i.'_'.j.' matchgroup=Ignore'
\.' start=/'.ch.'/'.skip_def
\.' end=/'.b:txtfmt_re_any_tok_atom.'/me=e-1'
\.nextgroup_def
\.contains_def
\.' contained'
\.' contains='.'Tfsm_clrfmt_'.i.'_'.j
exe 'syn sync match Tfsm_clrfmt_'.i.'_'.j.' contained grouphere Tf_clrfmt_'.i.'_'.j.' /./'
" Update for next iteration
let j = j + 1
let ch = nr2char(b:txtfmt_fmt_first_tok + j)
endwhile
" >>>
" Update for next iteration <<<
let i = i + 1
" >>>
endwhile
" >>>
" Loop over the fmtclr regions <<<
let i = 1
while i < b:txtfmt_num_formats
" fmt{i} -- clr{j} <<<
let j = 1
let ch = nr2char(b:txtfmt_clr_first_tok + 1)
while j < b:txtfmt_num_colors
" Add to appropriate clusters
exe 'syn cluster Tf_all add=Tf_fmtclr_'.i.'_'.j
exe 'syn cluster Tf_fmtclr_'.i.'_all add=Tf_fmtclr_'.i.'_'.j
let nextgroup_def =
\' nextgroup=@Tf_fmt_'.i.',@Tf_clr_'.j.',@Tf_fmtclr_'.i.'_all,@Tf_clrfmt_'.j.'_all'
exe 'syn region Tf_fmtclr_'.i.'_'.j.' matchgroup=Ignore'
\.' start=/'.ch.'/'.skip_def
\.' end=/'.b:txtfmt_re_any_tok_atom.'/me=e-1'
\.nextgroup_def
\.contains_def
\.' contained'
\.' contains='.'Tfsm_fmtclr_'.i.'_'.j
exe 'syn sync match Tfsm_fmtclr_'.i.'_'.j.' contained grouphere Tf_fmtclr_'.i.'_'.j.' /./'
" Update for next iteration
let j = j + 1
let ch = nr2char(b:txtfmt_clr_first_tok + j)
endwhile
" >>>
" Update for next iteration <<<
let i = i + 1
" >>>
endwhile
" >>>
endif
" >>>
endfu " >>>
" Function: s:Set_current_syntax() <<<
" Purpose: Set b:current_syntax to something sensible. If txtfmt is loaded
" in conjunction with one or more other plugins, we should set
" b:current_syntax to a dot-separated syntax name list that reflects all
" syntaxes loaded up to and including ours. Note that the b:txtfmt_syntax
" variable should permit us to do this even when other syntax plugins in the
" load chain have not respected assignments to b:current_syntax made by their
" predecessors in the load chain.
fu! s:Set_current_syntax()
if exists('b:txtfmt_syntax') && b:txtfmt_syntax =~ '\%(^\|\.\)txtfmt\%(\.\|$\)'
" Set b:current_syntax to the portion of b:txtfmt_syntax up to and
" including the first (and hopefully the only) occurrence of 'txtfmt'
let b:current_syntax =
\ substitute(b:txtfmt_syntax,
\ '\(.\{-}\%(^\|\.\)txtfmt\%(\.\|$\)\).*', '\1', '')
else
" This shouldn't happen unless user is manually sourcing the txtfmt
" plugin files (which also shouldn't happen). Still, if it does,
" 'txtfmt' is the most sensible choice.
let b:current_syntax = 'txtfmt'
endif
endfu
" >>>
" Call functions to define syntax and syntax syncing <<<
call s:Define_syntax()
call s:Define_syntax_syncing()
" >>>
" Call function to set b:current_syntax variable <<<
call s:Set_current_syntax()
" >>>
" LESSONS LEARNED <<<
" -By default, an item is contained only at top level.
" -containedin=TOP causes an item to be contained not just in top level, but
" in an item which does not have contained set.
" -When an inner (contained) region is truncated because of a keepend in a
" containing region, the inner regions highlighting is used up until the
" point where truncation occurs!!!!! This is not obvious from help. However,
" it's simple to demonstrate: copy the nested parens example from Vim help
" as-is, but add the keepend argument to par1 region. Source the file and
" view text with 3 levels of parens. Colors will be as expected until the
" first close paren is encountered. It will be colored according to the
" highlighting of the innermost nested paren region, not the outer as I would
" have expected.
" -You can use patterns for contains=, containedin=, etc..., but only groups
" defined at the time the command is executed will be matched! (In original
" implementation, this is why I ran the Define_syntax() function twice. Now I
" use clusters.)
" -With keepend, when doing matches for contained groups, the match is
" performed prior to checking for end of containing group. If containing
" group ends inside the contained group, the contained group will be
" truncated, but for purposes of ms=, me=, hs=, he=, the end of the contained
" group is not altered to reflect the point of truncation!!!!!
" -There is an apparent bug with the way contains= and containedin= work with
" matchgroup. I have submitted to Vim list, and am awaiting Bram's return
" from Uganda, at which time he has suggested he will investigate.
" -NOTE: A transparent group inherits the contains= arguments of its
" containing group! (Can lead to unexpected behavior.)
" -Apparent bug with transparent groups inheriting syntax of contained group,
" even when the current location in containing group has syntax disabled due
" to a he=<...>. Example: An empty format region has its open delimiter
" highlighted as error. The remainder of the region is not highlighted
" specially. However, when a transparent escape-escapee pair appears inside
" the empty region, it takes on Error syntax, even though it is past the
" portion of the empty region highlighted as error.
" -IT IS POSSIBLE to have multiple containedin= attributes in the same group,
" even where they would appear to conflict.
" Example: group A may be contained by any group whose name matches
" MyGroup.*Special; additionally, it may be contained in any group whose name
" does not begin with MyGroup.
" containedin=ALLBUT,MyGroup.* containedin=MyGroup.*Special
" Note that this works because when Vim encounters a containedin, it simply
" adds the appropriate contains= attributes to the specified containing
" groups; i.e., a containedin= cannot "rule out" future containment due to a
" subsequent containedin=.
" E56 - (* operand could be empty) workaround for the following pattern:
" \(ab\)\1*
" which will generate E56 in Vim, even though \1 cannot be empty
" Workaround: \(ab\)\%(\1\@=..\)*
" >>>
" IMPORTANT NOTE: The Vim script ends here. The perl script used to generate
" portions of this file follows...
finish
#!perl
# This script generates the core of the Define_syntax function of Brett
# Stahlman's Txtfmt Vim plugin
# It is designed to be invoked from a Vim external program read filter, as
# follows:
# :r !gen_txtfmt_def_syn.pl
# There are 2 passes:
# Pass 1) Generates definitions, which are specific to a token type combination
# (e.g., "fmt", "fmtclr", etc...)
# Pass 2) Generates the nested loops used to define syntax regions
@rgn = qw(clr bgc fmt);
# TODO: If I keep support for separate bgc and clr definitions, I can get rid
# of the %rhs hash (after making corresponding code modifications)
%rhs = qw(clr clr bgc bgc fmt fmt);
%ord = qw(clr 0 bgc 1 fmt 2);
# Note which types of regions can be disabled through Vim options
@can_dsbl = qw(clr bgc);
# Subtract 1 from b:txtfmt_num_formats (which currently includes the default
# format token)
%loopinfo = (
clr => {
cnt =>'b:txtfmt_cfg_numfgcolors',
indarr => 'b:txtfmt_cfg_fgcolor',
},
bgc => {
cnt =>'b:txtfmt_cfg_numbgcolors',
indarr => 'b:txtfmt_cfg_bgcolor',
},
fmt => {
cnt =>'b:txtfmt_num_formats - 1',
indarr => undef,
},
);
# TODO: Get rid of %cnt and %idxind if I elect to keep %loopinfo
%cnt = (
clr => 'b:txtfmt_cfg_numfgcolors',
bgc => 'b:txtfmt_cfg_numbgcolors',
fmt => 'b:txtfmt_num_formats - 1'
);
# Define a hash supporting index indirection
%idxind = (
clr => 'b:txtfmt_cfg_fgcolor',
bgc => 'b:txtfmt_cfg_bgcolor',
fmt => undef
# Could omit fmt or leave it undef
);
# Define base indentlevel of the entire block
$init_il = 1;
# Define the various output passes
use constant {
DEFS => 0,
LOOPS => 1,
};
# This semaphore helps determine when an "if <typ>_enabled" construct in the
# Vim code would be redundant with a containing one.
# TODO: Currently unused - remove...
my $bgc_guard_cnt = 0;
sub do_lvl($$$)
{
# Description of arrays
# @a1 - $_[1]: lhs (fixed) array of token type names. Upon function entry,
# this array represents the most recent region combination to have
# been processed.
# @a1n - lhs (fixed) array of token type names that will be passed in next
# recursive call to this function. Created by appending a single
# token type name from @a2
# @a2 - $_[2]: rhs (unfixed) array of token type names. Upon function
# entry, this array contains the token type names not included in the
# currently processed region combination. (e.g, if we're currently
# processing "fmt-clr" regions, then @a2 contains "bgc")
# @a2n - rhs (unfixed) array of token type names that will be passed in
# next recursive call to this function. Created by removing a single
# token type name from @a2
# Basic algorithm
# Loop over the token type names in @a2, appending each, in turn, to @a1
# (and calling the result @a1n). For each iteration, process the
# corresponding region combination, which will involve all token type names
# contained in @a1n, then call self recursively (passing @a1n and @a2n) to
# process the next level.
my $section = shift;
my @a1 = @{shift()}; # Fixed portion
my @a2 = @{shift()}; # Unfixed portion
# Determine the level of this recursive call according to number of
# elements in @a1
my $lvl = @a1;
# Loop over unfixed portion
for my $a2 (@a2) {
my @a1n = (@a1, $a2);
# Create a hash mapping region names to loop var names
my %idx = ();
my $var = 'i';
for my $a1n (@a1n) {
$idx{$a1n} = $var++;
}
my @a2n = grep { $_ ne $a2 } @a2;
# Description of @lor, @sor, @hor
# These 3 arrays are a convenience. They are 2D arrays containing
# specific useful combinations of token type names corresponding to the
# preceding level, the current level, and the next level, respectively.
# Lower order
# Remove each element in turn from @a1n
my @lor = ();
if (@a1n > 1) {
for my $r (@a1n) {
push @lor, [ grep { $_ ne $r } @a1n ];
}
}
# Same order
# Move each element within @a1n to the end
my @sor = ();
for (my $i = 0; $i < @a1n; $i++) {
my @r = @a1n;
my $r = splice @r, $i, 1;
push @sor, [ @r, $r ];
}
# Higher order
# Add region types from @a2n to the end
my @hor = ();
for my $r (@a2n) {
push @hor, [ @a1n, $r ];
}
# Determine initial indent level
my $il;
if ($section == DEFS) {
$il = "\t";
} else { # if $section == LOOPS
$il = "\t" x ($init_il + $lvl);
}
# Set convenience variable $need_r2_guard if and only if all the
# region types yet to be pulled in (i.e., the ones whose end tokens
# could begin the current region) are regions that can be disabled.
my $need_r2_guard = join('', sort @can_dsbl) =~ join('', sort @a2n);
# Begin outputting
# Insert an "if <typ>_enabled" if and only if the rightmost region
# type in the fixed array is <typ> (i.e., the region being begun
# should not exist if <typ>_enabled is false). (If the fixed portion
# contains <typ> prior to the last element, we're already inside an
# "if <typ>_enabled", in which case, another would be redundant.)
for my $typ (grep { $_ eq $a1n[-1] } @can_dsbl) {
print "\n$il", '"============= BEGIN NON-INDENTING BLOCK =============';
print "\n$il", "if ${typ}_enabled";
}
# PRE RECURSION
if ($section == DEFS) {
# Determine current level's indent
$il = "\t";
print "\n$il\"===";
print "\n$il\"*** ", join("-", @a1n);
print "\n$il\"===";
print "\n$il", "if b:txtfmt_cfg_escape != 'none'";
print "\n$il\t", "let contains_", join("", @a1n), "=",
"\n$il\t\t\\' contains='",
"\n$il\t\t\\.'Tf_any_stok_inner_esc,'",
"\n$il\t\t\\.'",
join(",'\n$il\t\t\\.'",
map { "Tf_${_}_etok_inner_esc" } @a1n
),
"'"
;
print "\n$il\t", "if b:txtfmt_cfg_escape == 'bslash'";
print "\n$il\t\t", "let skip_", join("", @a1n), " = ' skip=/\\\\./'";
print "\n$il\t", "else";
# TODO: Decide whether to keep this or go back to the more complex pattern
print "\n$il\t\t", "let skip_", join("", @a1n), " = ' skip=/\\(.\\)\\1/'";
print "\n$il\t", "endif";
print "\n$il", "else";
print "\n$il\t", "let contains_", join("", @a1n), " = ''";
print "\n$il\t", "let skip_", join("", @a1n), " = ''";
print "\n$il", "endif";
print "\n$il", "let end_", join("", @a1n), " =";
print "\n$il\t", "\\' end=/['";
print "\n$il\t", "\\.b:txtfmt_re_any_stok_atom";
print "\n$il\t", "\\.",
join("\n$il\t\\.",
map { "b:txtfmt_re_${_}_etok_atom" } @a1n
),
"\n$il\t", "\\.']/me=e-'.tok_off"
;
# Define r1_<rgn> var
print "\n$il", "let r1_", join("", @a1n), " =";
print "\n$il\t", "\\skip_", join("", @a1n);
print "\n$il\t", "\\.contains_", join("", @a1n);
print "\n$il\t", "\\.end_", join("", @a1n);
if (@a1n == 1) {
print "\n$il\t", "\\.containedin_def";
} else {
print "\n$il\t", "\\.' contained'";
}
# Don't define r2_<rgn> var if there's not at least 1 higher order
# region
if (@a2n) {
# Ensure that we don't define the r2 region variables if all
# of the <typ>'s whose end token could begin the region are
# inactive. If at least one of these <typ>'s is active, the
# vars will be defined, and <typ>_enabled ternaries will be
# used as necessary to ensure that we don't consider end
# tokens for inactive region types.
if ($need_r2_guard) {
print "\n$il", '" Define the r2 region vars if and only if at least one of the';
print "\n$il", '" region types whose end token could begin this region is active';
print "\n$il", '"============= BEGIN NON-INDENTING BLOCK =============';
print "\n$il", "if ",
join ' || ', map { "${_}_enabled" } @a2n
;
}
print "\n$il", "let start_", join("", @a1n), " =";
print "\n$il\t", "\\' start=/['";
print "\n$il\t", "\\.",
join(".",
map {
# Wrap the end token for <typ> in ternary guard
# unless a containing `if <typ>_enabled' renders
# it redundant.
# Note: The ternary is never redundant when
# multiple types are logically or'ed in the
# containing if: e.g.,
# if <typ1>_enabled || <typ2>_enabled
# Note: If $need_r2_guard is true, @a2n is
# precisely the number of conditions in the if
my $typ = $_;
my $need_ternary =
(grep { $_ eq $typ } @can_dsbl
and !$need_r2_guard || @a2n > 1);
(
$need_ternary
? "(${typ}_enabled ? "
: ""
) .
"b:txtfmt_re_${typ}_etok_atom" .
(
$need_ternary
? " : '')"
: ""
)
} @a2n
)
;
print "\n$il\t", "\\.']/'";
print "\n$il", "let r2_", join("", @a1n), " =";
print "\n$il\t", "\\skip_", join("", @a1n);
print "\n$il\t", "\\.contains_", join("", @a1n);
print "\n$il\t", "\\.start_", join("", @a1n);
print "\n$il\t", "\\.end_", join("", @a1n);
print "\n$il\t", "\\.' contained'";
if ($need_r2_guard) {
print "\n$il", "endif \" ",
join ' || ', map { "${_}_enabled" } @a2n;
print "\n$il", '"============= END NON-INDENTING BLOCK =============';
}
}
} else { # $section == LOOPS
# Determine current level's indent
$il = "\t" x ($init_il + $lvl);
print "\n$il\"===";
print "\n$il\"*** Loop over ", join("-", @a1n), " levels";
print "\n$il\"===";
# TODO: Think about cleaning this up a bit and adding comments for
# the index indirection...
print "\n$il", "let $idx{$a1n[-1]}", ($loopinfo{$a1n[-1]}{indarr} ? 'p' : ''), " = 1";
print "\n$il", "while $idx{$a1n[-1]}", ($loopinfo{$a1n[-1]}{indarr} ? 'p' : ''), " <= $loopinfo{$a1n[-1]}{cnt}";
$il .= "\t";
print "\n$il", "let $idx{$a1n[-1]} = $loopinfo{$a1n[-1]}{indarr}\{$idx{$a1n[-1]}p\}"
if $loopinfo{$a1n[-1]}{indarr};
print "\n$il", "let ch$idx{$a1n[-1]} = nr2char(b:txtfmt_$a1n[-1]_first_tok + $idx{$a1n[-1]})";
print "\n$il\" Add to appropriate clusters";
print "\n$il", "exe 'syn cluster Tf'.cui.'_all add=Tf'.cui.'_",
join("", @a1n), "_'.",
join(".'_'.", @idx{@a1n})
;
print "\n$il", "exe 'syn cluster Tf'.cui.'_",
join("", @a1n),
(@a1n > 1
? "_'." . join(".'_'.", @idx{@a1n[0 .. $#a1n - 1]}) . ".'"
: ""
),
"_all add=Tf'.cui.'_",
join("", @a1n),
"_'.",
join(".'_'.", @idx{@a1n})
;
# Define matchgroup if background color could be changing (i.e., if
# last element of @a1n is 'bgc')
# Note: matchgroup will retain setting given until we move back to
# a lower order region
# Also note: bgc_enabled check would be superfluous here, since
# code won't be executed if bgc_enabled is false
if ($a1n[-1] eq 'bgc') {
print "\n$il", '" Ensure that this and higher order regions use bgc-specific concealment group';
print "\n$il", "let matchgroup_def = ' matchgroup=Tf'.cui.'_conceal_'.$idx{$a1n[-1]}";
}
# Define nextgroup
my $ng = "";
for my $lor (@lor) {
# Transitions to lower-order groups will always be made to one
# of the special "return to default" (rtd) groups.
$ng .= ",Tf'.cui.'_" . join("", @$lor) . "_'." . join(".'_'.", @idx{@$lor}) . ".'_rtd";
}
for my $sor (@sor) {
$ng .= ",\@Tf'.cui.'_" . join("", @$sor) .
(@$sor > 1
? "_'." . join(".'_'.", @idx{@{$sor}[0 .. $#$sor - 1]}) . ".'"
: ""
) .
"_all";
}
# Note: We didn't need to worry about checking <typ>_enabled for
# the lor and sor case (since this code will be inside an "if
# <typ>_enabled" if <typ> is in either of those arrays); however,
# the hor case pulls in a new region type, so we will need to
# check it.
my $unquoted = 0;
for my $hor (@hor) {
my $typ;
if (($typ) = grep { $_ eq $hor->[-1] } @can_dsbl) {
$ng .= ($unquoted ? '' : "'") . ".(${typ}_enabled ? '";
}
elsif ($unquoted) {
$ng .= ".'";
}
$ng .= ",\@Tf'.cui.'_" . join("", @$hor) . "_'." .
join(".'_'.", @idx{@a1n}) .
".'_all";
if ($typ) {
$ng .= "' : '')";
$unquoted = 1;
}
else {
$unquoted = 0;
}
}
if (@a1n == 1) {
$ng .= ($unquoted ? ".'" : '') . ",Tf_def_tok'";
} elsif (!$unquoted) {
$ng .= "'";
}
# Use substr to strip off the leading comma at the head of $ng
$ng = "' nextgroup=" . substr($ng, 1);
# If nextgroup is about to be used in 2 region definitions (r1 and
# r2), assign it to a variable for efficiency. (Many
# concatenations are required to build the entire nextgroup
# clause.)
# Note: If there are no more regions to pull in, the nextgroup
# clause will be used only once, so it's more efficient to build
# it within the region definition itself.
if (@a2n) {
print "\n$il\" Cache the nextgroup clause";
print "\n$il", "let ng = ", $ng;
# Obviate the need for subsequent logic within this script to
# know whether we're caching nextgroup clause or not
$ng = 'ng';
}
# Define the rgn that is begun with an stok
print "\n$il\" Define region that is begun by a start token";
# Save the beginning of the `syn region' statement, which is
# common to both the region begun by start tok and the region
# begun by end tok. (Note that they diverge at the `_rtd' in the
# latter's region name.)
my $pre_start = "\n$il" .
"exe 'syn region " .
"Tf'.cui.'_" . join("", @a1n) . "_'." . join(".'_'.", @idx{@a1n});
print "$pre_start.matchgroup_def",
"\n$il\t\\.' start=/'.ch$idx{$a1n[-1]}.'/'",
".r1_", join("", @a1n), ".$ng.concealends";
;
# Define the region introduced by 'no rgn' token (if it exists)
if (@a2n) {
# Ensure that we don't define the region if all of the <typ>'s
# whose end token could begin the region are inactive. If at
# least one of these <typ>'s is active, the region will be
# defined, and <typ>_enabled ternaries will be used as
# necessary to ensure that we don't consider end tokens for
# inactive region types.
if ($need_r2_guard) {
print "\n$il", '" Define the following region if and only if at least one of the';
print "\n$il", '" region types whose end token could begin this region is active';
print "\n$il", '"============= BEGIN NON-INDENTING BLOCK =============';
print "\n$il", "if ",
join ' || ', map { "${_}_enabled" } @a2n
;
}
print "\n$il\" Define region that is begun by an end token";
print "\n$il\" (when permitted by a nextgroup)";
print "$pre_start.'_rtd'.matchgroup_def\n$il\t\\.",
"r2_", join("", @a1n), ".$ng.concealends";
;
if ($need_r2_guard) {
print "\n$il", "endif \" ",
join ' || ', map { "${_}_enabled" } @a2n;
print "\n$il", '"============= END NON-INDENTING BLOCK =============';
}
}
# Define the highlighting region
print "\n$il\" Define highlighting for this region";
print "\n$il\" Note: cterm= MUST come after ctermfg= to ensure that bold attribute is";
print "\n$il\" handled correctly in a cterm.";
print "\n$il\"\t:help cterm-colors";
print "\n$il", "exe 'hi Tf'.cui.'_", join("", @a1n), "_'.",
join(".'_'.", @idx{@a1n}),
"\n$il\t\\.",
join(".", map {
"eq_$_.b:txtfmt_$rhs{$_}\{$idx{$_}\}"
} sort { $ord{$a} <=> $ord{$b} } @a1n
),
;
# Define the highlighting region for the rtd group (if it exists)
if (@a2n) {
# Link rtd to non-rtd group, since highlighting is identical
print "\n$il\" Link rtd to non-rtd group";
print "\n$il", "exe 'hi link Tf'.cui.'_", join("", @a1n), "_'.",
join(".'_'.", @idx{@a1n}), ".'_rtd",
" Tf'.cui.'_", join("", @a1n), "_'.",
join(".'_'.", @idx{@a1n})
;
}
}
# RECURSE
# Call ourself recursively to handle the next level
do_lvl($section, \@a1n, \@a2n);
# POST RECURSION
if ($section == DEFS) {
} else { # if $section == LOOPS
# Update for next iteration
my $idx = $idx{$a1n[-1]};
if ($a1n[-1] eq 'fmt') {
print "\n$il", "let $idx = $idx + 1";
} else {
print "\n$il", "let ${idx}p = ${idx}p + 1";
}
# Strip a level of indent
chop $il;
print "\n$il", "endwhile";
}
# Handle departure from blocks corresponding to <typ>'s that can be
# disabled
if (my ($typ) = grep { $_ eq $a1n[-1] } @can_dsbl) {
if ($typ eq 'bgc') {
# Revert to toplevel (no bgc) matchgroup
# Note: Code emitted won't be reached if bgc_enabled is false
print "\n$il", '" Revert to toplevel (no background color) matchgroup';
print "\n$il", "let matchgroup_def = matchgroup_top_def" if $section eq LOOPS;
}
print "\n$il", "endif \" ${typ}_enabled";
print "\n$il", '"============= END NON-INDENTING BLOCK =============';
}
}
}
# Top level recursion for both sections
# When the following call returns, the entire DEFS section will have been
# output
print "\t\" BEGIN AUTOGENERATED CODE BLOCK ", "<<<";
print "\n\t\" Last update: ", scalar(localtime), "\n";
do_lvl(DEFS, [], \@rgn);
# When the following call returns, the entire LOOPS section will have been
# output
do_lvl(LOOPS, [], \@rgn);
print "\n\t\" END AUTOGENERATED CODE BLOCK ", ">>>";
__END__
" vim: sw=4 ts=4 foldmethod=marker foldmarker=<<<,>>> :