aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/eval.txt1
-rw-r--r--runtime/ftplugin/jsonc.vim10
-rw-r--r--runtime/pack/dist/opt/termdebug/plugin/termdebug.vim175
-rw-r--r--runtime/syntax/vim.vim8
-rw-r--r--runtime/tools/check_colors.vim14
5 files changed, 120 insertions, 88 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index dfa99beee7..46f4faefea 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -8552,6 +8552,7 @@ setbufline({buf}, {lnum}, {text}) *setbufline()*
For the use of {buf}, see |bufname()| above.
{lnum} is used like with |setline()|.
+ Use "$" to refer to the last line in buffer {buf}.
When {lnum} is just below the last line the {text} will be
added below the last line.
On success 0 is returned, on failure 1 is returned.
diff --git a/runtime/ftplugin/jsonc.vim b/runtime/ftplugin/jsonc.vim
index 90d52cd0d3..e47a75f574 100644
--- a/runtime/ftplugin/jsonc.vim
+++ b/runtime/ftplugin/jsonc.vim
@@ -4,7 +4,7 @@
" Acknowledgement: Based off of vim-jsonc maintained by Kevin Locke <kevin@kevinlocke.name>
" https://github.com/kevinoid/vim-jsonc
" License: MIT
-" Last Change: 2021-07-01
+" Last Change: 2021 Nov 22
runtime! ftplugin/json.vim
@@ -14,14 +14,8 @@ else
let b:did_ftplugin_jsonc = 1
endif
-" A list of commands that undo buffer local changes made below.
-let s:undo_ftplugin = []
-
" Set comment (formatting) related options. {{{1
setlocal commentstring=//%s comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,://
-call add(s:undo_ftplugin, 'commentstring< comments<')
" Let Vim know how to disable the plug-in.
-call map(s:undo_ftplugin, "'execute ' . string(v:val)")
-let b:undo_ftplugin = join(s:undo_ftplugin, ' | ')
-unlet s:undo_ftplugin
+let b:undo_ftplugin = 'setlocal commentstring< comments<'
diff --git a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim
index c5a9f503d5..4a58bee8ce 100644
--- a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim
+++ b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim
@@ -2,7 +2,7 @@
"
" Author: Bram Moolenaar
" Copyright: Vim license applies, see ":help license"
-" Last Change: 2021 Nov 21
+" Last Change: 2021 Nov 27
"
" WORK IN PROGRESS - Only the basics work
" Note: On MS-Windows you need a recent version of gdb. The one included with
@@ -102,6 +102,7 @@ endfunc
call s:Highlight(1, '', &background)
hi default debugBreakpoint term=reverse ctermbg=red guibg=red
+hi default debugBreakpointDisabled term=reverse ctermbg=gray guibg=gray
func s:StartDebug(bang, ...)
" First argument is the command to debug, second core file or process ID.
@@ -241,15 +242,29 @@ func s:StartDebug_term(dict)
let comm_job_info = nvim_get_chan_info(s:comm_job_id)
let commpty = comm_job_info['pty']
- " Open a terminal window to run the debugger.
- " Add -quiet to avoid the intro message causing a hit-enter prompt.
let gdb_args = get(a:dict, 'gdb_args', [])
let proc_args = get(a:dict, 'proc_args', [])
- let cmd = [g:termdebugger, '-quiet', '-tty', pty, '--eval-command', 'echo startupdone\n'] + gdb_args
- "call ch_log('executing "' . join(cmd) . '"')
+ let gdb_cmd = [g:termdebugger]
+ " Add -quiet to avoid the intro message causing a hit-enter prompt.
+ let gdb_cmd += ['-quiet']
+ " Disable pagination, it causes everything to stop at the gdb
+ let gdb_cmd += ['-iex', 'set pagination off']
+ " Interpret commands while the target is running. This should usually only
+ " be exec-interrupt, since many commands don't work properly while the
+ " target is running (so execute during startup).
+ let gdb_cmd += ['-iex', 'set mi-async on']
+ " Open a terminal window to run the debugger.
+ let gdb_cmd += ['-tty', pty]
+ " Command executed _after_ startup is done, provides us with the necessary feedback
+ let gdb_cmd += ['-ex', 'echo startupdone\n']
+
+ " Adding arguments requested by the user
+ let gdb_cmd += gdb_args
+
execute 'new'
- let s:gdb_job_id = termopen(cmd, {'on_exit': function('s:EndTermDebug')})
+ " call ch_log('executing "' . join(gdb_cmd) . '"')
+ let s:gdb_job_id = termopen(gdb_cmd, {'on_exit': function('s:EndTermDebug')})
if s:gdb_job_id == 0
echoerr 'invalid argument (or job table is full) while opening gdb terminal window'
exe 'bwipe! ' . s:ptybuf
@@ -272,8 +287,8 @@ func s:StartDebug_term(dict)
for lnum in range(1, 200)
if get(getbufline(s:gdbbuf, lnum), 0, '') =~ 'startupdone'
- let try_count = 9999
- break
+ let try_count = 9999
+ break
endif
endfor
let try_count += 1
@@ -286,7 +301,7 @@ func s:StartDebug_term(dict)
" Set arguments to be run.
if len(proc_args)
- call chansend(s:gdb_job_id, 'set args ' . join(proc_args) . "\r")
+ call chansend(s:gdb_job_id, 'server set args ' . join(proc_args) . "\r")
endif
" Connect gdb to the communication pty, using the GDB/MI interface.
@@ -310,6 +325,7 @@ func s:StartDebug_term(dict)
let response = line1 . line2
if response =~ 'Undefined command'
echoerr 'Sorry, your gdb is too old, gdb 7.12 is required'
+ " CHECKME: possibly send a "server show version" here
call s:CloseBuffers()
return
endif
@@ -333,17 +349,6 @@ func s:StartDebug_term(dict)
sleep 10m
endwhile
- " Interpret commands while the target is running. This should usually only be
- " exec-interrupt, since many commands don't work properly while the target is
- " running.
- call s:SendCommand('-gdb-set mi-async on')
- " Older gdb uses a different command.
- call s:SendCommand('-gdb-set target-async on')
-
- " Disable pagination, it causes everything to stop at the gdb
- " "Type <return> to continue" prompt.
- call s:SendCommand('set pagination off')
-
" Set the filetype, this can be used to add mappings.
set filetype=termdebug
@@ -371,14 +376,26 @@ func s:StartDebug_prompt(dict)
exe (&columns / 2 - 1) . "wincmd |"
endif
- " Add -quiet to avoid the intro message causing a hit-enter prompt.
let gdb_args = get(a:dict, 'gdb_args', [])
let proc_args = get(a:dict, 'proc_args', [])
- let cmd = [g:termdebugger, '-quiet', '--interpreter=mi2'] + gdb_args
- "call ch_log('executing "' . join(cmd) . '"')
+ let gdb_cmd = [g:termdebugger]
+ " Add -quiet to avoid the intro message causing a hit-enter prompt.
+ let gdb_cmd += ['-quiet']
+ " Disable pagination, it causes everything to stop at the gdb, needs to be run early
+ let gdb_cmd += ['-iex', 'set pagination off']
+ " Interpret commands while the target is running. This should usually only
+ " be exec-interrupt, since many commands don't work properly while the
+ " target is running (so execute during startup).
+ let gdb_cmd += ['-iex', 'set mi-async on']
+ " directly communicate via mi2
+ let gdb_cmd += ['--interpreter=mi2']
+
+ " Adding arguments requested by the user
+ let gdb_cmd += gdb_args
- let s:gdbjob = jobstart(cmd, {
+ " call ch_log('executing "' . join(gdb_cmd) . '"')
+ let s:gdbjob = jobstart(gdb_cmd, {
\ 'on_exit': function('s:EndPromptDebug'),
\ 'on_stdout': function('s:GdbOutCallback'),
\ })
@@ -392,13 +409,6 @@ func s:StartDebug_prompt(dict)
return
endif
- " Interpret commands while the target is running. This should usually only
- " be exec-interrupt, since many commands don't work properly while the
- " target is running.
- call s:SendCommand('-gdb-set mi-async on')
- " Older gdb uses a different command.
- call s:SendCommand('-gdb-set target-async on')
-
let s:ptybuf = 0
if has('win32')
" MS-Windows: run in a new console window for maximum compatibility
@@ -433,8 +443,6 @@ func s:StartDebug_prompt(dict)
endif
call s:SendCommand('set print pretty on')
call s:SendCommand('set breakpoint pending on')
- " Disable pagination, it causes everything to stop at the gdb
- call s:SendCommand('set pagination off')
" Set arguments to be run
if len(proc_args)
@@ -516,6 +524,15 @@ func TermDebugSendCommand(cmd)
endif
endfunc
+" Send a command only when stopped. Used for :Next and :Step.
+func s:SendCommandIfStopped(cmd)
+ if s:stopped
+ call s:SendCommand(a:cmd)
+ " else
+ " call ch_log('dropping command, program is running: ' . a:cmd)
+ endif
+endfunc
+
" Function called when entering a line in the prompt buffer.
func s:PromptCallback(text)
call s:SendCommand(a:text)
@@ -584,32 +601,23 @@ func s:GdbOutCallback(job_id, msgs, event)
endfunc
" Decode a message from gdb. quotedText starts with a ", return the text up
-" to the next ", unescaping characters.
+" to the next ", unescaping characters:
+" - remove line breaks
+" - change \\t to \t
+" - change \0xhh to \xhh
+" - change \ooo to octal
+" - change \\ to \
func s:DecodeMessage(quotedText)
if a:quotedText[0] != '"'
echoerr 'DecodeMessage(): missing quote in ' . a:quotedText
return
endif
- let result = ''
- let i = 1
- while a:quotedText[i] != '"' && i < len(a:quotedText)
- if a:quotedText[i] == '\'
- let i += 1
- if a:quotedText[i] == 'n'
- " drop \n
- let i += 1
- continue
- elseif a:quotedText[i] == 't'
- " append \t
- let i += 1
- let result .= "\t"
- continue
- endif
- endif
- let result .= a:quotedText[i]
- let i += 1
- endwhile
- return result
+ return a:quotedText
+ \->substitute('^"\|".*\|\\n', '', 'g')
+ \->substitute('\\t', "\t", 'g')
+ \->substitute('\\0x\(\x\x\)', {-> eval('"\x' .. submatch(1) .. '"')}, 'g')
+ \->substitute('\\\o\o\o', {-> eval('"' .. submatch(0) .. '"')}, 'g')
+ \->substitute('\\\\', '\', 'g')
endfunc
" Extract the "name" value from a gdb message with fullname="name".
@@ -770,8 +778,10 @@ func s:CommOutput(job_id, msgs, event)
elseif msg != ''
if msg =~ '^\(\*stopped\|\*running\|=thread-selected\)'
call s:HandleCursor(msg)
- elseif msg =~ '^\^done,bkpt=' || msg =~ '^=breakpoint-created,' || msg =~ '^=breakpoint-modified,'
- call s:HandleNewBreakpoint(msg)
+ elseif msg =~ '^\^done,bkpt=' || msg =~ '^=breakpoint-created,'
+ call s:HandleNewBreakpoint(msg, 0)
+ elseif msg =~ '^=breakpoint-modified,'
+ call s:HandleNewBreakpoint(msg, 1)
elseif msg =~ '^=breakpoint-deleted,'
call s:HandleBreakpointDelete(msg)
elseif msg =~ '^=thread-group-started'
@@ -805,9 +815,9 @@ func s:InstallCommands()
command -nargs=? Break call s:SetBreakpoint(<q-args>)
command Clear call s:ClearBreakpoint()
- command Step call s:SendCommand('-exec-step')
- command Over call s:SendCommand('-exec-next')
- command Finish call s:SendCommand('-exec-finish')
+ command Step call s:SendCommandIfStopped('-exec-step')
+ command Over call s:SendCommandIfStopped('-exec-next')
+ command Finish call s:SendCommandIfStopped('-exec-finish')
command -nargs=* Run call s:Run(<q-args>)
command -nargs=* Arguments call s:SendCommand('-exec-arguments ' . <q-args>)
@@ -1024,21 +1034,24 @@ endfunc
" clean up expression that may got in because of range
" (newlines and surrounding whitespace)
+" As it can also be specified via ex-command for assignments this function
+" may not change the "content" parts (like replacing contained spaces
func s:CleanupExpr(expr)
" replace all embedded newlines/tabs/...
- let expr = substitute( a:expr, '\s', ' ', 'g')
+ let expr = substitute(a:expr, '\_s', ' ', 'g')
if &filetype ==# 'cobol'
- " extra cleanup for COBOL: _every: expression ends with a period,
- " a semicolon nmay be used instead of a space
- " a trailing comma is ignored as it commonly separates multiple expr
- let expr = substitute(expr, '\..*', '', '')
+ " extra cleanup for COBOL:
+ " - a semicolon nmay be used instead of a space
+ " - a trailing comma or period is ignored as it commonly separates/ends
+ " multiple expr
let expr = substitute(expr, ';', ' ', 'g')
- let expr = substitute(expr, ',*$', '', '')
+ let expr = substitute(expr, '[,.]\+ *$', '', '')
endif
- " get rid of surrounding spaces
- let expr = substitute(expr, '^ *\(.*\) *', '\1', '')
+ " get rid of leading and trailing spaces
+ let expr = substitute(expr, '^ *', '', '')
+ let expr = substitute(expr, ' *$', '', '')
return expr
endfunc
@@ -1050,6 +1063,8 @@ let s:evalFromBalloonExprResult = ''
func s:HandleEvaluate(msg)
let value = substitute(a:msg, '.*value="\(.*\)"', '\1', '')
let value = substitute(value, '\\"', '"', 'g')
+ " multi-byte characters arrive in octal form
+ let value = substitute(value, '\\\o\o\o', {-> eval('"' .. submatch(0) .. '"')}, 'g')
let value = substitute(value, ' ', '\1', '')
if s:evalFromBalloonExpr
if s:evalFromBalloonExprResult == ''
@@ -1329,11 +1344,16 @@ endfunc
let s:BreakpointSigns = []
-func s:CreateBreakpoint(id, subid)
+func s:CreateBreakpoint(id, subid, enabled)
let nr = printf('%d.%d', a:id, a:subid)
if index(s:BreakpointSigns, nr) == -1
call add(s:BreakpointSigns, nr)
- exe "sign define debugBreakpoint" . nr . " text=" . substitute(nr, '\..*', '', '') . " texthl=debugBreakpoint"
+ if a:enabled == "n"
+ let hiName = "debugBreakpointDisabled"
+ else
+ let hiName = "debugBreakpoint"
+ endif
+ exe "sign define debugBreakpoint" . nr . " text=" . substitute(nr, '\..*', '', '') . " texthl=" . hiName
endif
endfunc
@@ -1343,7 +1363,7 @@ endfunction
" Handle setting a breakpoint
" Will update the sign that shows the breakpoint
-func s:HandleNewBreakpoint(msg)
+func s:HandleNewBreakpoint(msg, modifiedFlag)
if a:msg !~ 'fullname='
" a watch or a pending breakpoint does not have a file name
if a:msg =~ 'pending='
@@ -1366,7 +1386,8 @@ func s:HandleNewBreakpoint(msg)
" If "nr" is 123 it becomes "123.0" and subid is "0".
" If "nr" is 123.4 it becomes "123.4.0" and subid is "4"; "0" is discarded.
let [id, subid; _] = map(split(nr . '.0', '\.'), 'v:val + 0')
- call s:CreateBreakpoint(id, subid)
+ let enabled = substitute(msg, '.*enabled="\([yn]\)".*', '\1', '')
+ call s:CreateBreakpoint(id, subid, enabled)
if has_key(s:breakpoints, id)
let entries = s:breakpoints[id]
@@ -1393,8 +1414,18 @@ func s:HandleNewBreakpoint(msg)
if bufloaded(fname)
call s:PlaceSign(id, subid, entry)
+ let posMsg = ' at line ' . lnum . '.'
+ else
+ let posMsg = ' in ' . fname . ' at line ' . lnum . '.'
+ endif
+ if !a:modifiedFlag
+ let actionTaken = 'created'
+ elseif enabled == 'n'
+ let actionTaken = 'disabled'
+ else
+ let actionTaken = 'enabled'
endif
- echomsg 'Breakpoint ' . nr . ' created at line ' . lnum . '.'
+ echomsg 'Breakpoint ' . nr . ' ' . actionTaken . posMsg
endfor
endfunc
diff --git a/runtime/syntax/vim.vim b/runtime/syntax/vim.vim
index f7b5ce0f63..d0272916b9 100644
--- a/runtime/syntax/vim.vim
+++ b/runtime/syntax/vim.vim
@@ -741,10 +741,10 @@ if g:vimsyn_embed =~# 'P' && filereadable(s:pythonpath)
unlet! b:current_syntax
syn cluster vimFuncBodyList add=vimPythonRegion
exe "syn include @vimPythonScript ".s:pythonpath
- VimFoldP syn region vimPythonRegion matchgroup=vimScriptDelim start=+py\%[thon][3x]\=\s*<<\s*\z(\S*\)\ze\(\s*#.*\)\=$+ end=+^\z1\ze\(\s*".*\)\=$+ contains=@vimPythonScript
- VimFoldP syn region vimPythonRegion matchgroup=vimScriptDelim start=+py\%[thon][3x]\=\s*<<\s*$+ end=+\.$+ contains=@vimPythonScript
- VimFoldP syn region vimPythonRegion matchgroup=vimScriptDelim start=+Py\%[thon]2or3\s*<<\s*\z(\S*\)\ze\(\s*#.*\)\=$+ end=+^\z1\ze\(\s*".*\)\=$+ contains=@vimPythonScript
- VimFoldP syn region vimPythonRegion matchgroup=vimScriptDelim start=+Py\%[thon]2or3\=\s*<<\s*$+ end=+\.$+ contains=@vimPythonScript
+ VimFoldP syn region vimPythonRegion matchgroup=vimScriptDelim start=+py\%[thon][3x]\=\s*<<\s*\%(trim\s*\)\=\z(\S*\)\ze\(\s*#.*\)\=$+ end=+^\z1\ze\(\s*".*\)\=$+ contains=@vimPythonScript
+ VimFoldP syn region vimPythonRegion matchgroup=vimScriptDelim start=+py\%[thon][3x]\=\s*<<\s*\%(trim\s*\)\=$+ end=+\.$+ contains=@vimPythonScript
+ VimFoldP syn region vimPythonRegion matchgroup=vimScriptDelim start=+Py\%[thon]2or3\s*<<\s*\%(trim\s*\)\=\z(\S*\)\ze\(\s*#.*\)\=$+ end=+^\z1\ze\(\s*".*\)\=$+ contains=@vimPythonScript
+ VimFoldP syn region vimPythonRegion matchgroup=vimScriptDelim start=+Py\%[thon]2or3\=\s*<<\s*\%(trim\s*\)\=$+ end=+\.$+ contains=@vimPythonScript
syn cluster vimFuncBodyList add=vimPythonRegion
else
syn region vimEmbedError start=+py\%[thon]3\=\s*<<\s*\z(.*\)$+ end=+^\z1$+
diff --git a/runtime/tools/check_colors.vim b/runtime/tools/check_colors.vim
index 966072c706..85df882d1e 100644
--- a/runtime/tools/check_colors.vim
+++ b/runtime/tools/check_colors.vim
@@ -226,7 +226,13 @@ fu! Result(err)
endif
endfu
-call Test_check_colors()
-
-let &cpo = s:save_cpo
-unlet s:save_cpo
+try
+ call Test_check_colors()
+catch
+ echohl ErrorMsg
+ echomsg v:exception
+ echohl NONE
+finally
+ let &cpo = s:save_cpo
+ unlet s:save_cpo
+endtry