Fix to #8159: Undo doesn't restore environment depth correctly

The idea is to record undo at the place where the document is modified:

1/ in Buffer::updateBuffer, add a recordUndo, with the caveat that a
   const_cast has to be used (because updateBuffer is const but
   modifies the document, go figure).

2/ in GuiApplication::dispatch, add an extra undo group that
   encompasses the updateBuffer call. Some other undo groups may be
   redundant now, but it is not a problem since they do not cost
   anything.
This commit is contained in:
Jean-Marc Lasgouttes 2012-06-04 18:02:59 +02:00
parent c22334eb3b
commit bbbc2b6541
2 changed files with 21 additions and 2 deletions

View File

@ -4434,7 +4434,17 @@ void Buffer::updateBuffer(ParIterator & parit, UpdateType utype) const
pit_type const lastpit = parit.lastpit();
for ( ; parit.pit() <= lastpit ; ++parit.pit()) {
// reduce depth if necessary
parit->params().depth(min(parit->params().depth(), maxdepth));
if (parit->params().depth() > maxdepth) {
/** FIXME: this function is const, but
* nevertheless it modifies the buffer. To be
* cleaner, one should modify the buffer in
* another function, which is actually
* non-const. This would however be costly in
* terms of code duplication.
*/
const_cast<Buffer *>(this)->undo().recordUndo(parit);
parit->params().depth(maxdepth);
}
maxdepth = parit->getMaxDepthAfter();
if (utype == OutputUpdate) {

View File

@ -1132,8 +1132,13 @@ static docstring makeDispatchMessage(docstring const & msg,
void GuiApplication::dispatch(FuncRequest const & cmd)
{
if (current_view_ && current_view_->currentBufferView())
Buffer * buffer = 0;
if (current_view_ && current_view_->currentBufferView()) {
current_view_->currentBufferView()->cursor().saveBeforeDispatchPosXY();
buffer = &current_view_->currentBufferView()->buffer();
if (buffer)
buffer->undo().beginUndoGroup();
}
DispatchResult dr;
// redraw the screen at the end (first of the two drawing steps).
@ -1141,6 +1146,10 @@ void GuiApplication::dispatch(FuncRequest const & cmd)
dr.screenUpdate(Update::FitCursor);
dispatch(cmd, dr);
updateCurrentView(cmd, dr);
// the buffer may have been closed by one action
if (theBufferList().isLoaded(buffer))
buffer->undo().endUndoGroup();
}