Enlarge selection n-times, than restrict selection one level

I use a lot ctrl-space
On windows this shortcut enlarges the current selection to its surrounding structure.
The problem is that a lot of time I select one level more than I need.
Is there a keyboard shortcut to restrict the selection of one level?

Hi @par8 and welcome to the forum.
I searched a bit, using ack, and for the moment I have found that what you are using is the keyboard shortcut

("structured:cmd space" (kbd-select-enlarge))

It is defined in generic/generic-kbd.scm

I havenā€™t (possibly yet) found out if a command to ā€œrevert onceā€ that exists. Let us see if someone else is able to help.

G.

I donā€™t think kind of function is available. Youā€™d need to keep a history of selections to implement this.

Iā€™ve looked around in the source and I could not find anything related to reversing the last change in selection. I agree that would be natural to do it. However it is not difficult to implement something which more or less works. Here how to do it. :slight_smile:

We have to look at how kbd-select-enlarge works. The code is (in progs/utils/edit/selections.scm)

(tm-define (kbd-select-enlarge)
  (if (selection-active-enlarging?)
      (select-enlarge)
      (begin
	(selection-cancel)
	(selection-set-start)
	(select-from-keyboard #t))))

The idea is to record the selection before it is modified so that we can reestablish it via another command, letā€™s call it kbd-select-enlarge-undo. We need variables to keep a stack of the selection starts and ends.

(define last-selection-start '())
(define last-selection-end '())

Each of these variables is a list of paths (a TeXmacs path is a list of integer uniquely identifying a subtree in a larger tree) which corresponds to the start and end point of the previous selections.
Now we modify kbd-select-enlarge to record the selection before enlarging it. We also clear the selection if we are at the start of an enlarging cycle, i.e. if (selection-active-enlarging?) is false.

(tm-define (kbd-select-enlarge)
  (if (selection-active-enlarging?)
      (begin
        (set! last-selection-start (cons (selection-get-start) last-selection-start))
        (set! last-selection-end (cons (selection-get-end) last-selection-end))
        (select-enlarge)
        )
      (begin
        (set! last-selection-start '())
        (set! last-selection-end '())
        (selection-cancel)
        (selection-set-start)
        (select-from-keyboard #t))))

It only remains to implement kbd-select-enlarge-undo, but this is easy, if we have a previous selection we reinstate it, otherwise we do nothing. We still check that (selection-active-enlarging?) since it could happen that the selection stack is not cleared and we are not actively re-enlarging but still we have some prerecorded selections from a previous interaction, since (selection-cancel) is called in many other places.

(tm-define (kbd-select-enlarge-undo) 
  (when (and (selection-active-enlarging?) (pair? last-selection-start))
          (selection-set (car last-selection-start) 
                         (car last-selection-end))
          (set! last-selection-start (cdr last-selection-start))
          (set! last-selection-end (cdr last-selection-end))))

Now we bind this to an appropriate key combination, letā€™s say ā€˜Alt+S+spaceā€™ on my Mac:

(kbd-map
  ("structured:cmd S-space" (kbd-select-enlarge-undo)))

and it should work (it seems to do it for me).

2 Likes