patch 9.0.1921: not possible to use the jumplist like a stack

Problem:  not possible to use the jumplist like a stack
Solution: Add the 'jumpoptions' setting to make the jumplist
          a stack.

Add an option for using jumplist like tag stack

related: #7738
closes: #13134

ported from NeoVim:

- https://neovim.io/doc/user/motion.html#jumplist-stack
- neovim/neovim@39094b3
- neovim/neovim#11530
- https://vi.stackexchange.com/questions/18344/how-to-change-jumplist-behavior

Based on the feedback in the previous PR, it looks like many people like
this option.

Signed-off-by: Christian Brabandt <cb@256bit.org>
Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Co-authored-by: butwerenotthereyet <58348703+butwerenotthereyet@users.noreply.github.com>
diff --git a/src/testdir/gen_opt_test.vim b/src/testdir/gen_opt_test.vim
index f205d43..a195bca 100644
--- a/src/testdir/gen_opt_test.vim
+++ b/src/testdir/gen_opt_test.vim
@@ -112,6 +112,7 @@
       \ 'isident': [['', '@', '@,48-52'], ['xxx', '@48']],
       \ 'iskeyword': [['', '@', '@,48-52'], ['xxx', '@48']],
       \ 'isprint': [['', '@', '@,48-52'], ['xxx', '@48']],
+      \ 'jumpoptions': [['', 'stack'], ['xxx']],
       \ 'keymap': [['', 'accents'], ['xxx']],
       \ 'keymodel': [['', 'startsel', 'startsel,stopsel'], ['xxx']],
       \ 'keyprotocol': [['', 'xxx:none', 'yyy:mok2', 'zzz:kitty'],
diff --git a/src/testdir/test_jumplist.vim b/src/testdir/test_jumplist.vim
index 4b5e321..8fbf39f 100644
--- a/src/testdir/test_jumplist.vim
+++ b/src/testdir/test_jumplist.vim
@@ -98,4 +98,68 @@
   bwipe!
 endfunc
 
+" Test for 'jumpoptions'
+func Test_jumpoptions()
+  new
+  call setline(1, range(1, 200))
+  clearjumps
+  set jumpoptions=stack
+
+  " Jump around to add some locations to the jump list.
+  normal 10G
+  normal 20G
+  normal 30G
+  normal 40G
+  normal 50G
+  let bnr = bufnr()
+
+  " discards the tail when navigating from the middle
+  exe "normal \<C-O>\<C-O>"
+  call assert_equal([
+        \ [{'lnum': 1, 'bufnr': bnr, 'col': 0, 'coladd': 0},
+        \  {'lnum': 10, 'bufnr': bnr, 'col': 0, 'coladd': 0},
+        \  {'lnum': 20, 'bufnr': bnr, 'col': 0, 'coladd': 0},
+        \  {'lnum': 30, 'bufnr': bnr, 'col': 0, 'coladd': 0},
+        \  {'lnum': 40, 'bufnr': bnr, 'col': 0, 'coladd': 0},
+        \  {'lnum': 50, 'bufnr': bnr, 'col': 0, 'coladd': 0}
+        \ ], 3], getjumplist())
+
+  " new jump location is added immediately after the last one
+  normal 90G
+  call assert_equal([
+        \ [{'lnum': 1, 'bufnr': bnr, 'col': 0, 'coladd': 0},
+        \  {'lnum': 10, 'bufnr': bnr, 'col': 0, 'coladd': 0},
+        \  {'lnum': 20, 'bufnr': bnr, 'col': 0, 'coladd': 0},
+        \  {'lnum': 30, 'bufnr': bnr, 'col': 0, 'coladd': 0},
+        \ ], 4], getjumplist())
+
+  " does not add the same location twice adjacently
+  normal 60G
+  normal 60G
+  call assert_equal([
+        \ [{'lnum': 1, 'bufnr': bnr, 'col': 0, 'coladd': 0},
+        \  {'lnum': 10, 'bufnr': bnr, 'col': 0, 'coladd': 0},
+        \  {'lnum': 20, 'bufnr': bnr, 'col': 0, 'coladd': 0},
+        \  {'lnum': 30, 'bufnr': bnr, 'col': 0, 'coladd': 0},
+        \  {'lnum': 90, 'bufnr': bnr, 'col': 0, 'coladd': 0},
+        \  {'lnum': 60, 'bufnr': bnr, 'col': 0, 'coladd': 0},
+        \ ], 6], getjumplist())
+
+  " does add the same location twice non adjacently
+  normal 10G
+  normal 20G
+  call assert_equal([
+        \ [{'lnum': 1, 'bufnr': bnr, 'col': 0, 'coladd': 0},
+        \  {'lnum': 10, 'bufnr': bnr, 'col': 0, 'coladd': 0},
+        \  {'lnum': 20, 'bufnr': bnr, 'col': 0, 'coladd': 0},
+        \  {'lnum': 30, 'bufnr': bnr, 'col': 0, 'coladd': 0},
+        \  {'lnum': 90, 'bufnr': bnr, 'col': 0, 'coladd': 0},
+        \  {'lnum': 60, 'bufnr': bnr, 'col': 0, 'coladd': 0},
+        \  {'lnum': 10, 'bufnr': bnr, 'col': 0, 'coladd': 0},
+        \ ], 7], getjumplist())
+
+  set jumpoptions&
+  %bw!
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab