abo-abo / lispy

Short and sweet LISP editing
http://oremacs.com/lispy/
1.2k stars 132 forks source link

Teleport with `tt` fails on list with no contained lists #570

Open bpstahlman opened 3 years ago

bpstahlman commented 3 years ago

With point as shown below...

|(foo bar)
(blammo)

tt fails with the following error message: "Can't teleport expression inside itself"

But tt gives the expected targets if bar is wrapped in parens like so:

|(foo (bar))
(blammo)

The test producing that error message is appropriate for the t command, but not for tt. Perhaps the error message could be deferred for a few hundred milliseconds? More importantly, lispy probably needs to remain in a mode in which it accepts the second t of the command, even if the sexp at point isn't a valid candidate for the t command.

bpstahlman commented 3 years ago

Also... It would be nice if the teleport command supported a count to specify where it should be moved within the target sexp. I just happened to come across some old lispy release notes today and discovered that the P command supports such a count. I didn't see any mention of it in the lispy command reference, and I'm wondering how many other potentially useful (but undocumented and therefore unused) features I might be missing out on...

ComedyTomedy commented 3 years ago

It gets weirder if you use mt to mark the sexp first.

(bla (foo bar)
mmo)

It splits blammo after 3 characters because that's the length of `foo'. I suspect that this bug is what the "Can't teleport expression inside itself" error is trying to short-circuit.

ComedyTomedy commented 3 years ago

So, turns out avy-process, which takes a list of candidates and displays that "choose a char" interface, skips the interface if there's only one candidate (since I guess it doesn't expect t to be bound to a function that re-runs it with a wider area).

I guess the Emacs-Lispy thing to do would be to let-bind a variable that overrides this short-circuiting, but I can't actually see where it does it.

If you want a horrible hack, add an extra dummy candidate to the list, by editing lispy--avy-do, and replacing cands in the call to avy-process with:

 (append cands `(((1 . 1) . ,(get-buffer-window))))