Skip to content
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

Implicit autocompletion not working #12

Open
richardjharris opened this issue Jan 21, 2023 · 4 comments
Open

Implicit autocompletion not working #12

richardjharris opened this issue Jan 21, 2023 · 4 comments
Labels
bug Something isn't working

Comments

@richardjharris
Copy link

If you visit https://codemirror.net/try/ and type this in

import {basicSetup, EditorView} from "codemirror";
import {autocompletion, completeFromList} from "@codemirror/autocomplete";

function findAutoWords(context) {
  console.log("autocomplete called");
  const word = context.matchBefore(/#\w*/);
  if (word == null) return null;
  if (word.from == word.to && !context.explicit) return null;
  return {
    from: word.from,
    options: [{ label: "#match" }, { label: "#hello" }, { label: "#magic" }],
    // If user pressed Ctrl+Space, return all possible tags rather than those matching
    // the typed prefix.
    filter: !context.explicit,
  };
}

new EditorView({
  doc: "console.log('hello')\n",
  extensions: [autocompletion({
    icons: false,
    override: [findAutoWords],
  })],
  parent: document.body
})

... autocompletion automatically triggers when # is typed.

I tried to create the same code using vue-codemirror6 and the autocompletion only works when Ctrl+Space is pressed, e.g.

https://playcode.io/1085925

<script setup lang="ts">
import { autocompletion, CompletionContext } from "@codemirror/autocomplete";
import type { Extension } from "@codemirror/state";
import CodeMirror from "vue-codemirror6";
import { ref, watch } from "vue";

const diaryText = ref("");

function diaryAutocomplete(context: CompletionContext) {
  console.log("diaryAutocomplete called");
  const word = context.matchBefore(/#\w*/);
  if (word == null) return null;
  if (word.from == word.to && !context.explicit) return null;
  return {
    from: word.from,
    options: [{ label: "#match" }, { label: "#hello" }, { label: "#magic" }],
    // If user pressed Ctrl+Space, return all possible tags rather than those matching
    // the typed prefix.
    filter: !context.explicit,
  };
}


const extensions: Extension[] = [
  autocompletion({
    icons: false,
    override: [diaryAutocomplete],
  }),
];
</script>

<template>
  <div class="diary-editor">
    <code-mirror v-model="diaryText" :extensions="extensions" />
  </div>
</template>

<style>
/* start 150px and grow as user types */
.cm-content,
.cm-gutter {
  min-height: 150px;
}

.cm-gutters {
  margin: 1px;
}

.cm-scroller {
  overflow: auto;
}

.cm-wrap {
  border: 1px solid silver;
}

.diary-editor {
  border: 1px solid #cbd5e0;
  border-radius: 0.5rem;
}
</style>

@logue logue added the bug Something isn't working label Jan 22, 2023
@logue
Copy link
Owner

logue commented Jan 22, 2023

The possible cause at the moment is because the implementation is to register the extension by the method described in the address below.

https://codemirror.net/examples/config/

StateEffect.reconfigure.of(extensions)

With this method, it seems that some states and other values cannot be reflected, so there may be some ingenuity.

https://discuss.codemirror.net/t/how-update-extensions-after-creating/4064

@logue
Copy link
Owner

logue commented Jan 27, 2023

Although it is palliative, please try to reload the extension by executing the forceReconfigure() function that has been available since 1.19.

@g992
Copy link

g992 commented Feb 1, 2023

Hi, how can i trigger showing autocomplete after every keypress, not only after ctrl + space?

@logue
Copy link
Owner

logue commented Feb 2, 2023

According to the CodeMirror specifications, there are patterns that do not work unless the extension is registered at initialization, and patterns that work even if the extension is registered later with the reconfigure instruction, so it is difficult to isolate the problem.

In vue-codemirror6, I think that this problem occurred because it was processed with reconfigure at once.

As a temporary measure, I prepared the forceReconfigure() method. This is the process of canceling all registered extensions and then registering them.

It's a rough implementation, but please try to execute the forceReconfigure function on the component when the extensions are updated as shown below.

<script setup>
import { watch } from 'vue';
import CodeMirror from 'vue-codemirror6";

const editor = ref();

// some function

watch(
  () => extnetions.value, 
  () => editor.value?.forceReconfigure()); 
);
</script>

<template>
  <codemirror v-model="value" ref="editor" />
</template>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants