patch 8.2.3019: location list only has the start position.

Problem:    Location list only has the start position.
Solution:   Make it possible to add an end position. (Shane-XB-Qian,
            closes #8393)
diff --git a/src/testdir/dumps/Test_quickfix_cwindow_1.dump b/src/testdir/dumps/Test_quickfix_cwindow_1.dump
index ef153f9..c2b4872 100644
--- a/src/testdir/dumps/Test_quickfix_cwindow_1.dump
+++ b/src/testdir/dumps/Test_quickfix_cwindow_1.dump
@@ -4,9 +4,9 @@
 |m|a|t|c|h|e|s| @67
 |~+0#4040ff13&| @73
 |X+1#0000000&|C|w|i|n|d|o|w| @48|1|,|4| @11|A|l@1
->X+0#0000e05#ffff4012|C|w|i|n|d|o|w||+0#0000000&|1+0#af5f00255&| |c|o|l| |4||+0#0000000&| |s|o|m|e| @52
-|X+0#0000e05#ffffff0|C|w|i|n|d|o|w||+0#0000000&|2+0#af5f00255&| |c|o|l| |2||+0#0000000&| |t|e|x|t| @52
-|X+0#0000e05&|C|w|i|n|d|o|w||+0#0000000&|4+0#af5f00255&| |c|o|l| |6||+0#0000000&| |m|a|t|c|h|e|s| @49
+>X+0#0000e05#ffff4012|C|w|i|n|d|o|w||+0#0000000&|1+0#af5f00255&| |c|o|l| |4|-|5||+0#0000000&| |s|o|m|e| @50
+|X+0#0000e05#ffffff0|C|w|i|n|d|o|w||+0#0000000&|2+0#af5f00255&| |c|o|l| |2|-|3||+0#0000000&| |t|e|x|t| @50
+|X+0#0000e05&|C|w|i|n|d|o|w||+0#0000000&|4+0#af5f00255&| |c|o|l| |6|-|7||+0#0000000&| |m|a|t|c|h|e|s| @47
 |~+0#4040ff13&| @73
 |[+3#0000000&|Q|u|i|c|k|f|i|x| |L|i|s|t|]| |:|v|i|m|g|r|e|p| |e| |X|C|w|i|n|d|o|w| @20|1|,|1| @12|A|l@1
 | +0&&@74
diff --git a/src/testdir/dumps/Test_quickfix_cwindow_2.dump b/src/testdir/dumps/Test_quickfix_cwindow_2.dump
index 4c87ca0..0e7fa3c 100644
--- a/src/testdir/dumps/Test_quickfix_cwindow_2.dump
+++ b/src/testdir/dumps/Test_quickfix_cwindow_2.dump
@@ -4,9 +4,9 @@
 |m|a|t|c|h|e|s| @67
 |~+0#4040ff13&| @73
 |X+3#0000000&|C|w|i|n|d|o|w| @48|2|,|2| @11|A|l@1
-|X+0#0000e05&|C|w|i|n|d|o|w||+0#0000000&|1+0#af5f00255&| |c|o|l| |4||+0#0000000&| |s|o|m|e| @52
-|X+0#0000e05#ffff4012|C|w|i|n|d|o|w||+0#0000000&|2+0#af5f00255&| |c|o|l| |2||+0#0000000&| |t|e|x|t| @52
-|X+0#0000e05#ffffff0|C|w|i|n|d|o|w||+0#0000000&|4+0#af5f00255&| |c|o|l| |6||+0#0000000&| |m|a|t|c|h|e|s| @49
+|X+0#0000e05&|C|w|i|n|d|o|w||+0#0000000&|1+0#af5f00255&| |c|o|l| |4|-|5||+0#0000000&| |s|o|m|e| @50
+|X+0#0000e05#ffff4012|C|w|i|n|d|o|w||+0#0000000&|2+0#af5f00255&| |c|o|l| |2|-|3||+0#0000000&| |t|e|x|t| @50
+|X+0#0000e05#ffffff0|C|w|i|n|d|o|w||+0#0000000&|4+0#af5f00255&| |c|o|l| |6|-|7||+0#0000000&| |m|a|t|c|h|e|s| @47
 |~+0#4040ff13&| @73
 |[+1#0000000&|Q|u|i|c|k|f|i|x| |L|i|s|t|]| |:|v|i|m|g|r|e|p| |e| |X|C|w|i|n|d|o|w| @20|2|,|1| @12|A|l@1
 |:+0&&|c|n|e|x|t| @68
diff --git a/src/testdir/test_quickfix.vim b/src/testdir/test_quickfix.vim
index 263dbbd..e82ce68 100644
--- a/src/testdir/test_quickfix.vim
+++ b/src/testdir/test_quickfix.vim
@@ -134,6 +134,21 @@
   call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
 		   \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
 
+  " Ranged entries
+  call g:Xsetlist([{'lnum':10,'text':'Line1'},
+	      \ {'lnum':20,'col':10,'text':'Line2'},
+	      \ {'lnum':30,'col':15,'end_col':20,'text':'Line3'},
+	      \ {'lnum':40,'end_lnum':45,'text':'Line4'},
+	      \ {'lnum':50,'end_lnum':55,'col':15,'text':'Line5'},
+	      \ {'lnum':60,'end_lnum':65,'col':25,'end_col':35,'text':'Line6'}])
+  let l = split(execute('Xlist', ""), "\n")
+  call assert_equal([' 1:10: Line1',
+	      \ ' 2:20 col 10: Line2',
+	      \ ' 3:30 col 15-20: Line3',
+	      \ ' 4:40-45: Line4',
+	      \ ' 5:50-55 col 15: Line5',
+	      \ ' 6:60-65 col 25-35: Line6'], l)
+
   " Different types of errors
   call g:Xsetlist([{'lnum':10,'col':5,'type':'W', 'text':'Warning','nr':11},
 	      \ {'lnum':20,'col':10,'type':'e','text':'Error','nr':22},
@@ -644,6 +659,7 @@
   call assert_true(&buftype == 'help')
   call assert_true(winnr() == 1)
   call assert_true(winnr('$') == 2)
+  call assert_match('|\d\+ col \d\+-\d\+|', getbufline(winbufnr(2), 1)[0])
 
   " This wipes out the buffer, make sure that doesn't cause trouble.
   Xclose
@@ -1514,10 +1530,13 @@
   call s:setup_commands(a:cchar)
 
   call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 1},
-	      \  {'bufnr': a:bnum, 'lnum': 2}])
+	      \  {'bufnr': a:bnum, 'lnum': 2, 'end_lnum': 3, 'col': 4, 'end_col': 5}])
   let l = g:Xgetlist()
   call assert_equal(2, len(l))
   call assert_equal(2, l[1].lnum)
