Implement environment-split before and previous

Possibility to add an environment before the current one and to append
and environment from outside the nesting scope.

This commit includes all fixes that went in during testing these
functions in master. It also moves the menu items from Edit to Insert.
This commit is contained in:
Juergen Spitzmueller 2018-01-01 12:34:39 +01:00
parent 8ad7b0caea
commit 92613ac63c
6 changed files with 98 additions and 20 deletions

View File

@ -113,7 +113,7 @@ Format 4
\bind "M-a Down" "outline-down"
\bind "M-a Return" "environment-split"
\bind "M-a Return" "command-alternatives environment-split ; environment-split previous"
\bind "M-a S-Return" "environment-split outer"
# Obsolete Tastenbelegung: in die persönliche *.bind Datei kopieren und

View File

@ -126,7 +126,7 @@ Format 4
\bind "M-p Up" "outline-up"
\bind "M-p Down" "outline-down"
\bind "M-p Return" "environment-split"
\bind "M-p Return" "command-alternatives environment-split ; environment-split previous"
\bind "M-p S-Return" "environment-split outer"

View File

@ -134,7 +134,6 @@ Menuset
# obvious what the context is for the others)
OptItem "Increase List Depth|I" "depth-increment"
OptItem "Decrease List Depth|D" "depth-decrement"
EnvironmentSeparators
OptItem "Dissolve Inset" "inset-dissolve"
OptItem "TeX Code Settings...|C" "inset-settings ert"
# 'a' shortcut to match Insert entry, shouldn't clash with Table Settings
@ -393,6 +392,7 @@ Menuset
Item "Hyperlink...|k" "href-insert"
Item "Footnote|F" "footnote-insert"
Item "Marginal Note|M" "marginalnote-insert"
EnvironmentSeparators
Arguments
Item "TeX Code" "ert-insert"
Item "Program Listing[[Menu]]" "listing-insert"

View File

@ -1513,9 +1513,13 @@ void LyXAction::init()
/*!
* \var lyx::FuncCode lyx::LFUN_ENVIRONMENT_SPLIT
* \li Action: Splits the current environment with a Separator.
* \li Syntax: environment-split [outer]
* \li Syntax: environment-split [before|outer|previous]
* \li Params: outer: If this is given, LyX will split the outermost environment in
* the current nesting hierarchy.
the current nesting hierarchy.\n
previous: If this is given, LyX will split the environment in the previous
paragraph (is there is one).\n
before: If this is given, the new environment will be appended rather than
prepended.
* \li Origin: spitz, 23 Dec 2012
* \endvar
*/

View File

