Message Boards Message Boards

Avoid SelectionMove inconsistency?


I believe there is a bug in SelectionMove when it is used to select a CellGroup. The bug is two-fold: not only SelectionMove fails to perform the operation, but also it doesn't return $Failed is it should according to the Documentation:

SelectionMove returns $Failed if it cannot move the selection in the way you request.

Suppose we have a Notebook containing a CellGroup. Then we can paste the following cell after this CellGroup and evaluate it in order to select the previous CellGroup:

SelectionMove[PreviousCell[], All, CellGroup]

This works in the latest version of Mathematica if PreviousCell[] is indeed a member of a CellGroup. But what if it is not? In this case this piece of code just does nothing AND nothing is returned as output, the latter directly contradicts the cited Documentation statement.

The described behavior is also inconsistent with other cases, for example

SelectionMove[EvaluationCell[], Previous, CellGroup]

selects the previous cell (which isn't a member of a CellGroup). Why then the same approach fail to work with PreviousCell[]?

The fact that SelectionMove doesn't return $Failed when it is unable to perform the requested operation is very unfortunate because it makes programming much more difficult: we must check whether selection is moved after EVERY call to SelectionMove, but there is no universal way to do this. In the best case it complicates code a lot and is very inefficient. In the worst case it makes it impossible to perform some simple tasks, as a bright example consider this StackExchange question:

The problem raised in this question is so simple that it is hard to believe it can't be solved reliably: we need just to move the selection after the input cell OR after the CellGroup containing output generated by this cell, and print new cell without scrolling using NotebookWrite (CellPrint always scrolls, hence it cannot be used in this case). But careful investigation showed that it is currently impossible to do this in an efficient way mainly due to the described bug.

My main question is:
Is it possible to check in an efficient and reliable way, whether SelectionMove has failed or not?

Reported to the support as [CASE:3968507].

POSTED BY: Alexey Popkov
20 days ago

By request from the support I've prepared a Notebook demonstrating both the issues, which as I believe worth posting here. The problems (bugs?) are:

  1. SelectionMove doesn't return $Failed when it fails to move selection in the requested way (second and fourth input cells in the Notebook). This directly contradicts the Documentation statement cited at the beginning of my previous post.

  2. It isn't clear why SelectionMove can't select a standalone previous cell when it starts directly from PreviousCell[] (see second input cell in the Notebook), but is able to do this when it starts from EvaluationCell[] (see fifth input cell in the Notebook). How this difference could be explained? Isn't it an inconsistency?

The motivation for the second point is that I need a way to select either a certain single cell (if the cell is standalone, i.e. not a member of a cell group) or the whole cell group (if the cell is a member of this group) having only CellObject of the cell. The simplest example is given as third and fourth input cells in the Notebook: the code in the third cell correctly selects the surrounding cell group, but the code in the fourth cell does nothing and also doesn't tell me that it failed to select the fourth input cell. I should stress that I do not know beforehand whether the cell is inside of a cell group, or not (and have no idea how to obtain this information in an efficient way). Since SelectionMove doesn't return $Failed (as it should according to the docs), I don't know whether it failed or not. Is there an efficient way to find it out?

Please find the Notebook attached to the post.

POSTED BY: Alexey Popkov
6 days ago

Group Abstract Group Abstract