Reinventing the wheel
This kind of functionality already exists in the page
function, for example if you run this on the console:
page(cars, method=c('print'))
This will show the cars
object in a pager just like the less
command in UNIX. You can scroll up and down using naturally the arrow keys, and it even supports a wide range of the same keyboard shortcuts to skip screens (space
), half-screens (d
, u
), jump to beginning or end (g
, G
), and exit anytime (q
).
Inside RStudio, page
works a bit differently. It opens a new tab with all of the content at once. That might not be the way you want, indeed.
Bugs
Be careful with corner cases, as @flodel already pointed out.
In fact there were so many bugs he missed one:
the last page will never be shown, for example:
less(head(cars, n=20))
This will show only one page, with the first 10 items, if you try to scroll down with /
the function exits without showing anything.
Alternative implementation
The start
and end
variables are modified independently,
but they are tightly related:
start
should be the previous end
+ 1,
and end
should be the next start
- 1.
This relationship is not expressed directly in the code,
which could lead to accidents.
For example, you might change the code setting the value of start
,
and forget to make the similar change to end
.
An alternative approach that would solve this could be pre-calculating the start values into a vector,
and track a single index pointing to the current start value in this vector.
That is, the start is the value at the index,
and the end is the value at [index+1] - 1.
less <- function(x, n = 10) {
intervals <- c(seq(1, nrow(x), by=n), nrow(x) + 1)
index <- 1
next_index <- function() {
input <- readline("Type . to scroll up, type / to scroll down: ")
if (input == ".") index - 1
else if (input == "/") index + 1
else Recall()
}
repeat {
start <- intervals[index]
end <- intervals[index + 1] - 1
print(x[start:end, , drop = FALSE])
if (length(intervals) -1 <= index) break
index <- next_index()
if (index < 1) break
}
}
Usability
/
and .
seems unusual as navigation shortcuts.
How about d
and u
instead, for "down" and "up"?
Or, though this might get too geeky,
but many software use j
and k
for vertical navigation.