diff --git a/lua/orgmode/org/mappings.lua b/lua/orgmode/org/mappings.lua index 41d7c9fee..47ff3499e 100644 --- a/lua/orgmode/org/mappings.lua +++ b/lua/orgmode/org/mappings.lua @@ -762,7 +762,14 @@ function OrgMappings:move_subtree_up() return utils.echo_warning('Cannot move past superior level.') end local range = item:get_range() - vim.cmd(string.format(':%d,%dmove %d', range.start_line, range.end_line, prev_headline:get_range().start_line - 1)) + local target_line = prev_headline:get_range().start_line - 1 + local foldclosed = vim.fn.foldclosed('.') + vim.cmd(string.format(':%d,%dmove %d', range.start_line, range.end_line, target_line)) + local pos = vim.fn.getcurpos() + vim.fn.cursor(target_line + 1, pos[2]) + if foldclosed > -1 and vim.fn.foldclosed('.') == -1 then + vim.cmd([[norm!zc]]) + end end function OrgMappings:move_subtree_down() @@ -772,7 +779,14 @@ function OrgMappings:move_subtree_down() return utils.echo_warning('Cannot move past superior level.') end local range = item:get_range() - vim.cmd(string.format(':%d,%dmove %d', range.start_line, range.end_line, next_headline:get_range().end_line)) + local target_line = next_headline:get_range().end_line + local foldclosed = vim.fn.foldclosed('.') + vim.cmd(string.format(':%d,%dmove %d', range.start_line, range.end_line, target_line)) + local pos = vim.fn.getcurpos() + vim.fn.cursor(target_line + range.start_line - range.end_line, pos[2]) + if foldclosed > -1 and vim.fn.foldclosed('.') == -1 then + vim.cmd([[norm!zc]]) + end end function OrgMappings:show_help(type) diff --git a/tests/plenary/ui/mappings/headline_spec.lua b/tests/plenary/ui/mappings/headline_spec.lua index 1c267a358..42063aa88 100644 --- a/tests/plenary/ui/mappings/headline_spec.lua +++ b/tests/plenary/ui/mappings/headline_spec.lua @@ -301,7 +301,7 @@ describe('Heading mappings', function() }, vim.api.nvim_buf_get_lines(0, 0, 2, false)) end) - it('should move subtree up (org_move_subtree_up)', function() + it('should move subtree up once (org_move_subtree_up)', function() helpers.create_file({ '#TITLE: Test', '', @@ -311,9 +311,11 @@ describe('Heading mappings', function() 'Some content for level 2', '*** NEXT [#1] Level 3', 'Content Level 3', + '* TODO top level todo with multiple tags :OFFICE:PROJECT:', '* DONE top level todo :WORK:', 'content for top level todo', - '* TODO top level todo with multiple tags :OFFICE:PROJECT:', + '** Subtree level 2', + ' Content of subtree level 2', }) assert.are.same({ @@ -323,15 +325,77 @@ describe('Heading mappings', function() 'Some content for level 2', '*** NEXT [#1] Level 3', 'Content Level 3', + '* TODO top level todo with multiple tags :OFFICE:PROJECT:', + '* DONE top level todo :WORK:', + 'content for top level todo', + '** Subtree level 2', + ' Content of subtree level 2', + }, vim.api.nvim_buf_get_lines(0, 2, 13, false)) + vim.fn.cursor(10, 1) + vim.cmd([[norm ,oK]]) + assert.are.same({ + '* TODO Test orgmode', + ' DEADLINE: <2021-07-21 Wed 22:02>', + '** TODO [#A] Test orgmode level 2 :PRIVATE:', + 'Some content for level 2', + '*** NEXT [#1] Level 3', + 'Content Level 3', + '* DONE top level todo :WORK:', + 'content for top level todo', + '** Subtree level 2', + ' Content of subtree level 2', + '* TODO top level todo with multiple tags :OFFICE:PROJECT:', + }, vim.api.nvim_buf_get_lines(0, 2, 13, false)) + end) + + it('should move subtree up twice (org_move_subtree_up)', function() + helpers.create_file({ + '#TITLE: Test', + '', + '* TODO Test orgmode', + ' DEADLINE: <2021-07-21 Wed 22:02>', + '** TODO [#A] Test orgmode level 2 :PRIVATE:', + 'Some content for level 2', + '*** NEXT [#1] Level 3', + 'Content Level 3', + '* TODO top level todo with multiple tags :OFFICE:PROJECT:', '* DONE top level todo :WORK:', 'content for top level todo', + '** Subtree level 2', + ' Content of subtree level 2', + }) + + assert.are.same({ + '* TODO Test orgmode', + ' DEADLINE: <2021-07-21 Wed 22:02>', + '** TODO [#A] Test orgmode level 2 :PRIVATE:', + 'Some content for level 2', + '*** NEXT [#1] Level 3', + 'Content Level 3', '* TODO top level todo with multiple tags :OFFICE:PROJECT:', - }, vim.api.nvim_buf_get_lines(0, 2, 11, false)) - vim.fn.cursor(9, 1) + '* DONE top level todo :WORK:', + 'content for top level todo', + '** Subtree level 2', + ' Content of subtree level 2', + }, vim.api.nvim_buf_get_lines(0, 2, 13, false)) + vim.fn.cursor(10, 1) + assert.are_same({ + '* DONE top level todo :WORK:', + }, vim.api.nvim_buf_get_lines(0, 9, 10, false)) + vim.cmd([[norm ,oK]]) + local cursor_line = vim.fn.getcurpos()[2] + assert.are.same(9, cursor_line) + assert.are_same({ + '* DONE top level todo :WORK:', + }, vim.api.nvim_buf_get_lines(0, 8, 9, false)) vim.cmd([[norm ,oK]]) + cursor_line = vim.fn.getcurpos()[2] + assert.are.same(3, cursor_line) assert.are.same({ '* DONE top level todo :WORK:', 'content for top level todo', + '** Subtree level 2', + ' Content of subtree level 2', '* TODO Test orgmode', ' DEADLINE: <2021-07-21 Wed 22:02>', '** TODO [#A] Test orgmode level 2 :PRIVATE:', @@ -339,7 +403,7 @@ describe('Heading mappings', function() '*** NEXT [#1] Level 3', 'Content Level 3', '* TODO top level todo with multiple tags :OFFICE:PROJECT:', - }, vim.api.nvim_buf_get_lines(0, 2, 11, false)) + }, vim.api.nvim_buf_get_lines(0, 2, 13, false)) end) it('should move subtree down (org_move_subtree_down)', function() @@ -382,15 +446,19 @@ describe('Heading mappings', function() ' 1. First item', ' 2. Second item', }, vim.api.nvim_buf_get_lines(0, 2, 18, false)) - vim.fn.cursor(9, 1) + vim.fn.cursor(3, 1) vim.cmd([[norm ,oJ]]) + local cursor_line = vim.fn.getcurpos()[2] + assert.are.same(5, cursor_line) assert.are.same({ '* TODO Test orgmode', - ' DEADLINE: <2021-07-21 Wed 22:02>', - '** TODO [#A] Test orgmode level 2 :PRIVATE:', - 'Some content for level 2', - '*** NEXT [#1] Level 3', - 'Content Level 3', + }, vim.api.nvim_buf_get_lines(0, 4, 5, false)) + vim.cmd([[norm ,oJ]]) + cursor_line = vim.fn.getcurpos()[2] + assert.are.same(13, cursor_line) + assert.are.same({ + '* DONE top level todo :WORK:', + 'content for top level todo', '* TODO top level todo with multiple tags :OFFICE:PROJECT:', ' - [ ] The checkbox', ' - [X] The checkbox 2', @@ -399,8 +467,12 @@ describe('Heading mappings', function() '** NEXT Working on this now :OFFICE:NESTED:', ' 1. First item', ' 2. Second item', - '* DONE top level todo :WORK:', - 'content for top level todo', + '* TODO Test orgmode', + ' DEADLINE: <2021-07-21 Wed 22:02>', + '** TODO [#A] Test orgmode level 2 :PRIVATE:', + 'Some content for level 2', + '*** NEXT [#1] Level 3', + 'Content Level 3', }, vim.api.nvim_buf_get_lines(0, 2, 18, false)) end)