patch 9.1.0482: termdebug plugin needs more love

Commit: 
https://github.com/vim/vim/commit/ef8eab86e29091eaff0d3fb0bc3f7c90f468f6aa
Author: Ubaldo Tiberi <ubaldo.tib...@volvo.com>
Date:   Thu Jun 13 19:23:07 2024 +0200

    patch 9.1.0482: termdebug plugin needs more love
    
    Problem:  termdebug plugin needs more love
    Solution: start with some more Vim9 refactoring
              to improve maintenance and readability
              (Ubaldo Tiberi)
    
    List of Changes and the Reasoning Behind Them:
    
    1) Introduction of InitScriptVariables() Function:
    
    Reasoning: This function has been introduced to ensure that when you open 
and
    close Termdebug, and then open it again, there are no leftover script 
variable
    values from the previous session. Leftover values could potentially cause
    issues. The goal is for each Termdebug session to be independent of previous
    sessions. At startup, all script variables are initialized. The only 
exception
    is g:termdebug_loaded located at the very beginning of the script to prevent
    sourcing the script twice. The variables are declared at script level and
    defined in InitScriptVariables().
    
    2) More Descriptive Variable Names:
    
    Reasoning: The names of variables have been made more comprehensive. Almost
    every Termdebug buffer now has a variable to indicate its name and another
    variable to indicate its number, improving code readability and
    maintainability. Due to the latest discussion around the &mousemodel option
    save/restore mechanism, perhaps some other variables shall be prepended with
    saved_.
    
    3) Consistent Naming for GDB Terminal Buffers:
    
    Reasoning: The name of the GDB terminal buffer now matches the name of the 
GDB
    program being used, e.g., 'gdb', 'mygdb', 'arm-eabi-none-gdb', etc. This
    ensures clarity and consistency in identifying buffers.
    
    4) Other minor improvements:
    Moved EchoErr() on top, added another test, some refactoring, mainly changed
    several 0 and 1 to true and false
    
    closes: #14980
    
    Signed-off-by: Ubaldo Tiberi <ubaldo.tib...@volvo.com>
    Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim 
b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim
index 0a40164b7..15d039719 100644
--- a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim
+++ b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim
@@ -4,7 +4,7 @@ vim9script
 
 # Author: Bram Moolenaar
 # Copyright: Vim license applies, see ":help license"
-# Last Change: 2024 Jun 03
+# Last Change: 2024 Jun 13
 # Converted to Vim9: Ubaldo Tiberi <ubaldo.tib...@gmail.com>
 
 # WORK IN PROGRESS - The basics works stable, more to come
@@ -38,44 +38,56 @@ vim9script
 # The communication with gdb uses GDB/MI.  See:
 # https://sourceware.org/gdb/current/onlinedocs/gdb/GDB_002fMI.html
 
-# In case this gets sourced twice.
+def Echoerr(msg: string)
+  echohl ErrorMsg | echom $'[termdebug] {msg}' | echohl None
+enddef
+
+
+# Variables to keep their status among multiple instances of Termdebug
+# Avoid to source the script twice.
 if exists('g:termdebug_loaded')
-  finish
+    Echoerr('Termdebug already loaded.')
+    finish
 endif
 g:termdebug_loaded = true
 
-var way = 'terminal'
-var err = 'no errors'
+# Script variables declaration. These variables are re-initialized at every
+# Termdebug instance
+var way: string
+var err: string
 
-var pc_id = 12
-var asm_id = 13
-var break_id = 14  # breakpoint number is added to this
-var stopped = 1
-var running = 0
+var pc_id: number
+var asm_id: number
+var break_id: number
+var stopped: bool
+var running: bool
 
-var parsing_disasm_msg = 0
-var asm_lines = []
-var asm_addr = ''
+var parsing_disasm_msg: number
+var asm_lines: list<string>
+var asm_addr: string
 
 # These shall be constants but cannot be initialized here
 # They indicate the buffer numbers of the main buffers used
-var gdbbuf = 0
-var varbuf = 0
-var asmbuf = 0
-var promptbuf = 0
+var gdbbufnr: number
+var gdbbufname: string
+var varbufnr: number
+var varbufname: string
+var asmbufnr: number
+var asmbufname: string
+var promptbuf: number
 # This is for the "debugged program" thing
