Mercurial > vim
view runtime/autoload/typeset.vim @ 34623:65e7eaf68f19 v9.1.0200
patch 9.1.0200: `gj`/`gk` not skipping over outer virtual text lines
Commit: https://github.com/vim/vim/commit/b2d124c6258ff41e1f951bf39a4afc386d79ddc4
Author: Dylan Thacker-Smith <dylan.ah.smith@gmail.com>
Date: Sun Mar 24 09:43:25 2024 +0100
patch 9.1.0200: `gj`/`gk` not skipping over outer virtual text lines
Problem: `gj`/`gk` was updating the desired cursor virtual column to
the outer virtual text, even though the actual cursor position
was moved to not be on the virtual text, leading the need to
do an extra `gj`/`gk` to move past each virtual text line.
(rickhowe)
Solution: Exclude the outer virtual text when getting the line length
for moving the cursor with `gj`/`gk`, so that no extra
movement is needed to skip over virtual text lines.
(Dylan Thacker-Smith)
fixes: #12028
related: #14262
Signed-off-by: Dylan Thacker-Smith <dylan.ah.smith@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Sun, 24 Mar 2024 10:00:05 +0100 |
parents | d6dde6229b36 |
children |
line wrap: on
line source
vim9script # Language: Generic TeX typesetting engine # Maintainer: Nicola Vitacolonna <nvitacolonna@gmail.com> # Latest Revision: 2022 Aug 12 # Constants and helpers {{{ const SLASH = !exists("+shellslash") || &shellslash ? '/' : '\' def Echo(msg: string, mode: string, label: string) redraw echo "\r" execute 'echohl' mode echomsg printf('[%s] %s', label, msg) echohl None enddef def EchoMsg(msg: string, label = 'Notice') Echo(msg, 'ModeMsg', label) enddef def EchoWarn(msg: string, label = 'Warning') Echo(msg, 'WarningMsg', label) enddef def EchoErr(msg: string, label = 'Error') Echo(msg, 'ErrorMsg', label) enddef # }}} # Track jobs {{{ var running_jobs = {} # Dictionary of job IDs of jobs currently executing def AddJob(label: string, j: job) if !has_key(running_jobs, label) running_jobs[label] = [] endif add(running_jobs[label], j) enddef def RemoveJob(label: string, j: job) if has_key(running_jobs, label) && index(running_jobs[label], j) != -1 remove(running_jobs[label], index(running_jobs[label], j)) endif enddef def GetRunningJobs(label: string): list<job> return has_key(running_jobs, label) ? running_jobs[label] : [] enddef # }}} # Callbacks {{{ def ProcessOutput(qfid: number, wd: string, efm: string, ch: channel, msg: string) # Make sure the quickfix list still exists if getqflist({'id': qfid}).id != qfid EchoErr("Quickfix list not found, stopping the job") call job_stop(ch_getjob(ch)) return endif # Make sure the working directory is correct silent execute "lcd" wd setqflist([], 'a', {'id': qfid, 'lines': [msg], 'efm': efm}) silent lcd - enddef def CloseCb(ch: channel) job_status(ch_getjob(ch)) # Trigger exit_cb's callback enddef def ExitCb(label: string, jobid: job, exitStatus: number) RemoveJob(label, jobid) if exitStatus == 0 botright cwindow EchoMsg('Success!', label) elseif exitStatus < 0 EchoWarn('Job terminated', label) else botright copen wincmd p EchoWarn('There are errors.', label) endif enddef # }}} # Create a new empty quickfix list at the end of the stack and return its id {{{ def NewQuickfixList(path: string): number if setqflist([], ' ', {'nr': '$', 'title': path}) == -1 return -1 endif return getqflist({'nr': '$', 'id': 0}).id enddef # }}} # Public interface {{{ # When a TeX document is split into several source files, each source file # may contain a "magic line" specifying the "root" file, e.g.: # # % !TEX root = main.tex # # Using this line, Vim can know which file to typeset even if the current # buffer is different from main.tex. # # This function searches for the magic line in the first ten lines of the # given buffer, and returns the full path of the root document. # # NOTE: the value of "% !TEX root" *must* be a relative path. export def FindRootDocument(bufname: string = bufname("%")): string const bufnr = bufnr(bufname) if !bufexists(bufnr) return bufname endif var rootpath = fnamemodify(bufname(bufnr), ':p') # Search for magic line `% !TEX root = ...` in the first ten lines const header = getbufline(bufnr, 1, 10) const idx = match(header, '^\s*%\s\+!TEX\s\+root\s*=\s*\S') if idx > -1 const main = matchstr(header[idx], '!TEX\s\+root\s*=\s*\zs.*$') rootpath = simplify(fnamemodify(rootpath, ":h") .. SLASH .. main) endif return rootpath enddef export def LogPath(bufname: string): string const logfile = FindRootDocument(bufname) return fnamemodify(logfile, ":r") .. ".log" enddef # Typeset the specified path # # Parameters: # label: a descriptive string used in messages to identify the kind of job # Cmd: a function that takes the path of a document and returns the typesetting command # path: the path of the document to be typeset. To avoid ambiguities, pass a *full* path. # efm: the error format string to parse the output of the command. # env: environment variables for the process (passed to job_start()) # # Returns: # true if the job is started successfully; # false otherwise. export def Typeset( label: string, Cmd: func(string): list<string>, path: string, efm: string, env: dict<string> = {} ): bool var fp = fnamemodify(path, ":p") var wd = fnamemodify(fp, ":h") var qfid = NewQuickfixList(fp) if qfid == -1 EchoErr('Could not create quickfix list', label) return false endif if !filereadable(fp) EchoErr(printf('File not readable: %s', fp), label) return false endif var jobid = job_start(Cmd(path), { env: env, cwd: wd, in_io: "null", callback: (c, m) => ProcessOutput(qfid, wd, efm, c, m), close_cb: CloseCb, exit_cb: (j, e) => ExitCb(label, j, e), }) if job_status(jobid) ==# "fail" EchoErr("Failed to start job", label) return false endif AddJob(label, jobid) EchoMsg('Typesetting...', label) return true enddef export def JobStatus(label: string) EchoMsg('Jobs still running: ' .. string(len(GetRunningJobs(label))), label) enddef export def StopJobs(label: string) for job in GetRunningJobs(label) job_stop(job) endfor EchoMsg('Done.', label) enddef # Typeset the specified buffer # # Parameters: # name: a buffer's name. this may be empty to indicate the current buffer. # cmd: a function that takes the path of a document and returns the typesetting command # label: a descriptive string used in messages to identify the kind of job # env: environment variables for the process (passed to job_start()) # # Returns: # true if the job is started successfully; # false otherwise. export def TypesetBuffer( name: string, Cmd: func(string): list<string>, env = {}, label = 'Typeset' ): bool const bufname = bufname(name) if empty(bufname) EchoErr('Please save the buffer first.', label) return false endif const efm = getbufvar(bufnr(bufname), "&efm") const rootpath = FindRootDocument(bufname) return Typeset('ConTeXt', Cmd, rootpath, efm, env) enddef # }}} # vim: sw=2 fdm=marker