+  call assert_equal(3, l[1].end_lnum)
+  call assert_equal(4, l[1].col)
+  call assert_equal(5, l[1].end_col)
 
   Xnext
   call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3}], 'a')
@@ -2852,7 +2871,9 @@
   let l = g:Xgetlist()
   call assert_equal(2, len(l))
   call assert_equal(8, l[0].col)
+  call assert_equal(11, l[0].end_col)
   call assert_equal(12, l[1].col)
+  call assert_equal(15, l[1].end_col)
 
   1Xvimgrep ?Editor? Xtestfile*
   let l = g:Xgetlist()
@@ -5098,15 +5119,21 @@
   call assert_equal('Tqfexpr', &quickfixtextfunc)
   call assert_equal('',
         \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
-  Xexpr ['F1:10:2:green', 'F1:20:4:blue']
+  call g:Xsetlist([
+        \ { 'filename': 'F1', 'lnum': 10, 'col': 2,
+        \   'end_col': 7, 'text': 'green'},
+        \ { 'filename': 'F1', 'lnum': 20, 'end_lnum': 25, 'col': 4,
+        \   'end_col': 8, 'text': 'blue'},
+        \ ])
+
   Xwindow
   call assert_equal('F1-L10C2-green', getline(1))
   call assert_equal('F1-L20C4-blue', getline(2))
   Xclose
   set quickfixtextfunc&vim
   Xwindow
-  call assert_equal('F1|10 col 2| green', getline(1))
-  call assert_equal('F1|20 col 4| blue', getline(2))
+  call assert_equal('F1|10 col 2-7| green', getline(1))
+  call assert_equal('F1|20-25 col 4-8| blue', getline(2))
   Xclose
   set efm&
   set quickfixtextfunc&
@@ -5339,7 +5366,7 @@
   call setqflist(['bb'], 'a')
   call assert_equal(1, line('$'))
   call assert_equal(['Xfile1|10| aa'], getline(1, '$'))
-  call assert_equal([{'lnum': 10, 'bufnr': bufnr('Xfile1'), 'col': 0, 'pattern': '', 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'module': '', 'text': 'aa'}], getqflist())
+  call assert_equal([{'lnum': 10, 'end_lnum': 0, 'bufnr': bufnr('Xfile1'), 'col': 0, 'end_col': 0, 'pattern': '', 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'module': '', 'text': 'aa'}], getqflist())
   cclose
 endfunc
 
diff --git a/src/testdir/test_tagjump.vim b/src/testdir/test_tagjump.vim
index c789dc9..92af0d0 100644
--- a/src/testdir/test_tagjump.vim
+++ b/src/testdir/test_tagjump.vim
@@ -837,15 +837,16 @@
   ltag third
   call assert_equal('Xfoo', bufname(''))
   call assert_equal(3, line('.'))
-  call assert_equal([{'lnum': 3, 'bufnr': bufnr('Xfoo'), 'col': 0,
-        \ 'pattern': '', 'valid': 1, 'vcol': 0, 'nr': 0, 'type': '',
-        \ 'module': '', 'text': 'third'}], getloclist(0))
+  call assert_equal([{'lnum': 3, 'end_lnum': 0, 'bufnr': bufnr('Xfoo'),
+        \ 'col': 0, 'end_col': 0, 'pattern': '', 'valid': 1, 'vcol': 0,
+        \ 'nr': 0, 'type': '', 'module': '', 'text': 'third'}], getloclist(0))
 
   ltag second
   call assert_equal(2, line('.'))
-  call assert_equal([{'lnum': 0, 'bufnr': bufnr('Xfoo'), 'col': 0,
-        \ 'pattern': '^\Vint second() {}\$', 'valid': 1, 'vcol': 0, 'nr': 0,
-        \ 'type': '', 'module': '', 'text': 'second'}], getloclist(0))
+  call assert_equal([{'lnum': 0, 'end_lnum': 0, 'bufnr': bufnr('Xfoo'),
+        \ 'col': 0, 'end_col': 0, 'pattern': '^\Vint second() {}\$',
+        \ 'valid': 1, 'vcol': 0, 'nr': 0, 'type': '', 'module': '',
+        \ 'text': 'second'}], getloclist(0))
 
   call delete('Xtags')
   call delete('Xfoo')
diff --git a/src/testdir/test_vim9_expr.vim b/src/testdir/test_vim9_expr.vim
index 974ca85..9170cc9 100644
--- a/src/testdir/test_vim9_expr.vim
+++ b/src/testdir/test_vim9_expr.vim
@@ -2943,7 +2943,9 @@
       loclist->setloclist(0)
       assert_equal([{bufnr: bufnr,
                     lnum: 42,
+                    end_lnum: 0,
                     col: 17,
+                    end_col: 0,
                     text: 'wrong',
                     pattern: '',
                     valid: 1,