-var ptybuf = 0
-var commbuf = 0
+var ptybufnr: number
+var commbufnr: number
 
-var gdbjob = null_job
-var gdb_channel = null_channel
+var gdbjob: job
+var gdb_channel: channel
 # These changes because they relate to windows
-var pid = 0
-var gdbwin = 0
-var varwin = 0
-var asmwin = 0
-var ptywin = 0
-var sourcewin = 0
+var pid: number
+var gdbwin: number
+var varwin: number
+var asmwin: number
+var ptywin: number
+var sourcewin: number
 
 # Contains breakpoints that have been placed, key is a string with the GDB
 # breakpoint number.
@@ -84,52 +96,112 @@ var sourcewin = 0
 # For a breakpoint "123.4" the id is "123" and subid is "4".
 # Example, when breakpoint "44", "123", "123.1" and "123.2" exist:
 # {'44': {'0': entry}, '123': {'0': entry, '1': entry, '2': entry}}
-var breakpoints = {}
+var breakpoints: dict<any>
 
 # Contains breakpoints by file/lnum.  The key is "fname:lnum".
 # Each entry is a list of breakpoint IDs at that position.
-var breakpoint_locations = {}
-var BreakpointSigns: list<string> = []
-
+var breakpoint_locations: dict<any>
+var BreakpointSigns: list<string>
 
-var evalFromBalloonExpr = 0
-var evalFromBalloonExprResult = ''
-var ignoreEvalError = 0
-var evalexpr = ''
+var evalFromBalloonExpr: bool
+var evalFromBalloonExprResult: string
+var ignoreEvalError: bool
+var evalexpr: string
 # Remember the old value of 'signcolumn' for each buffer that it's set in, so
 # that we can restore the value for all buffers.
-var signcolumn_buflist = [bufnr()]
-var save_columns = 0
+var signcolumn_buflist: list<number>
+var save_columns: number
 
-var allleft = 0
+var allleft: bool
 # This was s:vertical but I cannot use vertical as variable name
-var vvertical = 0
-
-var winbar_winids = []
-var plus_map_saved = {}
-var minus_map_saved = {}
-var k_map_saved = {}
-var saved_mousemodel = null_string
-
-
-# Need either the +terminal feature or +channel and the prompt buffer.
-# The terminal feature does not work with gdb on win32.
-if has('terminal') && !has('win32')
-  way = 'terminal'
-elseif has('channel') && exists('*prompt_setprompt')
-  way = 'prompt'
-else
-  if has('terminal')
-    err = 'Cannot debug, missing prompt buffer support'
+var vvertical: bool
+
+var winbar_winids: list<number>
+
+var saved_mousemodel: string
+
+var k_map_saved: dict<any>
+var plus_map_saved: dict<any>
+var minus_map_saved: dict<any>
+
+
+def InitScriptVariables()
+  if exists('g:termdebug_config') && has_key(g:termdebug_config, 'use_prompt')
+    way = g:termdebug_config['use_prompt'] ? 'prompt' : 'terminal'
+  elseif exists('g:termdebug_use_prompt')
+    way = g:termdebug_use_prompt
+  elseif has('terminal') && !has('win32')
+    way = 'terminal'
   else
-    err = 'Cannot debug, +channel feature is not supported'
+    way = 'prompt'
   endif
