-
-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Autocomplete using parameter objects #410
Changes from 3 commits
1881eb4
bb293dd
a27256d
972c0fd
8692443
acb8a00
4b1e29f
c1d064f
6ce3a40
11bbbac
2676192
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -2,9 +2,9 @@ | |||||||
import { onDestroy, onMount, createEventDispatcher, tick } from "svelte" | ||||||||
import { basicSetup } from "codemirror" | ||||||||
import { EditorView, keymap } from "@codemirror/view" | ||||||||
import { EditorState, EditorSelection } from "@codemirror/state" | ||||||||
import { EditorState, EditorSelection, Transaction } from "@codemirror/state" | ||||||||
import { indentUnit, StreamLanguage, syntaxHighlighting } from "@codemirror/language" | ||||||||
import { autocompletion } from "@codemirror/autocomplete" | ||||||||
import { autocompletion, pickedCompletion } from "@codemirror/autocomplete" | ||||||||
import { redo } from "@codemirror/commands" | ||||||||
import { linter, lintGutter } from "@codemirror/lint" | ||||||||
import { indentationMarkers } from "@replit/codemirror-indentation-markers" | ||||||||
|
@@ -94,9 +94,12 @@ | |||||||
{ key: "Enter", run: autoIndentOnEnter }, | ||||||||
{ key: "Ctrl-Shift-z", run: redoAction } | ||||||||
]), | ||||||||
EditorView.updateListener.of((state) => { | ||||||||
if (state.docChanged) updateItem() | ||||||||
if (state.selectionSet) $editorStates[currentId].selection = view.state.selection | ||||||||
EditorView.updateListener.of((transaction) => { | ||||||||
if (transaction.docChanged) { | ||||||||
indentMultilineInserts(transaction) | ||||||||
updateItem() | ||||||||
} | ||||||||
if (transaction.selectionSet) $editorStates[currentId].selection = view.state.selection | ||||||||
}), | ||||||||
basicSetup, | ||||||||
parameterTooltip(), | ||||||||
|
@@ -225,6 +228,7 @@ | |||||||
|
||||||||
const tabs = /^\t*/.exec(lineText)?.[0].length | ||||||||
const spaces = /^\s*/.exec(lineText)?.[0].length - tabs | ||||||||
|
||||||||
return Math.floor(spaces / 4) + tabs | ||||||||
} | ||||||||
|
||||||||
|
@@ -281,10 +285,28 @@ | |||||||
}) | ||||||||
} | ||||||||
|
||||||||
async function setScrollPosition() { | ||||||||
function setScrollPosition() { | ||||||||
view.scrollDOM.scrollTo({ top: $editorScrollPositions[currentId] || 0 }) | ||||||||
} | ||||||||
|
||||||||
function indentMultilineInserts(transaction) { | ||||||||
// Only perform this function if transaction is of an expected type performed by the user to prevent infinite loops on changes made by CodeMirror | ||||||||
if (transaction.transactions.every(tr => ["input.paste", "input.complete"].includes(tr.annotation(Transaction.userEvent)))) { | ||||||||
const [range] = transaction.changedRanges | ||||||||
const text = transaction.state.doc.toString().slice(range.fromB, range.toB) | ||||||||
const indents = getIndentForLine(view.state, range.fromB) | ||||||||
let tabs = "" | ||||||||
for (let i = 0; i < indents; i++) { tabs += "\t" } | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, neat! |
||||||||
|
||||||||
const changes = { | ||||||||
from: range.fromB, | ||||||||
to: range.toB, | ||||||||
insert: text.replaceAll(/\n/g, "\n" + tabs) | ||||||||
} | ||||||||
|
||||||||
view.dispatch({ changes }) | ||||||||
} | ||||||||
} | ||||||||
</script> | ||||||||
|
||||||||
<svelte:window | ||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,8 +33,9 @@ | |
$: if ($currentProject && $sortedItems?.length && $currentItem && !Object.keys($currentItem).length) | ||
$currentItem = $sortedItems.filter(i => i.type == "item")?.[0] || {} | ||
|
||
$: $completionsMap = parseKeywords($settings) | ||
|
||
onMount(() => { | ||
$completionsMap = parseKeywords() | ||
$workshopConstants = constants | ||
$currentItem = $items?.[0] || {} | ||
$projects = _projects || [] | ||
|
@@ -76,32 +77,37 @@ | |
if (nullCount) params.args_min_length = v.args.length - nullCount | ||
} | ||
|
||
if (v.args?.length) { | ||
// Add detail arguments in autocomplete results | ||
const detail = v.args.map(a => `${ toCapitalize(a.name) }`) | ||
const joinedDetail = detail.join(", ") | ||
if (!params.args_length) return params | ||
|
||
params.detail_full = joinedDetail | ||
params.detail = `(${ joinedDetail.slice(0, 30) }${ joinedDetail.length > 30 ? "..." : "" })` | ||
// Add detail arguments in autocomplete results | ||
const detail = v.args.map(a => `${ toCapitalize(a.name) }`) | ||
const joinedDetail = detail.join(", ") | ||
|
||
// Add apply values when selecting autocomplete, filling in default args | ||
const lowercaseDefaults = Object.keys(defaults).map(k => k.toLowerCase()) | ||
const apply = v.args.map(a => { | ||
const string = a.default?.toString().toLowerCase().replaceAll(",", "") | ||
params.detail_full = joinedDetail | ||
params.detail = `(${ joinedDetail.slice(0, 30) }${ joinedDetail.length > 30 ? "..." : "" })` | ||
|
||
if (lowercaseDefaults.includes(string)) return defaults[toCapitalize(string)] | ||
// Add apply values when selecting autocomplete, filling in default args | ||
const lowercaseDefaults = Object.keys(defaults).map(k => k.toLowerCase()) | ||
const useParameterObject = $settings["autocomplete-parameter-objects"] && params.args_length >= $settings["autocomplete-min-parameter-size"] | ||
const apply = v.args.map(a => { | ||
let string = a.default?.toString().toLowerCase().replaceAll(",", "") | ||
if (useParameterObject) string = `\n\t${ a.name }: ${ string }` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would it make sense to have a limit on when each parameter is put on a new line and when not? If I was one of those people that put There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
||
return toCapitalize(string) | ||
}) | ||
if (lowercaseDefaults.includes(string)) return defaults[toCapitalize(string)] | ||
|
||
params.parameter_keys = detail | ||
params.parameter_defaults = apply | ||
params.apply = `${ v["en-US"] }(${ apply.join(", ") })` | ||
return toCapitalize(string) | ||
}) | ||
|
||
// Add arguments to info box | ||
params.info += "\n\nArguments: " | ||
params.info += detail | ||
} | ||
params.parameter_keys = detail | ||
params.parameter_defaults = apply | ||
|
||
params.apply = useParameterObject ? | ||
`${ v["en-US"] }({ ${ apply.join(", ") }\n})` : | ||
`${ v["en-US"] }(${ apply.join(", ") })` | ||
|
||
// Add arguments to info box | ||
params.info += "\n\nArguments: " | ||
params.info += detail | ||
|
||
return params | ||
}) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -104,5 +104,7 @@ export const settings = writable({ | |
"color-invalid": "#b33834", | ||
"color-custom-keyword": "#c678dd", | ||
"show-indent-markers": true, | ||
"word-wrap": false | ||
"word-wrap": false, | ||
"autocomplete-parameter-objects": false, | ||
"autocomplete-min-parameter-size": 2 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. PR description says 3, but this is set to 2. Which one should it be? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah yes, it should be 2. I had it at 3 initially, but 2 felt better |
||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indentation is not all sunshine and rainbows, sadly
brave_IJ8rPnV7Up.mp4
I think this could benefit from reapplying indentation on each line of the pasted content?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made some improvements and it should be much better. It's not quite perfect but the imperfections make enough sense. VSCode has similar (but different) inconsistencies. I think this is about as close as we can get without fully parsing the text, which would be too slow for larger texts anyway.