rksm / paredit.js

Generic reader and editor for s-expressions.
MIT License
107 stars 21 forks source link

Structural editing in plain JavaScript with Paredit #26

Open pfernandez opened 2 years ago

pfernandez commented 2 years ago

Please let me know if there’s a better place to bring up this topic and I’ll gladly take it there. Depending on your thoughts I may open a PR later.

A few years ago I had the privilege to work on a Clojure/ClojureScript project, but these days I write mostly React in JS with the CoC plugin for Vim (a VSCode language server adapter). I still use structural editing wherever I can, and have cobbled together an “okay” Vim setup with the vim-sexp and vim-surround plugins to get wrap, unwrap, slurp, barf, and raise in JS. I write in as functional a style as possible, favoring nested functions and data and avoiding procedural statements. Whatever I can get away with while still passing code reviews. :)

In my personal setup I’ve taken to using thin function wrappers and eslint’s formatting capabilities to get a more Lisp-like style:

const assignDeep  = (target, source) =>
  reduce(
    entries(source),
      (t, [k, v]) => 
        (t[k] = v, 
        isObject(v) && assignDeep(t[k], v),
        t), 
    target)

or

const getSelector = (tagName, { id, className }) =>
  tagName
    + (id
    ? `#${id}`
    : className
      ? `.${className.split(' ').filter(s => s).join('.')}`
      : '')

An obvious limitation of the existing Paredit-like tools in non-Lisp code are that certain combinations of symbols aren’t recognized, notably comma-separated list items (item,), function names with leading paren (func(), and keys with colon in key:-value pairs. I’m sure there are many other cases that would need special treatment as well, but identifying and handling the basic cases could unlock at least some of the power of structural editing in any C-based language.

My thought is that I could use paredit.js to extend the capabilities of (say) the VSCode paredit plugin by submitting a PR (if they would accept it) so that others can benefit from it, then use CoC to use the plugin for my own Vim setup. One approach might be to simply allow additional symbols to be included in what’s considered a “form”, “expression”, etc.

How realistic does this sound to you, and how suitable is paredit.js for what I’d like to do? Do you know whether this has ever been tried, or what potential roadblocks I might run into?

Thanks. I admit that I haven’t done much exploration yet into whether this could work— I’m hoping you might save me some frustration up front. But I won’t be offended if you tell me that I need to dig deeper first. :)