changeset 32971:ccfca4f03a2b

Some more missing changes :(
author Christian Brabandt <cb@256bit.org>
date Wed, 23 Aug 2023 19:56:02 +0200
parents 41154ccdb413
children e4851934751a
files runtime/doc/terminal.txt runtime/lang/menu_it_it.latin1.vim runtime/pack/dist/opt/termdebug/plugin/termdebug.vim runtime/syntax/cmake.vim runtime/syntax/crontab.vim src/charset.c src/drawline.c src/edit.c src/structs.h src/testdir/test_listlbr.vim src/testdir/test_listlbr_utf8.vim src/testdir/test_options.vim src/testdir/test_textprop.vim src/version.c
diffstat 14 files changed, 607 insertions(+), 166 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/doc/terminal.txt
+++ b/runtime/doc/terminal.txt
@@ -1,4 +1,4 @@
-*terminal.txt*	For Vim version 9.0.  Last change: 2023 Jun 28
+*terminal.txt*	For Vim version 9.0.  Last change: 2023 Aug 23
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -38,6 +38,7 @@ 6. Debugging				|terminal-debug|
       Example session				|termdebug-example|
       Stepping through code			|termdebug-stepping|
       Inspecting variables			|termdebug-variables|
+      Navigating stack frames			|termdebug-frames|
       Other commands				|termdebug-commands|
       Events					|termdebug-events|
       Prompt mode				|termdebug-prompt|
@@ -1376,6 +1377,18 @@ This is similar to using "print" in the 
 You can usually shorten `:Evaluate` to `:Ev`.
 
 
+Navigating stack frames ~
+				*termdebug-frames* *:Frame* *:Up* *:Down*
+ `:Frame` [frame]	select frame [frame], which is a frame number,
+			address, or function name (default: current frame)
+ `:Up` [count]		go up [count] frames (default: 1; the frame that
+			called the current)
+ `+`			same (see |termdebug_map_plus| to disable)
+ `:Down` [count]	go down [count] frames (default: 1; the frame called
+			by the current)
+ `-`			same (see |termdebug_map_minus| to disable)
+
+
 Other commands ~
 							*termdebug-commands*
  *:Gdb*	     jump to the gdb window
@@ -1449,11 +1462,19 @@ If there is no g:termdebug_config you ca
 	let g:termdebug_use_prompt = 1
 <
 						*termdebug_map_K*
-The K key is normally mapped to :Evaluate. If you do not want this use: >
+The K key is normally mapped to |:Evaluate|. If you do not want this use: >
 	let g:termdebug_config['map_K'] = 0
 If there is no g:termdebug_config you can use: >
 	let g:termdebug_map_K = 0
 <
+						*termdebug_map_minus*
+The - key is normally mapped to |:Down|. If you do not want this use: >
+	let g:termdebug_config['map_minus'] = 0
+<
+						*termdebug_map_plus*
+The + key is normally mapped to |:Up|. If you do not want this use: >
+	let g:termdebug_config['map_plus'] = 0
+<
 						*termdebug_disasm_window*
 If you want the Asm window shown by default, set the "disasm_window" flag to
 1.  The "disasm_window_height" entry can be used to set the window height: >
--- a/runtime/lang/menu_it_it.latin1.vim
+++ b/runtime/lang/menu_it_it.latin1.vim
@@ -2,7 +2,7 @@
 " Maintainer:		Antonio Colombo <azc100@gmail.com>
 "			Vlad Sandrini <vlad.gently@gmail.com>
 "			Luciano Montanaro <mikelima@cirulla.net>
-" Last Change:	2022 Jun 17
+" Last Change:	2023 Aug 22
 " Original translations
 
 " Quit when menu translations have already been done.
@@ -20,7 +20,7 @@ menut &Help			&Aiuto
 
 menut &Overview<Tab><F1>	&Panoramica<Tab><F1>
 menut &User\ Manual		Manuale\ &Utente
-menut &How-to\ links	Co&Me\.\.\.
+menut &How-To\ Links	Co&Me\.\.\.
 menut &Find\.\.\.	&Cerca\.\.\.
 menut &Credits		Cr&Editi
 menut Co&pying		C&Opie
@@ -29,7 +29,7 @@ menut O&rphans		O&Rfani
 menut &Version		&Versione
 menut &About		&Intro
 
-let g:menutrans_help_dialog = "Batti un comando o una parola per cercare aiuto:\n\nPremetti i_ per comandi in modo Input (p.es.: i_CTRL-X)\nPremetti c_ per comandi che editano la linea-comandi (p.es.: c_<Del>)\nPremetti ' per un nome di opzione (p.es.: 'shiftwidth')"
+let g:menutrans_help_dialog = "Batti un comando o una parola per cercare aiuto su:\n\nPremetti i_ per comandi in modo Input (p.es.: i_CTRL-X)\nPremetti c_ per comandi che editano la linea-comandi (p.es.: c_<Del>)\nPremetti ' per un nome di opzione (p.es.: 'shiftwidth')"
 
 " File / File
 menut &File				&File
@@ -68,7 +68,6 @@ menut Find\ and\ Rep&lace\.\.\.<Tab>:s	&
 menut Settings\ &Window			&Finestra\ Impostazioni
 menut Startup\ &Settings		Impostazioni\ di\ &Avvio
 menut &Global\ Settings			Impostazioni\ &Globali
-menut Question				Domanda
 
 " Edit / Modifica / Impostazioni Globali
 
@@ -80,7 +79,7 @@ menut &Context\ lines		&Linee\ di\ conte
 
 menut &Virtual\ Edit		&Edit\ virtuale
 menut Never			Mai
-menut Block\ Selection		Selezione\ Blocco
+menut Block\ Selection		Seleziona\ Blocco
 menut Insert\ mode		Modo\ Insert
 menut Block\ and\ Insert	Selezione\ Blocco\ e\ Inserimento
 menut Always			Sempre
@@ -167,7 +166,7 @@ menut &File\ Format\.\.\.				Formato\ &F
 
 let g:menutrans_textwidth_dialog = "Batti nuova lunghezza linea (0 per inibire la formattazione): "
 let g:menutrans_fileformat_dialog = "Scegli formato con cui scrivere il file"
-let g:menutrans_fileformat_choices = " &Unix \n &Dos \n &Mac \n &Annullare "
+let g:menutrans_fileformat_choices = " &Unix\n&Dos\n&Mac\n&Annullare "
 
 menut Show\ C&olor\ Schemes\ in\ Menu	Mostra\ Schemi\ C&olore\ in\ Menù
 menut C&olor\ Scheme		Schema\ c&Olori
@@ -180,8 +179,12 @@ menut evening		sera
 menut industry		industria
 menut morning		mattino
 menut peachpuff		pesca
+menut quiet		quieto
 menut shine		brillante
+menut sorbet		sorbetto
 menut slate		ardesia
+menut torte		torta
+menut wildcharm		fascino\ selvaggio
 menut BLUE		BLÙ
 menut DARKBLUE		BLÙ\ SCURO
 menut DESERT		DESERTO
@@ -190,8 +193,12 @@ menut EVENING		SERA
 menut INDUSTRY		INDUSTRIA
 menut MORNING		MATTINO
 menut PEACHPUFF		PESCA
+menut QUIET		QUIETO
 menut SHINE		BRILLANTE
+menut SORBET		SORBETTO
 menut SLATE		ARDESIA
+menut TORTE		TORTA
+menut WILDCHARM		FASCINO\ SELVAGGIO
 
 menut Show\ &Keymaps\ in\ Menu	Mostra\ Ma&ppe\ tastiera\ in\ Menù
 menut &Keymap			Ma&ppa\ tastiera
@@ -202,29 +209,105 @@ menut arabic			arabo
 menut armenian-eastern		armeno-orientale
 menut armenian-western		armeno-occidentale
 menut belarusian-jcuken		bielorusso-jcuken
+menut bulgarian-bds		bulgaro-bds
+menut bulgarian-phonetic	bulgaro-fonetico
+menut canfr-win			franco-canadese-win
+menut croatian			croato
 menut czech			ceco
+menut dvorak			tastiera-dvorak
+menut esperanto			esperanto
+menut french-azerty		francese-azerty
+menut german-qwertz		tedesco-qwertz
 menut greek			greco
 menut hebrew			ebraico
 menut hebrewp			ebraicop
+menut kana			kana
+menut kazakh-jcuken		kazako-jcuken
+menut korean			coreano
+menut korean-dubeolsik		coreano-dubeolsik
+menut lithuanian-baltic		lituano-baltico
 menut magyar			ungherese
+menut mongolian			mongolo
+menut oldturkic-orkhon		turco-antico-orkhon
+menut oldturkic-yenisei		turco-antico-yenisei
 menut persian			persiano
+menut persian-iranian		persiano-iraniano
+menut pinyin			pinyin
+menut polish-slash		polacco-slash
+menut russian-dvorak		russo-dvorak
+menut russian-jcuken		russo-jcuken
+menut russian-jcukenmac		russo-jcukenmac
+menut russian-jcukenwin		russo-jcukenwin
+menut russian-jcukenwintype	russo-jcukenwintype
+menut russian-typograph		russo-tipografico
+menut russian-yawerty		russo-yawerty
 menut serbian			serbo
 menut serbian-latin		serbo-latino
+menut sinhala			singalese
+menut sinhala-phonetic		singalese-phonetic
 menut slovak			slovacco
+menut tamil			tamil
+menut thaana			thaana
+menut thaana-phonetic		thaana-fonetico
+menut turkish-f			turco-f
+menut turkish-q			turco-q
+menut ukrainian-dvorak		ukraino-dvorak
+menut ukrainian-jcuken		ukraino-jcuken
+menut vietnamese-telex		vietnamita-telex
+menut vietnamese-viqr		vietnamita-viqr
+menut vietnamese-vni		vietnamita-vni
 menut ACCENTS			ACCENTI
 menut ARABIC			ARABO
 menut ARMENIAN-EASTERN		ARMENO-ORIENTALE
 menut ARMENIAN-WESTERN		ARMENO-OCCIDENTALE
 menut BELARUSIAN-JCUKEN		BIELORUSSO-JCUKEN
+menut BULGARIAN-BDS		BULGARO-BDS
+menut BULGARIAN-PHONETIC	BULGARO-FONETICO
+menut CANFR-WIN			FRANCO-CANADESE-WIN
+menut CROATIAN			CROATO
 menut CZECH			CECO
+menut DVORAK			TASTIERA-DVORAK
+menut ESPERANTO			ESPERANTO
+menut FRENCH-AZERTY		FRANCESE-AZERTY
+menut GERMAN-QWERTZ		TEDESCO-QWERTZ
 menut GREEK			GRECO
 menut HEBREW			EBRAICO
 menut HEBREWP			EBRAICOP
+menut KANA			KANA
+menut KAZAKH-JCUKEN		KAZAKO-JCUKEN
+menut KOREAN			COREANO
+menut KOREAN-DUBEOLSIK		COREANO-DUBEOLSIK
+menut LITHUANIAN-BALTIC		LITUANO-BALTICO
 menut MAGYAR			UNGHERESE
+menut MONGOLIAN			MONGOLO
+menut OLDTURKIC-ORKHON		TURCO-ANTICO-ORKHON
+menut OLDTURKIC-YENISEI		TURCO-ANTICO-YENISEI
 menut PERSIAN			PERSIANO
+menut PERSIAN-IRANIAN		PERSIANO-IRANIANO
+menut PINYIN			PINYIN
+menut POLISH-SLASH		POLACCO-SLASH
+menut RUSSIAN-DVORAK		RUSSO-DVORAK
+menut RUSSIAN-JCUKEN		RUSSO-JCUKEN
+menut RUSSIAN-JCUKENMAC		RUSSO-JCUKENMAC
+menut RUSSIAN-JCUKENWIN		RUSSO-JCUKENWIN
+menut RUSSIAN-JCUKENWINTYPE	RUSSO-JCUKENWINTYPE
+menut RUSSIAN-TYPOGRAPH		RUSSO-TIPOGRAFICO
+menut RUSSIAN-YAWERTY		RUSSO-YAWERTY
 menut SERBIAN			SERBO
 menut SERBIAN-LATIN		SERBO-LATINO
+menut SINHALA			SINGALESE
+menut SINHALA-PHONETIC		SINGALESE-PHONETIC
 menut SLOVAK			SLOVACCO
+menut TAMIL			TAMIL
+menut THAANA			THAANA
+menut THAANA-PHONETIC		THAANA-FONETICO
+menut TURKISH-F			TURCO-F
+menut TURKISH-Q			TURCO-Q
+menut UKRAINIAN-DVORAK		UKRAINO-DVORAK
+menut UKRAINIAN-JCUKEN		UKRAINO-JCUKEN
+menut VIETNAMESE-TELEX		VIETNAMITA-TELEX
+menut VIETNAMESE-VIQR		VIETNAMITA-VIQR
+menut VIETNAMESE-VNI		VIETNAMITA-VNI
 
 menut Select\ Fo&nt\.\.\.		Scegli\ &Font\.\.\.
 
@@ -233,7 +316,7 @@ menut &Tools				&Strumenti
 
 menut &Jump\ to\ this\ tag<Tab>g^]	&Vai\ a\ questa\ tag<Tab>g^]
 menut Jump\ &back<Tab>^T		Torna\ &Indietro<Tab>^T
