{"id":17210640,"url":"https://github.com/rmculpepper/sexp-rewrite","last_synced_at":"2025-04-11T16:13:19.538Z","repository":{"id":9085640,"uuid":"10861050","full_name":"rmculpepper/sexp-rewrite","owner":"rmculpepper","description":"emacs package for pattern-based rewriting of sexp-structured code","archived":false,"fork":false,"pushed_at":"2021-12-21T23:01:44.000Z","size":149,"stargazers_count":37,"open_issues_count":3,"forks_count":2,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-25T12:16:34.339Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Emacs Lisp","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"thaystg/SuperERP","license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rmculpepper.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-06-22T07:33:47.000Z","updated_at":"2024-08-08T14:42:01.000Z","dependencies_parsed_at":"2022-08-30T18:52:04.539Z","dependency_job_id":null,"html_url":"https://github.com/rmculpepper/sexp-rewrite","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rmculpepper%2Fsexp-rewrite","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rmculpepper%2Fsexp-rewrite/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rmculpepper%2Fsexp-rewrite/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rmculpepper%2Fsexp-rewrite/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rmculpepper","download_url":"https://codeload.github.com/rmculpepper/sexp-rewrite/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248438513,"owners_count":21103410,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-15T02:54:56.562Z","updated_at":"2025-04-11T16:13:19.518Z","avatar_url":"https://github.com/rmculpepper.png","language":"Emacs Lisp","funding_links":[],"categories":[],"sub_categories":[],"readme":"# sexp-rewrite\n\nsexp-rewrite (abbreviated sexprw) is an Emacs package for doing\npattern-based rewriting of sexp-structured code---ie, code in Lisp,\nScheme, and primarily Racket.\n\nSome examples of pattern-based rewriting are:\n\n - Turn a chain of `if` expressions into a `cond` expression.\n\n - Rewrite an application of `map` with `lambda` to `for/list`---or\n   `andmap` to `for/and`, etc.\n\n - Turn a `letrec` into a sequence of internal definitions.\n\nThe pattern language is simple enough that you can easily define your\nown rewriting rules.\n\nTransformations preserve comments and are halfway decent at preserving\nformatting, with the occasional help of appropriate spacing\nannotations.\n\n## Try it out\n\nVisit `sexp-rewrite.el` and evaluate the buffer (`M-x eval-buffer`).\nThen visit `racket-rewrites.el` and evaluate that buffer too.\n\nMost of the rewrite rules (or \"tactics\") in `racket-rewrites.el` have\nexamples after them.  Go to the example labeled \"`example for\nif-to-cond...`\" and place the cursor at the first left\nparenthesis---that is, at `(if (\u003c x 10)...`.\n\nRun the `if-to-cond` tactic by entering `M-x sexprw-execute-tactic`\nand then `if-to-cond`.\nThe `if` expression gets rewritten to a `cond` expression---but only\nthe first `if`; there are still `if` expressions left in the `else` branch.\nNow run the `cond-else-absorb-if` tactic. There's a keybinding for\n`sexprw-execute-tactic` that makes executing a specific tactic\nquicker: `C-c C-s x`. Then type `cond-else-absorb-if` at the prompt\n(you can use tab completion to save typing).\nThe `if` expression gets \"absorbed\" into the `cond`. There's just one\n`if` left, but it's inside a `let`, so let's leave it alone for now.\n\nWhat a bother to have to type in the tactic names. Fortunately,\nthere's an even quicker way.\n\nUndo twice (`C-/ C-/`) to reset the example to the original form,\nand make sure the cursor is back at the beginning of the example.\nNow enter `C-c C-s e` (which runs the `sexprw-auto-expression`\ncommand). The command automatically tries a bunch of tactics until one\nworks, and it reports the name of the tactic in the minibuffer.\n\nFaster?\n\nUndo once (`C-/`) to reset the example again.  Now type `C-c C-s r e`,\nwhich repeatedly tries tactics (up to about a hundred times) until\nthey stop working. This time we get the first two `if` expressions in\none shot, as well as the `if` under the `let`, which can be converted\nto an `=\u003e` clause.\n\nNote that the rewrite that produced the `=\u003e` can be unsafe: the\nelse-branch expression was originally in the scope of the `let`-bound\nvariable, but after rewriting it is in a separate clause. That's\n*usually* not a problem, because the variable is always known to be\nfalse in the else, branch (unless it's mutated...) so there's no\nreason to refer to it. But it's always a good idea to keep an eye on\nthe tactics applied to make sure they don't break your code.\n\n## Keybindings\n\nThe prefix for all sexp-rewrite commands is `C-c C-s`.\n\nThe following keybindings invoke sexp-rewrite tactics:\n\n- `\u003cprefix\u003e x` : runs `sexprw-execute-tactic`, which applies the given tactic\n\n- `\u003cprefix\u003e e` : runs `sexprw-auto-expression`\n- `\u003cprefix\u003e r e` : runs `sexprw-auto-expression` repeatedly until no tactic applies\n- `\u003cprefix\u003e d` : runs `sexprw-auto-definition`\n- `\u003cprefix\u003e r d` : runs `sexprw-auto-definition` repeatedly until no tactic applies\n\nThe following keybindings manipulate sexpagons:\n\n- `\u003cprefix\u003e k` : runs `sexprw-kill-next-sexpagon-sexp`\n- `\u003cprefix\u003e w` : runs `sexprw-kill-sexpagon-region`\n- `\u003cprefix\u003e y` : runs `sexprw-yank-sexpagon`\n- `\u003cprefix\u003e M-SPC` : runs `sexprw-collapse-space/move-sexps`\n\nThe following other keybindings are also provided:\n\n- `\u003cprefix\u003e s` : runs `sexprw-search-pattern`, which searches forward\n  for a term matching the given sexprw pattern\n\n- `\u003cprefix\u003e [` : runs `sexprw-squarify`, which converts parentheses to square brackets\n  for all following terms at the given level\n\n- `\u003cprefix\u003e (` : runs `sexprw-roundify`, which converts square brackets to parentheses\n  for all following terms at the given level\n\n## Defining Tactics\n\nSee `REFERENCE.md` for a description of the tactic language.\n\n## Known bugs and limitations\n\nThis library has a vague notion of sexp syntax. Notions like\nimproper lists are not supported, and `.` is treated as an\natom. Reader abbreviations like `'` for `quote` are not recognized.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frmculpepper%2Fsexp-rewrite","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frmculpepper%2Fsexp-rewrite","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frmculpepper%2Fsexp-rewrite/lists"}