From 80a7d4fbf8c0633c16cf31341563e8dfb3202fa3 Mon Sep 17 00:00:00 2001 From: Adam Obuchowicz Date: Fri, 7 Mar 2025 16:46:28 +0100 Subject: [PATCH] Literals and operators in Component Browser (#12420) Fixes #12372 https://github.com/user-attachments/assets/69b08aaf-71ca-4598-83ad-de4895d04dcd --- CHANGELOG.md | 4 + .../components/ComponentBrowser.vue | 57 +++++++------- .../ComponentBrowser/ComponentList.vue | 35 +++++++-- .../ComponentBrowser/__tests__/input.test.ts | 74 +++++++++++++++++++ .../components/ComponentBrowser/component.ts | 4 +- .../components/ComponentBrowser/input.ts | 30 ++++++-- .../util/ast/__tests__/abstract.test.ts | 14 ++++ app/rust-ffi/src/lib.rs | 46 +++++++++++- app/ydoc-server-polyglot/src/ffiPolyglot.ts | 1 + app/ydoc-server-polyglot/src/polyglot.d.ts | 1 + app/ydoc-shared/src/ast/ffi.ts | 12 ++- app/ydoc-shared/src/ast/token.ts | 15 +++- app/ydoc-shared/src/ast/tree.ts | 16 +++- 13 files changed, 259 insertions(+), 50 deletions(-) create mode 100644 app/gui/src/project-view/components/ComponentBrowser/__tests__/input.test.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 117ea0ce0d14..5d6c499722d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,9 @@ - ["Insert link" button added to documentation panel][12365] - [Cloud File Browser, when opened first time after opening project, shows and highlights the currently set file][12184] +- [It's easier to write numeric/text nodes in Component Browser][12420]. When + typing digits only, any names containing digits are not the best match + anymore. Also unclosed text literals will be automatically closed. [11889]: https://github.com/enso-org/enso/pull/11889 [11836]: https://github.com/enso-org/enso/pull/11836 @@ -56,6 +59,7 @@ [12386]: https://github.com/enso-org/enso/pull/12386 [12365]: https://github.com/enso-org/enso/pull/12365 [12184]: https://github.com/enso-org/enso/pull/12184 +[12420]: https://github.com/enso-org/enso/pull/12420 #### Enso Standard Library diff --git a/app/gui/src/project-view/components/ComponentBrowser.vue b/app/gui/src/project-view/components/ComponentBrowser.vue index f65f09d5a6ae..3f736ebe6fb1 100644 --- a/app/gui/src/project-view/components/ComponentBrowser.vue +++ b/app/gui/src/project-view/components/ComponentBrowser.vue @@ -3,7 +3,6 @@ import { componentBrowserBindings, listBindings } from '@/bindings' import { type Component } from '@/components/ComponentBrowser/component' import ComponentEditor from '@/components/ComponentBrowser/ComponentEditor.vue' import ComponentList from '@/components/ComponentBrowser/ComponentList.vue' -import { Filtering } from '@/components/ComponentBrowser/filtering' import { useComponentBrowserInput, type Usage } from '@/components/ComponentBrowser/input' import GraphVisualization from '@/components/GraphEditor/GraphVisualization.vue' import SvgButton from '@/components/SvgButton.vue' @@ -15,7 +14,6 @@ import { injectNodeColors } from '@/providers/graphNodeColors' import { injectInteractionHandler, type Interaction } from '@/providers/interactionHandler' import { useGraphStore } from '@/stores/graph' import type { RequiredImport } from '@/stores/graph/imports' -import { useProjectStore } from '@/stores/project' import { injectProjectNames } from '@/stores/projectNames' import { useSuggestionDbStore } from '@/stores/suggestionDatabase' import { type Typename } from '@/stores/suggestionDatabase/entry' @@ -29,6 +27,8 @@ import { debouncedGetter } from '@/util/reactivity' import type { ComponentInstance } from 'vue' import { computed, onMounted, onUnmounted, ref, toValue, watch, watchEffect } from 'vue' import type { SuggestionId } from 'ydoc-shared/languageServerTypes/suggestions' +import { Range } from 'ydoc-shared/util/data/range' +import { Ok } from 'ydoc-shared/util/data/result' import type { VisualizationIdentifier } from 'ydoc-shared/yjsModel' // Difference in position between the component browser and a node for the input of the component browser to @@ -47,7 +47,6 @@ const EDGE_Y_OFFSET = -8 const cssComponentEditorPadding = `${COMPONENT_EDITOR_PADDING}px` -const projectStore = useProjectStore() const suggestionDbStore = useSuggestionDbStore() const graphStore = useGraphStore() const interaction = injectInteractionHandler() @@ -177,15 +176,6 @@ const selectedSuggestion = computed(() => { const input = useComponentBrowserInput() -const currentFiltering = computed(() => { - if (input.mode.mode === 'componentBrowsing') { - const currentModule = projectStore.moduleProjectPath - return new Filtering(input.mode.filter, currentModule?.ok ? currentModule.value : undefined) - } else { - return undefined - } -}) - onUnmounted(() => { graphStore.cbEditedEdge = undefined }) @@ -285,19 +275,26 @@ watch( // === Accepting Entry === -function acceptSuggestion(component: Opt = null) { - const suggestionId = component?.suggestionId ?? selectedSuggestionId.value - if (suggestionId == null) return acceptInput() - const result = input.applySuggestion(suggestionId) - if (result.ok) acceptInput() - else result.error.log('Cannot apply suggestion') +function applyComponent(component: Opt = null) { + component ??= selected.value + if (component == null) { + input.switchToCodeEditMode() + return Ok() + } + if (component.suggestionId != null) { + return input.applySuggestion(component.suggestionId) + } else { + // Component without suggestion database entry, for example "literal" component. + input.content = { text: component.label, selection: Range.emptyAt(component.label.length) } + input.switchToCodeEditMode() + return Ok() + } } -function applySuggestion(component: Opt = null) { - const suggestionId = component?.suggestionId ?? selectedSuggestionId.value - if (suggestionId == null) return input.switchToCodeEditMode() - const result = input.applySuggestion(suggestionId) - if (!result.ok) result.error.log('Cannot apply suggestion') +function acceptComponent(component: Opt = null) { + const result = applyComponent(component) + if (result.ok) acceptInput() + else result.error.log('Cannot apply suggestion') } function acceptInput() { @@ -314,11 +311,14 @@ function acceptInput() { const outsideComponentBrowsing = computed(() => input.mode.mode != 'componentBrowsing') const actions = registerHandlers({ 'componentBrowser.editSuggestion': { - action: applySuggestion, + action: () => { + const result = applyComponent() + if (!result.ok) result.error.log('Cannot apply component') + }, disabled: outsideComponentBrowsing, }, 'componentBrowser.acceptSuggestion': { - action: acceptSuggestion, + action: acceptComponent, disabled: outsideComponentBrowsing, }, 'componentBrowser.acceptInputAsCode': { @@ -427,10 +427,11 @@ const listsHandler = listBindings.handler({ /> diff --git a/app/gui/src/project-view/components/ComponentBrowser/ComponentList.vue b/app/gui/src/project-view/components/ComponentBrowser/ComponentList.vue index 8364f845b2bb..807e65e50c4b 100644 --- a/app/gui/src/project-view/components/ComponentBrowser/ComponentList.vue +++ b/app/gui/src/project-view/components/ComponentBrowser/ComponentList.vue @@ -1,13 +1,16 @@