Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- BeginPackage["Undo`"]
- SetUpUndo::usage="";
- Begin["`Private`"]
- getCellID[]:="CellID"/.Developer`CellInformation[EvaluationNotebook[]]
- ClearAll[appendEvents];
- appendEvents[evList_,(Rule|RuleDelayed)[lhs_,rhs_]]/;MemberQ[evList, (Rule|RuleDelayed)[lhs,_]]:=evList/.(Rule|RuleDelayed)[lhs,sth_]:>(lhs:>(sth;rhs));
- appendEvents[evList_, ev_]:=Append[evList, ev]
- checkCreateUndoNotebook[]:=Refresh[
- With[{nb:=CurrentValue[EvaluationNotebook[], {TaggingRules,"undoNotebook"}]},
- If[(* if the undo notebook is not created or open *)!TrueQ@NotebookTools`NotebookOpenQ@nb,
- nb=CreateDocument[{}, CellGrouping->Manual,Visible->False,ShowSelection->False,
- WindowTitle->FileBaseName[WindowTitle/.AbsoluteOptions[EvaluationNotebook[], WindowTitle]]<>"_undoData"];
- ]], None]
- nbdeRules={Dynamic[rhs_]:>Dynamic[rhs; Needs["Undo`"];Undo`Private`checkCreateUndoNotebook[]], Null:>Dynamic[Needs["Undo`"];Undo`Private`checkCreateUndoNotebook[]],rhs_:>Dynamic[rhs;Needs["Undo`"];Undo`Private`checkCreateUndoNotebook[]]};
- parseNBEOptions[nb_]:=ReleaseHold@Replace[Hold[NotebookDynamicExpression]/.Options[nb, NotebookDynamicExpression], nbdeRules, {1}]
- appendNDE[nb_NotebookObject]:=SetOptions[nb, parseNBEOptions[nb]/.newNDE_:>NotebookDynamicExpression:>newNDE]
- appendNEA[nb_NotebookObject]:=(* appends the notebook event action WindowClose *)
- appendEvents[Replace[NotebookEventActions/.Options[nb, NotebookEventActions], None:>{}], "WindowClose":>NotebookClose@CurrentValue[EvaluationNotebook[], {TaggingRules,"undoNotebook"}]]/.newOpts_:>SetOptions[nb, NotebookEventActions:>newOpts]
- SetUpUndo[nb_NotebookObject,styles_List]:=SetOptions[initializeNotebook[nb];nb, StyleDefinitions->Fold[
- #1/.{s_String:>Notebook[{Cell[StyleData[StyleDefinitions->s]],Cell[StyleData[#2],cellEventActions
- ]}],
- Notebook[{bef___,Cell[StyleData[#2],cellRest___],aft___}, rest___]:>Notebook[{bef,Cell[StyleData[#2], cellRest, cellEventActions],aft}, rest],
- Notebook[{all___}, rest___]:>Notebook[{all, Cell[StyleData[#2], cellEventActions]},rest]
- }&,
- FullOptions[nb, StyleDefinitions],styles]];
- SetUpUndo[nb_,styles_]:=SetUpUndo[nb, {styles}];
- $defaultFrequency=15;
- initializeNotebook[nb_NotebookObject]:=Through@{appendNDE, appendNEA,
- SetOptions[#, CreateCellID->True]&,
- (CurrentValue[#, {TaggingRules, "undoSettings", "frequency"}]=$defaultFrequency)&}[
- nb];
- cellEventActions=CellEventActions:>{PassEventsDown -> True, "KeyDown" :> If[CurrentValue["EventKey"]=!=None,undoSave[CurrentValue[CellID]]],"MouseClicked":>If[CurrentValue["AltKey"], undoLoad@CurrentValue@CellID]};
- ClearAll[undoSave];
- undoSave[id_Integer]:=
- If[Mod[ ++ idCounter[id],
- CurrentValue[EvaluationNotebook[], {TaggingRules, "undoSettings", "frequency"}]] === 0,
- undoSave[ToString@id, CurrentValue[EvaluationNotebook[], {TaggingRules,"undoNotebook"}]]];
- undoSave[id_, undoNb_]:=(If[
- NotebookFind[undoNb, ToString@id<>"End", All, CellTags]===$Failed,
- createCellIDZone[id][undoNb],
- SelectionMove[undoNb, Before, Cell]];
- copyCell[EvaluationNotebook[], undoNb]);
- createCellIDZone[id_][nb_NotebookObject]:=(ToString@id/.idStr_:>{idStr<>"Start", idStr<>"End"}/.{stag_, etag_}:>FrontEndExecute[{
- FrontEnd`SelectionMove[nb,After,CellGroup],
- FrontEnd`NotebookWrite[nb,Cell@CellGroupData[{Cell["Start", CellTags->stag],Cell["End", CellTags->etag]}]],
- FrontEnd`SelectionMove[undoNb, Previous, Cell],
- FrontEnd`SelectionMove[undoNb, Before, Cell]}];
- nb)
- undoNb:=CurrentValue[EvaluationNotebook[], {TaggingRules, "undoNotebook"}];
- idCounter[_]=0;
- ClearAll[doSthWithWholeCellSelected];
- doSthWithWholeCellSelected[sth_,what_:Cell][nb_]:=With[{val=CurrentValue[nb, ShowSelection],
- cursor=("CursorPosition"/.Developer`CellInformation[nb])[[1,1]]},
- FrontEndExecute[{
- FrontEnd`SetOptions[nb, ShowSelection->False],
- FrontEnd`SelectionMove[nb, All, what,AutoScroll->False]}];
- With[{cell=sth[nb]},
- {FrontEnd`SelectionMove[nb, Before, CellContents, AutoScroll->False],
- FrontEnd`SelectionMove[nb, Next, Character, cursor, AutoScroll->False],
- FrontEnd`SetOptions[nb, ShowSelection->val]}/.l:{a_, b_, c_}:>If[cursor>0,FrontEndExecute@l,FrontEndExecute[{a,c}]];
- cell
- ]
- ]
- getCurrentCell[nb_NotebookObject]:=doSthWithWholeCellSelected[NotebookRead][nb];
- copyCell[nbFrom_, nbTo_]:=NotebookWrite[nbTo, getCurrentCell[nbFrom]]
- replaceCurrentCellContents[nb_NotebookObject, newCell_]:=doSthWithWholeCellSelected[NotebookWrite[#, newCell]&, CellContents][nb];
- undoLoad[id_Integer]:=undoLoad[ToString@id,CurrentValue[EvaluationNotebook[], {TaggingRules, "undoNotebook"}]];
- undoLoad[id_, nb_]:=If[(* if it is found *)
- NotebookFind[undoNb, ToString@id<>"End", All, CellTags]=!=$Failed,
- SelectionMove[undoNb, Previous, Cell];
- replaceCurrentCellContents[EvaluationNotebook[],If[CurrentValue[NotebookSelection@undoNb, CellTags]=!=ToString@id<>"Start",(NotebookDelete[undoNb];#)&@NotebookRead[undoNb],SelectionMove[undoNb, After, Cell];""]]]
- End[];
- EndPackage[];
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement