29 votos

¿Cómo se implementan generalmente editores de texto?

Esta pregunta es, probablemente, va a hacer que me suenan bastante despistado. Eso es porque yo soy.

Sólo estoy pensando, si yo fuera hipotéticamente interesados en diseñar mi propio editor de texto control de la GUI, widget, o lo que sea que quieras llamarlo (que no soy), ¿cómo puedo hacer?

La tentación para un novato como yo sería la de almacenar el contenido en el editor de texto en forma de una cadena, lo que parece bastante costoso (no estoy demasiado familiarizado con la forma de la cadena implementaciones variar entre un lenguaje/plataforma y el siguiente; pero yo sé que en .NET, por ejemplo, son inmutables, tan frecuentes de manipulación tales como lo que usted necesita para apoyar en un editor de texto sería magníficamente despilfarro, la construcción de una instancia de string tras otro en muy rápida sucesión).

Posiblemente algunos mutable estructura de datos que contiene texto se utiliza en su lugar; pero de averiguar lo que esta estructura podría parecer me parece un poco de un desafío. De acceso aleatorio sería bueno (me gustaría pensar que, de todos modos-después de todo, no desea que el usuario sea capaz de saltar de una a cualquier lugar en el texto?), pero entonces me pregunto sobre el costo de, por ejemplo, desplazarse a algún lugar en el medio de un enorme documento y comenzando a escribir de inmediato. De nuevo, el novato enfoque (dicen que almacenar el texto como un resizeable matriz de caracteres) daría lugar a un muy pobre desempeño, estoy pensando que, como con todos los caracteres tecleados por el usuario habría una enorme cantidad de datos para realizar un "cambio".

Así que si tuviera que adivinar, yo supongo que los editores de texto que se emplean algún tipo de estructura que rompe el texto en partes más pequeñas (líneas, tal vez?), que, individualmente, constituyen matrices de caracteres con acceso aleatorio, y que son en sí mismos al azar accesible como discretos trozos. Aun que parece que debe ser un lugar monstruoso simplificación, aunque, si es que ni remotamente cerca de empezar.

Por supuesto, también me doy cuenta de que no puede ser un "estándar" de manera que los editores de texto son de aplicación; tal vez varía drásticamente de un editor a otro. Pero pensé que, ya que es claramente un problema que ha sido abordado muchas, muchas veces, tal vez de un enfoque relativamente común ha surgido en los últimos años.

De todos modos, estoy interesado en saber si alguien por ahí tiene un poco de conocimiento sobre este tema. Como he dicho, yo definitivamente no estoy buscando a escribir mi propio editor de texto; sólo tengo curiosidad.

22voto

Jerry Coffin Puntos 237758

Una técnica común (especialmente en los mayores editores) se llama una fracción de amortiguamiento. Básicamente, se "rompe" el texto en todo antes de que el cursor y todo después de que el cursor. Todo lo anterior va al principio del buffer. Todo lo que después va a la final del búfer.

Cuando el usuario escribe en el texto, entra en el espacio vacío en el medio sin mover los datos. Cuando el usuario mueve el cursor, mover la cantidad apropiada de texto de uno de los lados de la "ruptura" a la otra. Normalmente, hay un montón de movimiento alrededor de una sola área, por lo que usted está por lo general sólo mover pequeñas cantidades de texto en un momento. La principal excepción es si usted tiene un "ir a la línea xxx" tipo de capacidad.

Charles Crowley ha escrito una mucho más completa que la discusión del tema. También puede que desee ver en el arte de La Edición de Texto, que cubre split buffers (y otras posibilidades) con mucha más profundidad.

4voto

jarmod Puntos 1582

Para algunos recursos, se podía leer ¿Cómo funcionan los editores de texto?

2voto

slebetman Puntos 28276

Hace un tiempo, escribí mi propio editor de texto en Tcl (en realidad, me robó el código en alguna parte y se extendió más allá del reconocimiento, ah, las maravillas de la fuente abierta).

