eve
Version:
Filesystem-first framework for durable backend AI agents that run anywhere.
6 lines • 6.88 kB
JavaScript
import{inputTextWidth,offsetAtVisibleColumn}from"#cli/ui/terminal-text.js";import{graphemeBoundaryAtOrAfter,graphemes,nextGraphemeBoundary,previousGraphemeBoundary}from"#shared/text-boundaries.js";const EMPTY_LINE={text:``,cursor:0};function lineOf(e){return{text:e,cursor:e.length}}function maskLine(e){return{text:`•`.repeat(graphemes(e.text).length),cursor:graphemes(e.text.slice(0,e.cursor)).length}}function insert(e,t){if(t.length===0)return e;let n=e.text.slice(0,e.cursor)+t+e.text.slice(e.cursor);return{text:n,cursor:graphemeBoundaryAtOrAfter(n,e.cursor+t.length)}}function backspace(e){if(e.cursor===0)return e;let t=previousGraphemeBoundary(e.text,e.cursor),n=e.text.slice(0,t)+e.text.slice(e.cursor);return{text:n,cursor:graphemeBoundaryAtOrAfter(n,t)}}function deleteForward(e){if(e.cursor>=e.text.length)return e;let t=nextGraphemeBoundary(e.text,e.cursor),n=e.text.slice(0,e.cursor)+e.text.slice(t);return{text:n,cursor:graphemeBoundaryAtOrAfter(n,e.cursor)}}function moveLeft(e){return e.cursor===0?e:{text:e.text,cursor:previousGraphemeBoundary(e.text,e.cursor)}}function moveRight(e){return e.cursor>=e.text.length?e:{text:e.text,cursor:nextGraphemeBoundary(e.text,e.cursor)}}function moveWordBackward(e){let t=e.cursor;for(;t>0;){let n=previousGraphemeBoundary(e.text,t);if(isWordCharacter(e.text.slice(n,t)))break;t=n}for(;t>0;){let n=previousGraphemeBoundary(e.text,t);if(!isWordCharacter(e.text.slice(n,t)))break;t=n}return t===e.cursor?e:{text:e.text,cursor:t}}function moveWordForward(e){let t=e.cursor;for(;t<e.text.length;){let n=nextGraphemeBoundary(e.text,t);if(isWordCharacter(e.text.slice(t,n)))break;t=n}for(;t<e.text.length;){let n=nextGraphemeBoundary(e.text,t);if(!isWordCharacter(e.text.slice(t,n)))break;t=n}return t===e.cursor?e:{text:e.text,cursor:t}}function moveHome(e){let t=logicalLineStart(e.text,e.cursor);return e.cursor===t?e:{text:e.text,cursor:t}}function moveEnd(e){let t=logicalLineEnd(e.text,e.cursor);return e.cursor===t?e:{text:e.text,cursor:t}}function killToEnd(e){let t=logicalLineEnd(e.text,e.cursor);return e.cursor>=t?e:{text:e.text.slice(0,e.cursor)+e.text.slice(t),cursor:e.cursor}}function killToStart(e){let t=logicalLineStart(e.text,e.cursor);return e.cursor<=t?e:{text:e.text.slice(0,t)+e.text.slice(e.cursor),cursor:t}}function deleteWordBackward(e){let t=moveWordBackward(e).cursor;if(t===e.cursor)return e;let n=e.text.slice(0,t)+e.text.slice(e.cursor);return{text:n,cursor:graphemeBoundaryAtOrAfter(n,t)}}function deleteWord(e){if(e.cursor===0)return e;let t=logicalLineStart(e.text,e.cursor),n=e.cursor;for(;n>t;){let t=previousGraphemeBoundary(e.text,n);if(!isWhitespace(e.text.slice(t,n)))break;n=t}for(;n>t;){let t=previousGraphemeBoundary(e.text,n);if(isWhitespace(e.text.slice(t,n)))break;n=t}let r=e.text.slice(0,n)+e.text.slice(e.cursor);return{text:r,cursor:graphemeBoundaryAtOrAfter(r,n)}}function logicalLineStart(e,t){return t===0?0:e.lastIndexOf(`
`,t-1)+1}function logicalLineEnd(e,t){let n=e.indexOf(`
`,t);return n===-1?e.length:n}function applyLineEditorKey(e,t,n){let r=n?.multiline??!1;switch(t.type){case`text`:return insert(e,r?t.value:t.value.replaceAll(`
`,` `));case`newline`:return r?insert(e,`
`):void 0;case`backspace`:return backspace(e);case`delete`:return deleteForward(e);case`left`:case`ctrl-b`:return moveLeft(e);case`right`:case`ctrl-f`:return moveRight(e);case`alt-b`:return moveWordBackward(e);case`alt-f`:return moveWordForward(e);case`alt-backspace`:return deleteWordBackward(e);case`home`:case`ctrl-a`:return moveHome(e);case`end`:case`ctrl-e`:return moveEnd(e);case`ctrl-k`:return killToEnd(e);case`ctrl-u`:return killToStart(e);case`ctrl-w`:return deleteWord(e);default:return}}var KillRing=class{#e=[];#t;#n;constructor(e=20){this.#t=e}clear(){this.#e.length=0,this.#n=void 0}interruptYank(e){e.type!==`ctrl-y`&&e.type!==`alt-y`&&(this.#n=void 0)}apply(e,t,n){if(t.type===`ctrl-y`)return this.#i(e);if(t.type===`alt-y`)return this.#a(e);this.#n=void 0;let r=applyLineEditorKey(e,t,n);return r!==void 0&&this.#r(killedText(e,r,t)),r}#r(e){e.length===0||this.#t<=0||(this.#e.unshift(e),this.#e.length>this.#t&&(this.#e.length=this.#t))}#i(e){let t=this.#e[0];if(t===void 0)return this.#n=void 0,e;let n=insert(e,t);return this.#n={state:n,start:e.cursor,replacementEnd:e.cursor+t.length,ringIndex:0},n}#a(e){let t=this.#n;if(t===void 0||this.#e.length<2||e!==t.state)return e;let n=(t.ringIndex+1)%this.#e.length,r=this.#e[n],i=t.start+r.length,a=e.text.slice(0,t.start)+r+e.text.slice(t.replacementEnd),o={text:a,cursor:graphemeBoundaryAtOrAfter(a,i)};return this.#n={state:o,start:t.start,replacementEnd:i,ringIndex:n},o}};function killedText(e,t,n){switch(n.type){case`ctrl-k`:return e.text.slice(e.cursor,logicalLineEnd(e.text,e.cursor));case`ctrl-u`:case`ctrl-w`:return e.text.slice(t.cursor,e.cursor);default:return``}}function isWhitespace(e){return/^\s+$/u.test(e)}function isWordCharacter(e){return/^[\p{L}\p{M}\p{N}_]/u.test(e)}function visibleLine(e,t,n=`…`){let r=Math.max(1,t),{text:i,cursor:a}=e,o=graphemes(i),s=o.findIndex(e=>e.start===a),c=s===-1?o.length:s,l=o[c]?.text??``;if(inputTextWidth(i)<=r)return{before:i.slice(0,a),under:l,after:i.slice(a+l.length)};let u=c,d=c+ +(l.length>0),windowWidth=(e,t)=>{let r=o[e]?.start??i.length,a=o[t]?.start??i.length;return inputTextWidth(i.slice(r,a))+(e>0?inputTextWidth(n):0)+(t<o.length?inputTextWidth(n):0)},f=!0;for(;;){let e=u>0&&windowWidth(u-1,d)<=r,t=d<o.length&&windowWidth(u,d+1)<=r;if(!e&&!t)break;f&&e||!t?--u:d+=1,f=!f}let p=o[u]?.start??i.length,m=o[d]?.start??i.length;return{before:`${u>0?n:``}${i.slice(p,a)}`,under:l,after:`${i.slice(a+l.length,m)}${d<o.length?n:``}`}}function layoutPromptInput(e){let t=[],n=0,r=0,i=0;for(let a of e.text.split(`
`))e.cursor>=i&&e.cursor<=i+a.length&&(n=t.length,r=e.cursor-i),t.push({text:a,start:i}),i+=a.length+1;return{rows:t,caretRow:n,caretOffset:r}}function movePromptLine(e,t){let n=layoutPromptInput(e),r=t===`up`?n.caretRow-1:n.caretRow+1;if(r<0||r>=n.rows.length)return;let i=n.rows[n.caretRow],a=n.rows[r],o=inputTextWidth(i.text.slice(0,n.caretOffset));return{text:e.text,cursor:a.start+offsetAtVisibleColumn(a.text,o)}}var PromptHistory=class{#e=[];#t=0;#n=``;add(e){if(e.trim().length!==0){if(this.#e.at(-1)===e){this.#r();return}this.#e.push(e),this.#r()}}begin(e){this.#t=this.#e.length,this.#n=e}previous(e){if(this.#e.length!==0&&(this.#t===this.#e.length&&(this.#n=e),this.#t!==0))return--this.#t,this.#e[this.#t]}next(){if(!(this.#t>=this.#e.length))return this.#t+=1,this.#t===this.#e.length?this.#n:this.#e[this.#t]}#r(){this.#t=this.#e.length,this.#n=``}};export{EMPTY_LINE,KillRing,PromptHistory,applyLineEditorKey,backspace,deleteForward,deleteWord,deleteWordBackward,insert,killToEnd,killToStart,layoutPromptInput,lineOf,maskLine,moveEnd,moveHome,moveLeft,movePromptLine,moveRight,moveWordBackward,moveWordForward,visibleLine};