mirror of
				https://github.com/neovim/neovim.git
				synced 2025-11-03 17:24:29 +00:00 
			
		
		
		
	Merge #34921 tutor: reimplement interactive marks as extmarks
This commit is contained in:
		@@ -77,46 +77,6 @@ function! tutor#TutorFolds()
 | 
			
		||||
    endif
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
" Marks: {{{1
 | 
			
		||||
 | 
			
		||||
function! tutor#ApplyMarks()
 | 
			
		||||
    hi! link tutorExpect Special
 | 
			
		||||
    if exists('b:tutor_metadata') && has_key(b:tutor_metadata, 'expect')
 | 
			
		||||
        let b:tutor_sign_id = 1
 | 
			
		||||
        for expct in keys(b:tutor_metadata['expect'])
 | 
			
		||||
            let lnum = eval(expct)
 | 
			
		||||
            call matchaddpos('tutorExpect', [lnum])
 | 
			
		||||
            call tutor#CheckLine(lnum)
 | 
			
		||||
        endfor
 | 
			
		||||
    endif
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! tutor#ApplyMarksOnChanged()
 | 
			
		||||
    if exists('b:tutor_metadata') && has_key(b:tutor_metadata, 'expect')
 | 
			
		||||
        let lnum = line('.')
 | 
			
		||||
        if index(keys(b:tutor_metadata['expect']), string(lnum)) > -1
 | 
			
		||||
            call tutor#CheckLine(lnum)
 | 
			
		||||
        endif
 | 
			
		||||
    endif
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
function! tutor#CheckLine(line)
 | 
			
		||||
    if exists('b:tutor_metadata') && has_key(b:tutor_metadata, 'expect')
 | 
			
		||||
        let bufn = bufnr('%')
 | 
			
		||||
        let ctext = getline(a:line)
 | 
			
		||||
        let signs = sign_getplaced(bufn, {'lnum': a:line})[0].signs
 | 
			
		||||
        if !empty(signs)
 | 
			
		||||
            call sign_unplace('', {'id': signs[0].id})
 | 
			
		||||
        endif
 | 
			
		||||
        if b:tutor_metadata['expect'][string(a:line)] == -1 || ctext ==# b:tutor_metadata['expect'][string(a:line)]
 | 
			
		||||
            exe "sign place ".b:tutor_sign_id." line=".a:line." name=tutorok buffer=".bufn
 | 
			
		||||
        else
 | 
			
		||||
            exe "sign place ".b:tutor_sign_id." line=".a:line." name=tutorbad buffer=".bufn
 | 
			
		||||
        endif
 | 
			
		||||
        let b:tutor_sign_id+=1
 | 
			
		||||
    endif
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
" Tutor Cmd: {{{1
 | 
			
		||||
 | 
			
		||||
function! s:Locale()
 | 
			
		||||
@@ -243,9 +203,9 @@ function! tutor#EnableInteractive(enable)
 | 
			
		||||
        setlocal buftype=nofile
 | 
			
		||||
        setlocal concealcursor+=inv
 | 
			
		||||
        setlocal conceallevel=2
 | 
			
		||||
        call tutor#ApplyMarks()
 | 
			
		||||
        lua require('nvim.tutor').apply_marks()
 | 
			
		||||
        augroup tutor_interactive
 | 
			
		||||
            autocmd! TextChanged,TextChangedI <buffer> call tutor#ApplyMarksOnChanged()
 | 
			
		||||
            autocmd! TextChanged,TextChangedI <buffer> lua require('nvim.tutor').apply_marks_on_changed()
 | 
			
		||||
        augroup END
 | 
			
		||||
    else
 | 
			
		||||
        setlocal buftype<
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										80
									
								
								runtime/lua/nvim/tutor.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								runtime/lua/nvim/tutor.lua
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,80 @@
 | 
			
		||||
---@class nvim.TutorMetadata
 | 
			
		||||
---@field expect table<string, string|-1>
 | 
			
		||||
 | 
			
		||||
---@alias nvim.TutorExtmarks table<string, string>
 | 
			
		||||
 | 
			
		||||
---@type nvim.TutorExtmarks?
 | 
			
		||||
vim.b.tutor_extmarks = vim.b.tutor_extmarks
 | 
			
		||||
 | 
			
		||||
---@type nvim.TutorMetadata?
 | 
			
		||||
vim.b.tutor_metadata = vim.b.tutor_metadata
 | 
			
		||||
 | 
			
		||||
