{"id":25195860,"url":"https://github.com/s-expressionists/incrementalist","last_synced_at":"2026-01-15T23:03:34.893Z","repository":{"id":189296398,"uuid":"680052057","full_name":"s-expressionists/Incrementalist","owner":"s-expressionists","description":"Incremental parsing of Common Lisp code in a Cluffer editor buffer","archived":false,"fork":false,"pushed_at":"2025-08-08T12:44:11.000Z","size":265,"stargazers_count":9,"open_issues_count":0,"forks_count":1,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-08-08T14:38:24.923Z","etag":null,"topics":["editor","incremental","parsing"],"latest_commit_sha":null,"homepage":"https://s-expressionists.github.io/Incrementalist/","language":"Common Lisp","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/s-expressionists.png","metadata":{"files":{"readme":"README.org","changelog":null,"contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-08-18T08:20:15.000Z","updated_at":"2025-08-08T12:44:15.000Z","dependencies_parsed_at":null,"dependency_job_id":"fd864f44-b21f-441b-a8e3-3bf85192f268","html_url":"https://github.com/s-expressionists/Incrementalist","commit_stats":null,"previous_names":["robert-strandh/incrementalist","s-expressionists/incrementalist"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/s-expressionists/Incrementalist","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/s-expressionists%2FIncrementalist","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/s-expressionists%2FIncrementalist/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/s-expressionists%2FIncrementalist/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/s-expressionists%2FIncrementalist/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/s-expressionists","download_url":"https://codeload.github.com/s-expressionists/Incrementalist/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/s-expressionists%2FIncrementalist/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28473974,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-15T22:27:41.514Z","status":"ssl_error","status_checked_at":"2026-01-15T21:54:47.910Z","response_time":62,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["editor","incremental","parsing"],"created_at":"2025-02-10T01:38:51.745Z","updated_at":"2026-01-15T23:03:34.887Z","avatar_url":"https://github.com/s-expressionists.png","language":"Common Lisp","readme":"#+TITLE:    Incrementalist README\n#+AUTHOR:   Jan Moringen\n#+EMAIL:    jmoringe@techfak.uni-bielefeld.de\n#+LANGUAGE: en\n\n#+OPTIONS:  toc:nil num:nil\n\n* Introduction\n\n  The purpose of the Incrementalist library is incremental parsing of\n  Common Lisp code that is contained in a [[https://github.com/robert-strandh/cluffer][Cluffer]] buffer into a syntax\n  tree. The parsing is incremental in the sense that after a small\n  change in the buffer text, the syntax tree can usually be updated\n  with a small amount of parsing work.\n\n  *This library is under active development. Its ASDF system\n  structure, package structure, exported symbols and protocols may\n  change at any time. Consult the NEWS file or the \"Changelog\" section\n  of the manual for lists of changes in specific versions.*\n\n  This document only gives a very brief overview and highlights some\n  features. Proper documentation can be found in the\n  file:documentation directory.\n\n* Usage Overview\n\n  A central concept of the Incrementalist library is the \"analyzer\"\n  which, given a Cluffer buffer, creates and maintains a concrete\n  syntax tree that represents the content of the buffer. We therefore\n  start by creating and populating a buffer:\n\n  #+BEGIN_SRC lisp :exports both :results value :wrap example\n    (defun example-buffer (\u0026key (content \"(((1)))\"))\n      (let* ((line (make-instance 'cluffer-standard-line:open-line))\n             (buffer (make-instance 'cluffer-standard-buffer:buffer :initial-line line))\n             (cursor (make-instance 'cluffer-standard-line:right-sticky-cursor)))\n        (cluffer:attach-cursor cursor line 0)\n        (loop for c across content\n              do (case c\n                   (#\\Newline (cluffer:split-line cursor))\n                   (t         (cluffer:insert-item cursor c))))\n        (values buffer cursor)))\n\n    (example-buffer)\n  #+END_SRC\n\n  #+RESULTS:\n  #+begin_example\n  #\u003cCLUFFER-STANDARD-BUFFER:BUFFER 1 line 7 items {10055953A3}\u003e\n  #\u003cCLUFFER-STANDARD-LINE:RIGHT-STICKY-CURSOR 0:7 {1005595453}\u003e\n  #+end_example\n\n  We can now attach an analyzer to a buffer:\n\n  #+BEGIN_SRC lisp :exports both :results value :wrap example\n    (defun example-analyzer (buffer)\n      (make-instance 'incrementalist:analyzer :buffer buffer))\n\n    (example-analyzer (example-buffer))\n  #+END_SRC\n\n  #+RESULTS:\n  #+begin_example\n  #\u003cINCREMENTALIST:ANALYZER N/A,N/A {1005642B73}\u003e\n  #+end_example\n\n  To obtain the concrete syntax tree, we must update the analyzer\n  after attaching it to the buffer and after changes to the contents\n  of the buffer:\n\n  #+BEGIN_SRC lisp :exports both :results output :wrap example\n    (multiple-value-bind (buffer cursor) (example-buffer :content \"(((11)))\")\n      (let ((analyzer (example-analyzer buffer)))\n        (let ((cache (incrementalist:cache analyzer)))\n          (format t \"Initial\")\n          (incrementalist:update analyzer)\n          (mapc #'print (incrementalist:find-wads-containing-position\n                         cache 0 4))\n          ;; Delete first and last buffer item and update analyzer\n          (cluffer:erase-item cursor)\n          (setf (cluffer:cursor-position cursor) 0)\n          (cluffer:delete-item cursor)\n          (incrementalist:update analyzer)\n          (format t \"~\u0026After change\")\n          (mapc #'print (incrementalist:find-wads-containing-position\n                         cache 0 3)))))\n  #+END_SRC\n\n  #+RESULTS:\n  #+begin_example\n  Initial\n  (0 . #\u003cINCREMENTALIST:ATOM-WAD rel:0[0],3 -\u003e 0,5 raw: 11\u003e)\n  (0 . #\u003cINCREMENTALIST:CONS-WAD rel:0[0],2 -\u003e 0,6\u003e)\n  (0 . #\u003cINCREMENTALIST:CONS-WAD rel:0[0],1 -\u003e 0,7\u003e)\n  (0 . #\u003cINCREMENTALIST:CONS-WAD abs:0[0],0 -\u003e 0,8\u003e)\n  After change\n  (0 . #\u003cINCREMENTALIST:ATOM-WAD rel:0[0],2 -\u003e 0,4 raw: 11\u003e)\n  (0 . #\u003cINCREMENTALIST:CONS-WAD rel:0[0],1 -\u003e 0,5\u003e)\n  (0 . #\u003cINCREMENTALIST:CONS-WAD abs:0[0],0 -\u003e 0,6\u003e)\n  #+end_example\n\n  Incrementalist handles syntax errors by adding special nodes to the\n  concrete syntax tree:\n\n  #+BEGIN_SRC lisp :exports both :results output :wrap example\n    (let* ((analyzer (example-analyzer (example-buffer :content \"(#\\\\Foo\")))\n           (cache (incrementalist:cache analyzer)))\n      (incrementalist:update analyzer)\n      (let* ((wads (incrementalist:find-wads-containing-position\n                    cache 0 2))\n             (wad1 (cdr (first wads)))\n             (wad2 (cdr (second wads))))\n        (format t \"wad    ~A~%errors ~:A~2%\" wad1 (incrementalist:errors wad1))\n        (format t \"wad    ~A~%errors ~:A~%\" wad2 (incrementalist:errors wad2))))\n  #+END_SRC\n\n  #+RESULTS:\n  #+begin_example\n  wad    #\u003cATOM-WAD rel:0[0],1 -\u003e 0,6 raw: #\\?\u003e\n  errors (#\u003cERROR-WAD rel:0[0],3 -\u003e 0,6 condition: UNKNOWN-CHARACTER-NAME\u003e)\n\n  wad    #\u003cCONS-WAD abs:0[0],0 -\u003e 0,6\u003e\n  errors (#\u003cERROR-WAD rel:0[0],6 -\u003e 0,6 condition: UNTERMINATED-LIST\u003e)\n  #+end_example\n\n# Local Variables:\n# eval: (load-library 'ob-lisp)\n# End:\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fs-expressionists%2Fincrementalist","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fs-expressionists%2Fincrementalist","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fs-expressionists%2Fincrementalist/lists"}