Como usted ha mencionado, haciendo operaciones de cadena muy, muy grandes cadenas pueden ser caros. Así que el editor se divide el texto en pequeñas cadenas en cada salto de línea ("\n" o "\r" o "\r\n"). Así que lo único que me queda es la edición de pequeñas cadenas de nivel de línea y haciendo la lista de operaciones cuando se mueven entre líneas.

La otra ventaja de esto es que es un método simple y natural concepto a trabajar. Mi mente ya se considera cada línea de texto separado reforzado por los años de programación, donde las nuevas líneas son estilísticamente o sintácticamente significativo.

También ayuda a que el caso de uso para mi editor de texto es como una programadores editor. Por ejemplo, he implementado sintaxis hilighting pero no de la palabra de línea/envoltura. Así que en mi caso no es un 1:1 mapa entre saltos de línea en el texto y las líneas dibujadas en la pantalla.

En caso de que desee echar un vistazo, aquí está el código fuente de mi editor: http://wiki.tcl.tk/16056

No es un juguete, por CIERTO. Yo lo uso a diario ya que mi consola estándar editor de texto, a menos que el archivo es demasiado grande para caber en la memoria RAM (en Serio, lo del archivo de texto es? Incluso novelas, que son normalmente de 4 a 5 MB, caben en la memoria RAM. Sólo he visto los archivos de registro de crecer a cientos de MB).

1voto

Chris Smith Puntos 2858

Dependiendo de la cantidad de texto que tiene que estar en el editor a la vez, una cadena para todo el búfer enfoque probablemente iba a estar bien. Creo que el Bloc de notas hace esto ... ¿te has dado cuenta mucho más lento se vuelve a insertar el texto en un archivo grande?

Tener una cadena de texto por línea en una tabla hash parece un buen compromiso. Sería hacer que la navegación a una línea en particular y eliminar/pegar eficiente sin mucha complejidad.

Si desea implementar una función de deshacer, usted querrá una representación que le permite volver a versiones anteriores sin que el almacenamiento de 30 copias de la totalidad del archivo de 30 cambios, a pesar de que probablemente iba a estar bien si el archivo es lo suficientemente pequeño.

1voto

Bill Michell Puntos 4879

La forma más sencilla sería utilizar algún tipo de búfer de cadena de la clase que proporciona el lenguaje. Incluso un simple array de char objetos haría en un apuro.

Anexar, la sustitución y la búsqueda de texto son relativamente rápido. Otras operaciones son potencialmente más tiempo, por supuesto, con la inserción de una secuencia de caracteres al inicio del búfer de ser uno de los más caros acciones.

Sin embargo, esto puede ser perfectamente aceptable en cuanto al rendimiento de un caso de uso sencillo.

Si el costo de las inserciones y deleciones es particularmente significativo, estaría tentado a optimizar mediante la creación de un búfer de la clase contenedora que internamente mantiene una lista de objetos de búfer. Cualquier acción (a excepción de la sustitución simple) que no se producen en la cola de un búfer existente sería el resultado en el búfer de que se trate se va a dividir en el punto correspondiente, por lo que el búfer podría ser modificado en su cola. Sin embargo, la envoltura exterior mantendría la misma, como una interfaz simple de amortiguamiento, por lo que no tuve que reescribir por ejemplo, mi acción de búsqueda.

Por supuesto, este enfoque simple sería rápidamente terminan con un extremadamente fragmentado de búfer, y me gustaría considerar la posibilidad de tener algún tipo de regla para unificar los búferes cuando corresponda, o aplazar la división de un buffer en el caso de, por ejemplo, una sola inserción de caracteres. Tal vez la regla sería que yo sólo había siempre tienen en la mayoría de 2 búferes internos, y a mi me unen a ellos antes de crear uno nuevo, o cuando algo me pidió una vista de todo el buffer a la vez. No estoy seguro.

El punto es, me gustaría comenzar por lo más fácil, pero el acceso a la mutable búfer a través de una cuidada interfaz, y jugar con la implementación interna si perfilado me mostró que yo necesitaba.

Sin embargo, yo definitivamente no empezar con inmutable objetos de Cadena!

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X