Jean-Marc Lasgouttes wrote:
LFUN_TAB_INSERT currently
only works with listings. You might be able to redo the bindings so
that the tab key would insert a tab, perhaps via unicode-insert and
then the tab character, but I'm not sure.
This probably that this code should be made more generic and usable in
custom insets... I am not sure how difficult this would be.
Fairly easy, I think. The attached basically just moves the code from
InsetListings to InsetCollapsable and tests against PassThru. I haven't
actually tested it but can't see how it wouldn't work.
rh
Index: src/insets/InsetListings.cpp
===================================================================
--- src/insets/InsetListings.cpp (revision 30194)
+++ src/insets/InsetListings.cpp (working copy)
@@ -325,86 +325,6 @@
cur.bv().updateDialog("listings", params2string(params()));
break;
- case LFUN_TAB_INSERT: {
- bool const multi_par_selection = cur.selection() &&
- cur.selBegin().pit() != cur.selEnd().pit();
- if (multi_par_selection) {
- // If there is a multi-paragraph selection, a tab is
inserted
- // at the beginning of each paragraph.
- cur.recordUndoSelection();
- pit_type const pit_end = cur.selEnd().pit();
- for (pit_type pit = cur.selBegin().pit(); pit <=
pit_end; pit++) {
- paragraphs()[pit].insertChar(0, '\t',
- buffer().params().trackChanges);
- // Update the selection pos to make sure the
selection does not
- // change as the inserted tab will increase the
logical pos.
- if (cur.anchor_.pit() == pit)
- cur.anchor_.forwardPos();
- if (cur.pit() == pit)
- cur.forwardPos();
- }
- cur.finishUndo();
- } else {
- // Maybe we shouldn't allow tabs within a line, because
they
- // are not (yet) aligned as one might do expect.
- FuncRequest cmd(LFUN_SELF_INSERT, from_ascii("\t"));
- dispatch(cur, cmd);
- }
- break;
- }
-
- case LFUN_TAB_DELETE:
- if (cur.selection()) {
- // If there is a selection, a tab (if present) is
removed from
- // the beginning of each paragraph.
- cur.recordUndoSelection();
- pit_type const pit_end = cur.selEnd().pit();
- for (pit_type pit = cur.selBegin().pit(); pit <=
pit_end; pit++) {
- Paragraph & par = paragraphs()[pit];
- if (par.getChar(0) == '\t') {
- if (cur.pit() == pit)
- cur.posBackward();
- if (cur.anchor_.pit() == pit &&
cur.anchor_.pos() > 0 )
- cur.anchor_.backwardPos();
-
- par.eraseChar(0,
buffer().params().trackChanges);
- } else
- // If no tab was present, try to remove
up to four spaces.
- for (int n_spaces = 0;
- par.getChar(0) == ' ' &&
n_spaces < 4; ++n_spaces) {
- if (cur.pit() == pit)
-
cur.posBackward();
- if (cur.anchor_.pit()
== pit && cur.anchor_.pos() > 0 )
-
cur.anchor_.backwardPos();
-
- par.eraseChar(0,
buffer().params().trackChanges);
- }
- }
- cur.finishUndo();
- } else {
- // If there is no selection, try to remove a tab or
some spaces
- // before the position of the cursor.
- Paragraph & par = paragraphs()[cur.pit()];
- pos_type const pos = cur.pos();
-
- if (pos == 0)
- break;
-
- char_type const c = par.getChar(pos - 1);
- cur.recordUndo();
- if (c == '\t') {
- cur.posBackward();
- par.eraseChar(cur.pos(),
buffer().params().trackChanges);
- } else
- for (int n_spaces = 0; cur.pos() > 0
- && par.getChar(cur.pos() - 1) == ' ' &&
n_spaces < 4;
- ++n_spaces) {
- cur.posBackward();
- par.eraseChar(cur.pos(),
buffer().params().trackChanges);
- }
- cur.finishUndo();
- }
- break;
default:
InsetCollapsable::doDispatch(cur, cmd);
break;
@@ -423,10 +343,6 @@
case LFUN_CAPTION_INSERT:
status.setEnabled(!params().isInline());
return true;
- case LFUN_TAB_INSERT:
- case LFUN_TAB_DELETE:
- status.setEnabled(true);
- return true;
default:
return InsetCollapsable::getStatus(cur, cmd, status);
}
Index: src/insets/InsetCollapsable.cpp
===================================================================
--- src/insets/InsetCollapsable.cpp (revision 30192)
+++ src/insets/InsetCollapsable.cpp (working copy)
@@ -597,6 +597,87 @@
break;
}
+ case LFUN_TAB_INSERT: {
+ bool const multi_par_selection = cur.selection() &&
+ cur.selBegin().pit() != cur.selEnd().pit();
+ if (multi_par_selection) {
+ // If there is a multi-paragraph selection, a tab is
inserted
+ // at the beginning of each paragraph.
+ cur.recordUndoSelection();
+ pit_type const pit_end = cur.selEnd().pit();
+ for (pit_type pit = cur.selBegin().pit(); pit <=
pit_end; pit++) {
+ paragraphs()[pit].insertChar(0, '\t',
+ buffer().params().trackChanges);
+ // Update the selection pos to make sure the
selection does not
+ // change as the inserted tab will increase the
logical pos.
+ if (cur.anchor_.pit() == pit)
+ cur.anchor_.forwardPos();
+ if (cur.pit() == pit)
+ cur.forwardPos();
+ }
+ cur.finishUndo();
+ } else {
+ // Maybe we shouldn't allow tabs within a line, because
they
+ // are not (yet) aligned as one might do expect.
+ FuncRequest cmd(LFUN_SELF_INSERT, from_ascii("\t"));
+ dispatch(cur, cmd);
+ }
+ break;
+ }
+
+ case LFUN_TAB_DELETE:
+ if (cur.selection()) {
+ // If there is a selection, a tab (if present) is
removed from
+ // the beginning of each paragraph.
+ cur.recordUndoSelection();
+ pit_type const pit_end = cur.selEnd().pit();
+ for (pit_type pit = cur.selBegin().pit(); pit <=
pit_end; pit++) {
+ Paragraph & par = paragraphs()[pit];
+ if (par.getChar(0) == '\t') {
+ if (cur.pit() == pit)
+ cur.posBackward();
+ if (cur.anchor_.pit() == pit &&
cur.anchor_.pos() > 0 )
+ cur.anchor_.backwardPos();
+
+ par.eraseChar(0,
buffer().params().trackChanges);
+ } else
+ // If no tab was present, try to remove
up to four spaces.
+ for (int n_spaces = 0;
+ par.getChar(0) == ' ' &&
n_spaces < 4; ++n_spaces) {
+ if (cur.pit() == pit)
+
cur.posBackward();
+ if (cur.anchor_.pit()
== pit && cur.anchor_.pos() > 0 )
+
cur.anchor_.backwardPos();
+
+ par.eraseChar(0,
buffer().params().trackChanges);
+ }
+ }
+ cur.finishUndo();
+ } else {
+ // If there is no selection, try to remove a tab or
some spaces
+ // before the position of the cursor.
+ Paragraph & par = paragraphs()[cur.pit()];
+ pos_type const pos = cur.pos();
+
+ if (pos == 0)
+ break;
+
+ char_type const c = par.getChar(pos - 1);
+ cur.recordUndo();
+ if (c == '\t') {
+ cur.posBackward();
+ par.eraseChar(cur.pos(),
buffer().params().trackChanges);
+ } else
+ for (int n_spaces = 0; cur.pos() > 0
+ && par.getChar(cur.pos() - 1) == ' ' &&
n_spaces < 4;
+ ++n_spaces) {
+ cur.posBackward();
+ par.eraseChar(cur.pos(),
buffer().params().trackChanges);
+ }
+ cur.finishUndo();
+ }
+ break;
+
default:
if (layout_ && layout_->isForceLtr()) {
// Force any new text to latex_language
@@ -750,6 +831,14 @@
flag.setEnabled(layout_->isMultiPar());
return true;
+ case LFUN_TAB_INSERT:
+ case LFUN_TAB_DELETE:
+ if (layout_->isPassThru()) {
+ flag.setEnabled(true);
+ return true;
+ }
+ return InsetText::getStatus(cur, cmd, flag);
+
default:
return InsetText::getStatus(cur, cmd, flag);
}