local sign_text_correct = '✓'
 | 
			
		||||
local sign_text_incorrect = '✗'
 | 
			
		||||
local tutor_mark_ns = vim.api.nvim_create_namespace('nvim.tutor.mark')
 | 
			
		||||
local tutor_hl_ns = vim.api.nvim_create_namespace('nvim.tutor.hl')
 | 
			
		||||
 | 
			
		||||
local M = {}
 | 
			
		||||
 | 
			
		||||
---@param line integer 1-based
 | 
			
		||||
local function check_line(line)
 | 
			
		||||
  if vim.b.tutor_metadata and vim.b.tutor_metadata.expect and vim.b.tutor_extmarks then
 | 
			
		||||
    local ctext = vim.fn.getline(line)
 | 
			
		||||
 | 
			
		||||
    local extmarks = vim.api.nvim_buf_get_extmarks(
 | 
			
		||||
      0,
 | 
			
		||||
      tutor_mark_ns,
 | 
			
		||||
      { line - 1, 0 },
 | 
			
		||||
      { line - 1, -1 }, -- the extmark can move to col > 0 if users insert text there
 | 
			
		||||
      {}
 | 
			
		||||
    )
 | 
			
		||||
    for _, extmark in ipairs(extmarks) do
 | 
			
		||||
      local mark_id = extmark[1]
 | 
			
		||||
      local expct = vim.b.tutor_extmarks[tostring(mark_id)]
 | 
			
		||||
      local expect = vim.b.tutor_metadata.expect[expct]
 | 
			
		||||
      local is_correct = expect == -1 or ctext == expect
 | 
			
		||||
 | 
			
		||||
      vim.api.nvim_buf_set_extmark(0, tutor_mark_ns, line - 1, 0, {
 | 
			
		||||
        id = mark_id,
 | 
			
		||||
        sign_text = is_correct and sign_text_correct or sign_text_incorrect,
 | 
			
		||||
        sign_hl_group = is_correct and 'tutorOK' or 'tutorX',
 | 
			
		||||
        -- This may be a hack. By default, all extmarks only move forward, so a line cannot contain
 | 
			
		||||
        -- any extmarks that were originally created for later lines.
 | 
			
		||||
        priority = tonumber(expct),
 | 
			
		||||
      })
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function M.apply_marks()
 | 
			
		||||
  vim.cmd [[hi! link tutorExpect Special]]
 | 
			
		||||
  if vim.b.tutor_metadata and vim.b.tutor_metadata.expect then
 | 
			
		||||
    vim.b.tutor_extmarks = {}
 | 
			
		||||
    for expct, _ in pairs(vim.b.tutor_metadata.expect) do
 | 
			
		||||
      ---@diagnostic disable-next-line: assign-type-mismatch
 | 
			
		||||
      local lnum = tonumber(expct) ---@type integer
 | 
			
		||||
      vim.api.nvim_buf_set_extmark(0, tutor_hl_ns, lnum - 1, 0, {
 | 
			
		||||
        line_hl_group = 'tutorExpect',
 | 
			
		||||
      })
 | 
			
		||||
 | 
			
		||||
      local mark_id = vim.api.nvim_buf_set_extmark(0, tutor_mark_ns, lnum - 1, 0, {})
 | 
			
		||||
 | 
			
		||||
      -- Cannot edit field of a Vimscript dictionary from Lua directly, see `:h lua-vim-variables`
 | 
			
		||||
      ---@type nvim.TutorExtmarks
 | 
			
		||||
      local tutor_extmarks = vim.b.tutor_extmarks
 | 
			
		||||
      tutor_extmarks[tostring(mark_id)] = expct
 | 
			
		||||
      vim.b.tutor_extmarks = tutor_extmarks
 | 
			
		||||
 | 
			
		||||
      check_line(lnum)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function M.apply_marks_on_changed()
 | 
			
		||||
  if vim.b.tutor_metadata and vim.b.tutor_metadata.expect and vim.b.tutor_extmarks then
 | 
			
		||||
    local lnum = vim.fn.line('.')
 | 
			
		||||
    check_line(lnum)
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
return M
 | 
			
		||||
@@ -304,7 +304,7 @@ it would be easier to simply type two d's to delete a line.
 | 
			
		||||
 | 
			
		||||
 3. Now move to the fourth line.
 | 
			
		||||
 | 
			
		||||
 4. Type `2dd`{normal} to delete two lines, then press `u`{normal} twice to undo all three lines.
 | 
			
		||||
 4. Type `2dd`{normal} to delete two lines.
 | 
			
		||||
 | 
			
		||||