-menut Build\ &Tags\ File		Costruisci\ file\ &Tags\
+menut Build\ &Tags\ File		Costruisci\ file\ &Tag\
 " Menù ortografia / Spelling
 menut &Spelling			&Ortografia
 
@@ -243,6 +326,7 @@ menut To\ &Next\ error<Tab>]s		Errore\ &
 menut To\ &Previous\ error<Tab>[s	Errore\ &Precedente<tab>[s
 menut Suggest\ &Corrections<Tab>z=	&Suggerimenti<Tab>z=
 menut &Repeat\ correction<Tab>:spellrepall	&Ripeti\ correzione<Tab>:spellrepall
+menut Set\ language\ to			Imposta\ lingua\ a
 menut Set\ language\ to\ "en"		Imposta\ lingua\ a\ "en"
 menut Set\ language\ to\ "en_au"	Imposta\ lingua\ a\ "en_au"
 menut Set\ language\ to\ "en_ca"	Imposta\ lingua\ a\ "en_ca"
@@ -255,25 +339,25 @@ menut &Find\ More\ Languages		&Trova\ al
 menut &Folding					&Piegature
 " apri e chiudi piegature
 menut &Enable/Disable\ folds<Tab>zi		Pi&egature\ Sì/No<Tab>zi
-menut &View\ Cursor\ Line<Tab>zv			&Vedi\ linea\ col\ Cursore<Tab>zv
-menut Vie&w\ Cursor\ Line\ only<Tab>zMzx		Vedi\ &Solo\ linea\ col\ Cursore<Tab>zMzx
-menut C&lose\ more\ folds<Tab>zm			C&Hiudi\ più\ piegature<Tab>zm
-menut &Close\ all\ folds<Tab>zM			&Chiudi\ tutte\ le\ piegature<Tab>zM
-menut O&pen\ more\ folds<Tab>zr			A&Pri\ più\ piegature<Tab>zr
-menut &Open\ all\ folds<Tab>zR			&Apri\ tutte\ le\ piegature<Tab>zR
+menut &View\ Cursor\ Line<Tab>zv		&Vedi\ linea\ col\ Cursore<Tab>zv
+menut Vie&w\ Cursor\ Line\ only<Tab>zMzx	Vedi\ &Solo\ linea\ col\ Cursore<Tab>zMzx
+menut C&lose\ More\ folds<Tab>zm		C&Hiudi\ più\ piegature<Tab>zm
+menut &Close\ All\ folds<Tab>zM			&Chiudi\ tutte\ le\ piegature<Tab>zM
+menut O&pen\ More\ folds<Tab>zr			A&Pri\ più\ piegature<Tab>zr
+menut &Open\ All\ folds<Tab>zR			&Apri\ tutte\ le\ piegature<Tab>zR
 " metodo piegatura
 menut Fold\ Met&hod				Meto&Do\ piegatura
 menut M&anual					&Manuale
 menut I&ndent					&Nidificazione
-menut E&xpression					&Espressione\ Reg\.
+menut E&xpression				&Espressione\ Reg\.
 menut S&yntax					&Sintassi
 menut &Diff					&Differenza
 menut Ma&rker					Mar&Catura
 
 " crea e cancella piegature
 menut Create\ &Fold<Tab>zf			Crea\ &Piegatura<Tab>zf
-menut &Delete\ Fold<Tab>zd			&Leva\ piegatura<Tab>zd
-menut Delete\ &All\ Folds<Tab>zD			Leva\ &Tutte\ le\ piegature<Tab>zD
+menut &Delete\ Fold<Tab>zd			&Togli\ piegatura<Tab>zd
+menut Delete\ &All\ Folds<Tab>zD		Togli\ &Tutte\ le\ piegature<Tab>zD
 " movimenti all'interno delle piegature
 menut Fold\ col&umn\ width			Larghezza\ piegat&Ure\ in\ colonne
 
@@ -285,9 +369,9 @@ menut &Put\ Block				&Esporta\ differenz
 
 menut &Make<Tab>:make		Esegui\ &Make<Tab>:make
 
-menut &List\ Errors<Tab>:cl		Lista\ &Errori<Tab>:cl
+menut &List\ Errors<Tab>:cl	Lista\ &Errori<Tab>:cl
 menut L&ist\ Messages<Tab>:cl!	Lista\ &Messaggi<Tab>:cl!
-menut &Next\ Error<Tab>:cn		Errore\ s&Uccessivo<Tab>:cn
+menut &Next\ Error<Tab>:cn	Errore\ s&Uccessivo<Tab>:cn
 menut &Previous\ Error<Tab>:cp	Errore\ &Precedente<Tab>:cp
 menut &Older\ List<Tab>:cold	Lista\ men&O\ recente<Tab>:cold
 menut N&ewer\ List<Tab>:cnew	Lista\ più\ rece&Nte<Tab>:cnew
@@ -302,11 +386,12 @@ menut &Convert\ to\ HEX<Tab>:%!xxd	&Conv
 menut Conve&rt\ back<Tab>:%!xxd\ -r	Conve&rti\ da\ esadecimale<Tab>:%!xxd\ -r
 
 menut Se&T\ Compiler		Impo&Sta\ Compilatore
+menut Show\ Compiler\ Se&ttings\ in\ Menu	Mostra\ Impos&Tazioni\ Compilatore\ nel\ Menù
 
 " Buffers / Buffer
 menut &Buffers			&Buffer
 
-menut &Refresh\ menu		A&ggiorna\ menù
+menut &Refresh\ menu		A&Ggiorna\ menù
 menut &Delete			&Elimina
 menut &Alternate		&Alternato
 menut &Next			&Successivo
@@ -352,10 +437,10 @@ menut &Right\ side<Tab>^WL		Lato\ &Destr
 menut Rotate\ &Up<Tab>^WR		Ruota\ verso\ l'&Alto<Tab>^WR
 menut Rotate\ &Down<Tab>^Wr		Ruota\ verso\ il\ &Basso<Tab>^Wr
 menut &Equal\ Size<Tab>^W=		&Uguale\ ampiezza<Tab>^W=
-menut &Max\ Height<Tab>^W_		&Altezza\ massima<Tab>^W_
-menut M&in\ Height<Tab>^W1_		A&Ltezza\ minima<Tab>^W1_
-menut Max\ &Width<Tab>^W\|		Larghezza\ massima<Tab>^W\|
-menut Min\ Widt&h<Tab>^W1\|		Larghezza\ minima<Tab>^W1\|
+menut &Max\ Height<Tab>^W_		A&Ltezza\ massima<Tab>^W_
+menut M&in\ Height<Tab>^W1_		Al&Tezza\ minima<Tab>^W1_
+menut Max\ &Width<Tab>^W\|		Lar&Ghezza\ massima<Tab>^W\|
+menut Min\ Widt&h<Tab>^W1\|		Larg&hhezza\ minima<Tab>^W1\|
 
 " The popup menu
 menut &Undo		&Annulla
@@ -363,11 +448,13 @@ menut Cu&t		&Taglia
 menut &Copy		&Copia
 menut &Paste		&Incolla
 menut &Delete		&Elimina
-menut Select\ Blockwise 	Seleziona\ in\ blocco
+menut Select\ Blockwise 	Seleziona\ Blocco
 menut Select\ &Word		Seleziona\ &Parola
-menut Select\ &Line		Seleziona\ &Linea
+menut Select\ &Line		Seleziona\ &Riga
 menut Select\ &Block 		Seleziona\ &Blocco
-menut Select\ &All		Seleziona\ t&Utto
+menut Select\ &All		Seleziona\ &Tutto
+menut Select\ &Sentence		Seleziona\ &Frase
+menut Select\ Pa&ragraph	Seleziona\ Para&Grafo
 
 " The GUI Toolbar / Barra Strumenti
 menut Open		Apri
--- 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: 2023 Jun 24
+" Last Change: 2023 Aug 23
 "
 " WORK IN PROGRESS - The basics works stable, more to come
 " Note: In general you need at least GDB 7.12 because this provides the
@@ -229,13 +229,13 @@ endfunc
 func s:CloseBuffers()
   exe 'bwipe! ' . s:ptybuf
   exe 'bwipe! ' . s:commbuf
-  if s:asmbuf > 0
+  if s:asmbuf > 0 && bufexists(s:asmbuf)
     exe 'bwipe! ' . s:asmbuf
   endif
-  if s:varbuf > 0
+  if s:varbuf > 0 && bufexists(s:varbuf)
     exe 'bwipe! ' . s:varbuf
   endif
-  s:running = 0
+  let s:running = 0
   unlet! s:gdbwin
 endfunc
 
@@ -453,6 +453,8 @@ func s:StartDebug_prompt(dict)
     exe 'bwipe! ' . s:promptbuf
     return
   endif
+  exe $'au BufUnload <buffer={s:promptbuf}> ++once ' ..
+	\ 'call job_stop(s:gdbjob, ''kill'')'
   " Mark the buffer modified so that it's not easy to close.
   set modified
   let s:gdb_channel = job_getchannel(s:gdbjob)
@@ -617,9 +619,16 @@ endfunc
 func s:GdbOutCallback(channel, text)
   call ch_log('received from gdb: ' . a:text)
 
+  " Disassembly messages need to be forwarded as-is.
+  if s:parsing_disasm_msg
+    call s:CommOutput(a:channel, a:text)
+    return
+  end
+
   " Drop the gdb prompt, we have our own.
   " Drop status and echo'd commands.
-  if a:text == '(gdb) ' || a:text == '^done' || a:text[0] == '&'
+  if a:text == '(gdb) ' || a:text == '^done' ||
+	\ (a:text[0] == '&' && a:text !~ '^&"disassemble')
     return
   endif
   if a:text =~ '^\^error,msg='
@@ -647,8 +656,9 @@ func s:GdbOutCallback(channel, text)
 endfunc
 
 " Decode a message from gdb.  "quotedText" starts with a ", return the text up
-" to the next ", unescaping characters:
+" to the next unescaped ", unescaping characters:
 " - remove line breaks (unless "literal" is v:true)
+" - change \" to "
 " - change \\t to \t (unless "literal" is v:true)
 " - change \0xhh to \xhh (disabled for now)
 " - change \ooo to octal
@@ -659,24 +669,25 @@ func s:DecodeMessage(quotedText, literal
     return
   endif
   let msg = a:quotedText
-        \ ->substitute('^"\|".*', '', 'g')
-        " multi-byte characters arrive in octal form
-        " NULL-values must be kept encoded as those break the string otherwise
+        \ ->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', s:NullRepl, 'g')
         \ ->substitute('\\\o\o\o', {-> eval('"' .. submatch(0) .. '"')}, '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', s:NullRepl, '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', s:NullRepl, 'g')
         \ ->substitute('\\\\', '\', 'g')
         \ ->substitute(s:NullRepl, '\\000', 'g')
   if !a:literal
-          return msg
+    return msg
         \ ->substitute('\\t', "\t", 'g')
         \ ->substitute('\\n', '', 'g')
   else
-          return msg
+    return msg
   endif
 endfunc
 const s:NullRepl = 'XXXNULLXXX'
@@ -709,15 +720,7 @@ func s:EndTermDebug(job, status)
   endif
 
   exe 'bwipe! ' . s:commbuf
-  if s:asmbuf > 0
-    exe 'bwipe! ' . s:asmbuf
-  endif
-  if s:varbuf > 0
-    exe 'bwipe! ' . s:varbuf
-  endif
-  let s:running = 0
   unlet s:gdbwin
-
   call s:EndDebugCommon()
 endfunc
 
@@ -727,6 +730,13 @@ func s:EndDebugCommon()
   if exists('s:ptybuf') && s:ptybuf
     exe 'bwipe! ' . s:ptybuf
   endif
+  if s:asmbuf > 0 && bufexists(s:asmbuf)
+    exe 'bwipe! ' . s:asmbuf
+  endif
+  if s:varbuf > 0 && bufexists(s:varbuf)
+    exe 'bwipe! ' . s:varbuf
+  endif
+  let s:running = 0
 
   " Restore 'signcolumn' in all buffers for which it was set.
   call win_gotoid(s:sourcewin)
@@ -774,12 +784,8 @@ func s:EndPromptDebug(job, status)
     doauto <nomodeline> User TermdebugStopPre
   endif
 
-  let curwinid = win_getid()
-  call win_gotoid(s:gdbwin)
-  set nomodified
-  close
-  if curwinid != s:gdbwin
-    call win_gotoid(curwinid)
+  if bufexists(s:promptbuf)
+    exe 'bwipe! ' . s:promptbuf
   endif
 
   call s:EndDebugCommon()
@@ -789,7 +795,6 @@ endfunc
 
 " Disassembly window - added by Michael Sartain
 "
-" - CommOutput: disassemble $pc
 " - CommOutput: &"disassemble $pc\n"
 " - CommOutput: ~"Dump of assembler code for function main(int, char**):\n"
 " - CommOutput: ~"   0x0000555556466f69 <+0>:\tpush   rbp\n"
@@ -799,7 +804,6 @@ endfunc
 " - CommOutput: ~"End of assembler dump.\n"
 " - CommOutput: ^done
 
-" - CommOutput: disassemble $pc
 " - CommOutput: &"disassemble $pc\n"
 " - CommOutput: &"No function contains specified address.\n"
 " - CommOutput: ^error,msg="No function contains specified address."
@@ -831,12 +835,12 @@ func s:HandleDisasmMsg(msg)
       call s:SendCommand('disassemble $pc,+100')
     endif
     let s:parsing_disasm_msg = 0
-  elseif a:msg =~ '\&\"disassemble \$pc'
+  elseif a:msg =~ '^&"disassemble \$pc'
     if a:msg =~ '+100'
       " This is our second disasm attempt
       let s:parsing_disasm_msg = 2
     endif
-  else
+  elseif a:msg !~ '^&"disassemble'
     let value = substitute(a:msg, '^\~\"[ ]*', '', '')
     let value = substitute(value, '^=>[ ]*', '', '')
     let value = substitute(value, '\\n\"\r$', '', '')
@@ -920,9 +924,10 @@ func s:CommOutput(chan, msg)
         call s:HandleEvaluate(msg)
       elseif msg =~ '^\^error,msg='
         call s:HandleError(msg)
-      elseif msg =~ '^disassemble'
+      elseif msg =~ '^&"disassemble'
         let s:parsing_disasm_msg = 1
         let s:asm_lines = []
+	call s:HandleDisasmMsg(msg)
       elseif msg =~ '^\^done,variables='
 	call s:HandleVariablesMsg(msg)
       endif
@@ -965,6 +970,10 @@ func s:InstallCommands()
     command Continue call term_sendkeys(s:gdbbuf, "continue\r")
   endif
 
+  command -nargs=* Frame call s:Frame(<q-args>)
+  command -count=1 Up call s:Up(<count>)
+  command -count=1 Down call s:Down(<count>)
+
   command -range -nargs=* Evaluate call s:Evaluate(<range>, <q-args>)
   command Gdb call win_gotoid(s:gdbwin)
   command Program call s:GotoProgram()
@@ -984,6 +993,25 @@ func s:InstallCommands()
     nnoremap K :Evaluate<CR>
   endif
 
+  let map = 1
+  if exists('g:termdebug_config')
+    let map = get(g:termdebug_config, 'map_plus', 1)
+  endif
+  if map
+    let s:plus_map_saved = maparg('+', 'n', 0, 1)
+    nnoremap <expr> + $'<Cmd>{v:count1}Up<CR>'
+  endif
+
+  let map = 1
+  if exists('g:termdebug_config')
+    let map = get(g:termdebug_config, 'map_minus', 1)
+  endif
+  if map
+    let s:minus_map_saved = maparg('-', 'n', 0, 1)
+    nnoremap <expr> - $'<Cmd>{v:count1}Down<CR>'
+  endif
+
+
   if has('menu') && &mouse != ''
     call s:InstallWinbar(0)
 
@@ -1040,6 +1068,9 @@ func s:DeleteCommands()
   delcommand Arguments
   delcommand Stop
   delcommand Continue
+  delcommand Frame
+  delcommand Up
+  delcommand Down
   delcommand Evaluate
   delcommand Gdb
   delcommand Program
@@ -1056,6 +1087,22 @@ func s:DeleteCommands()
     endif
     unlet s:k_map_saved
   endif
+  if exists('s:plus_map_saved')
+    if empty(s:plus_map_saved)
+      nunmap +
+    else
+      call mapset(s:plus_map_saved)
+    endif
+    unlet s:plus_map_saved
+  endif
+  if exists('s:minus_map_saved')
+    if empty(s:minus_map_saved)
+      nunmap -
+    else
+      call mapset(s:minus_map_saved)
+    endif
+    unlet s:minus_map_saved
+  endif
 
   if has('menu')
     " Remove the WinBar entries from all windows where it was added.
@@ -1172,6 +1219,37 @@ func s:Run(args)
   call s:SendResumingCommand('-exec-run')
 endfunc
 
+" :Frame - go to a specfic frame in the stack
+func s:Frame(arg)
+  " Note: we explicit do not use mi's command
+  " call s:SendCommand('-stack-select-frame "' . a:arg .'"')
+  " as we only get a "done" mi response and would have to open the file
+  " 'manually' - using cli command "frame" provides us with the mi response
+  " already parsed and allows for more formats
+  if a:arg =~ '^\d\+$' || a:arg == ''
+    " specify frame by number
+    call s:SendCommand('-interpreter-exec mi "frame ' . a:arg .'"')
+  elseif a:arg =~ '^0x[0-9a-fA-F]\+$'
+    " specify frame by stack address
+    call s:SendCommand('-interpreter-exec mi "frame address ' . a:arg .'"')
+  else
+    " specify frame by function name
+    call s:SendCommand('-interpreter-exec mi "frame function ' . a:arg .'"')
+  endif
+endfunc
+
+" :Up - go a:count frames in the stack "higher"
+func s:Up(count)
+  " the 'correct' one would be -stack-select-frame N, but we don't know N
+  call s:SendCommand($'-interpreter-exec console "up {a:count}"')
+endfunc
+
+" :Down - go a:count frames in the stack "below"
+func s:Down(count)
+  " the 'correct' one would be -stack-select-frame N, but we don't know N
+  call s:SendCommand($'-interpreter-exec console "down {a:count}"')
+endfunc
+
 func s:SendEval(expr)
   " check for "likely" boolean expressions, in which case we take it as lhs
   if a:expr =~ "[=!<>]="
@@ -1358,7 +1436,7 @@ func s:GotoAsmwinOrCreateIt()
     setlocal signcolumn=no
     setlocal modifiable
 
-    if s:asmbuf > 0
+    if s:asmbuf > 0 && bufexists(s:asmbuf)
       exe 'buffer' . s:asmbuf
     else
       silent file Termdebug-asm-listing
@@ -1420,7 +1498,7 @@ func s:GotoVariableswinOrCreateIt()
     setlocal signcolumn=no
     setlocal modifiable
 
-    if s:varbuf > 0
+    if s:varbuf > 0 && bufexists(s:varbuf)
       exe 'buffer' . s:varbuf
     else
       silent file Termdebug-variables-listing
--- a/runtime/syntax/cmake.vim
+++ b/runtime/syntax/cmake.vim
@@ -335,7 +335,7 @@ syn keyword cmakeGeneratorExpressions co
 syn case ignore
 
 syn keyword cmakeCommand
-            \ add_compile_options add_custom_command add_custom_target add_definitions add_dependencies add_executable add_library add_subdirectory add_test aux_source_directory break build_command cmake_host_system_information cmake_minimum_required cmake_parse_arguments cmake_policy configure_file continue create_test_sourcelist ctest_build ctest_configure ctest_coverage ctest_empty_binary_directory ctest_memcheck ctest_read_custom_files ctest_run_script ctest_sleep ctest_start ctest_submit ctest_test ctest_update ctest_upload define_property enable_language enable_testing endfunction endmacro execute_process export file find_file find_library find_package find_path find_program fltk_wrap_ui function get_cmake_property get_directory_property get_filename_component get_property get_source_file_property get_target_property get_test_property include include_directories include_external_msproject include_guard include_regular_expression install link_directories list load_cache load_command macro mark_as_advanced math message option project qt_wrap_cpp qt_wrap_ui remove_definitions return separate_arguments set set_directory_properties set_property set_source_files_properties set_target_properties set_tests_properties site_name source_group string target_compile_definitions target_compile_features target_compile_options target_include_directories target_link_libraries target_sources try_compile try_run unset variable_watch
+            \ add_compile_options add_compile_definitions add_custom_command add_custom_target add_definitions add_dependencies add_executable add_library add_subdirectory add_test aux_source_directory break build_command cmake_host_system_information cmake_minimum_required cmake_parse_arguments cmake_policy configure_file continue create_test_sourcelist ctest_build ctest_configure ctest_coverage ctest_empty_binary_directory ctest_memcheck ctest_read_custom_files ctest_run_script ctest_sleep ctest_start ctest_submit ctest_test ctest_update ctest_upload define_property enable_language enable_testing endfunction endmacro execute_process export file find_file find_library find_package find_path find_program fltk_wrap_ui function get_cmake_property get_directory_property get_filename_component get_property get_source_file_property get_target_property get_test_property include include_directories include_external_msproject include_guard include_regular_expression install link_directories list load_cache load_command macro mark_as_advanced math message option project qt_wrap_cpp qt_wrap_ui remove_definitions return separate_arguments set set_directory_properties set_property set_source_files_properties set_target_properties set_tests_properties site_name source_group string target_compile_definitions target_compile_features target_compile_options target_include_directories target_link_libraries target_sources try_compile try_run unset variable_watch
             \ nextgroup=cmakeArguments
 
 syn keyword cmakeCommandConditional
--- a/runtime/syntax/crontab.vim
+++ b/runtime/syntax/crontab.vim
@@ -5,7 +5,7 @@
 " License: This file can be redistribued and/or modified under the same terms
 "   as Vim itself.
 " Filenames: /tmp/crontab.* used by "crontab -e"
-" Last Change: 2015-01-20
+" Last Change: 2022-09-22
 "
 " crontab line format:
 " Minutes   Hours   Days   Months   Days_of_Week   Commands # comments
@@ -15,20 +15,20 @@ if exists("b:current_syntax")
 	finish
 endif
 
-syntax match crontabNick "^\s*@\(reboot\|yearly\|annually\|monthly\|weekly\|daily\|midnight\|hourly\)\>" nextgroup=crontabCmd skipwhite
+syntax match crontabNick "^\s*@\(reboot\|yearly\|annually\|monthly\|weekly\|daily\|midnight\|hourly\|every_minute\|every_second\)\>" nextgroup=crontabCmd skipwhite
 
 syntax match crontabVar "^\s*\k\w*\s*="me=e-1
 
 syntax case ignore
 
-syntax match crontabMin "^\s*[-0-9/,.*]\+" nextgroup=crontabHr skipwhite
-syntax match crontabHr "\s[-0-9/,.*]\+" nextgroup=crontabDay skipwhite contained
-syntax match crontabDay "\s[-0-9/,.*]\+" nextgroup=crontabMnth skipwhite contained
+syntax match crontabMin "^\s*[-~0-9/,.*]\+" nextgroup=crontabHr skipwhite
+syntax match crontabHr "\s[-~0-9/,.*]\+" nextgroup=crontabDay skipwhite contained
+syntax match crontabDay "\s[-~0-9/,.*]\+" nextgroup=crontabMnth skipwhite contained
 
-syntax match crontabMnth "\s[-a-z0-9/,.*]\+" nextgroup=crontabDow skipwhite contained
+syntax match crontabMnth "\s[-~a-z0-9/,.*]\+" nextgroup=crontabDow skipwhite contained
 syntax keyword crontabMnth12 contained jan feb mar apr may jun jul aug sep oct nov dec
 
-syntax match crontabDow "\s[-a-z0-9/,.*]\+" nextgroup=crontabCmd skipwhite contained
+syntax match crontabDow "\s[-~a-z0-9/,.*]\+" nextgroup=crontabCmd skipwhite contained
 syntax keyword crontabDow7 contained sun mon tue wed thu fri sat
 
 syntax region crontabCmd start="\S" end="$" skipwhite contained keepend contains=crontabPercent
--- a/src/charset.c
+++ b/src/charset.c
@@ -1097,9 +1097,14 @@ lbr_chartabsize_adv(chartabsize_T *cts)
  * inserts text.
  * This function is used very often, keep it fast!!!!
  *
- * If "headp" not NULL, set *headp to the size of what we for 'showbreak'
- * string at start of line.  Warning: *headp is only set if it's a non-zero
- * value, init to 0 before calling.
+ * If "headp" not NULL, set "*headp" to the size of 'showbreak'/'breakindent'
+ * included in the return value.
+ * When "cts->cts_max_head_vcol" is positive, only count in "*headp" the size
+ * of 'showbreak'/'breakindent' before "cts->cts_max_head_vcol".
+ * When "cts->cts_max_head_vcol" is negative, only count in "*headp" the size
+ * of 'showbreak'/'breakindent' before where cursor should be placed.
+ *
+ * Warning: "*headp" may not be set if it's 0, init to 0 before calling.
  */
     int
 win_lbr_chartabsize(
@@ -1118,9 +1123,7 @@ win_lbr_chartabsize(
     colnr_T	col2;
     colnr_T	col_adj = 0; // vcol + screen size of tab
     colnr_T	colmax;
-    int		added;
     int		mb_added = 0;
-    int		numberextra;
     char_u	*ps;
     int		tab_corr = (*s == TAB);
     int		n;
@@ -1256,7 +1259,7 @@ win_lbr_chartabsize(
 	 * Count all characters from first non-blank after a blank up to next
 	 * non-blank after a blank.
 	 */
-	numberextra = win_col_off(wp);
+	int numberextra = win_col_off(wp);
 	col2 = vcol;
 	colmax = (colnr_T)(wp->w_width - numberextra - col_adj);
 	if (vcol >= colmax)
@@ -1296,72 +1299,93 @@ win_lbr_chartabsize(
     /*
      * May have to add something for 'breakindent' and/or 'showbreak'
      * string at start of line.
-     * Set *headp to the size of what we add.
      * Do not use 'showbreak' at the NUL after the text.
      */
-    added = 0;
+    int head = mb_added;
     sbr = (c == NUL || no_sbr) ? empty_option : get_showbreak_value(wp);
-    if ((*sbr != NUL || wp->w_p_bri) && wp->w_p_wrap && vcol != 0)
+    if ((*sbr != NUL || wp->w_p_bri) && wp->w_p_wrap)
     {
-	colnr_T sbrlen = 0;
-	int	numberwidth = win_col_off(wp);
-
-	numberextra = numberwidth;
-	vcol += numberextra + mb_added;
+	int	col_off_prev = win_col_off(wp);
+	int	width2 = wp->w_width - col_off_prev + win_col_off2(wp);
+	vcol += mb_added;
 #ifdef FEAT_PROP_POPUP
 	vcol -= wp->w_virtcol_first_char;
 #endif
-	if (vcol >= (colnr_T)wp->w_width)
+	colnr_T	wcol = vcol + col_off_prev;
+	// cells taken by 'showbreak'/'breakindent' before current char
+	int	head_prev = 0;
+	if (wcol >= wp->w_width)
 	{
-	    vcol -= wp->w_width;
-	    numberextra = wp->w_width - (numberextra - win_col_off2(wp));
-	    if (vcol >= numberextra && numberextra > 0)
-		vcol %= numberextra;
+	    wcol -= wp->w_width;
+	    col_off_prev = wp->w_width - width2;
+	    if (wcol >= width2 && width2 > 0)
+		wcol %= width2;
 	    if (*sbr != NUL)
+		head_prev += vim_strsize(sbr);
+	    if (wp->w_p_bri)
+		head_prev += get_breakindent_win(wp, line);
+	    if (wcol < head_prev)
+		wcol = head_prev;
+	    wcol += col_off_prev;
+	}
+
+	if ((vcol > 0 && wcol == col_off_prev + head_prev)
+						  || wcol + size > wp->w_width)
+	{
+	    int added = 0;
+	    colnr_T max_head_vcol = cts->cts_max_head_vcol;
+
+	    if (vcol > 0 && wcol == col_off_prev + head_prev)
 	    {
-		sbrlen = (colnr_T)MB_CHARLEN(sbr);
-		if (vcol >= sbrlen)
-		    vcol -= sbrlen;
+		added += head_prev;
+		if (max_head_vcol <= 0 || vcol < max_head_vcol)
+		    head += head_prev;
 	    }
-	    if (vcol >= numberextra && numberextra > 0)
-		vcol = vcol % numberextra;
-	    else if (vcol > 0 && numberextra > 0)
-		vcol += numberwidth - win_col_off2(wp);
 
-	    numberwidth -= win_col_off2(wp);
-	}
-	if (vcol == 0 || vcol + size + sbrlen > (colnr_T)wp->w_width)
-	{
-	    added = 0;
+	    // cells taken by 'showbreak'/'breakindent' halfway current char
+	    int	head_mid = 0;
 	    if (*sbr != NUL)
+		head_mid += vim_strsize(sbr);
+	    if (wp->w_p_bri)
+		head_mid += get_breakindent_win(wp, line);
+	    if (head_mid > 0)
 	    {
-		if (size + sbrlen + numberwidth > (colnr_T)wp->w_width)
+		if (wcol + size > wp->w_width)
 		{
 		    // calculate effective window width
-		    int width = (colnr_T)wp->w_width - sbrlen - numberwidth;
-		    int prev_width = vcol
-			       ? ((colnr_T)wp->w_width - (sbrlen + vcol)) : 0;
+		    int prev_rem = wp->w_width - wcol;
+		    int width = width2 - head_mid;
 
 		    if (width <= 0)
-			width = (colnr_T)1;
-		    added += ((size - prev_width) / width) * vim_strsize(sbr);
-		    if ((size - prev_width) % width)
-			// wrapped, add another length of 'sbr'
-			added += vim_strsize(sbr);
+			width = 1;
+		    // divide "size - prev_width" by "width", rounding up
+		    int cnt = (size - prev_rem + width - 1) / width;
+		    added += cnt * head_mid;
+
+		    if (max_head_vcol == 0
+					|| vcol + size + added < max_head_vcol)
+			head += cnt * head_mid;
+		    else if (max_head_vcol > vcol + head_prev + prev_rem)
+			head += (max_head_vcol - (vcol + head_prev + prev_rem)
+					     + width2 - 1) / width2 * head_mid;
+#ifdef FEAT_PROP_POPUP
+		    else if (max_head_vcol < 0)
+		    {
+			int off = 0;
+			if ((State & MODE_NORMAL) || cts->cts_start_incl)
+			    off += cts->cts_cur_text_width;
+			if (off >= prev_rem)
+			    head += (1 + (off - prev_rem) / width) * head_mid;
+		    }
+#endif
 		}
-		else
-		    added += vim_strsize(sbr);
 	    }
-	    if (wp->w_p_bri)
-		added += get_breakindent_win(wp, line);
 
 	    size += added;
-	    if (vcol != 0)
-		added = 0;
 	}
     }
     if (headp != NULL)
-	*headp = added + mb_added;
+	*headp = head;
     return size;
 # endif
 #endif
@@ -1483,6 +1507,7 @@ getvcol(
     }
 
     init_chartabsize_arg(&cts, wp, pos->lnum, 0, line, line);
+    cts.cts_max_head_vcol = -1;
 
     /*
      * This function is used very often, do some speed optimizations.
--- a/src/drawline.c
+++ b/src/drawline.c
@@ -1110,14 +1110,10 @@ win_line(
     int		n_attr3 = 0;	    // chars with overruling special attr
     int		saved_attr3 = 0;    // char_attr saved for n_attr3
 
-    int		n_skip = 0;		// nr of cells to skip for 'nowrap' or
-					// concealing
-#ifdef FEAT_PROP_POPUP
-    int		skip_cells = 0;		// nr of cells to skip for virtual text
-					// after the line, when w_skipcol is
-					// larger than the text length
-#endif
-
+    int		skip_cells = 0;		// nr of cells to skip for w_leftcol or
+					// w_skipcol or concealing
+    int		skipped_cells = 0;	// nr of skipped cells for virtual text
+					// to be added to wlv.vcol later
     int		fromcol_prev = -2;	// start of inverting after cursor
     int		noinvcur = FALSE;	// don't invert the cursor
     int		lnum_in_visual_area = FALSE;
@@ -1665,11 +1661,14 @@ win_line(
 	char_u		*prev_ptr = ptr;
 	chartabsize_T	cts;
 	int		charsize = 0;
+	int		head = 0;
 
 	init_chartabsize_arg(&cts, wp, lnum, wlv.vcol, line, ptr);
+	cts.cts_max_head_vcol = v;
 	while (cts.cts_vcol < v && *cts.cts_ptr != NUL)
 	{
-	    charsize = win_lbr_chartabsize(&cts, NULL);
+	    head = 0;
+	    charsize = win_lbr_chartabsize(&cts, &head);
 	    cts.cts_vcol += charsize;
 	    prev_ptr = cts.cts_ptr;
 	    MB_PTR_ADV(cts.cts_ptr);
@@ -1698,20 +1697,9 @@ win_line(
 	{
 	    wlv.vcol -= charsize;
 	    ptr = prev_ptr;
-	    // If the character fits on the screen, don't need to skip it.
-	    // Except for a TAB.
-	    if (((*mb_ptr2cells)(ptr) >= charsize || *ptr == TAB)
-							       && wlv.col == 0)
-	       n_skip = v - wlv.vcol;
 	}
-
-#ifdef FEAT_PROP_POPUP
-	// If there the text doesn't reach to the desired column, need to skip
-	// "skip_cells" cells when virtual text follows.
-	if ((!wp->w_p_wrap || (lnum == wp->w_topline && wp->w_skipcol > 0))
-							       && v > wlv.vcol)
-	    skip_cells = v - wlv.vcol;
-#endif
+	if (v > wlv.vcol)
+	    skip_cells = v - wlv.vcol - head;
 
 	// Adjust for when the inverted text is before the screen,
 	// and when the start of the inverted text is before the screen.
@@ -2205,6 +2193,7 @@ win_line(
 				wlv.n_attr_skip -= skip_cells;
 				if (wlv.n_attr_skip < 0)
 				    wlv.n_attr_skip = 0;
+				skipped_cells += skip_cells;
 				skip_cells = 0;
 			    }
 			    else
@@ -2212,6 +2201,7 @@ win_line(
 				// the whole text is left of the window, drop
 				// it and advance to the next one
 				skip_cells -= wlv.n_extra;
+				skipped_cells += wlv.n_extra;
 				wlv.n_extra = 0;
 				wlv.n_attr_skip = 0;
 				bail_out = TRUE;
@@ -2592,11 +2582,15 @@ win_line(
 #ifdef FEAT_LINEBREAK
 	    c0 = *ptr;
 #endif
+	    if (c == NUL)
+	    {
 #ifdef FEAT_PROP_POPUP
-	    if (c == NUL)
 		// text is finished, may display a "below" virtual text
 		did_line = TRUE;
 #endif
+		// no more cells to skip
+		skip_cells = 0;
+	    }
 
 	    if (has_mbyte)
 	    {
@@ -2762,7 +2756,7 @@ win_line(
 		// If a double-width char doesn't fit at the left side display
 		// a '<' in the first column.  Don't do this for unprintable
 		// characters.
-		if (n_skip > 0 && mb_l > 1 && wlv.n_extra == 0)
+		if (skip_cells > 0 && mb_l > 1 && wlv.n_extra == 0)
 		{
 		    wlv.n_extra = 1;
 		    wlv.c_extra = MB_FILLER_CHAR;
@@ -3438,10 +3432,10 @@ win_line(
 		    wlv.n_extra = 0;
 		    n_attr = 0;
 		}
-		else if (n_skip == 0)
+		else if (skip_cells == 0)
 		{
 		    is_concealing = TRUE;
-		    n_skip = 1;
+		    skip_cells = 1;
 		}
 		mb_c = c;
 		if (enc_utf8 && utf_char2len(c) > 1)
@@ -3459,7 +3453,7 @@ win_line(
 		is_concealing = FALSE;
 	    }
 
-	    if (n_skip > 0 && did_decrement_ptr)
+	    if (skip_cells > 0 && did_decrement_ptr)
 		// not showing the '>', put pointer back to avoid getting stuck
 		++ptr;
 
@@ -3472,7 +3466,7 @@ win_line(
 	if (!did_wcol && wlv.draw_state == WL_LINE
 		&& wp == curwin && lnum == wp->w_cursor.lnum
 		&& conceal_cursor_line(wp)
-		&& (int)wp->w_virtcol <= wlv.vcol + n_skip)
+		&& (int)wp->w_virtcol <= wlv.vcol + skip_cells)
 	{
 # ifdef FEAT_RIGHTLEFT
 	    if (wp->w_p_rl)
@@ -3797,7 +3791,7 @@ win_line(
 
 	// Store character to be displayed.
 	// Skip characters that are left of the screen for 'nowrap'.
-	if (wlv.draw_state < WL_LINE || n_skip <= 0)
+	if (wlv.draw_state < WL_LINE || skip_cells <= 0)
 	{
 	    // Store the character.
 #if defined(FEAT_RIGHTLEFT)
@@ -3893,7 +3887,7 @@ win_line(
 #ifdef FEAT_CONCEAL
 	else if (wp->w_p_cole > 0 && is_concealing)
 	{
-	    --n_skip;
+	    --skip_cells;
 	    ++wlv.vcol_off_co;
 	    if (wlv.n_extra > 0)
 		wlv.vcol_off_co += wlv.n_extra;
@@ -3973,7 +3967,13 @@ win_line(
 	}
 #endif // FEAT_CONCEAL
 	else
-	    --n_skip;
+	    --skip_cells;
+
+	if (wlv.draw_state > WL_NR && skipped_cells > 0)
+	{
+	    wlv.vcol += skipped_cells;
+	    skipped_cells = 0;
+	}
 
 	// Only advance the "wlv.vcol" when after the 'number' or
 	// 'relativenumber' column.
--- a/src/edit.c
+++ b/src/edit.c
@@ -3705,8 +3705,13 @@ ins_esc(
 
     State = MODE_NORMAL;
     may_trigger_modechanged();
-    // need to position cursor again when on a TAB
-    if (gchar_cursor() == TAB)
+    // need to position cursor again when on a TAB and when on a char with
+    // virtual text.
+    if (gchar_cursor() == TAB
+#ifdef FEAT_PROP_POPUP
+	    || curbuf->b_has_textprop
+#endif
+       )
 	curwin->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL);
 
     setmouse();
--- a/src/structs.h
+++ b/src/structs.h
@@ -4816,21 +4816,22 @@ typedef struct {
 // Argument for lbr_chartabsize().
 typedef struct {
     win_T	*cts_win;
-    char_u	*cts_line;	    // start of the line
-    char_u	*cts_ptr;	    // current position in line
+    char_u	*cts_line;		// start of the line
+    char_u	*cts_ptr;		// current position in line
 #ifdef FEAT_PROP_POPUP
     int		cts_text_prop_count;	// number of text props; when zero
 					// cts_text_props is not used
     textprop_T	*cts_text_props;	// text props (allocated)
-    char	cts_has_prop_with_text; // TRUE if a property inserts text
-    int		cts_cur_text_width;     // width of current inserted text
+    char	cts_has_prop_with_text;	// TRUE if a property inserts text
+    int		cts_cur_text_width;	// width of current inserted text
     int		cts_prop_lines;		// nr of properties above or below
     int		cts_first_char;		// width text props above the line
     int		cts_with_trailing;	// include size of trailing props with
 					// last character
     int		cts_start_incl;		// prop has true "start_incl" arg
 #endif
-    int		cts_vcol;	    // virtual column at current position
+    int		cts_vcol;		// virtual column at current position
+    int		cts_max_head_vcol;	// see win_lbr_chartabsize()
 } chartabsize_T;
 
 /*
--- a/src/testdir/test_listlbr.vim
+++ b/src/testdir/test_listlbr.vim
@@ -15,7 +15,7 @@ function s:screen_lines(lnum, width) abo
 endfunction
 
 func s:compare_lines(expect, actual)
-  call assert_equal(join(a:expect, "\n"), join(a:actual, "\n"))
+  call assert_equal(a:expect, a:actual)
 endfunc
 
 function s:test_windows(...)
@@ -331,4 +331,45 @@ func Test_list_with_tab_and_skipping_fir
   call s:close_windows()
 endfunc
 
+func Test_ctrl_char_on_wrap_column()
+  call s:test_windows("setl nolbr wrap sbr=")
+  call setline(1, 'aaa' .. repeat("\<C-A>", 150) .. 'bbb')
+  call cursor(1,1)
+  norm! $
+  redraw!
+  let expect=[
+\ '<<<^A^A^A^A^A^A^A^A^',
+\ 'A^A^A^A^A^A^A^A^A^A^',
+\ 'A^A^A^A^A^A^A^A^A^A^',
+\ 'A^A^A^A^A^A^A^A^A^A^',
+\ 'A^A^A^A^A^A^A^A^A^A^',
+\ 'A^A^A^A^A^A^A^A^A^A^',
+\ 'A^A^A^A^A^A^A^A^A^A^',
+\ 'A^A^A^A^A^A^A^A^A^A^',
+\ 'A^A^A^A^A^A^A^A^A^A^',
+\ 'A^Abbb              ']
+  let lines = s:screen_lines([1, 10], winwidth(0))
+  call s:compare_lines(expect, lines)
+  call assert_equal(len(expect), winline())
+  call assert_equal(strwidth(trim(expect[-1], ' ', 2)), wincol())
+  setl sbr=!!
+  redraw!
+  let expect=[
+\ '!!A^A^A^A^A^A^A^A^A^',
+\ '!!A^A^A^A^A^A^A^A^A^',
+\ '!!A^A^A^A^A^A^A^A^A^',
+\ '!!A^A^A^A^A^A^A^A^A^',
+\ '!!A^A^A^A^A^A^A^A^A^',
+\ '!!A^A^A^A^A^A^A^A^A^',
+\ '!!A^A^A^A^A^A^A^A^A^',
+\ '!!A^A^A^A^A^A^A^A^A^',
+\ '!!A^A^A^A^A^A^A^A^A^',
+\ '!!A^A^A^A^A^A^Abbb  ']
+  let lines = s:screen_lines([1, 10], winwidth(0))
+  call s:compare_lines(expect, lines)
+  call assert_equal(len(expect), winline())
+  call assert_equal(strwidth(trim(expect[-1], ' ', 2)), wincol())
+  call s:close_windows()
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_listlbr_utf8.vim
+++ b/src/testdir/test_listlbr_utf8.vim
@@ -249,7 +249,6 @@ endfunc
 
 func Test_chinese_char_on_wrap_column()
   call s:test_windows("setl nolbr wrap sbr=")
-  syntax off
   call setline(1, [
 \ 'aaaaaaaaaaaaaaaaaaa中'.
 \ 'aaaaaaaaaaaaaaaaa中'.
@@ -278,6 +277,84 @@ func Test_chinese_char_on_wrap_column()
 \ '中hello             ']
   let lines = s:screen_lines([1, 10], winwidth(0))
   call s:compare_lines(expect, lines)
+  call assert_equal(len(expect), winline())
+  call assert_equal(strwidth(trim(expect[-1], ' ', 2)), wincol())
+  call s:close_windows()
+endfunc
+
+func Test_chinese_char_on_wrap_column_sbr()
+  call s:test_windows("setl nolbr wrap sbr=!!!")
+  call setline(1, [
+\ 'aaaaaaaaaaaaaaaaaaa中'.
+\ 'aaaaaaaaaaaaaa中'.
+\ 'aaaaaaaaaaaaaa中'.
+\ 'aaaaaaaaaaaaaa中'.
+\ 'aaaaaaaaaaaaaa中'.
+\ 'aaaaaaaaaaaaaa中'.
+\ 'aaaaaaaaaaaaaa中'.
+\ 'aaaaaaaaaaaaaa中'.
+\ 'aaaaaaaaaaaaaa中'.
+\ 'aaaaaaaaaaaaaa中'.
+\ 'hello'])
+  call cursor(1,1)
+  norm! $
+  redraw!
+  let expect=[
+\ '!!!中aaaaaaaaaaaaaa>',
+\ '!!!中aaaaaaaaaaaaaa>',
+\ '!!!中aaaaaaaaaaaaaa>',
+\ '!!!中aaaaaaaaaaaaaa>',
+\ '!!!中aaaaaaaaaaaaaa>',
+\ '!!!中aaaaaaaaaaaaaa>',
+\ '!!!中aaaaaaaaaaaaaa>',
+\ '!!!中aaaaaaaaaaaaaa>',
+\ '!!!中aaaaaaaaaaaaaa>',
+\ '!!!中hello          ']
+  let lines = s:screen_lines([1, 10], winwidth(0))
+  call s:compare_lines(expect, lines)
+  call assert_equal(len(expect), winline())
+  call assert_equal(strwidth(trim(expect[-1], ' ', 2)), wincol())
+  call s:close_windows()
+endfunc
+
+func Test_unprintable_char_on_wrap_column()
+  call s:test_windows("setl nolbr wrap sbr=")
+  call setline(1, 'aaa' .. repeat("\uFEFF", 50) .. 'bbb')
+  call cursor(1,1)
+  norm! $
+  redraw!
+  let expect=[
+\ '<<<<feff><feff><feff',
+\ '><feff><feff><feff><',
+\ 'feff><feff><feff><fe',
+\ 'ff><feff><feff><feff',
+\ '><feff><feff><feff><',
+\ 'feff><feff><feff><fe',
+\ 'ff><feff><feff><feff',
+\ '><feff><feff><feff><',
+\ 'feff><feff><feff><fe',
+\ 'ff>bbb              ']
+  let lines = s:screen_lines([1, 10], winwidth(0))
+  call s:compare_lines(expect, lines)
+  call assert_equal(len(expect), winline())
+  call assert_equal(strwidth(trim(expect[-1], ' ', 2)), wincol())
+  setl sbr=!!
+  redraw!
+  let expect=[
+\ '!!><feff><feff><feff',
+\ '!!><feff><feff><feff',
+\ '!!><feff><feff><feff',
+\ '!!><feff><feff><feff',
+\ '!!><feff><feff><feff',
+\ '!!><feff><feff><feff',
+\ '!!><feff><feff><feff',
+\ '!!><feff><feff><feff',
+\ '!!><feff><feff><feff',
+\ '!!><feff><feff>bbb  ']
+  let lines = s:screen_lines([1, 10], winwidth(0))
+  call s:compare_lines(expect, lines)
+  call assert_equal(len(expect), winline())
+  call assert_equal(strwidth(trim(expect[-1], ' ', 2)), wincol())
   call s:close_windows()
 endfunc
 
--- a/src/testdir/test_options.vim
+++ b/src/testdir/test_options.vim
@@ -1811,11 +1811,11 @@ func Test_paste_depending_options()
 
   let result = readfile('Xoutput_paste')->filter('!empty(v:val)')
   call assert_equal('noexpandtab', result[0])
-  call assert_match("^	Last set from .*Xvimrc_paste2 line 1$", result[1])
+  call assert_match("^\tLast set from .*Xvimrc_paste2 line 1$", result[1])
   call assert_equal('noexpandtab', result[2])
-  call assert_match("^	Last set from .*Xvimrc_paste2 line 1$", result[3])
+  call assert_match("^\tLast set from .*Xvimrc_paste2 line 1$", result[3])
   call assert_equal('noexpandtab', result[4])
-  call assert_match("^	Last set from .*Xvimrc_paste2 line 1$", result[5])
+  call assert_match("^\tLast set from .*Xvimrc_paste2 line 1$", result[5])
 
   call delete('Xoutput_paste')
 endfunc
@@ -1846,11 +1846,11 @@ func Test_binary_depending_options()
 
   let result = readfile('Xoutput_bin')->filter('!empty(v:val)')
   call assert_equal('noexpandtab', result[0])
-  call assert_match("^	Last set from .*Xvimrc_bin2 line 1$", result[1])
+  call assert_match("^\tLast set from .*Xvimrc_bin2 line 1$", result[1])
   call assert_equal('noexpandtab', result[2])
-  call assert_match("^	Last set from .*Xvimrc_bin2 line 1$", result[3])
+  call assert_match("^\tLast set from .*Xvimrc_bin2 line 1$", result[3])
   call assert_equal('noexpandtab', result[4])
-  call assert_match("^	Last set from .*Xvimrc_bin2 line 1$", result[5])
+  call assert_match("^\tLast set from .*Xvimrc_bin2 line 1$", result[5])
 
   call delete('Xoutput_bin')
 endfunc
--- a/src/testdir/test_textprop.vim
+++ b/src/testdir/test_textprop.vim
@@ -2630,6 +2630,110 @@ func Test_prop_inserts_text_visual_block
   call StopVimInTerminal(buf)
 endfunc
 
+func Run_test_prop_inserts_text_showbreak(cmd)
+  CheckRunVimInTerminal
+
+  let lines =<< trim END
+    highlight! link LineNr Normal
+    call setline(1, repeat('a', 28))
+    call prop_type_add('theprop', #{highlight: 'Special'})
+    call prop_add(1, 28, #{type: 'theprop', text: repeat('123', 23), text_wrap: 'wrap'})
+    setlocal number showbreak=+ breakindent breakindentopt=shift:2
+    setlocal scrolloff=0 smoothscroll
+    normal! $
+  END
+  let lines = insert(lines, a:cmd)
+  call writefile(lines, 'XscriptPropsShowbreak', 'D')
+  let buf = RunVimInTerminal('-S XscriptPropsShowbreak', #{rows: 6, cols: 30})
+  call term_sendkeys(buf, ":set noruler\<CR>")
+  call VerifyScreenDump(buf, 'Test_prop_inserts_text_showbreak_1', {})
+  call term_sendkeys(buf, "\<C-E>")
+  call VerifyScreenDump(buf, 'Test_prop_inserts_text_showbreak_2', {})
+  call term_sendkeys(buf, "\<C-E>")
+  call VerifyScreenDump(buf, 'Test_prop_inserts_text_showbreak_3', {})
+  call term_sendkeys(buf, "\<C-E>")
+  call VerifyScreenDump(buf, 'Test_prop_inserts_text_showbreak_4', {})
+  call term_sendkeys(buf, "\<C-E>")
+  call VerifyScreenDump(buf, 'Test_prop_inserts_text_showbreak_5', {})
+  call term_sendkeys(buf, "zbi")
+  call VerifyScreenDump(buf, 'Test_prop_inserts_text_showbreak_6', {})
+  call term_sendkeys(buf, "\<BS>")
+  call VerifyScreenDump(buf, 'Test_prop_inserts_text_showbreak_7', {})
+  call term_sendkeys(buf, "\<Esc>l")
+  call VerifyScreenDump(buf, 'Test_prop_inserts_text_showbreak_8', {})
+  call term_sendkeys(buf, "\<C-E>")
+  call VerifyScreenDump(buf, 'Test_prop_inserts_text_showbreak_9', {})
+  call term_sendkeys(buf, "\<C-E>")
+  call VerifyScreenDump(buf, 'Test_prop_inserts_text_showbreak_10', {})
+  call term_sendkeys(buf, "\<C-E>")
+  call VerifyScreenDump(buf, 'Test_prop_inserts_text_showbreak_11', {})
+  call term_sendkeys(buf, "\<C-E>")
+  call VerifyScreenDump(buf, 'Test_prop_inserts_text_showbreak_12', {})
+  call term_sendkeys(buf, "023x$")
+  call VerifyScreenDump(buf, 'Test_prop_inserts_text_showbreak_13', {})
+  call term_sendkeys(buf, "\<C-E>")
+  call VerifyScreenDump(buf, 'Test_prop_inserts_text_showbreak_14', {})
+  call term_sendkeys(buf, "\<C-E>")
+  call VerifyScreenDump(buf, 'Test_prop_inserts_text_showbreak_15', {})
+  call term_sendkeys(buf, "\<C-E>")
+  call VerifyScreenDump(buf, 'Test_prop_inserts_text_showbreak_16', {})
+  call term_sendkeys(buf, "zbi")
+  call VerifyScreenDump(buf, 'Test_prop_inserts_text_showbreak_17', {})
+  call term_sendkeys(buf, "\<C-U>")
+  call VerifyScreenDump(buf, 'Test_prop_inserts_text_showbreak_18', {})
+  call term_sendkeys(buf, "\<Esc>")
+  call VerifyScreenDump(buf, 'Test_prop_inserts_text_showbreak_19', {})
+  call term_sendkeys(buf, "\<C-E>")
+  call VerifyScreenDump(buf, 'Test_prop_inserts_text_showbreak_20', {})
+  call term_sendkeys(buf, "\<C-E>")
+  call VerifyScreenDump(buf, 'Test_prop_inserts_text_showbreak_21', {})
+
+  call StopVimInTerminal(buf)
+endfunc
+
+func Test_prop_inserts_text_showbreak()
+  call Run_test_prop_inserts_text_showbreak('')
+  " because of 'breakindent' the screendumps are the same
+  call Run_test_prop_inserts_text_showbreak('set cpoptions+=n')
+endfunc
+
+func Test_prop_before_tab_skipcol()
+  CheckRunVimInTerminal
+
+  let lines =<< trim END
+    call setline(1, repeat("\t", 4) .. 'a')
+    call prop_type_add('theprop', #{highlight: 'Special'})
+    call prop_add(1, 4, #{type: 'theprop', text: repeat('12', 32), text_wrap: 'wrap'})
+    setlocal list listchars=tab:<-> scrolloff=0 smoothscroll
+    normal! $
+  END
+  call writefile(lines, 'XscriptPropsBeforeTabSkipcol', 'D')
+  let buf = RunVimInTerminal('-S XscriptPropsBeforeTabSkipcol', #{rows: 6, cols: 30})
+  call VerifyScreenDump(buf, 'Test_prop_before_tab_skipcol_1', {})
+  call term_sendkeys(buf, "\<C-E>")
+  call VerifyScreenDump(buf, 'Test_prop_before_tab_skipcol_2', {})
+  call term_sendkeys(buf, "\<C-E>")
+  call VerifyScreenDump(buf, 'Test_prop_before_tab_skipcol_3', {})
+  call term_sendkeys(buf, "\<C-E>")
+  call VerifyScreenDump(buf, 'Test_prop_before_tab_skipcol_4', {})
+  call term_sendkeys(buf, "zbh")
+  call VerifyScreenDump(buf, 'Test_prop_before_tab_skipcol_5', {})
+  call term_sendkeys(buf, "i")
+  call VerifyScreenDump(buf, 'Test_prop_before_tab_skipcol_6', {})
+  call term_sendkeys(buf, "\<C-O>:setlocal nolist\<CR>")
+  call VerifyScreenDump(buf, 'Test_prop_before_tab_skipcol_7', {})
+  call term_sendkeys(buf, "\<Esc>l")
+  call VerifyScreenDump(buf, 'Test_prop_before_tab_skipcol_8', {})
+  call term_sendkeys(buf, "\<C-E>")
+  call VerifyScreenDump(buf, 'Test_prop_before_tab_skipcol_9', {})
+  call term_sendkeys(buf, "\<C-E>")
+  call VerifyScreenDump(buf, 'Test_prop_before_tab_skipcol_10', {})
+  call term_sendkeys(buf, "\<C-E>")
+  call VerifyScreenDump(buf, 'Test_prop_before_tab_skipcol_11', {})
+
+  call StopVimInTerminal(buf)
+endfunc
+
 func Test_prop_add_with_text_fails()
   call prop_type_add('failing', #{highlight: 'ErrorMsg'})
   call assert_fails("call prop_add(1, 0, #{type: 'failing', text: 'X', end_lnum: 1})", 'E1305:')
--- a/src/version.c
+++ b/src/version.c
@@ -700,6 +700,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1783,
+/**/
     1782,
 /**/
     1781,