Autocompletado con texto fantasma en línea
Cuando el usuario deja de escribir, el editor solicita a una función que tú proporcionas una continuación de la oración y la muestra en gris después del cursor. Tab la acepta; cualquier otra acción la descarta. El editor no incluye ningún modelo de IA ni realiza llamadas de red por su cuenta: tu función decide de dónde procede el texto.

Cómo activarlo
Esta función la ofrece el plugin ghostcomplete.js (también incluido en plugins/all_plugins.js). No tiene botón en la barra de herramientas. Solo se ejecuta cuando ghostText está configurado y ghostTextResolver es una función.
<link rel="stylesheet" href="/richtexteditor/rte_theme_default.css">
<script src="/richtexteditor/rte.js"></script>
<script src="/richtexteditor/plugins/ghostcomplete.js"></script>
<div id="editor"><p>Our support team answers</p></div>
<script>
var editor = new RichTextEditor("#editor", {
ghostText: true,
ghostTextResolver: function (ctx) {
return fetch("/api/complete", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ before: ctx.before })
})
.then(function (r) { return r.json(); })
.then(function (data) { return data.text; });
}
});
</script>
Aquí /api/complete es tu propio endpoint. Recibe el texto anterior al cursor, consulta el modelo que uses (conserva la clave de API en el servidor) y responde { "text": " every ticket within one business day." }. Inicia el texto devuelto con un espacio cuando continúe después de una palabra, porque se inserta exactamente como se devuelve.
Qué recibe y devuelve el resolver
ghostTextResolver(ctx) se llama con:
ctx.before: el texto desde el principio del párrafo actual (o encabezado, elemento de lista, celda…) hasta el cursor, limitado a los últimosmaxContextcaracteres;ctx.after: el texto desde el cursor hasta el final de ese bloque;ctx.full: el texto de todo el documento.
Devuelve una cadena o una Promise de una cadena. Una cadena vacía, un valor que no sea una cadena, un error lanzado o una Promise rechazada no muestran nada. Si el usuario vuelve a escribir antes de que llegue la respuesta, esta se descarta. Solo se solicita una sugerencia cuando ctx.before tiene al menos minChars caracteres que no sean espacios y no hay nada seleccionado.
Opciones
| Opción | Valor predeterminado | Función |
|---|---|---|
ghostText | false | true, o un objeto con los tres ajustes siguientes, activa la función. |
ghostText.delayMs | 600 | Pausa después de la última entrada antes de llamar al resolver. Usa un número positivo: 0 se considera sin definir y da 600. |
ghostText.minChars | 3 | Número mínimo de caracteres que no sean espacios antes del cursor. |
ghostText.maxContext | 2000 | Número máximo de caracteres que se pasan en ctx.before. |
ghostTextResolver | null | Tu función, tal como se describe arriba. |
Teclas y API
- Tab acepta la sugerencia. Se inserta como texto escrito, de modo que un solo Ctrl+Z la elimina.
- Escape, las flechas, Home, End, PageUp y PageDown la descartan. Escribir cualquier carácter la descarta e inicia una nueva espera.
- Hacer clic o tocar el texto gris lo acepta (la única forma en un teléfono, que no tiene tecla Tab). Hacer clic en cualquier otro sitio lo descarta.
Métodos: editor.setGhostTextResolver(fn) sustituye el resolver durante la ejecución; editor.requestGhostText() solicita una sugerencia de inmediato, sin esperar; editor.acceptGhostText(), editor.dismissGhostText() y editor.hasGhostText() hacen lo que indican sus nombres. Con el plugin de comandos con barra cargado, el menú "/" tiene una entrada "AI complete" que llama a requestGhostText(). Si no hay un resolver configurado, esa llamada muestra una breve nota en el editor que indica que el autocompletado no está configurado.
Aspectos a tener en cuenta
- Mientras se muestra, la sugerencia es este elemento después del cursor:
<span class="rte-ghost" contenteditable="false" data-rte-ghost="1" aria-hidden="true"> every ticket within one business day.</span>getHTMLCode(),getHTMLContent()ygetJSON()lo eliminan, de modo que el HTML guardado solo contiene texto aceptado por el usuario. Los lectores de pantalla lo omiten (aria-hidden). - El recuento de palabras y caracteres de la barra inferior incluye el texto gris mientras se muestra.
- Cada pausa al escribir produce una llamada a tu endpoint. Limita la frecuencia y usa caché en el servidor, y aumenta
delayMssi las llamadas tienen costo. requestGhostText()también necesita queghostTextesté configurado; con solo un resolver no hace nada.
Relacionado: AI Toolkit (acciones de IA mediante comandos), proveedores de IA y streaming, demo de asistencia de escritura.