guns / vim-sexp

Precision Editing for S-expressions
MIT License
612 stars 33 forks source link

paste? #32

Open hoclun-rigsep opened 9 months ago

hoclun-rigsep commented 9 months ago

I just want to make sure I am getting the most out of this very useful plugin. My question is, if I want to move an element from one form to another it seems like I am left to deal with whitespace manually, eg:

(a form [with an ele|ment])
(target form)
;; daf
(a form)
(target form|)
;; p
(a form)
(another form[an element])

meaning I have to add the space between "form" and "[an element]".

And also, if I had put the cursor on the bracket and used dae, the paste would work as expected, i.e. (another form [an element])

bpstahlman commented 9 months ago

@hoclun-rigsep If you have an easy way to try out different forks/branches, you might take a look at the enhanced-sexp-objects branch on my fork of vim-sexp. I mentioned it several years ago in a comment on another issue. Since I never got any feedback, I never merged the branch, but the functionality was working and documented.

The primary purpose of the branch was to enhance treatment of text objects, but it also adds fairly sophisticated logic for whitespace cleanup, which is triggered by an indent. This branch diff should give a feel for what was added...

hoclun-rigsep commented 8 months ago

@bpstahlman thanks for the response. I checked out the diff, haven't had time to try it out, but perhaps your "clone" commands are a jumping off point?

What I think we need is sexp-specific paste commands that do not rely on placing the cursor to achieve the desired result and that get whitespace right every time.

sexp_paste_at_list_head
sexp_paste_at_list_tail
sexp_paste_after
sexp_paste_before

sexp_paste_after would mean "paste after the element containing the cursor." These should take a buffer and a count and paste into the counth outer sexp relative to the cursor. I do not know a lick of vimscript but I think I can help describe the desired UI and behavior and it doesn't seem prohibitively complex to get it right in 99% of cases, since you pretty much never want whitespace between the enclosing bracket and the element and pretty much always want it between the element and any adjacent elements.

bpstahlman commented 7 months ago

@hoclun-rigsep Sorry for the delayed reply. I agree that the ability to paste at an arbitrary location within the sexp tree would be very useful. The interface probably needs some thinking through... While it's possible to accomplish a lot with counts supplied to regular mappings, it would be nice if the user could specify the target location using a more visual approach (think EasyMotion). I haven't yet investigated to see how this might work from an implementation standpoint, but I'd hate to reimplement all that functionality unnecessarily.

At any rate, it occurs to me that I really need to merge the branch containing the clone command, as there's a lot of added functionality there, especially with regard to whitespace cleanup.

hoclun-rigsep commented 7 months ago

@bpstahlman Thanks for response. I've been using your branch for a few weeks now to edit clj/cljs; I'm not familiar with any other LISP. I wonder what specifically motivated you to implement the clone commands as I seldom find myself needing identical adjacent forms. What stands out to me is that your implementation of the clone commands understands the desired outcome with respect to whitespace, whether single- or multi-line, which is great and which motivated https://github.com/bpstahlman/vim-sexp/issues/5.

I cannot commit to learning VimScript at this time but I would still like to help realize a solution for this issue. If you have thoughts on how I can do that let me know.

bpstahlman commented 7 months ago

@hoclun-rigsep I believe the original inspiration for clone may have come from abo-abo's lispy plugin. While I agree that truly identical adjacent forms are rare, I think "cloning and tweaking" is a fairly common (though probably overused) scenario: e.g., copy a line or a block of code, changing x to y, min to max, etc...

I appreciate your willingness to contribute and may get back with you after I've had a chance to think through the interface a bit. It's always helpful to bounce ideas off an actual user when designing these types of interfaces.