patch 8.0.1309: cannot use 'balloonexpr' in a terminal

Problem:    Cannot use 'balloonexpr' in a terminal.
Solution:   Add 'balloonevalterm' and add code to handle mouse movements in a
            terminal. Initial implementation for Unix with GUI.
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index b9e82d7..f9acff8 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -1,4 +1,4 @@
-*options.txt*	For Vim version 8.0.  Last change: 2017 Nov 11
+*options.txt*	For Vim version 8.0.  Last change: 2017 Nov 18
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -1127,7 +1127,16 @@
 			{not in Vi}
 			{only available when compiled with the |+balloon_eval|
 			feature}
-	Switch on the |balloon-eval| functionality.
+	Switch on the |balloon-eval| functionality for the GUI.
+
+		       *'balloonevalterm'* *'bevalterm'* *'noballoonevalterm'*
+		       *'nobevalterm'*
+'balloonevalterm' 'bevalterm'	boolean	(default off)
+			global
+			{not in Vi}
+			{only available when compiled with the
+			|+balloon_eval_term| feature}
+	Switch on the |balloon-eval| functionality for the terminal.
 
 						     *'balloonexpr'* *'bexpr'*
 'balloonexpr' 'bexpr'	string	(default "")
@@ -3521,6 +3530,8 @@
 	systems without an fsync() implementation, this variable is always
 	off.
 	Also see 'swapsync' for controlling fsync() on swap files.
+	'fsync' also applies to |writefile()|, unless a flag is used to
+	overrule it.
 
 				   *'gdefault'* *'gd'* *'nogdefault'* *'nogd'*
 'gdefault' 'gd'		boolean	(default off)
@@ -3944,7 +3955,7 @@
 		toolbar, tabline, etc.  Instead, the behavior is similar to
 		when the window is maximized and will adjust 'lines' and
 		'columns' to fit to the window.  Without the 'k' flag Vim will
-		try to keep 'lines' and 'columns the same when adding and
+		try to keep 'lines' and 'columns' the same when adding and
 		removing GUI components.
 
 						*'guipty'* *'noguipty'*
@@ -8221,7 +8232,7 @@
 	number, more intelligent detection process runs.
 	The "xterm2" value will be set if the xterm version is reported to be
 	from 95 to 276.  The "sgr" value will be set if the xterm version is
-	277 or highter.
+	277 or highter and when Vim detects Mac Terminal.app or Iterm2.
 	If you do not want 'ttymouse' to be set to "xterm2" or "sgr"
 	automatically, set t_RV to an empty string: >
 		:set t_RV=
diff --git a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim
index 635bf93..1c3c9df 100644
--- a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim
+++ b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim
@@ -69,6 +69,11 @@
   endif
   let pty = job_info(term_getjob(s:ptybuf))['tty_out']
   let s:ptywin = win_getid(winnr())
+  if vertical
+    " Assuming the source code window will get a signcolumn, use two more
+    " columns for that, thus one less for the terminal window.
+    exe (&columns / 2 - 1) . "wincmd |"
+  endif
 
   " Create a hidden terminal window to communicate with gdb
   let s:commbuf = term_start('NONE', {
@@ -121,6 +126,15 @@
   call s:InstallCommands()
   call win_gotoid(s:gdbwin)
 
+  " Enable showing a balloon with eval info
+  if has("balloon_eval")
+    set ballooneval
+    set balloonexpr=TermDebugBalloonExpr()
+    if has("balloon_eval_term")
+      set balloonevalterm
+    endif
+  endif
+
   let s:breakpoints = {}
 
   augroup TermDebug
@@ -144,6 +158,14 @@
     let &columns = s:save_columns
   endif
 
+  if has("balloon_eval")
+    set noballooneval
+    set balloonexpr=
+    if has("balloon_eval_term")
+      set noballoonevalterm
+    endif
+  endif
+
   au! TermDebug
 endfunc
 
@@ -279,6 +301,11 @@
   call s:SendCommand('-exec-run')
 endfunc
 
+func s:SendEval(expr)
+  call s:SendCommand('-data-evaluate-expression "' . a:expr . '"')
+  let s:evalexpr = a:expr
+endfunc
+
 " :Evaluate - evaluate what is under the cursor
 func s:Evaluate(range, arg)
   if a:arg != ''
@@ -294,25 +321,54 @@
   else
     let expr = expand('<cexpr>')
   endif
-  call s:SendCommand('-data-evaluate-expression "' . expr . '"')
-  let s:evalexpr = expr
+  call s:SendEval(expr)
 endfunc
 
+let s:evalFromBalloonExpr = 0
+
 " Handle the result of data-evaluate-expression
 func s:HandleEvaluate(msg)
   let value = substitute(a:msg, '.*value="\(.*\)"', '\1', '')
   let value = substitute(value, '\\"', '"', 'g')
-  echomsg '"' . s:evalexpr . '": ' . value
+  if s:evalFromBalloonExpr
+    if s:evalFromBalloonExprResult == ''
+      let s:evalFromBalloonExprResult = s:evalexpr . ': ' . value
+    else
+      let s:evalFromBalloonExprResult .= ' = ' . value
+    endif
+    call balloon_show(s:evalFromBalloonExprResult)
+  else
+    echomsg '"' . s:evalexpr . '": ' . value
+  endif
 
   if s:evalexpr[0] != '*' && value =~ '^0x' && value != '0x0' && value !~ '"$'
     " Looks like a pointer, also display what it points to.
-    let s:evalexpr = '*' . s:evalexpr
-    call term_sendkeys(s:commbuf, '-data-evaluate-expression "' . s:evalexpr . "\"\r")
+    call s:SendEval('*' . s:evalexpr)
+  else
+    let s:evalFromBalloonExpr = 0
   endif
 endfunc
 
+" Show a balloon with information of the variable under the mouse pointer,
+" if there is any.
+func TermDebugBalloonExpr()
+  if v:beval_winid != s:startwin
+    return
+  endif
+  call s:SendEval(v:beval_text)
+  let s:evalFromBalloonExpr = 1
+  let s:evalFromBalloonExprResult = ''
+  return ''
+endfunc
+
 " Handle an error.
 func s:HandleError(msg)
+  if a:msg =~ 'No symbol .* in current context'
+	\ || a:msg =~ 'Cannot access memory at address '
+	\ || a:msg =~ 'Attempt to use a type name as an expression'
+    " Result of s:SendEval() failed, ignore.
+    return
+  endif
   echoerr substitute(a:msg, '.*msg="\(.*\)"', '\1', '')
 endfunc