diff options
author | Přemysl Eric Janouch <p@janouch.name> | 2022-09-18 05:53:44 +0200 |
---|---|---|
committer | Přemysl Eric Janouch <p@janouch.name> | 2022-09-18 05:54:23 +0200 |
commit | ec20fdef7badebc12621e20c0d66de94243fdb1a (patch) | |
tree | da41981a4f7953714b2697c4ee1d66c90f99e669 /xP | |
parent | 21e5d80ab1505442c96e11075f09d98bcaa211ba (diff) | |
download | xK-ec20fdef7badebc12621e20c0d66de94243fdb1a.tar.gz xK-ec20fdef7badebc12621e20c0d66de94243fdb1a.tar.xz xK-ec20fdef7badebc12621e20c0d66de94243fdb1a.zip |
xP: show all completion options
Diffstat (limited to 'xP')
-rw-r--r-- | xP/public/xP.css | 17 | ||||
-rw-r--r-- | xP/public/xP.js | 42 |
2 files changed, 52 insertions, 7 deletions
diff --git a/xP/public/xP.css b/xP/public/xP.css index c231620..96d6525 100644 --- a/xP/public/xP.css +++ b/xP/public/xP.css @@ -91,6 +91,7 @@ button { display: flex; flex-direction: column; overflow: hidden; + position: relative; } .filler { flex: auto; @@ -170,6 +171,22 @@ button { font-family: monospace; } +.completions { + position: absolute; + left: 0; + right: 0; + bottom: 0; + background: #fff; + padding: .05em .3em; + border-top: 1px solid #888; + + max-height: 50%; + display: flex; + flex-flow: column wrap; + column-gap: .6em; + overflow-x: auto; +} + textarea { font: inherit; padding: .05em .3em; diff --git a/xP/public/xP.js b/xP/public/xP.js index 1cdb8b0..dbba7e2 100644 --- a/xP/public/xP.js +++ b/xP/public/xP.js @@ -652,11 +652,28 @@ let Log = { }, } +let Completions = { + entries: [], + + reset: list => { + Completions.entries = list || [] + m.redraw() + }, + + view: vnode => { + if (!Completions.entries.length) + return + return m('.completions', {}, + Completions.entries.map(option => m('.completion', {}, option))) + }, +} + let BufferContainer = { view: vnode => { return m('.buffer-container', {}, [ m('.filler'), bufferLog !== undefined ? m(Log) : m(Buffer), + m(Completions), ]) }, } @@ -711,17 +728,20 @@ let Input = { let preceding = utf8Encode(textarea.value).slice(0, resp.start) let start = utf8Decode(preceding).length - - // TODO: Somehow display remaining options, or cycle through. - if (resp.completions.length) { + if (resp.completions.length > 0) { textarea.setRangeText(resp.completions[0], start, textarea.selectionEnd, 'end') - } else { - beep() } - if (resp.completions.length === 1) + + if (resp.completions.length == 1) { textarea.setRangeText(' ', textarea.selectionStart, textarea.selectionEnd, 'end') + } else { + beep() + } + + if (resp.completions.length > 1) + Completions.reset(resp.completions.slice(1)) }) return true }, @@ -886,7 +906,15 @@ let Input = { }, view: vnode => { - return m('textarea#input', {rows: 1, onkeydown: Input.onKeyDown}) + return m('textarea#input', { + rows: 1, + onkeydown: Input.onKeyDown, + oninput: event => Completions.reset(), + // Sadly only supported in Firefox as of writing. + onselectionchange: event => Completions.reset(), + // The list of completions is scrollable without receiving focus. + onblur: event => Completions.reset(), + }) }, } |