view runtime/indent/context.vim @ 34018:d81556766132

runtime(context): update ConTeXt keywords and other minor fixes (#13778) Commit: https://github.com/vim/vim/commit/0bca4a00188ccde335e0d6a7b7c093998e09182f Author: Lifepillar <lifepillar@users.noreply.github.com> Date: Wed Dec 27 18:49:50 2023 +0100 runtime(context): update ConTeXt keywords and other minor fixes (https://github.com/vim/vim/issues/13778) Update to the ConTeXt runtime files. Changes: 1. shared syntax files updated with `mtxrun --script interface --vim` using the latest ConTeXt LMTX. 2. fixed reference to `make` tag in the help file. 3. added `keepend` to mitigate issues with embedded Lua syntax (see below). 4. the latest revision date of each ConTeXt runtime file has been updated to the date of this commit. The issue about embedded Lua was reported by a user: >Take the following valid ConTeXt file: > \starttext > \ctxlua{context("Text generated from Lua.")} > \ctxlua{context("Another text generated from Lua.")} > \stoptext >On my Vim installation (including when I start Vim with `--clean`), the >closing bracket and curly braces on line 2 are highlighted red and the >syntax highlighting after that is off. >I was trying to dig a little bit into what was going on, using the >`synID()` and `synIDattr()` functions. It appears that the closing >bracket on line 2 is matched as a `luaParentError` instead of the end >of the `luaParen` region. Therefore, the `luaParen` region continues >all the way to the end of the file. The closing curly brace on line >2 is matched as a `luaError`, the 2nd `\ctxlua` on line 3 as >`luaParen`, etc. >This issue doesn't occur in a plain Lua file, where the closing bracket >is correctly matched as the end of the `luaParen` region. So it seems >that something goes wrong when the Lua syntax file is included in the >ConTeXt one. By adding `keepend`, the right parenthesis for some reason is still highlighted as a `luaParenError`, but at least the right curly brace should correctly end the Lua block. From what I've seen, I think it is very difficult to embed Lua syntax properly without help from the Lua syntax file (that is, without patching it). It has global rules such as: syn match luaParenError ")" syn match luaError "}" which make it difficult, if not impossible, to contain Lua syntax without `keepend` (and its limitations). Signed-off-by: Lifepillar <lifepillar@lifepillar.me> Signed-off-by: Christian Brabandt <cb@256bit.org>
author Christian Brabandt <cb@256bit.org>
date Wed, 27 Dec 2023 19:00:06 +0100
parents f00c56ee8118
children
line wrap: on
line source

vim9script

# Language:           ConTeXt typesetting engine
# Maintainer:         Nicola Vitacolonna <nvitacolonna@gmail.com>
# Former Maintainers: Nikolai Weibull <now@bitwi.se>
# Latest Revision:    2023 Dec 26

if exists("b:did_indent")
  finish
endif

# Load MetaPost indentation script (this will also set b:did_indent)
runtime! indent/mp.vim

setlocal indentexpr=ConTeXtIndent()

b:undo_indent = "setl indentexpr<"

def PrevNotComment(l: number): number
  var prevlnum = prevnonblank(l)

  while prevlnum > 0 && getline(prevlnum) =~# '^\s*%'
    prevlnum = prevnonblank(prevlnum - 1)
  endwhile

  return prevlnum
enddef

def FindPair(pstart: string, pmid: string, pend: string): number
  cursor(v:lnum, 1)
  return indent(searchpair(pstart, pmid, pend, 'bWn',
    'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\\|comment"'))
enddef

def ConTeXtIndent(): number
  # Use MetaPost rules inside MetaPost graphic environments
  if len(synstack(v:lnum, 1)) > 0 &&
    synIDattr(synstack(v:lnum, 1)[0], "name") ==# 'contextMPGraphic'
    return g:MetaPostIndent()
  endif

  const prevlnum = PrevNotComment(v:lnum - 1)
  const prevind  = indent(prevlnum)
  const prevline = getline(prevlnum)
  const currline = getline(v:lnum)

  # If the current line starts with ], match indentation.
  if currline =~# '^\s*\]'
    return FindPair('\[', '', '\]')
  endif

  # If the current line starts with }, match indentation.
  if currline =~# '^\s*}'
    return FindPair('{', '', '}')
  endif

  # If the previous line ends with [ or { (possibly followed by a comment) then indent.
  if prevline =~# '[{[]\s*\%(%.*\)\=$'
    return prevind + shiftwidth()
  endif

  return -1
enddef

# vim: sw=2 fdm=marker