Select Cells to End of Notebook

Building on Albert's answer I added code such that Ctrl Shift End will select all cells downwards. Just execute this code in a notebook and restart Mathematica:

   mymenuitems="
         (* Select all cells downwards *)
         Item[KeyEvent[\"End\", Modifiers -> {Control, Shift}], 
         KernelExecute[
          Module[{ enb = EvaluationNotebook[],
                   tag = StringJoin[\"tmp\", ToString[Round[AbsoluteTime[]/$TimeUnit]]],editable 
                   },
                editable = ReplaceAll[Editable, Options[enb, Editable]];
                SetOptions[enb, Editable -> False];
                SelectionMove[enb, Next, Cell, AutoScroll -> False];
                MathLink`CallFrontEnd[FrontEnd`SelectionAddCellTags[enb, {tag}]];
                SelectionMove[enb, After, Notebook, AutoScroll -> False];
                SelectionMove[enb, Previous, Cell, AutoScroll -> False];
                While[FreeQ[ReplaceAll[CellTags,Options[NotebookSelection[]]], tag],
                      MathLink`CallFrontEnd[FrontEnd`SelectionAddCellTags[enb, {tag}]];
                      SelectionMove[enb, Previous, Cell, AutoScroll -> False]
                ];
                NotebookFind[enb, tag, All, CellTags, AutoScroll -> False];
                MathLink`CallFrontEnd[FrontEnd`SelectionRemoveCellTags[enb, {tag}]];
                SetOptions[enb, Editable -> editable]
            ]
            ], MenuEvaluator -> Automatic ]
            ";
    Quiet@CreateDirectory@FileNameJoin[{$UserBaseDirectory,"SystemFiles","FrontEnd","TextResources",$OperatingSystem}];
    mykeyeventtrans=FileNameJoin[{$UserBaseDirectory,"SystemFiles","FrontEnd","TextResources",$OperatingSystem,"KeyEventTranslations.tr"}];
    If[FileExistsQ[mykeyeventtrans],DeleteFile@mykeyeventtrans];
    CopyFile[FileNameJoin[{$InstallationDirectory,"SystemFiles","FrontEnd","TextResources",$OperatingSystem,"KeyEventTranslations.tr"}],mykeyeventtrans];
keytext=Import[mykeyeventtrans,"Text"];
mykeytext=StringReplace[keytext,"EventTranslations[{":>StringJoin["EventTranslations[{\n(* User defined *)\n",mymenuitems,",\n"]];
Export[mykeyeventtrans,mykeytext,"Text"];

I only tested this on Windows. No idea if it works on MacOSX and Linux.


I also don't know a straightforward way to do what you want, so Mr.Wizard could well be right. But there are workarounds as e.g. the following which is "abusing" CellTags. It is however somewhat hacky and not very fast and reliable and I'm not sure whether it is good enough for your every day use:

Module[{
  enb = EvaluationNotebook[],
  tag = StringJoin[
    RandomChoice[
     Join[CharacterRange["A", "Z"], CharacterRange["a", "z"], 
      CharacterRange["0", "9"]],
     30]
    ],
    editable
  },
 editable = Editable /. Options[enb,Editable];
 SetOptions[enb, Editable -> False];
 SelectionMove[enb, Next, Cell, AutoScroll -> False];
 MathLink`CallFrontEnd[FrontEnd`SelectionAddCellTags[enb, {tag}]];
 SelectionMove[enb, After, Notebook, AutoScroll -> False];
 SelectionMove[enb, Previous, Cell, AutoScroll -> False];
 While[FreeQ[CellTags /. Options[NotebookSelection[]], tag],
  MathLink`CallFrontEnd[FrontEnd`SelectionAddCellTags[enb, {tag}]];
  SelectionMove[enb, Previous, Cell, AutoScroll -> False];
  ];
 NotebookFind[enb, tag, All, CellTags, AutoScroll -> False];
 MathLink`CallFrontEnd[FrontEnd`SelectionRemoveCellTags[enb, {tag}]];
 SetOptions[EvaluationNotebook[], Editable -> editable]
 ]

It should be relatively clear what this does, nevertheless I think some remarks might be helpful:

  • I'm using a random tag to mark the cells to be selected (a common strategy to create global unique identifiers GUIDs), you could probably think of something smarter and e.g. check whether the tag you want to use is already present in the notebook to be on the really save side. I think it would, for almost all use cases, also be good enough to work with a constant unique identifier, though...
  • to temporarily add tags without destroying already existing ones, I'm using the undocumented frontend functionality SelectionAddCellTags and SelectionRemoveCellTags which I know from the excellent talk "The joy of Tagging" given by David Reiss at a Wolfram User Conference some years ago. You should be able to find the corresponding notebook in the web which is a good read if you try to do any kind of advanced notebook manipulating...
  • except for the random tag generation it should be possible to do this completely in the frontend which might be a good idea if you want it to be executed from a keyboard shortcut or button.
  • as suggested by Rolf Mertig I did set the notebook to not be editable while the code is running so that it should be relatively safe against user input.
  • there might well be other features, especially undocumented ones, which might let you do the same thing more reliable and faster, so don't accept this answer too early...

In case this is helpful to anyone stumbling upon this thread this as I did, here is simpler code to select all cells from the end of a notebook to the current evaluation cell.

endAtID = First @ EvaluationCell[];
SelectionMove[EvaluationNotebook[], After, Notebook];
SelectionMove[EvaluationNotebook[], Previous, Cell];
While[
    SelectedCells[][[1, 1]] =!= endAtID,
    FrontEndTokenExecute[EvaluationNotebook[], "SelectPreviousLine"];
] 

This can be modified to start from the cell containing the current insertion point, here is a button which will do this.

Button["press to select all cells from insertion point to end of notebook",
    SelectionMove[InputNotebook[], All, Cell];
    If[
        SelectedCells[InputNotebook[]] === {}, 
        SelectionMove[InputNotebook[], Next, Cell]
    ];
    endAtID = First @ SelectedCells[InputNotebook[]][[1]];
    SelectionMove[InputNotebook[], After, Notebook];
    SelectionMove[InputNotebook[], Previous, Cell];
    While[
        SelectedCells[InputNotebook[]][[1, 1]] =!= endAtID, 
        FrontEndTokenExecute[InputNotebook[], "SelectPreviousLine"];
    ]
]

The code inside the button above should work fine when triggered from a keyboard shortcut or palette button or wherever you want. To make it delete the selected cells, simply add

NotebookDelete[InputNotebook[]] 

to the end of the code inside the button.

AMENDMENTS: To make the selection go from the insertion point to the end of the notebook, you can modify the code as such

Button["press to select all cells from insertion point to end of notebook",
    SelectionMove[InputNotebook[], After, Notebook];
    SelectionMove[InputNotebook[], Previous, Cell];
    endAtID = First@SelectedCells[InputNotebook[]][[1]];
    SelectionMove[EvaluationCell[], All, Cell];
    While[
        SelectedCells[InputNotebook[]][[-1, 1]] =!= endAtID, 
        FrontEndTokenExecute[InputNotebook[], "SelectNextLine"];
    ]
]

I like Albert Riley's suggestion in the comments to use FixedPoint so much I thought we should add it here

SelectionMove[InputNotebook[], All, Cell];
FixedPoint[
    (
        FrontEndTokenExecute[InputNotebook[], "SelectNextLine"];
        SelectedCells[InputNotebook[]]
    ) &,
    {}
]