-  command -nargs=* -complete=file -bang Termdebug echoerr err
-  command -nargs=+ -complete=file -bang TermdebugCommand echoerr err
-  finish
-endif
+  err = ''
+
+  pc_id = 12
+  asm_id = 13
+  break_id = 14  # breakpoint number is added to this
+  stopped = true
+  running = false
+
+  parsing_disasm_msg = 0
+  asm_lines = []
+  asm_addr = ''
+
+  # They indicate the buffer numbers of the main buffers used
+  gdbbufnr = 0
+  gdbbufname = 'gdb'
+  varbufnr = 0
+  varbufname = 'Termdebug-variables-listing'
+  asmbufnr = 0
+  asmbufname = 'Termdebug-asm-listing'
+  promptbuf = 0
+  # This is for the "debugged program" thing
+  ptybufnr = 0
+  commbufnr = 0
+
+  gdbjob = null_job
+  gdb_channel = null_channel
+  # These changes because they relate to windows
+  pid = 0
+  gdbwin = 0
+  varwin = 0
+  asmwin = 0
+  ptywin = 0
+  sourcewin = 0
+
+  # Contains breakpoints that have been placed, key is a string with the GDB
+  # breakpoint number.
+  # Each entry is a dict, containing the sub-breakpoints.  Key is the subid.
+  # For a breakpoint that is just a number the subid is zero.
+  # For a breakpoint "123.4" the id is "123" and subid is "4".
+  # Example, when breakpoint "44", "123", "123.1" and "123.2" exist:
+  # {'44': {'0': entry}, '123': {'0': entry, '1': entry, '2': entry}}
+  breakpoints = {}
+
+  # Contains breakpoints by file/lnum.  The key is "fname:lnum".
+  # Each entry is a list of breakpoint IDs at that position.
+  breakpoint_locations = {}
+  BreakpointSigns = []
+
+  evalFromBalloonExpr = false
+  evalFromBalloonExprResult = ''
+  ignoreEvalError = false
+  evalexpr = ''
+  # Remember the old value of 'signcolumn' for each buffer that it's set in, so
+  # that we can restore the value for all buffers.
+  signcolumn_buflist = [bufnr()]
+  save_columns = 0
 
+  winbar_winids = []
 
+  k_map_saved = {}
+  plus_map_saved = {}
+  minus_map_saved = {}
+
+  if has('menu')
+    saved_mousemodel = null_string
+  endif
+enddef
 # The command that starts debugging, e.g. ":Termdebug vim".
 # To end type "quit" in the gdb window.
 command -nargs=* -complete=file -bang Termdebug StartDebug(<bang>0, <f-args>)
@@ -182,11 +254,8 @@ def GetCommand(): list<string>
   return type(cmd) == v:t_list ? copy(cmd) : [cmd]
 enddef
 
-def Echoerr(msg: string)
-  echohl ErrorMsg | echom $'[termdebug] {msg}' | echohl None
-enddef
-
 def StartDebug(bang: bool, ...gdb_args: list<string>)
+  InitScriptVariables()
   # First argument is the command to debug, second core file or process ID.
   StartDebug_internal({gdb_args: gdb_args, bang: bang})
 enddef
@@ -227,24 +296,11 @@ def StartDebug_internal(dict: dict<any>)
       &columns = wide
       # If we make the Vim window wider, use the whole left half for the debug
       # windows.
-      allleft = 1
+      allleft = true
     endif
-    vvertical = 1
-  else
-    vvertical = 0
-  endif
-
-  # Override using a terminal window by setting g:termdebug_use_prompt to 1.
-  var use_prompt = 0
-  if exists('g:termdebug_config')
-    use_prompt = get(g:termdebug_config, 'use_prompt', 0)
-  elseif exists('g:termdebug_use_prompt')
-    use_prompt = g:termdebug_use_prompt
-  endif
-  if has('terminal') && !has('win32') && !use_prompt
-    way = 'terminal'
+    vvertical = true
   else
-    way = 'prompt'
+    vvertical = false
   endif
 
   if way == 'prompt'
@@ -272,45 +328,42 @@ enddef
 
 # Use when debugger didn't start or ended.
 def CloseBuffers()
-  exe $'bwipe! {ptybuf}'
-  exe $'bwipe! {commbuf}'
-  if asmbuf > 0 && bufexists(asmbuf)
-    exe $'bwipe! {asmbuf}'
+  exe $'bwipe! {ptybufnr}'
+  exe $'bwipe! {commbufnr}'
+  if asmbufnr > 0 && bufexists(asmbufnr)
+    exe $'bwipe! {asmbufnr}'
   endif
-  if varbuf > 0 && bufexists(varbuf)
-    exe $'bwipe! {varbuf}'
+  if varbufnr > 0 && bufexists(varbufnr)
+    exe $'bwipe! {varbufnr}'
   endif
   running = 0
   gdbwin = 0
 enddef
 
 # IsGdbRunning(): bool may be a better name?
