5
$\begingroup$

Every time I open a new notebook I have to manually evaluate this code in that notebook. In order order to stop my cursor moving to a new cell.

How would I automate this? I would love this functionality to auto-load on startup.

I have tried putting it in a file.m file and adding a Get["/path/to/file.m"] line, to my FileNameJoin[{$UserBaseDirectory , "Kernel", "init.m"}]. Unfortunately this does not work. As it seems to need to be evaluated in the SelectedNotebook[] to work.

Here is the code by @Kuba

With[
  { nb := EvaluationNotebook[]
  , c := EvaluationCell[]
  }
, With[
    { cv := CurrentValue[nb, {"TaggingRules", "LastCursorPosition"}]
    , pos := FrontEndExecute@FrontEnd`UndocumentedGetSelectionPacket[nb]
    }
  , With[
      { savePosition := (
          cv = If[MemberQ[pos, "CharacterRange" -> _], Last["CharacterRange" /. pos], False]
        )
      }
    , SetOptions[nb
      , CellEventActions :> {
          {"MenuCommand", "HandleShiftReturn"} :> savePosition
        , {"MenuCommand", "EvaluateCells"} :> savePosition
        , PassEventsDown -> True
        }
      , CellEpilog :>  If[
          IntegerQ[cv]
        , SelectionMove[c, Before, CellContents]
        ; SelectionMove[nb, Next, Character, cv]
        ; cv = False
        ]
      ]
    ]
  ]
]
$\endgroup$
9
$\begingroup$

Here's a stylesheet version that mimics Kuba's code:

With[{cv := CurrentValue[EvaluationCell[], {TaggingRules, "LastCursorPosition"}]},
    SetOptions[EvaluationNotebook[],
        StyleDefinitions -> Notebook[
            {
            Cell[StyleData[StyleDefinitions->"Default.nb"]],
            Cell[StyleData["Input"],
                CellEventActions -> {
                    {"MenuCommand","HandleShiftReturn"} :> Set[
                        cv,
                        Replace[
                            Lookup[
                                Developer`CellInformation @ EvaluationCell[],
                                "CursorPosition"
                            ],
                            {
                                {_, i_} -> i,
                                _ -> False
                            }
                        ]
                    ],
                    PassEventsDown->True
                },
                CellEpilog :> Replace[cv,
                    i_Integer :> (
                        SelectionMove[EvaluationCell[], Before, CellContents];
                        SelectionMove[EvaluationNotebook[], Next, Character, i];
                        cv = False
                    )
                ],
                TaggingRules -> {}
            ]
            },
            StyleDefinitions->"PrivateStylesheetFormatting.nb"
        ]
    ]
]

You can modify the default stylesheet to use for new notebooks, see the answers to How to change the default Notebook stylesheet.

$\endgroup$
2
  • $\begingroup$ Thanks for your answer. I followed the link and I have successfully changed my default notebook stylesheet from Default.nb to DefaultModified.nb. I am confused. Where do I put your code? Do I paste it somewhere inside DefaultModified.nb? $\endgroup$ May 26 '19 at 14:11
  • 3
    $\begingroup$ @ConorCosnett If you have a stylesheet that you want to modify to include the above styles, you can open a new notebook and run the above code in the notebook. Then, edit the notebook stylesheet, copy the "Input" style, and paste it into the stylesheet you want to modify. $\endgroup$
    – Carl Woll
    May 27 '19 at 5:09
2
$\begingroup$

For future generations, this is how you do it. Place this in your init.m:

If[$Notebooks,
AppendTo[CurrentValue[$FrontEnd, {CodeAssistOptions, "IncludedCompletions"}], "Blacklisted"];
Begin["CursorSave`"];
SaveCursorPosition[] := ( 
    $LastNotebookObject = EvaluationNotebook[];
    $LastCellObject = First @ SelectedCells[$LastNotebookObject];
    $LastCellCursorPosition = First @ Lookup[
        Developer`CellInformation[EvaluationCell[]], 
        "CursorPosition"
    ];
);
RestoreCursorPosition[] := (
    SelectionMove[$LastCellObject, Before, CellContents];
    SelectionMove[$LastNotebookObject, Next, Character, $LastCellCursorPosition];
);
SetOptions[$FrontEndSession, FrontEndEventActions -> {{"MenuCommand", "HandleShiftReturn"} :> 
    (SaveCursorPosition[]; FrontEndTokenExecute["EvaluateCells"]; RestoreCursorPosition[])}];
End[];
];
$\endgroup$

This site is temporarily in read only mode and not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .