Skip to content

Commit

Permalink
enable paths autocompletions (#2949)
Browse files Browse the repository at this point in the history
Co-authored-by: Fons van der Plas <[email protected]>
  • Loading branch information
Pangoraw and fonsp authored Jul 15, 2024
1 parent c470cdc commit c247126
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 45 deletions.
50 changes: 12 additions & 38 deletions frontend/components/CellInput/pluto_autocomplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,34 +13,6 @@ let { autocompletion, completionKeymap, completionStatus, acceptCompletion, sele
// These should be imported from @codemirror/autocomplete, but they are not exported.
const completionState = autocompletion()[1]

/** @type {any} */
const TabCompletionEffect = StateEffect.define()
const tabCompletionState = StateField.define({
create() {
return false
},

update(value, /** @type {Transaction} */ tr) {
// Tab was pressed
for (let effect of tr.effects) {
if (effect.is(TabCompletionEffect)) return true
}
if (!value) return false

let previous_selected = autocomplete.selectedCompletion(tr.startState)
let current_selected = autocomplete.selectedCompletion(tr.state)

// Autocomplete window was closed
if (previous_selected != null && current_selected == null) {
return false
}
if (previous_selected != null && previous_selected !== current_selected) {
return false
}
return value
},
})

/** @param {EditorView} cm */
const tab_completion_command = (cm) => {
// This will return true if the autocomplete select popup is open
Expand All @@ -66,9 +38,6 @@ const tab_completion_command = (cm) => {
// ?([1,2], 3)<TAB> should trigger autocomplete
if (last_char === ")" && !last_line.includes("?")) return false

cm.dispatch({
effects: TabCompletionEffect.of(10),
})
return autocomplete.startCompletion(cm)
}

Expand Down Expand Up @@ -224,9 +193,11 @@ const julia_code_completions_to_cm =
// console.debug({ definitions })
// const proposed = new Set()

let to_complete_onto = to_complete.slice(0, start)
let is_field_expression = to_complete_onto.endsWith(".")
let is_listing_all_fields_of_a_module = is_field_expression && start === stop
const to_complete_onto = to_complete.slice(0, start)
const is_field_expression = to_complete_onto.endsWith(".")

// skip autocomplete's filter if we are completing a ~ path (userexpand)
const skip_filter = ctx.matchBefore(/\~[^\s\"]*/) != null

return {
from: start,
Expand All @@ -239,10 +210,14 @@ const julia_code_completions_to_cm =
validFor,

commitCharacters: julia_commit_characters,
filter: !skip_filter,

options: [
...results
.filter(([text, _1, _2, is_from_notebook]) => !(is_from_notebook && is_already_a_global(text)))
.filter(
([text, _1, _2, is_from_notebook, completion_type]) =>
(ctx.explicit || completion_type != "path") && !(is_from_notebook && is_already_a_global(text))
)
.map(([text, value_type, is_exported, is_from_notebook, completion_type, _ignored], i) => {
// (quick) fix for identifiers that need to be escaped
// Ideally this is done with Meta.isoperator on the julia side
Expand Down Expand Up @@ -420,7 +395,7 @@ const special_emoji_examples = ["🐶", "🐱", "🐭", "🐰", "🐼", "🐨",
const apply_completion = (view, completion, from, to) => {
const currentComp = view.state.sliceDoc(from, to)

let insert = completion.detail ?? completion.label;
let insert = completion.detail ?? completion.label
const is_emoji = completion.label.startsWith("\\:")
if (!is_emoji && currentComp !== completion.label) {
const is_inside_string = match_string_complete(view.state, to)
Expand All @@ -429,7 +404,7 @@ const apply_completion = (view, completion, from, to) => {
}
}

view.dispatch({ changes: {from, to, insert}, annotations: autocomplete.pickedCompletion.of(completion), })
view.dispatch({ changes: { from, to, insert }, annotations: autocomplete.pickedCompletion.of(completion) })
}

const special_symbols_completion = (/** @type {() => Promise<SpecialSymbols?>} */ request_special_symbols) => {
Expand Down Expand Up @@ -535,7 +510,6 @@ export let pluto_autocomplete = ({ request_autocomplete, request_special_symbols
}

return [
tabCompletionState,
autocompletion({
activateOnTyping: ENABLE_CM_AUTOCOMPLETE_ON_TYPE,
override: [
Expand Down
20 changes: 13 additions & 7 deletions src/runner/PlutoRunner/src/PlutoRunner.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2025,25 +2025,31 @@ function completion_fetcher(query, pos, workspace::Module)
results, loc, found = FuzzyCompletions.completions(
query, pos, workspace;
enable_questionmark_methods=false,
enable_expanduser=false,
enable_path=false,
enable_expanduser=true,
enable_path=true,
enable_methods=false,
enable_packages=false,
)
partial = query[1:pos]
if endswith(partial, '.')
filter!(is_dot_completion, results)
# we are autocompleting a module, and we want to see its fields alphabetically
sort!(results; by=(r -> completion_text(r)))
sort!(results; by=completion_text)
elseif endswith(partial, '/')
filter!(is_path_completion, results)
sort!(results; by=(r -> completion_text(r)))
sort!(results; by=completion_text)
elseif endswith(partial, '[')
filter!(is_dict_completion, results)
sort!(results; by=(r -> completion_text(r)))
sort!(results; by=completion_text)
else
isenough(x) = x 0
filter!(r -> is_kwarg_completion(r) || isenough(score(r)) && !is_path_completion(r), results) # too many candiates otherwise
contains_slash = '/' partial
if !contains_slash
filter!(!is_path_completion, results)
end
filter!(
r -> is_kwarg_completion(r) || score(r) >= 0,
results
) # too many candidates otherwise
end

exported = completions_exported(results)
Expand Down

0 comments on commit c247126

Please sign in to comment.