Sign in Join
Wiki copytemporary

SynEdit/es: what changed

Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11## SynEdit
22
33   SynEdit es un paquete de Lazarus que incluye diversos componentes orientados a la implementación de editores de texto para diversos lenguajes y sintaxis. Estos componentes se pueden encontrar dentro de la paleta de componentes en la solapa 'SynEdit'.
44
55   Contiene un componente editor de código fuente llamado TSynEdit, varios resaltadores de sintaxis y otros componentes utilizados para la edición de código fuente.
66
7-<center>
8-
9-<figure>
10-<img src="Lazarus_Paleta_SynEdit.png" title="Lazarus_Paleta_SynEdit.png" />
11-<figcaption>Lazarus_Paleta_SynEdit.png</figcaption>
12-</figure>
13-
14-</center>
7+![](/wiki-images/a/aa/Lazarus_Paleta_SynEdit.png)
158
169
1710TSynEdit, TSynAutoComplete, TSynExporterHTML, TSynMacroRecorder, TSynMemo, TSynPasSyn, TSynFreePascalSyn, TSynCppSyn, TSynJavaSyn, TSynPerlSyn, TSynHTMLSyn, TSynXMLSyn, TSynLFMSyn, TSynUNIXShellScriptSyn, TSynCssSyn, TSynPHPSyn, TSynTeXSyn, TSynSQLSyn, TSynPhytonSyn, TSynAnySyn, TSynMultiSyn
1811
1912   Frecuentemente se usa el término "SynEdit" para referirse específicamente al componente TSynEdit (del paquete SynEdit) en lugar de referirse a todo el paquete en si.
2013
2114   Está basado en el proyecto independiente SynEdit [[http://synedit.sourceforge.net/]], tomado en la versión 1.3 a partir del cual fue adaptado y extendido con características tales como soporte UTF-8 y plegado de código (code folding). A pesar de que el SynEdit de Lazarus comparte mucho del código original del SynEdit original, la cantidad de cambios introducidos desde su bifurcación, hacen que el actual SynEdit de Lazarus sea incompatible con el SynEdit original.
2215
2316   Está licenciado bajo los mismos términos que el SynEdit original (MPL o GPL).
2417
2518## Características
2619
2720- Viene incluido en la paleta de componentes de Lazarus.
2821- Es un componente que no requiere de dependencias externas (a diferencia de Scintilla).
2922- Es de ejecución rápida. Está optimizado para manejar bloques grandes de datos.
3023- Trabaja en codificación UTF-8.
3124- Permite implementar coloreado de sintaxis, usando resaltadores predefinidos o creando nuevos resaltadores.
3225- Soporta las opciones de "Deshacer" y "Rehacer"
3326- Implementa funciones integradas de Búsqueda/Reemplazo.
3427- Soporta completado y autocompletado de código.
3528- Soporta numeración de líneas.
3629- Soporta plegado de código (folding).
3730- Soporta marcadores de texto, con íconos.
3831- Incluye opciones para exportar a 'html' o 'rtf'.
3932- Soporta selección sencilla en modo columna.
4033- Permite trabajar con complementos.
4134
4235## Uso de SynEdit
4336
4437El componente TSynEdit, se agrega como cualquier control desde la paleta de componentes. Una vez en el formulario ya es funcional como control de edición de texto.
4538
46-<center>
47-
48-<figure>
49-<img src="SynEdit_en_Form.png‎" title="SynEdit_en_Form.png‎" />
50-<figcaption>SynEdit_en_Form.png‎</figcaption>
51-</figure>
52-
53-</center>
39+![](/wiki-images/d/d1/SynEdit_en_Form.png%E2%80%8E)
5440
5541El componente TSynEdit se comporta como un control TMemo, pero con característcias avanzadas de presentación. Todo el contenido se mostrará en un solo tipo de letra, y con caracteres mono-espacio (del mismo ancho).
5642
5743Por defecto tiene habilitadas las funciones del cortapapeles (cortar, copiar, pegar), y las opciones para deshacer y rehacer.
5844
5945Además incluirá las barras de desplazamiento y un panel vertical (Gutter) con información útil sobre el contenido (como el número de línea).
6046
6147Inicialmente no incluirá opciones de resaltado excepto el remarcado de los delimitadores paréntesis, llaves y corchetes (brackets).
6248
6349### Gutter
6450
6551El panel lateral que aparece a la izquierda del control es llamado 'Gutter' o canal. Aquí se muestra información importante del editor, como:
6652
6753- Marcadores.
6854- Número de Línea.
6955- Marcas de cambio.
7056- Marcas de plegado.
7157
7258La propiedad 'Gutter', permite acceder a las propiedades del panel lateral. Para mostrar u ocultar el panel lateral, se accede al campo 'Visible':
7359
7460``` pascal
7561 SynEdit1.Gutter.Visible := False;
7662```
7763
7864Para tener una mejor idea de las propiedades que se pueden configurar, es mejor usar el Inspector de Objetos.
7965
8066### Margen Derecho
8167
8268Al crear el editor, se crea por defecto un margen visible, al lado derecho del contenido del editor.
8369
8470Este margen es una ayuda visual para limitar el ancho del texto, con fines de no exceder el tamaño de una página para cuando se desee imprimir el contenido.
8571
8672Para cambiar su posición:
8773
8874``` pascal
8975 SynEdit1.RightEdge:= 100; //en pixeles
9076```
9177
9278Para ocultarlo:
9379
9480``` pascal
9581 SynEdit1.Options := SynEdit1.Options + [eoHideRightMargin];
9682```
9783
9884### Coordenadas Lógicas y Físicas
9985
10086La información mostrada en el editor, está distribuida en la pantalla como si fuera una matriz de celdas. Por otro lado la información que se desea mostrar, está por lo general, distribuida como un arreglo de bytes (variables de tipo cadena).
10187
10288La relación:
10389
10490(Caracter en pantalla) \<---\> (Byte de información)
10591
10692No es una relación de 1 a 1:
10793
10894- Un caracter en pantalla puede estar representado por más de un byte, (efecto de la codificación UTF-8)
10995- Un byte de datos puede representar más de un caracter en pantalla (efecto de las tabulaciones).
11096
11197Para manejar esta falta de correspondencia, SynEdit maneja dos tipos de coordenadas para el cursor de texto (Caret):
11298
11399- Física: Corresponde a la posición visible del cursor en la pantalla.
114100- Lógica: Corresponde a la posición del cursor dentro de la cadena de texto real.
115101
116102La coordenada X lógica y física suelen ser distintas. La coordenada Y lógica y física son siempre iguales (Podría variar en el futuro).
117103
118104La coordenada física es la posición en la grilla de la pantalla (ignorando los desplazamientos). Esto significa que:
119105
120106
121107Las letras "a" y "á" ocupan ambas una celda en pantalla, y se cuentan como un caracter, aún cuando en UTF-8 (la codificación usada por SynEdit) la letra "a" ocupa un byte, y "á" ocupa dos bytes (en coordenadas lógicas tiene dos bytes de ancho). Existen otros caracteres en UTF-8, que pueden ocupar 3 o hasta 4 bytes.
122108
123109El caracter de tabulación (#9), por otros lado, ocupa un byte como cualquier otro caracter, pero en la pantalla puede ocupar más de una celda, es decir que físicamente ocupa más de una celda de ancho.
124110
125111La coordenada lógica está referida a la posición que ocupan los bytes que representan a un caracter, dentro de toda la cadena.
126112
127113
128114La letra "a" tiene un byte de ancho, e incrementa la coordenada lógica en 1.
129115
130116La letra "á" tiene dos byte de ancho, e incrementa la coordenada lógica en 2.
131117
132118El caracter de tabulación tiene un byte de ancho e incrementa la coordenada lógica en 1.
133119
134120La coordenada X física es siempre contabilizada desde la izquierda del texto, aún si hay desplazamiento en la visualización.
135121
136122Para obtener la celda-X actual desplazada en SynEdit se debe hacer:
137123
138124
139125grid-X-in-visible-part-of-synedit := PhysicalX - SynEdit.LeftChar + 1
140126
141127Para obtener la celda-Y actual desplazada en SynEdit se debe hacer:
142128
143129
144130grid-y-in-visible-part-of-synedit := SynEdit.RowToScreenRow(PhysicalY); // incluye plegado
145131
146132### Búsqueda y Reemplazo
147133
148134Para realizar las operaciones de búsqueda y reemplazo sobre SynEdit, existen dos métodos especiales:
149135
150136``` pascal
151137function SearchReplace(const ASearch, AReplace: string;
152138 AOptions: TSynSearchOptions): integer;
153139
154140function SearchReplaceEx(const ASearch, AReplace: string;
155141 AOptions: TSynSearchOptions; AStart: TPoint): integer;
156142```
157143
158144La función SearchReplaceEx(), es similar a SearchReplace(), excepto que permite definir la posición inicial desde donde se realizará la búsqueda.
159145
160146Las opciones que se pueden usar en 'AOptions' son:
161147
162148- ssoMatchCase
163149- ssoWholeWord
164150- ssoBackwards
165151- ssoEntireScope
166152- ssoSelectedOnly
167153- ssoReplace
168154- ssoReplaceAll
169155- ssoPrompt
170156- ssoSearchInReplacement
171157- ssoRegExpr
172158- ssoRegExprMultiLine
173159- ssoFindContinue
174160
175161En búsqueda, la función SearchReplace() puede devolver los siguientes valores:
176162
1771630 -\> Elemento no encontrado 1 -\> Se encontró al menos un elemento.
178164
179165En reemplazo, la función SearchReplace() puede devolver los siguientes valores:
180166
1811670 -\> Elemento no encontrado n -\> Se reemplazó “n” elementos
182168
183169Ejemplo de búsqueda simple:
184170
185171``` pascal
186172var
187173 encontrado : integer;
188174 buscado : string;
189175
190176...
191177 buscado := 'texto a buscar';
192178 encontrado := editor.SearchReplace(buscado,'',[]);
193179 if encontrado = 0 then
194180 ShowMessage('No se encuentra: ' + buscado);
195181...
196182```
197183
198184Si se encuentra algún elemento que cumpla el criterio de búsqueda, se selecciona la primera coincidencia. Si es que la selección no es visible, se desplaza el contenido del editor, de modo que la selección se haga visible.
199185
200186Por defecto, la búsqueda se hace desde la posición del cursor hacia adelante, ignorando las mayúsculas/minúsculas.
201187
202188Con el siguiente código, se realiza la búsqueda en sentido contrario:
203189
204190``` pascal
205191 encontrado := editor.SearchReplace(buscado,'',[ssoBackwards]);
206192```
207193
208194Para realizar reemplazo, se debe indicar la opción 'ssoReplace':
209195
210196``` pascal
211197var
212198 encontrado : integer;
213199 buscado : string;
214200begin
215201 buscado := 'texto a buscar';
216202 encontrado := editor.SearchReplace(buscado,'texto a reemplazar',[ssoReplace]);
217203 if encontrado = 0 then
218204 ShowMessage('No se encuentra: ' + buscado);
219205...
220206```
221207
222208Si es que se encuentra alguna coincidencia, se reemplaza el texto, y se hace visible en el editor.
223209
224210### Remarcado de texto
225211
226212SynEdit soporta diversos tipos de remarcados para el contenido:
227213
228214Se puede cambiar el color de fondo de una línea implementando el evento 'OnSpecialLineMarkup'.
229215
230216``` pascal
231217procedure TForm1.SynEdit1SpecialLineMarkup(Sender: TObject;
232218 Line: integer; var Special: boolean;
233219 Markup: TSynSelectedColor);
234220begin
235221 if Line = 5 then begin //línea a marcar
236222 Special := True ;
237223 Markup.Background := clGreen; //color de fondo
238224 end;
239225end;
240226```
241227
242228Para marcar ciertos bloques de texto, se puede usar el método 'SetHighlightSearch':
243229
244230``` pascal
245231uses ..., SynEditTypes;
246232...
247233SynEdit1.HighlightAllColor.Background := clRed;
248234SynEdit1.SetHighlightSearch('xyz', [ssoSelectedOnly]) ;
249235```
250236
251237Con este método es posible marcar cualquier combinación de caracteres, no solo alfabéticos. Las opciones que se usan son similares a las opciones de las operaciones de búsqueda/reemplazo.
252238
253239Para información sobre remarcados complejos, ver:
254240
255241<http://forum.lazarus.freepascal.org/index.php/topic,17415.msg95964.html>
256242
257243<http://forum.lazarus.freepascal.org/index.php/topic,17485.msg96510.html>
258244
259245### Marcadores de texto (BookMarks)
260246
261247Los marcadores de texto permiten mostrar un ícono en el panel vertical del editor (Gutter).
262248
263249El siguiente ejemplo, muestra como crear un marcador de texto y hacerlo visible en la línea 2:
264250
265251``` pascal
266252uses ... , SynEditMarks;
267253var
268254 marcador: TSynEditMark;
269255...
270256
271257marcador := TSynEditMark.Create(SynEdit1); //nuevo marcador
272258marcador.ImageList:=ImageList1;
273259marcador.ImageIndex:=1; //elige su ícono
274260marcador.Line:=1; //línea 2
275261marcador.Visible:=true;
276262SynEdit1.Marks.Add(marcador); //agrega el marcador
277263```
278264
279265La lista de imágenes ImageList1, debe conteenr el ícono que aparecerá en el panel vertical del editor.
280266
281267## Modificando el texto por código
282268
283269Para fijar o leer el contenido de SynEdit, se puede acceder a la propiedad 'Text'.
284270
285271La información del texto que muestra SynEdit, se guarda internamente en un TStrigList, visible en la propiedad 'Lines'.
286272
287273Así, para acceder a la primera línea de SynEdit, se accede a:
288274
289275SynEdit1.Lines\[0\]
290276
291277Para modificar el contenido de SynEdit, existen diversos métodos:
292278
293279- Accediendo directamente a 'SynEdit.Lines'. Este método es rápido, porque se modifica directamente a los datos del texto. Sin embargo, este tipo de modificación no guarda registros de las modificaciones hechas de modo que los cambios no se podrán deshacer con la opción 'Undo'.
294280- Usando métodos como InsertTextAtCaret, TextBetweenPoints o TextBetweenPointsEx. Este tipo de modificación del texto si permite deshacer los cambios. Es rápido, pero puede requerir conocer con precisión, las coordenadas del texto a modificar.
295281- Usando comandos de edición. Es la forma como se editaría el texto usando teclado. Se hace uso del método ExecuteCommand(). Este método es lento porque hace modificaciones por caracter. También permite deshacer los cambios.
296282
297283- Usando el portapapeles. Este método está limitado a operaciones de cortado, copiado y pegado, pero se pueden realizar operaciones más elaboradas accedidendo directamente al portapapeles para modificar su contenido. Tanbién se pueden deshacer los cambios.
298284
299285### Menus con Duplicar e intercambiar líneas
300286
301287``` pascal
302288 //Duplicar Línea
303289 procedure TForm1.MenuDuplicarLinea(Sender: TObject);
304290 begin
305291 SynEdit1.Lines.Insert(CustSynEdit().CaretY,CustSynEdit().LineText);
306292 end;
307293
308294 //Intercambiar Línea hacia Arriba
309295 procedure TForm1.MenuLineaArriba(Sender: TObject);
310296 begin
311297 if CustSynEdit.CaretY -1 >= 1 then
312298 begin
313299 CustSynEdit.Lines.Exchange(CustSynEdit.CaretY -1 ,CustSynEdit.CaretY-2);
314300 CustSynEdit.CaretY:=CustSynEdit.CaretY-1;
315301 end;
316302 end;
317303
318304 //Intercambiar Línea hacia Abajo
319305 procedure TForm1.MenuLineaAbajo(Sender: TObject);
320306 begin
321307 if ( CustSynEdit.CaretY + 1 <= CustSynEdit.Lines.Count) then
322308 begin
323309 CustSynEdit.Lines.Exchange(CustSynEdit.CaretY-1,CustSynEdit.CaretY);
324310 CustSynEdit.CaretY:=CustSynEdit.CaretY+1;
325311 end;
326312 end;
327313```
328314
329315### Insertar caracteres en la posición actual
330316
331317``` pascal
332318 procedure TForm1.Button1Click(Sender: TObject);
333319 begin
334320 SynEdit1.CommandProcessor(ecChar,'a', nil); //Inserta a
335321 SynEdit1.SetFocus;
336322 end;
337323```
338324
339325## Portapapeles
340326
341327   SynEdit soporta complétamente las operaciones "Cortar", "Copiar" y "Pegar"
342328
343329   Las operaciones con el protapapeles se implementan con los siguientes métodos:
344330
345331``` pascal
346332 SynEdit1.CopyToClipboard;
347333 SynEdit1.CutToClipboard;
348334 SynEdit1.PasteFromClipboard;
349335```
350336
351337    Para obtener las coordenadas del bloque de selección, usar las propiedades: BlockBegin y BlockEnd.
352338
353339    También se pueden acceder a las acciones del portapapeles, usando comandos de teclado. El siguiente ejemplo, muestra como implementar los atajos por teclado para las acciones 'Cortar', 'Copiar' y 'Pegar':
354340
355341``` pascal
356342 uses
357343 ...
358344 SynEdit, SynEditKeyCmds;
359345
360346 procedure TfrmPrincipal.HandleCodigoKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
361347 begin
362348 if (Shift = [ssCtrl]) then
363349 begin
364350 case Key of
365351 VK_C: synCodigo.CommandProcessor(ecCopy, ' ', nil);
366352 VK_V: synCodigo.CommandProcessor(ecPaste, ' ', nil);
367353 VK_X: synCodigo.CommandProcessor(ecCut, ' ', nil);
368354 end;
369355 end;
370356 end;
371357```
372358
373359### Menú con Deshacer y Rehacer
374360
375361``` pascal
376362 procedure TForm1.MenuRehacer(Sender: TObject);
377363 begin
378364 SynEdit1.Redo;
379365 end;
380366
381367 procedure TForm1.MenuDeshacer(Sender: TObject);
382368 begin
383369 SynEdit1.Undo;
384370 end;
385371```
386372
387373## Resaltado de sintaxis
388374
389375SynEdit soporta el resaltado de sintaxis, usando atributos de texto como el color o el tipo de letra.
390376
391377Para que SynEdit reconozca una sintaxis en particular, debe estar asociado a un objeto resaltador (Highlighter). Existen diversos componentes con varias sintaxis ya creadas (resaltadores) en la paleta de componentes de Lazarus.
392378
393-<center>
394-
395-<figure>
396379<img src="SynEdit_con_res_Python.png" title="Control SynEdit con resaltador de Python." width="355" />
397-<figcaption>Control SynEdit con resaltador de Python.</figcaption>
398-</figure>
399380
400-</center>
401-
402381Para asociar a un componente SynEdit a un resaltador, se debe hacer que su propiedad "Highlighter", apunte al resaltador de sintaxis. Esto se puede hacer usando el Inspector de Objetos o por código.
403382
404383Luego, se puede cambair los atributos de cada tipo de token (identificadores, números, palabras reservadas, etc), cambiando las propiedades del resaltador, que sean de tipo "TSynHighlighterAttributes". Existen diversos atributos que se pueden cambiar, como el color del texto, el color de fondo o el color del borde.
405384
406385También se pueden encontrar resaltadores adicionales en [Highlighter for SynEdit](http://bugs.freepascal.org/view.php?id=18248)
407386
408387Si se quiere un resaltador para una sintaxis nueva, se puede usar alguno de los resaltadores que soportan personalización: SynAnySyn or SynPositionSyn (Ver ejemplos de uso).
409388
410389Otra opción es crear nuestro propio resaltador de sintaxis. Hay algo de información en inglés en [[SynEdit Highlighter]]. Pero hay más información, y en español en [1](http://blog.pucp.edu.pe/action.php?action=plugin&name=LinkCounter&type=c&k=20140710-la_biblia_del_synedit_-_rev6.pdf).
411390
412391## Completado de Código
413392
414393SynEdit permite implementar la opción de completado de código, que permite mostrar una lista de opciones para completar el texto que se está escribiendo, o se puede completar el texto escrito parcialmente.
415394
416395Existen 3 complementos de completado para SynEdit:
417396
418397- TSynCompletion
419398 - Ofrece una lista de palabras en un menú contextual.
420399 - Usado en la IDE par el completado de identificadores.
421400 - Incluido en los ejemplos.
422401 - Disponible en la paleta de componentes desde la versión 0.9.31
423402- TSynAutoComplete
424403 - Reemplaza la palabra actual (si es identificada) con un texto pre-definido. **No** es interactivo ni incluye menú contextual.
425404 - Incluido en los ejemplos.
426405 - Disponible en la paleta de componentes.
427406- TSynEditAutoComplete
428407 - Módulo Básico de plantillas. **No** es interactivo ni incluye menú contextual.
429408 - Es usado por la IDE para el completamiento de codigo usando plantillas. La IDE contiene código adicional que extiende sus características.
430409 - **Not** incluido en los ejemplos.
431410
432411Los tipos TSynAutoComplete y TSynEditAutoComplete no están muy bien diferenciados y probablemente se fusionen.
433412
434413Se recomienda ver los ejemplos que vienen con Lazarus.
435414
436415### Completado de Código con SynCompletion
437416
438417``` pascal
439418 Uses
440419 ... ...
441420 LCLType,//Para poder usar VK_SPACE
442421 syncompletion;
443422
444423 ... ... ....
445424 var
446425 Completion:TSynCompletion;
447426 begin
448427 Completion:=TSynCompletion.Create(Self);
449428 Completion.Editor:=SynEdit;
450429 Completion.ShortCut:=Menus.ShortCut(VK_SPACE, [ssCtrl]);
451430 Completion.ItemList.add('Arc( )');
452431 Completion.ItemList.add('Axes( )');
453432 Completion.ItemList.add('Bezier( )');
454433 Completion.ItemList.add('Cercle( )');
455434 end;
456435```
457436
458437### Desplegar TSynCompletion en la posición actual
459438
460439``` pascal
461440 procedure TForm1.Button1Click(Sender: TObject);
462441 var p:TPoint;
463442 begin
464443 with SynEdit1 do
465444 begin
466445 P := Point(CaretXPix,CaretYPix + LineHeight);
467446 P.X:=Max(0,Min(P.X,ClientWidth-Completion.Width));
468447 P := ClientToScreen(p);
469448 end;
470449 Completion.Execute('',p.x,p.y);
471450 end;
472451```
473452
474453## SynEdit en el IDE
475454
476455    El componente SynEdit es un paquete que ya viene integrado con Lazarus debido a que lo utiliza el propio IDE. Por lo tanto, el paquete no puede ser removido de la lista de instalación. Es por ello que no existe un fichero .lpk.
477456
478457    Al estar integardo en el IDE, se garantiza su estabilidad y madurez. Además podemos verlo trabajando en el mismo IDE y así conocer sus funcionalidades y potencialidades.
479458
480-<figure>
481-<img src="Lazarus_Editor_Codigo_Fuente.png" title="Lazarus_Editor_Codigo_Fuente.png" />
482-<figcaption>Lazarus_Editor_Codigo_Fuente.png</figcaption>
483-</figure>
459+![](/wiki-images/b/b2/Lazarus_Editor_Codigo_Fuente.png)
484460
485461## Synedit 2.0.5 port
486462
487463    Existe una versión alterna de SynEdit, portada desde la versión más reciente del original SynEdit 2.0.5:
488464
489465<http://wiki.lazarus.freepascal.org/SynEdit/port>
490466
491467code: <https://github.com/rnapoles/>
492468
493469## Documentación
494470
495471   Existe amplia información en [La Biblia del SynEdit](http://blog.pucp.edu.pe/blog/tito/wp-content/uploads/sites/610/2013/10/la_biblia_del_synedit_-_rev6.pdf)
496472
497473   Sobre resaltado de sintaxis (en ingles): [[SynEdit Highlighter]]
498474
499475## Más desarrollos, discusiones
500476
501477- RTL (de derecha a izquierda (Right-To-Left)): comenzado por Mazen
502478- Selección automática de fuente UTF-8: Igual que el caso anterior de monoespaciado, pero con una cadena UTF-8 de fuente, de modo que por ejemplo umlaute se muestra correctamente. Por ahora el usuario tiene que elegir la fuente correcta.
503479- Teclas muertas. La mayoría de los teclados soportan pulsar una o más teclas para crear un carácter especial (como en los caracteres acentuados (á,é,í,...) o con el [umlaut](http://es.wikipedia.org/wiki/Umlaut)).
504480- [[Redesign of the SynEdit component|Rediseño del componente SynEdit]]. El objetivo principal es una presentación y un navegación por el texto más fiable. Un enfoque más modular para permitir una mejor integración de las extensiones, y por controles especializados, para su utilización fuera de Lazarus.
505481
506482---
507483*From the Free Pascal wiki, page "SynEdit/es", as it stood on 2020-02-28 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
508484Category: Castellano
509485Category: Español

Back to history