{"id":22318649,"url":"https://github.com/scymtym/text.editing","last_synced_at":"2026-01-05T23:05:58.807Z","repository":{"id":215775586,"uuid":"728632866","full_name":"scymtym/text.editing","owner":"scymtym","description":"Motion, editing, search, etc. operations for Cluffer buffers","archived":false,"fork":false,"pushed_at":"2024-12-07T12:38:21.000Z","size":199,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-01-31T05:47:22.438Z","etag":null,"topics":["editing","search","text","undo"],"latest_commit_sha":null,"homepage":"https://scymtym.github.io/text.editing","language":"Common Lisp","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/scymtym.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}},"created_at":"2023-12-07T11:06:29.000Z","updated_at":"2024-12-07T12:38:25.000Z","dependencies_parsed_at":"2024-02-06T19:30:17.408Z","dependency_job_id":"14b3cf4c-242b-4308-941a-fdcad7625f93","html_url":"https://github.com/scymtym/text.editing","commit_stats":{"total_commits":45,"total_committers":1,"mean_commits":45.0,"dds":0.0,"last_synced_commit":"19606b41197eed9f1a88ceef88e1774e09463e20"},"previous_names":["scymtym/text.editing"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scymtym%2Ftext.editing","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scymtym%2Ftext.editing/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scymtym%2Ftext.editing/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scymtym%2Ftext.editing/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/scymtym","download_url":"https://codeload.github.com/scymtym/text.editing/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245585811,"owners_count":20639671,"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":["editing","search","text","undo"],"created_at":"2024-12-03T23:42:07.250Z","updated_at":"2026-01-05T23:05:58.740Z","avatar_url":"https://github.com/scymtym.png","language":"Common Lisp","readme":"#+TITLE:    text.editing README\n#+AUTHOR:   Jan Moringen\n#+EMAIL:    jmoringe@techfak.uni-bielefeld.de\n#+LANGUAGE: en\n\n#+OPTIONS:  toc:nil num:nil\n#+SEQ_TODO: TODO STARTED | DONE\n\n* Introduction\n\n  This library provides protocols and implementations of those\n  protocols for text editing operations which are required by, for\n  example, text editors or commandline processors (like REPLs). This\n  library relies on the [[https://github.com/Robert-Strandh/cluffer][Cluffer]] library for the fundamental concepts\n  of buffers, lines and cursors. The functionality provided by this\n  library includes:\n\n  + Cursor movement (by various \"units\")\n\n  + Insertion and deletion (by various \"units\")\n\n  + Transformations (for example changing case or transposing)\n\n  + Killing, copying and inserting\n\n  + Multiple cursors\n\n  + \"Mark\" cursors and regions\n\n  + Undo (work in progress)\n\n  + Operations on expression (like paredit for Emacs)\n\n  + Search and incremental search\n\n  + Abbreviations (work in progress)\n\n  This library does not provide\n\n  + Data structures for editor buffers (the cluffer library does that)\n\n  + Input handling or a command processor\n\n  + Advanced parsing (see [[https://github.com/s-expressionists/incrementalist][incrementalist]] for that)\n\n  + Syntax highlighting (see TODO for that)\n\n  + Presentation/rendering/display functions for the contents of text buffers\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  Using this library typically requires a buffer class defined by the\n  client which includes the desired mixin classes. For example\n\n  #+BEGIN_SRC lisp :exports both :results value verbatim :wrap EXAMPLE\n    (defclass my-buffer (text.editing:multiple-site-mixin\n                         text.editing:site-mixin\n                         cluffer-standard-buffer:buffer)\n      ())\n  #+END_SRC\n\n  #+RESULTS:\n  #+BEGIN_EXAMPLE\n  #\u003cSTANDARD-CLASS COMMON-LISP-USER::MY-BUFFER\u003e\n  #+END_EXAMPLE\n\n  This buffer class is like a Cluffer buffer but also has a primary\n  and zero or more additional sites. Creating an instance of the\n  buffer class automatically creates the primary site an attaches its\n  point cursor to the initial line of the buffer:\n\n  #+BEGIN_SRC lisp :exports both :results output verbatim :wrap EXAMPLE\n    (defvar *my-buffer*\n      (make-instance 'my-buffer :initial-line (make-instance 'cluffer-standard-line:closed-line)))\n\n    (print *my-buffer*)\n    (print (text.editing:site *my-buffer*))\n    (print (text.editing:sites *my-buffer*))\n    (print (text.editing:point (text.editing:site *my-buffer*)))\n  #+END_SRC\n\n  #+RESULTS:\n  #+BEGIN_EXAMPLE\n\n  #\u003cMY-BUFFER 1 line 0 items {1006791483}\u003e\n  #\u003cSITE 0:0 {1006B03D03}\u003e\n  (#\u003cSITE 0:0 {1006B03D03}\u003e)\n  #\u003cCLUFFER-STANDARD-LINE:RIGHT-STICKY-CURSOR 0:0 {1006D4EDC3}\u003e\n  #+END_EXAMPLE\n\n  This buffer instance is usable with the operations provided by this\n  library:\n\n  #+BEGIN_SRC lisp :exports both :results values verbatim :wrap EXAMPLE\n    (defvar *point* (text.editing:point *my-buffer*))\n    (setf (text.editing:items *point* text.editing:buffer :forward)\n          (format nil \"one~%two!~%three~%\"))\n    (defun summary ()\n      (values (coerce (text.editing:items *point* text.editing:buffer :forward) 'string)\n              (text.editing:sites *my-buffer*)))\n    (summary)\n  #+END_SRC\n\n  #+RESULTS:\n  #+BEGIN_EXAMPLE\n  \"one\n  two!\n  three\n  \"\n  (#\u003cSITE 3:0 {1006B03D03}\u003e)\n  #+END_EXAMPLE\n\n  #+BEGIN_SRC lisp :exports both :results values verbatim :wrap EXAMPLE\n    (text.editing:change-case *point* text.editing:word :backward :up)\n    (summary)\n  #+END_SRC\n\n  #+RESULTS:\n  #+BEGIN_EXAMPLE\n  \"one\n  two!\n  THREE\n  \"\n  (#\u003cSITE 2:0 {1006B03D03}\u003e)\n  #+END_EXAMPLE\n\n  While many operations can be applied directly to a cursor, it is\n  preferable use to the \"operation protocol\" and let the library\n  figure out how and to which object to apply the operation in\n  question:\n\n  #+BEGIN_SRC lisp :exports both :results values verbatim :wrap EXAMPLE\n    (text.editing:perform *my-buffer* 'text.editing:move text.editing:word :backward)\n    (text.editing:perform *my-buffer* 'text.editing:delete text.editing:line :forward)\n    (summary)\n  #+END_SRC\n\n  #+RESULTS:\n  #+BEGIN_EXAMPLE\n  \"one\n\n  THREE\n  \"\n  (#\u003cSITE 1:0 {1006B03D03}\u003e)\n  #+END_EXAMPLE\n\n  The deleted word is now in the insertion stack (which is like the\n  \"kill ring\" in Emacs) and can be inserted:\n\n  #+BEGIN_SRC lisp :exports both :results values verbatim :wrap EXAMPLE\n    (loop :repeat 3 :do (text.editing:perform *my-buffer* 'text.editing:yank :forward))\n    (summary)\n  #+END_SRC\n\n  #+RESULTS:\n  #+BEGIN_EXAMPLE\n  \"one\n  two!two!two!\n  THREE\n  \"\n  (#\u003cSITE 1:12 {1006B03D03}\u003e)\n  #+END_EXAMPLE\n\n  It is easy to see how the operation protocol comes into play when\n  multiple sites are used:\n\n  #+BEGIN_SRC lisp :exports both :results values verbatim :wrap EXAMPLE\n    (text.editing:push-site-relative *my-buffer* text.editing:line :forward)\n    (summary)\n  #+END_SRC\n\n  #+RESULTS:\n  #+BEGIN_EXAMPLE\n  \"one\n  two!two!two!\n  THREE\n  \"\n  (#\u003cSITE 1:12 {1006B03D03}\u003e #\u003cSITE 2:5 {100AE016D3}\u003e)\n  #+END_EXAMPLE\n\n  #+BEGIN_SRC lisp :exports both :results values verbatim :wrap EXAMPLE\n    (text.editing:perform *my-buffer* 'text.editing:move text.editing:line-boundary :backward)\n    (text.editing:perform *my-buffer* 'text.editing:change-case text.editing:word :forward :capital)\n    (summary)\n  #+END_SRC\n\n  #+RESULTS:\n  #+BEGIN_EXAMPLE\n  \"one\n  Two!two!two!\n  Three\n  \"\n  (#\u003cSITE 1:3 {1006B03D03}\u003e #\u003cSITE 2:5 {100AE016D3}\u003e)\n  #+END_EXAMPLE\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscymtym%2Ftext.editing","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fscymtym%2Ftext.editing","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscymtym%2Ftext.editing/lists"}