@ -1491,36 +1491,74 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
case LFUN_ENVIRONMENT_SPLIT: {
bool const outer = cmd.argument() == "outer";
bool const previous = cmd.argument() == "previous";
bool const before = cmd.argument() == "before";
bool const normal = cmd.argument().empty();
Paragraph const & para = cur.paragraph();
docstring layout = para.layout().name();
docstring layout;
if (para.layout().isEnvironment())
layout = para.layout().name();
depth_type split_depth = cur.paragraph().params().depth();
if (outer) {
// check if we have an environment in our nesting hierarchy
depth_type nextpar_depth = 0;
if (outer || previous) {
// check if we have an environment in our scope
pit_type pit = cur.pit();
Paragraph cpar = pars_[pit];
while (true) {
if (pit == 0 || cpar.params().depth() == 0)
if (pit == 0)
break;
--pit;
cpar = pars_[pit];
if (layout.empty() && previous
&& cpar.layout().isEnvironment()
&& cpar.params().depth() <= split_depth)
layout = cpar.layout().name();
if (cpar.params().depth() < split_depth
&& cpar.layout().isEnvironment()) {
layout = cpar.layout().name();
if (!previous)
layout = cpar.layout().name();
split_depth = cpar.params().depth();
}
if (cpar.params().depth() == 0)
break;
}
}
if (cur.pos() > 0)
if ((outer || normal) && cur.pit() < cur.lastpit()) {
// save nesting of following paragraph
Paragraph cpar = pars_[cur.pit() + 1];
nextpar_depth = cpar.params().depth();
}
if (before)
cur.top().setPitPos(cur.pit(), 0);
if (before || cur.pos() > 0)
lyx::dispatch(FuncRequest(LFUN_PARAGRAPH_BREAK));
else if (previous && cur.nextInset() && cur.nextInset()->lyxCode() == SEPARATOR_CODE)
lyx::dispatch(FuncRequest(LFUN_PARAGRAPH_BREAK, "inverse ignoresep"));
if (outer) {
while (cur.paragraph().params().depth() > split_depth)
lyx::dispatch(FuncRequest(LFUN_DEPTH_DECREMENT));
}
DocumentClass const & tc = bv->buffer().params().documentClass();
lyx::dispatch(FuncRequest(LFUN_LAYOUT, tc.plainLayout().name()));
lyx::dispatch(FuncRequest(LFUN_LAYOUT, from_ascii("\"") + tc.plainLayout().name()
+ from_ascii("\" ignoreautonests")));
lyx::dispatch(FuncRequest(LFUN_SEPARATOR_INSERT, "plain"));
lyx::dispatch(FuncRequest(LFUN_PARAGRAPH_BREAK, "inverse"));
if (before) {
cur.backwardPos();
lyx::dispatch(FuncRequest(LFUN_PARAGRAPH_BREAK, "inverse ignoresep"));
while (cur.paragraph().params().depth() < split_depth)
lyx::dispatch(FuncRequest(LFUN_DEPTH_INCREMENT));
}
else
lyx::dispatch(FuncRequest(LFUN_PARAGRAPH_BREAK, "inverse"));
lyx::dispatch(FuncRequest(LFUN_LAYOUT, layout));
if ((outer || normal) && nextpar_depth > 0) {
// restore nesting of following paragraph
DocIterator scur = cur;
cur.forwardPar();
while (cur.paragraph().params().depth() < nextpar_depth)
lyx::dispatch(FuncRequest(LFUN_DEPTH_INCREMENT));
cur.setCursor(scur);
}
break;
}
@ -3180,6 +3218,19 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
enable = res;
break;
}
else if (cmd.argument() == "previous") {
// look if we have an environment in the previous par
pit_type pit = cur.pit();
Paragraph cpar = pars_[pit];
if (pit > 0) {
--pit;
cpar = pars_[pit];
enable = cpar.layout().isEnvironment();
break;
}
enable = false;
break;
}
else if (cur.paragraph().layout().isEnvironment()) {
enable = true;
break;

View File

@ -1856,33 +1856,56 @@ void MenuDefinition::expandEnvironmentSeparators(BufferView const * bv)
return;
pit_type pit = bv->cursor().selBegin().pit();
pos_type pos = bv->cursor().selBegin().pos();
Paragraph const & par = text->getPar(pit);
docstring const curlayout = par.layout().name();
docstring outerlayout;
docstring prevlayout;
depth_type current_depth = par.params().depth();
// check if we have an environment in our nesting hierarchy
// check if we have an environment in our scope
Paragraph cpar = par;
while (true) {
if (pit == 0 || cpar.params().depth() == 0)
if (pit == 0)
break;
--pit;
cpar = text->getPar(pit);
if (cpar.layout().isEnvironment() && prevlayout.empty()
&& cpar.params().depth() <= current_depth)
prevlayout = cpar.layout().name();
if (cpar.params().depth() < current_depth
&& cpar.layout().isEnvironment()) {
outerlayout = cpar.layout().name();
current_depth = cpar.params().depth();
}
if (cpar.params().depth() == 0)
break;
}
if (par.layout().isEnvironment()) {
docstring const label =
bformat(_("Start New Environment (%1$s)"),
docstring label = bformat(_("Separated %1$s Above"),
translateIfPossible(curlayout));
add(MenuItem(MenuItem::Command, toqstr(label),
FuncRequest(LFUN_ENVIRONMENT_SPLIT)));
FuncRequest(LFUN_ENVIRONMENT_SPLIT,
from_ascii("before"))));
if (!par.layout().keepempty || pos > 0 || !text->isFirstInSequence(pit)) {
label = bformat(_("Separated %1$s Below"),
translateIfPossible(curlayout));
add(MenuItem(MenuItem::Command, toqstr(label),
FuncRequest(LFUN_ENVIRONMENT_SPLIT)));
}
}
else if (!prevlayout.empty()) {
docstring const label =
bformat(_("Separated %1$s Below"),
translateIfPossible(prevlayout));
add(MenuItem(MenuItem::Command, toqstr(label),
FuncRequest(LFUN_ENVIRONMENT_SPLIT,
from_ascii("previous"))));
}
if (!outerlayout.empty()) {
docstring const label =
bformat(_("Start New Parent Environment (%1$s)"),
docstring const label = (outerlayout == curlayout) ?
bformat(_("Separated Outer %1$s Below"),
translateIfPossible(outerlayout)) :
bformat(_("Separated %1$s Below"),
translateIfPossible(outerlayout));
add(MenuItem(MenuItem::Command, toqstr(label),
FuncRequest(LFUN_ENVIRONMENT_SPLIT,