Skip to main content
8 of 10
added 546 characters in body
Alexey Popkov
  • 62.3k
  • 7
  • 154
  • 375

Is there any way to Print without suffering form auto-scrolling in the front end?

You can define a custom myPrint function with AutoScroll -> False:

myPrint[expr_] := 
 NotebookWrite[EvaluationNotebook[], 
  Cell[BoxData@ToBoxes@expr, "Print"], AutoScroll -> False]

As it is noted in the comments, with this version clicking anywhere inside of the Notebook may result in changing the insertion point and further outputs will be printed starting from the new location. Also there are issues with evaluation of multiple cells at once. Here is an improved version which binds the printing to the EvaluationCell[] and as a result prints in the reverse order (what may be desirable in some situations):

myPrint[expr_] := (
  SelectionMove[EvaluationCell[], After, Cell, AutoScroll -> False];
  NotebookWrite[EvaluationNotebook[], 
   Cell[BoxData@ToBoxes@expr, "Print"], AutoScroll -> False])

And here is a version that prints in the usual order (based on the workaround from this answer):

myPrint[expr_] := (
  SelectionMove[EvaluationCell[], All, CellGroup, AutoScroll -> False];
  If[SelectedCells[] === {},
   SelectionMove[EvaluationCell[], After, Cell, AutoScroll -> False],
   SelectionMove[EvaluationNotebook[], After, CellGroup, AutoScroll -> False]];
  NotebookWrite[EvaluationNotebook[], 
   Cell[BoxData@ToBoxes@expr, "Print"], AutoScroll -> False])

Update: starting from Mathematica 12.0 we no longer need the workaround described in the linked answer and this code can be simplified to

myPrint[expr_] :=
 (If[SelectionMove[EvaluationCell[], All, CellGroup, AutoScroll -> False] === $Failed, 
   SelectionMove[EvaluationCell[], After, Cell, AutoScroll -> False], 
   SelectionMove[EvaluationNotebook[], After, CellGroup, AutoScroll -> False]];
  NotebookWrite[EvaluationNotebook[], Cell[BoxData@ToBoxes@expr, "Print"], 
   AutoScroll -> False])

Another implementation (based on the same answer):

myPrint[expr_] := (SelectionMove[EvaluationCell[], Before, CellGroup, AutoScroll -> False];
  SelectionMove[EvaluationNotebook[], Next, CellGroup, AutoScroll -> False];
  SelectionMove[EvaluationNotebook[], After, CellGroup, AutoScroll -> False];
  NotebookWrite[EvaluationNotebook[], 
   Cell[BoxData@ToBoxes@expr, "Print"], AutoScroll -> False])

And a completely different implementation which is based on the assumption that EvaluationCell[] can be only the first cell in a group (what usually holds, but in general isn't true):

myPrint[expr_] := (
  If["FirstCellInGroup" /. Developer`CellInformation@EvaluationCell[],
   SelectionMove[EvaluationCell[], All, CellGroup, AutoScroll -> False];
   SelectionMove[EvaluationNotebook[], After, CellGroup, AutoScroll -> False];,
   SelectionMove[EvaluationCell[], After, Cell, AutoScroll -> False]
   ];
  NotebookWrite[EvaluationNotebook[], 
   Cell[BoxData@ToBoxes@expr, "Print"], AutoScroll -> False])

The problem with loosing some output when clicking inside of the Notebook can be solved using FrontEnd`NotebookSuspendScreenUpdates and FrontEnd`NotebookResumeScreenUpdates as shown in this answer.

Alexey Popkov
  • 62.3k
  • 7
  • 154
  • 375