1)  Roses are red,
 | 
			
		||||
2)  Mud is fun,
 | 
			
		||||
 
 | 
			
		||||
@@ -12,11 +12,11 @@
 | 
			
		||||
    "273": -1,
 | 
			
		||||
    "292": "This line of words is cleaned up.",
 | 
			
		||||
    "309": "1)  Roses are red,",
 | 
			
		||||
    "310": "3)  Violets are blue,",
 | 
			
		||||
    "311": "6)  Sugar is sweet",
 | 
			
		||||
    "312": "7)  And so are you.",
 | 
			
		||||
    "313": "7)  And so are you.",
 | 
			
		||||
    "314": "7)  And so are you.",
 | 
			
		||||
    "310": "",
 | 
			
		||||
    "311": "3)  Violets are blue,",
 | 
			
		||||
    "312": "",
 | 
			
		||||
    "313": "",
 | 
			
		||||
    "314": "6)  Sugar is sweet",
 | 
			
		||||
    "315": "7)  And so are you.",
 | 
			
		||||
    "335": "Fix the errors on this line and replace them with undo.",
 | 
			
		||||
    "381": -1,
 | 
			
		||||
 
 | 
			
		||||
@@ -11,13 +11,13 @@
 | 
			
		||||
    "233": "誰かがこの行の最後を2度タイプしました。",
 | 
			
		||||
    "272": -1,
 | 
			
		||||
    "291": "この行の単語は綺麗になった。",
 | 
			
		||||
    "308": -1,
 | 
			
		||||
    "309": -1,
 | 
			
		||||
    "310": -1,
 | 
			
		||||
    "311": -1,
 | 
			
		||||
    "312": -1,
 | 
			
		||||
    "313": -1,
 | 
			
		||||
    "314": -1,
 | 
			
		||||
    "308": "1)  薔薇は赤く",
 | 
			
		||||
    "309": "",
 | 
			
		||||
    "310": "3)  菫は青く",
 | 
			
		||||
    "311": "",
 | 
			
		||||
    "312": "",
 | 
			
		||||
    "313": "6)  砂糖は甘く",
 | 
			
		||||
    "314": "7)  そして貴方も",
 | 
			
		||||
    "335": "この行の間違いを修正し、後でそれらの修正を取り消します。",
 | 
			
		||||
    "381": -1,
 | 
			
		||||
    "382": -1,
 | 
			
		||||
 
 | 
			
		||||
@@ -287,7 +287,7 @@ This ABC DE line FGHI JK LMN OP of words is Q RS TUV cleaned up.
 | 
			
		||||
 | 
			
		||||
 3. 现在移动到第 4 行。
 | 
			
		||||
 | 
			
		||||
 4. 输入 `2dd`{normal} 来删除两行,然后按两次 `u`{normal} 来恢复这三行。
 | 
			
		||||
 4. 输入 `2dd`{normal} 来删除两行。
 | 
			
		||||
 | 
			
		||||
1)  Roses are red,
 | 
			
		||||
2)  Mud is fun,
 | 
			
		||||
 
 | 
			
		||||
@@ -14,11 +14,11 @@
 | 
			
		||||
    "259": -1,
 | 
			
		||||
    "276": "This line of words is cleaned up.",
 | 
			
		||||
    "292": "1)  Roses are red,",
 | 
			
		||||
    "293": "3)  Violets are blue,",
 | 
			
		||||
    "294": "6)  Sugar is sweet",
 | 
			
		||||
    "295": "7)  And so are you.",
 | 
			
		||||
    "296": "7)  And so are you.",
 | 
			
		||||
    "297": "7)  And so are you.",
 | 
			
		||||
    "293": "",
 | 
			
		||||
    "294": "3)  Violets are blue,",
 | 
			
		||||
    "295": "",
 | 
			
		||||
    "296": "",
 | 
			
		||||
    "297": "6)  Sugar is sweet",
 | 
			
		||||
    "298": "7)  And so are you.",
 | 
			
		||||
    "318": "Fix the errors on this line and replace them with undo.",
 | 
			
		||||
    "319": "Fix the errors on this line and replace them with undo.",
 | 
			
		||||
 
 | 
			
		||||
@@ -16,16 +16,21 @@ describe(':Tutor', function()
 | 
			
		||||
    command('Tutor')
 | 
			
		||||
    screen = Screen.new(81, 30)
 | 
			
		||||
    screen:set_default_attr_ids({
 | 
			
		||||
      [0] = { foreground = Screen.colors.DarkBlue, background = Screen.colors.Gray },
 | 
			
		||||
      [0] = { foreground = Screen.colors.Blue4, background = Screen.colors.Grey },
 | 
			
		||||
      [1] = { bold = true },
 | 
			
		||||
      [2] = { underline = true, foreground = tonumber('0x0088ff') },
 | 
			
		||||
      [3] = { foreground = Screen.colors.SlateBlue },
 | 
			
		||||
      [4] = { bold = true, foreground = Screen.colors.Brown },
 | 
			
		||||
      [5] = { bold = true, foreground = Screen.colors.Magenta1 },
 | 
			
		||||
      [6] = { italic = true },
 | 
			
		||||
      [7] = { foreground = tonumber('0x00ff88'), bold = true, background = Screen.colors.Grey },
 | 
			
		||||
      [8] = { bold = true, foreground = Screen.colors.Blue },
 | 
			
		||||
      [9] = { foreground = Screen.colors.Magenta1 },
 | 
			
		||||
      [10] = { foreground = tonumber('0xff2000'), bold = true },
 | 
			
		||||
      [11] = { foreground = tonumber('0xff2000'), bold = true, background = Screen.colors.Grey },
 | 
			
		||||
      [12] = { foreground = tonumber('0x6a0dad') },
 | 
			
		||||
    })
 | 
			
		||||
  end)
 | 
			
		||||
 | 
			
		||||
  it('applies {unix:…,win:…} transform', function()
 | 
			
		||||
    local expected = is_os('win')
 | 
			
		||||
        and [[
 | 
			
		||||
@@ -134,62 +139,150 @@ describe(':Tutor', function()
 | 
			
		||||
    feed(':983<CR>zt')
 | 
			
		||||
    screen:expect(expected)
 | 
			
		||||
  end)
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
describe(':Tutor tutor', function()
 | 
			
		||||
  local screen --- @type test.functional.ui.screen
 | 
			
		||||
 | 
			
		||||
  before_each(function()
 | 
			
		||||
    clear({ args = { '--clean' } })
 | 
			
		||||
    command('set cmdheight=0')
 | 
			
		||||
    command('Tutor tutor')
 | 
			
		||||
    screen = Screen.new(81, 30)
 | 
			
		||||
    screen:set_default_attr_ids({
 | 
			
		||||
      [0] = { foreground = Screen.colors.DarkBlue, background = Screen.colors.Gray },
 | 
			
		||||
      [1] = { bold = true },
 | 
			
		||||
      [2] = { underline = true, foreground = tonumber('0x0088ff') },
 | 
			
		||||
      [3] = { foreground = Screen.colors.SlateBlue },
 | 
			
		||||
      [4] = { bold = true, foreground = Screen.colors.Brown },
 | 
			
		||||
      [5] = { bold = true, foreground = Screen.colors.Magenta1 },
 | 
			
		||||
      [6] = { italic = true },
 | 
			
		||||
      [7] = { foreground = tonumber('0x00ff88'), bold = true, background = Screen.colors.Grey },
 | 
			
		||||
      [8] = { bold = true, foreground = Screen.colors.Blue1 },
 | 
			
		||||
    })
 | 
			
		||||
  end)
 | 
			
		||||
 | 
			
		||||
  it('applies interactive marks', function()
 | 
			
		||||
    feed(':216<CR>zt')
 | 
			
		||||
  it("removing a line doesn't affect highlight/mark of other lines", function()
 | 
			
		||||
    -- Do lesson 2.6
 | 
			
		||||
    feed(':294<CR>zt')
 | 
			
		||||
    screen:expect([[
 | 
			
		||||
  {0:  }{3:^###}{5: expect }                                                                    |
 | 
			
		||||
  {0:  }                                                                               |
 | 
			
		||||
  {0:  }"expect" lines check that the contents of the line are identical to some preset|
 | 
			
		||||
  {0:  } text                                                                          |
 | 
			
		||||
  {0:  }(like in the exercises above).                                                 |
 | 
			
		||||
  {0:  }                                                                               |
 | 
			
		||||
  {0:  }These elements are specified in separate JSON files like this                  |
 | 
			
		||||
  {0:  }                                                                               |
 | 
			
		||||
  {0:  }{3:~~~ json}                                                                       |
 | 
			
		||||
  {0:  }{                                                                              |
 | 
			
		||||
  {0:  }  "expect": {                                                                  |
 | 
			
		||||
  {0:  }    "1": "This is how this line should look.",                                 |
 | 
			
		||||
  {0:  }    "2": "This is how this line should look.",                                 |
 | 
			
		||||
  {0:  }    "3": -1                                                                    |
 | 
			
		||||
  {0:  }  }                                                                            |
 | 
			
		||||
  {0:  }}                                                                              |
 | 
			
		||||
  {0:  }{3:~~~}                                                                            |
 | 
			
		||||
  {0:  }                                                                               |
 | 
			
		||||
  {0:  }These files contain an "expect" dictionary, for which the keys are line numbers|
 | 
			
		||||
  {0:  } and                                                                           |
 | 
			
		||||
  {0:  }the values are the expected text. A value of -1 means that the condition for th|
 | 
			
		||||
  {0:  }e line                                                                         |
 | 
			
		||||
  {0:  }will always be satisfied, no matter what (this is useful for letting the user p|
 | 
			
		||||
  {0:  }lay a bit).                                                                    |
 | 
			
		||||
  {0:  }                                                                               |
 | 
			
		||||
  {7:✓ }{3:This is an "expect" line that is always satisfied. Try changing it.}            |
 | 
			
		||||
  {0:  }                                                                               |
 | 
			
		||||
  {0:  }These files conventionally have the same name as the tutorial document with the|
 | 
			
		||||
  {0:  } .json                                                                         |
 | 
			
		||||
  {0:  }extension appended (for a full example, see the file that corresponds to thi{8:@@@}|
 | 
			
		||||
      {0:  }{3:^#}{5: Lesson 2.6: OPERATING ON LINES}                                               |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  }{1: Type }{4:dd}{1: to delete a whole line. }                                              |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  }Due to the frequency of whole line deletion, the designers of Vi decided       |
 | 
			
		||||
      {0:  }it would be easier to simply type two d's to delete a line.                    |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  } 1. Move the cursor to the second line in the phrase below.                    |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  } 2. Type {2:dd} to delete the line.                                                |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  } 3. Now move to the fourth line.                                               |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  } 4. Type {9:2}{4:dd} to delete two lines.                                              |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {7:✓ }{3:1)  Roses are red,                                                             }|
 | 
			
		||||
      {11:✗ }{3:2)  Mud is fun,                                                                }|
 | 
			
		||||
      {7:✓ }{3:3)  Violets are blue,                                                          }|
 | 
			
		||||
      {11:✗ }{3:4)  I have a car,                                                              }|
 | 
			
		||||
      {11:✗ }{3:5)  Clocks tell time,                                                          }|
 | 
			
		||||
      {7:✓ }{3:6)  Sugar is sweet                                                             }|
 | 
			
		||||
      {7:✓ }{3:7)  And so are you.                                                            }|
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  }{3:#}{5: Lesson 2.7: THE UNDO COMMAND}                                                 |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  }{1: Press }{4:u}{1: to undo the last commands, }{4:U}{1: to fix a whole line. }                    |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  } 1. Move the cursor to the line below marked {10:✗} and place it on the first error.|
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  } 2. Type {4:x} to delete the first unwanted character.                             |
 | 
			
		||||
]])
 | 
			
		||||
 | 
			
		||||
    feed('<Cmd>310<CR>dd<Cmd>311<CR>2dd')
 | 
			
		||||
    screen:expect([[
 | 
			
		||||
      {0:  }{3:#}{5: Lesson 2.6: OPERATING ON LINES}                                               |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  }{1: Type }{4:dd}{1: to delete a whole line. }                                              |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  }Due to the frequency of whole line deletion, the designers of Vi decided       |
 | 
			
		||||
      {0:  }it would be easier to simply type two d's to delete a line.                    |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  } 1. Move the cursor to the second line in the phrase below.                    |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  } 2. Type {2:dd} to delete the line.                                                |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  } 3. Now move to the fourth line.                                               |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  } 4. Type {9:2}{4:dd} to delete two lines.                                              |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {7:✓ }{3:1)  Roses are red,                                                             }|
 | 
			
		||||
      {7:✓ }{3:3)  Violets are blue,                                                          }|
 | 
			
		||||
      {7:✓ }{3:^6)  Sugar is sweet                                                             }|
 | 
			
		||||
      {7:✓ }{3:7)  And so are you.                                                            }|
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  }{3:#}{5: Lesson 2.7: THE UNDO COMMAND}                                                 |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  }{1: Press }{4:u}{1: to undo the last commands, }{4:U}{1: to fix a whole line. }                    |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  } 1. Move the cursor to the line below marked {10:✗} and place it on the first error.|
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  } 2. Type {4:x} to delete the first unwanted character.                             |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  } 3. Now type {4:u} to undo the last command executed.                              |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
    ]])
 | 
			
		||||
  end)
 | 
			
		||||
 | 
			
		||||
  it("inserting text at start of line doesn't affect highlight/sign", function()
 | 
			
		||||
    -- Go to lesson 1.3 and make it top line in the window
 | 
			
		||||
    feed('<Cmd>92<CR>zt')
 | 
			
		||||
    screen:expect([[
 | 
			
		||||
      {0:  }{3:^#}{5: Lesson 1.3: TEXT EDITING: DELETION}                                           |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  }{1: Press }{4:x}{1: to delete the character under the cursor. }                            |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  } 1. Move the cursor to the line below marked {10:✗}.                                |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  } 2. To fix the errors, move the cursor until it is on top of the               |
 | 
			
		||||
      {0:  }    character to be deleted.                                                   |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  } 3. Press {2:the x key} to delete the unwanted character.                          |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  } 4. Repeat steps 2 through 4 until the sentence is correct.                    |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {11:✗ }{3:The ccow jumpedd ovverr thhe mooon.                                            }|
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  } 5. Now that the line is correct, go on to Lesson 1.4.                         |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  }{1:NOTE}: As you go through this tutorial, do not try to memorize everything,      |
 | 
			
		||||
      {0:  }      your Neovim vocabulary will expand with usage. Consider returning to     |
 | 
			
		||||
      {0:  }      this tutorial periodically for a refresher.                              |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  }{3:#}{5: Lesson 1.4: TEXT EDITING: INSERTION}                                          |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  }{1: Press }{12:i}{1: to insert text. }                                                      |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  } 1. Move the cursor to the first line below marked {10:✗}.                          |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  } 2. To make the first line the same as the second, move the cursor on top      |
 | 
			
		||||
      {0:  }    of the first character AFTER where the text is to be inserted.             |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
    ]])
 | 
			
		||||
    -- Go to the test line and insert text at the start of the line
 | 
			
		||||
    feed('<Cmd>105<CR>iThe <Esc>')
 | 
			
		||||
    -- Remove redundant characters
 | 
			
		||||
    feed('fcxfdxfvxfrxfhxfox')
 | 
			
		||||
    -- Remove the original "The " text (not the just-inserted one)
 | 
			
		||||
    feed('^4ldw^')
 | 
			
		||||
    screen:expect([[
 | 
			
		||||
      {0:  }{3:#}{5: Lesson 1.3: TEXT EDITING: DELETION}                                           |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  }{1: Press }{4:x}{1: to delete the character under the cursor. }                            |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  } 1. Move the cursor to the line below marked {10:✗}.                                |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  } 2. To fix the errors, move the cursor until it is on top of the               |
 | 
			
		||||
      {0:  }    character to be deleted.                                                   |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  } 3. Press {2:the x key} to delete the unwanted character.                          |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  } 4. Repeat steps 2 through 4 until the sentence is correct.                    |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {7:✓ }{3:^The cow jumped over the moon.                                                  }|
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  } 5. Now that the line is correct, go on to Lesson 1.4.                         |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  }{1:NOTE}: As you go through this tutorial, do not try to memorize everything,      |
 | 
			
		||||
      {0:  }      your Neovim vocabulary will expand with usage. Consider returning to     |
 | 
			
		||||
      {0:  }      this tutorial periodically for a refresher.                              |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  }{3:#}{5: Lesson 1.4: TEXT EDITING: INSERTION}                                          |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  }{1: Press }{12:i}{1: to insert text. }                                                      |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  } 1. Move the cursor to the first line below marked {10:✗}.                          |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
      {0:  } 2. To make the first line the same as the second, move the cursor on top      |
 | 
			
		||||
      {0:  }    of the first character AFTER where the text is to be inserted.             |
 | 
			
		||||
      {0:  }                                                                               |
 | 
			
		||||
    ]])
 | 
			
		||||
  end)
 | 
			
		||||
end)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user