I've been working on a patch for LFUN_PARAGRAPH_MOVE_DOWN move subitems of an item along with the item. For example, consider the following situation:
1. One item <cur> a. "subitem" 2. Another item Currently (i.e., without the patch), if the cursor is at positiion <cur> and the user executes a paragraph-move-down, we get the following: 1. "subitem" 2. One item <cur> 3. Another item With the patch, the user would get the following: 1. Another item 2. One item <cur> a. "subitem" I believe this functionality would be consistent with the current behavior of outline-down (which has the same keybinding as paragraph-move-down), e.g., subsections are moved with sections. Does anyone have comments on the patch, either the desired functionality or the actual code? Can you think of any strange cases that I can test this code on? If no one is against this approach, I will continue working on it and commit. I still need to do the following: - Update the documentation of the LFUN and release notes. - Implement consistent behavior for paragraph-move-up. - Factor out code into methods (this will make it easy to implement paragraph-move-up). - The algorithm for swapping the paragraphs in this patch is inefficient (i.e., the end result could be achieved with fewer swaps). I can work on a more efficient algorithm. Scott
From ea70a6c3fe273c9c6ed9cedc7bebf6cc4d105d52 Mon Sep 17 00:00:00 2001 From: Scott Kostyshak <skost...@lyx.org> Date: Fri, 31 Jan 2020 13:35:16 -0500 Subject: [PATCH] paragraph-move-down now moves sub-items as well --- src/Text3.cpp | 50 ++++++++++++++++++++++++++++++---- src/support/RandomAccessList.h | 20 ++++++++++++++ 2 files changed, 65 insertions(+), 5 deletions(-) diff --git a/src/Text3.cpp b/src/Text3.cpp index 8643411da1..9a1470aea3 100644 --- a/src/Text3.cpp +++ b/src/Text3.cpp @@ -671,13 +671,53 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) switch (act) { case LFUN_PARAGRAPH_MOVE_DOWN: { - pit_type const pit = cur.pit(); - cur.recordUndo(pit, pit + 1); - cur.finishUndo(); - pars_.swap(pit, pit + 1); + depth_type const cur_depth = pars_[cur.pit()].params().depth(); + pit_type pit = cur.pit() + 1; + Paragraph cpar; + while (pit != pit_type(pars_.size())) { + cpar = pars_[pit]; + // <= because it's possible to go e.g. from depth 2 to 0 + if (cpar.params().depth() <= cur_depth) + break; + ++pit; + } + if (cpar.params().depth() < cur_depth) { + // we did not encounter an equal depth before a smaller + // depth, so there is no sibling. e.g.: + // 1. hello + // a. blah <cur> + // 2. goodbye + break; + } + if (cpar.params().depth() > cur_depth) { + // all paragraphs below cur have larger depth + // so there is no next sibling. e.g.: + // 1. hello <cur> + // a. blah + // <end of document> + break; + } + pit_type const next_sib = pit; + + // this is the depth of the paragraph below whose "family" we + // want to move. + depth_type next_sib_depth = cpar.params().depth(); + pit_type pit2 = next_sib + 1; + while (pit2 != pit_type(pars_.size())) { + cpar = pars_[pit2]; + // <= because it's possible to go e.g. from depth 2 to 0 + if (cpar.params().depth() <= next_sib_depth) + break; + ++pit2; + } + pit_type const next_sib_end = pit2 - 1; + + cur.recordUndo(cur.pit(), next_sib_end); + pars_.swap(cur.pit(), next_sib - 1, next_sib_end); needsUpdate = true; cur.forceBufferUpdate(); - ++cur.pit(); + // move the cursor with the paragraph + cur.pit() = next_sib_end - (next_sib - cur.pit()) + 1; break; } diff --git a/src/support/RandomAccessList.h b/src/support/RandomAccessList.h index 2565d62513..8a7eda0ca4 100644 --- a/src/support/RandomAccessList.h +++ b/src/support/RandomAccessList.h @@ -246,6 +246,26 @@ public: return it; } + void swap(size_t from_beg, size_t from_end, size_t to_end) + { + // swap of contiguous ranges of elements: + // + // swap elements from_beg through from_end with + // elements from_end + 1 through to_end. + // The ranges do not need to be the same length. + + // number of swaps for each element in "to" range + int const num_swaps = (from_end + 1) - from_beg; + + // swap each element in "to" range up to the correct + // location, one-by-one (i.e., inefficient) + for (size_t i = from_end + 1; i != to_end + 1; i++) { + for (size_t j = i; j != i - num_swaps; j--) { + swap(j, j - 1); + } + } + } + void swap(size_t i, size_t j) { size_t const p = std::max(i, j); -- 2.20.1
signature.asc
Description: PGP signature
-- lyx-devel mailing list lyx-devel@lists.lyx.org http://lists.lyx.org/mailman/listinfo/lyx-devel