-def CheckGdbRunning(): string
-  var gdbproc = term_getjob(gdbbuf)
-  var gdbproc_status = 'unknown'
-  if type(gdbproc) == v:t_job
-    gdbproc_status = job_status(gdbproc)
-  endif
-  if gdbproc == v:null || gdbproc_status !=# 'run'
+def IsGdbStarted(): bool
+  var gdbproc_status = job_status(term_getjob(gdbbufnr))
+  if gdbproc_status !=# 'run'
     var cmd_name = string(GetCommand()[0])
     Echoerr($'{cmd_name} exited unexpectedly')
     CloseBuffers()
-    return ''
+    return false
   endif
-  return 'ok'
+  return true
 enddef
 
 # Open a terminal window without a job, to run the debugged program in.
 def StartDebug_term(dict: dict<any>)
-  ptybuf = term_start('NONE', {
+  ptybufnr = term_start('NONE', {
     term_name: 'debugged program',
     vertical: vvertical})
-  if ptybuf == 0
+  if ptybufnr == 0
     Echoerr('Failed to open the program terminal window')
     return
   endif
-  var pty = job_info(term_getjob(ptybuf))['tty_out']
+  var pty = job_info(term_getjob(ptybufnr))['tty_out']
   ptywin = win_getid()
+
   if vvertical
     # Assuming the source code window will get a signcolumn, use two more
     # columns for that, thus one less for the terminal window.
@@ -322,23 +375,26 @@ def StartDebug_term(dict: dict<any>)
   endif
 
   # Create a hidden terminal window to communicate with gdb
-  commbuf = term_start('NONE', {
+  commbufnr = term_start('NONE', {
     term_name: 'gdb communication',
     out_cb: function('CommOutput'),
     hidden: 1
   })
-  if commbuf == 0
+  if commbufnr == 0
     Echoerr('Failed to open the communication terminal window')
-    exe $'bwipe! {ptybuf}'
+    exe $'bwipe! {ptybufnr}'
     return
   endif
-  var commpty = job_info(term_getjob(commbuf))['tty_out']
+  var commpty = job_info(term_getjob(commbufnr))['tty_out']
 
+  # Start the gdb buffer
   var gdb_args = get(dict, 'gdb_args', [])
   var proc_args = get(dict, 'proc_args', [])
 
   var gdb_cmd = GetCommand()
 
+  gdbbufname = gdb_cmd[0]
+
   if exists('g:termdebug_config') && has_key(g:termdebug_config, 
'command_add_args')
     gdb_cmd = g:termdebug_config.command_add_args(gdb_cmd, pty)
   else
@@ -365,11 +421,11 @@ def StartDebug_term(dict: dict<any>)
   gdb_cmd += gdb_args
 
   ch_log($'executing "{join(gdb_cmd)}"')
-  gdbbuf = term_start(gdb_cmd, {
-    term_name: 'gdb',
-    term_finish: 'close',
-  })
-  if gdbbuf == 0
+  gdbbufnr = term_start(gdb_cmd, {
+        term_name: gdbbufname,
+        term_finish: 'close',
+        })
+  if gdbbufnr == 0
     Echoerr('Failed to open the gdb terminal window')
     CloseBuffers()
     return
@@ -380,14 +436,14 @@ def StartDebug_term(dict: dict<any>)
   var counter = 0
   var counter_max = 300
   var success = false
-  while success == false && counter < counter_max
-    if CheckGdbRunning() != 'ok'
-      # Failure. If NOK just return.
+  while !success && counter < counter_max
+    if !IsGdbStarted()
+      CloseBuffers()
       return
     endif
 
     for lnum in range(1, 200)
-      if term_getline(gdbbuf, lnum) =~ 'startupdone'
+      if term_getline(gdbbufnr, lnum) =~ 'startupdone'
         success = true
       endif
     endfor
@@ -397,7 +453,7 @@ def StartDebug_term(dict: dict<any>)
     sleep 10m
   endwhile
 
-  if success == false
+  if !success
     Echoerr('Failed to startup the gdb program.')
     CloseBuffers()
     return
@@ -406,30 +462,30 @@ def StartDebug_term(dict: dict<any>)
   # ---- gdb started. Next, let's set the MI interface. ---
   # Set arguments to be run.
   if len(proc_args)
-    term_sendkeys(gdbbuf, $"server set args {join(proc_args)}
")
+    term_sendkeys(gdbbufnr, $"server set args {join(proc_args)}
")
   endif
 
   # Connect gdb to the communication pty, using the GDB/MI interface.
   # Prefix "server" to avoid adding this to the history.
-  term_sendkeys(gdbbuf, $"server new-ui mi {commpty}
")
+  term_sendkeys(gdbbufnr, $"server new-ui mi {commpty}
")
 
   # Wait for the response to show up, users may not notice the error and wonder
   # why the debugger doesn't work.
   counter = 0
   counter_max = 300
   success = false
-  while success == false && counter < counter_max
-    if CheckGdbRunning() != 'ok'
+  while !success && counter < counter_max
+    if !IsGdbStarted()
       return
     endif
 
     var response = ''
     for lnum in range(1, 200)
-      var line1 = term_getline(gdbbuf, lnum)
-      var line2 = term_getline(gdbbuf, lnum + 1)
+      var line1 = term_getline(gdbbufnr, lnum)
+      var line2 = term_getline(gdbbufnr, lnum + 1)
       if line1 =~ 'new-ui mi '
         # response can be in the same line or the next line
-        response = line1 .. line2
+        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
@@ -452,12 +508,12 @@ def StartDebug_term(dict: dict<any>)
     sleep 10m
   endwhile
 
-  if success == false
+  if !success
     Echoerr('Cannot check if your gdb works, continuing anyway')
     return
   endif
 
-  job_setoptions(term_getjob(gdbbuf), {exit_cb: function('EndTermDebug')})
+  job_setoptions(term_getjob(gdbbufnr), {exit_cb: function('EndTermDebug')})
 
   # Set the filetype, this can be used to add mappings.
   set filetype=termdebug
@@ -531,23 +587,24 @@ def StartDebug_prompt(dict: dict<any>)
   set modified
   gdb_channel = job_getchannel(gdbjob)
 
-  ptybuf = 0
+  ptybufnr = 0
   if has('win32')
     # MS-Windows: run in a new console window for maximum compatibility
     SendCommand('set new-console on')
   elseif has('terminal')
     # Unix: Run the debugged program in a terminal window.  Open it below the
     # gdb window.
-    belowright ptybuf = term_start('NONE', {
+    belowright ptybufnr = term_start('NONE', {
       term_name: 'debugged program',
+      vertical: vvertical
     })
-    if ptybuf == 0
+    if ptybufnr == 0
       Echoerr('Failed to open the program terminal window')
       job_stop(gdbjob)
       return
     endif
     ptywin = win_getid()
-    var pty = job_info(term_getjob(ptybuf))['tty_out']
+    var pty = job_info(term_getjob(ptybufnr))['tty_out']
     SendCommand($'tty {pty}')
 
     # Since GDB runs in a prompt window, the environment has not been set to
@@ -615,7 +672,7 @@ def SendCommand(cmd: string)
   if way == 'prompt'
     ch_sendraw(gdb_channel, $"{cmd}
")
   else
-    term_sendkeys(commbuf, $"{cmd}
")
+    term_sendkeys(commbufnr, $"{cmd}
")
   endif
 enddef
 
@@ -652,7 +709,7 @@ def TermDebugSendCommand(cmd: string)
       sleep 10m
     endif
     # TODO: should we prepend CTRL-U to clear the command?
-    term_sendkeys(gdbbuf, $"{cmd}
")
+    term_sendkeys(gdbbufnr, $"{cmd}
")
     if do_continue
       ContinueCommand()
     endif
@@ -665,7 +722,7 @@ enddef
 def SendResumingCommand(cmd: string)
   if stopped
     # reset stopped here, it may take a bit of time before we get a response
-    stopped = 0
+    stopped = false
     ch_log('assume that program is running after this command')
     SendCommand(cmd)
   else
@@ -715,9 +772,9 @@ def GdbOutCallback(channel: channel, text: string)
   var decoded_text = ''
   if text =~ '^\^error,msg='
     decoded_text = DecodeMessage(text[11 : ], false)
-    if exists('evalexpr') && decoded_text =~ 'A syntax error in expression, 
near\|No symbol .* in current context'
+    if !empty(evalexpr) && decoded_text =~ 'A syntax error in expression, 
near\|No symbol .* in current context'
       # Silently drop evaluation errors.
-      evalexpr = null_string
+      evalexpr = ''
       return
     endif
   elseif text[0] == '~'
@@ -739,9 +796,9 @@ enddef
 
 # Decode a message from gdb.  "quotedText" starts with a ", return the text up
 # to the next unescaped ", unescaping characters:
-# - remove line breaks (unless "literal" is v:true)
+# - remove line breaks (unless "literal" is true)
 # - change \" to "
-# - change \t to        (unless "literal" is v:true)
+# - change \t to        (unless "literal" is true)
 # - change 
 # - change \ooo to octal
 # - change \ to \
@@ -751,19 +808,20 @@ def DecodeMessage(quotedText: string, literal: bool): 
string
     return ''
   endif
   var msg = quotedText
-        \ ->substitute('^"\|[^\]\zs".*', '', 'g')
-        \ ->substitute('\"', '"', 'g')
+        ->substitute('^"\|[^\]\zs".*', '', 'g')
+        ->substitute('\"', '"', 'g')
         #\ multi-byte characters arrive in octal form
         #\ NULL-values must be kept encoded as those break the string otherwise
-        \ ->substitute('\000', NullRepl, 'g')
-        \ ->substitute('\\(\o\o\o\)', (m) => nr2char(str2nr(m[1], 8)), 'g')
+        ->substitute('\000', NullRepl, 'g')
+        ->substitute('\\(\o\o\o\)', (m) => nr2char(str2nr(m[1], 8)), 'g')
+        # You could also  use ->substitute('\\\(\o\o\o\)', 
'\=nr2char(str2nr(submatch(1), 8))', "g")
         #\ Note: GDB docs also mention hex encodings - the translations below 
work
         #\       but we keep them out for performance-reasons until we 
actually see
         #\       those in mi-returns
         #\ \ ->substitute('\0x\(\x\x\)', {-> eval('"\x' .. submatch(1) .. 
'"')}, 'g')
         #\ \ ->substitute('\0x00', NullRepl, 'g')
-        \ ->substitute('\\', '\', 'g')
-        \ ->substitute(NullRepl, '\000', 'g')
+        ->substitute('\\', '\', 'g')
+        ->substitute(NullRepl, '\000', 'g')
   if !literal
     return msg
       ->substitute('\t', "     ", 'g')
@@ -805,8 +863,8 @@ def EndTermDebug(job: any, status: any)
     doauto <nomodeline> User TermdebugStopPre
   endif
 
-  if bufexists(commbuf)
-    exe $'bwipe! {commbuf}'
+  if commbufnr > 0 && bufexists(commbufnr)
+    exe $'bwipe! {commbufnr}'
   endif
   gdbwin = 0
   EndDebugCommon()
@@ -815,16 +873,16 @@ enddef
 def EndDebugCommon()
   var curwinid = win_getid()
 
-  if bufexists(ptybuf)
-    exe $'bwipe! {ptybuf}'
+  if ptybufnr > 0 && bufexists(ptybufnr)
+    exe $'bwipe! {ptybufnr}'
   endif
-  if bufexists(asmbuf)
-    exe $'bwipe! {asmbuf}'
+  if asmbufnr > 0 && bufexists(asmbufnr)
+    exe $'bwipe! {asmbufnr}'
   endif
-  if bufexists(varbuf)
-    exe $'bwipe! {varbuf}'
+  if varbufnr > 0 && bufexists(varbufnr)
+    exe $'bwipe! {varbufnr}'
   endif
-  running = 0
+  running = false
 
   # Restore 'signcolumn' in all buffers for which it was set.
   win_gotoid(sourcewin)
@@ -932,11 +990,11 @@ def HandleDisasmMsg(msg: string)
     endif
   elseif msg !~ '^&"disassemble'
     var value = substitute(msg, '^\~\"[ ]*', '', '')
-    value = substitute(value, '^=>[ ]*', '', '')
-    value = substitute(value, '\n\"
$', '', '')
-    value = substitute(value, '\n\"$', '', '')
-    value = substitute(value, '
', '', '')
-    value = substitute(value, '\t', ' ', 'g')
+     ->substitute('^=>[ ]*', '', '')
+     ->substitute('\n\"
$', '', '')
+     ->substitute('\n\"$', '', '')
+     ->substitute('
', '', '')
+     ->substitute('\t', ' ', 'g')
 
     if value != '' || !empty(asm_lines)
       add(asm_lines, value)
@@ -1248,7 +1306,7 @@ def Until(at: string)
 
   if stopped
     # reset stopped here, it may take a bit of time before we get a response
-    stopped = 0
+    stopped = false
     ch_log('assume that program is running after this command')
 
     # Use the fname:lnum format
@@ -1379,8 +1437,8 @@ enddef
 # :Evaluate - evaluate what is specified / under the cursor
 def Evaluate(range: number, arg: string)
   var expr = GetEvaluationExpression(range, arg)
-  #echom $"expr: {expr}"
-  ignoreEvalError = 0
+  echom $"expr: {expr}"
+  ignoreEvalError = false
   SendEval(expr)
 enddef
 
@@ -1435,21 +1493,20 @@ enddef
 
 def HandleEvaluate(msg: string)
   var value = msg
-        \ ->substitute('.*value="\(.*\)"', ' ', '')
-        \ ->substitute('\"', '"', 'g')
-        \ ->substitute('\\', '\', 'g')
+        ->substitute('.*value="\(.*\)"', ' ', '')
+        ->substitute('\"', '"', 'g')
+        ->substitute('\\', '\', 'g')
         #\ multi-byte characters arrive in octal form, replace everything but 
NULL values
-        \ ->substitute('\000', NullRepl, 'g')
-        # \ ->substitute('\\o\o\o', {-> eval('"' .. submatch(0) .. '"')}, 'g')
-        \ ->substitute('\\(\o\o\o\)', (m) => nr2char(str2nr(m[1], 8)), 'g')
+        ->substitute('\000', NullRepl, 'g')
+        ->substitute('\\(\o\o\o\)', (m) => nr2char(str2nr(m[1], 8)), 'g')
         #\ Note: GDB docs also mention hex encodings - the translations below 
work
         #\       but we keep them out for performance-reasons until we 
actually see
         #\       those in mi-returns
         #\ ->substitute('\0x00', NullRep, 'g')
         #\ ->substitute('\0x\(\x\x\)', {-> eval('"\x' .. submatch(1) .. '"')}, 
'g')
-        \ ->substitute(NullRepl, '\000', 'g')
+        ->substitute(NullRepl, '\000', 'g')
   if evalFromBalloonExpr
-    if evalFromBalloonExprResult == ''
+    if empty(evalFromBalloonExprResult)
       evalFromBalloonExprResult = $'{evalexpr}: {value}'
     else
       evalFromBalloonExprResult ..= $' = {value}'
@@ -1461,10 +1518,10 @@ def HandleEvaluate(msg: string)
 
   if evalexpr[0] != '*' && value =~ '^0x' && value != '0x0' && value !~ '"$'
     # Looks like a pointer, also display what it points to.
-    ignoreEvalError = 1
+    ignoreEvalError = true
     SendEval($'*{evalexpr}')
   else
-    evalFromBalloonExpr = 0
+    evalFromBalloonExpr = false
   endif
 enddef
 
@@ -1480,9 +1537,9 @@ def TermDebugBalloonExpr(): string
     # mouse triggers a balloon.
     return ''
   endif
-  evalFromBalloonExpr = 1
+  evalFromBalloonExpr = true
   evalFromBalloonExprResult = ''
-  ignoreEvalError = 1
+  ignoreEvalError = true
   var expr = CleanupExpr(v:beval_text)
   SendEval(expr)
   return ''
@@ -1492,8 +1549,8 @@ enddef
 def HandleError(msg: string)
   if ignoreEvalError
     # Result of SendEval() failed, ignore.
-    ignoreEvalError = 0
-    evalFromBalloonExpr = 0
+    ignoreEvalError = false
+    evalFromBalloonExpr = true
     return
   endif
   var msgVal = substitute(msg, '.*msg="\(.*\)"', ' ', '')
@@ -1554,11 +1611,11 @@ def GotoAsmwinOrCreateIt()
     setlocal signcolumn=no
     setlocal modifiable
 
-    if asmbuf > 0 && bufexists(asmbuf)
-      exe $'buffer {asmbuf}'
+    if asmbufnr > 0 && bufexists(asmbufnr)
+      exe $'buffer {asmbufnr}'
     elseif empty(glob('Termdebug-asm-listing'))
       silent file Termdebug-asm-listing
-      asmbuf = bufnr('Termdebug-asm-listing')
+      asmbufnr = bufnr('Termdebug-asm-listing')
     else
       Echoerr("You have a file/folder named 'Termdebug-asm-listing'. " ..
               "Please exit and rename it because Termdebug may not work " ..
@@ -1628,11 +1685,11 @@ def GotoVariableswinOrCreateIt()
     setlocal signcolumn=no
     setlocal modifiable
 
-    if varbuf > 0 && bufexists(varbuf)
-      exe $'buffer {varbuf}'
+    if varbufnr > 0 && bufexists(varbufnr)
+      exe $'buffer {varbufnr}'
     elseif empty(glob('Termdebug-variables-listing'))
       silent file Termdebug-variables-listing
-      varbuf = bufnr('Termdebug-variables-listing')
+      varbufnr = bufnr('Termdebug-variables-listing')
     else
       Echoerr("You have a file/folder named 'Termdebug-variables-listing'. " ..
               "Please exit and rename it because Termdebug may not work " ..
@@ -1658,12 +1715,12 @@ def HandleCursor(msg: string)
     ch_log('program stopped')
     stopped = 1
     if msg =~ '^\*stopped,reason="exited-normally"'
-      running = 0
+      running = false
     endif
   elseif msg =~ '^\*running'
     ch_log('program running')
-    stopped = 0
-    running = 1
+    stopped = false
+    running = true
   endif
 
   var fname = ''
@@ -1692,7 +1749,7 @@ def HandleCursor(msg: string)
     endif
   endif
 
-  if running && stopped && bufwinnr('Termdebug-variables-listing') != -1
+  if running && stopped && bufwinnr(varbufname) != -1
     SendCommand('-stack-list-variables 2')
   endif
 
@@ -1709,13 +1766,13 @@ def HandleCursor(msg: string)
           au SwapExists * echohl WarningMsg
             | echo 'Warning: file is being edited elsewhere'
             | echohl None
-            | let v:swapchoice = 'o'
+            | v:swapchoice = 'o'
         augroup END
         if &modified
           # TODO: find existing window
           exe $'split {fnameescape(fname)}'
           sourcewin = win_getid()
-          call InstallWinbar(0)
+          InstallWinbar(0)
         else
           exe $'edit {fnameescape(fname)}'
         endif
diff --git a/src/testdir/test_termdebug.vim b/src/testdir/test_termdebug.vim
index 62cafccb6..a9762df8a 100644
--- a/src/testdir/test_termdebug.vim
+++ b/src/testdir/test_termdebug.vim
@@ -338,5 +338,16 @@ func Test_termdebug_bufnames()
   unlet g:termdebug_config
 endfunc
 
+function Test_termdebug_save_restore_variables()
+  let &mousemodel=''
+  Termdebug
+  call WaitForAssert({-> assert_equal(3, winnr('$'))})
+  call WaitForAssert({-> assert_match(&mousemodel, 'popup_setpos')})
+  wincmd t
+  quit!
+  call WaitForAssert({-> assert_equal(1, winnr('$'))})
+  call WaitForAssert({-> assert_true(empty(&mousemodel))})
+endfunction
+
 
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index 1360d1cfc..43a09d308 100644
--- a/src/version.c
+++ b/src/version.c
@@ -704,6 +704,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    482,
 /**/
     481,
 /**/

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/E1sHoH4-00Apj8-EI%40256bit.org.

Raspunde prin e-mail lui