Sign in Join
Wiki copytemporary

SynEdit/es: what changed

Revision 2 to 3. 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
77![](/wiki-images/a/aa/Lazarus_Paleta_SynEdit.png)
88
99
1010TSynEdit, TSynAutoComplete, TSynExporterHTML, TSynMacroRecorder, TSynMemo, TSynPasSyn, TSynFreePascalSyn, TSynCppSyn, TSynJavaSyn, TSynPerlSyn, TSynHTMLSyn, TSynXMLSyn, TSynLFMSyn, TSynUNIXShellScriptSyn, TSynCssSyn, TSynPHPSyn, TSynTeXSyn, TSynSQLSyn, TSynPhytonSyn, TSynAnySyn, TSynMultiSyn
1111
1212   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.
1313
1414   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.
1515
1616   Está licenciado bajo los mismos términos que el SynEdit original (MPL o GPL).
1717
1818## Características
1919
2020- Viene incluido en la paleta de componentes de Lazarus.
2121- Es un componente que no requiere de dependencias externas (a diferencia de Scintilla).
2222- Es de ejecución rápida. Está optimizado para manejar bloques grandes de datos.
2323- Trabaja en codificación UTF-8.
2424- Permite implementar coloreado de sintaxis, usando resaltadores predefinidos o creando nuevos resaltadores.
2525- Soporta las opciones de "Deshacer" y "Rehacer"
2626- Implementa funciones integradas de Búsqueda/Reemplazo.
2727- Soporta completado y autocompletado de código.
2828- Soporta numeración de líneas.
2929- Soporta plegado de código (folding).
3030- Soporta marcadores de texto, con íconos.
3131- Incluye opciones para exportar a 'html' o 'rtf'.
3232- Soporta selección sencilla en modo columna.
3333- Permite trabajar con complementos.
3434
3535## Uso de SynEdit
3636
3737El 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.
3838
3939![](/wiki-images/d/d1/SynEdit_en_Form.png%E2%80%8E)
4040
4141El 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).
4242
4343Por defecto tiene habilitadas las funciones del cortapapeles (cortar, copiar, pegar), y las opciones para deshacer y rehacer.
4444
4545Ademá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).
4646
4747Inicialmente no incluirá opciones de resaltado excepto el remarcado de los delimitadores paréntesis, llaves y corchetes (brackets).
4848
4949### Gutter
5050
5151El panel lateral que aparece a la izquierda del control es llamado 'Gutter' o canal. Aquí se muestra información importante del editor, como:
5252
5353- Marcadores.
5454- Número de Línea.
5555- Marcas de cambio.
5656- Marcas de plegado.
5757
5858La propiedad 'Gutter', permite acceder a las propiedades del panel lateral. Para mostrar u ocultar el panel lateral, se accede al campo 'Visible':
5959
6060``` pascal
6161 SynEdit1.Gutter.Visible := False;
6262```
6363
6464Para tener una mejor idea de las propiedades que se pueden configurar, es mejor usar el Inspector de Objetos.
6565
6666### Margen Derecho
6767
6868Al crear el editor, se crea por defecto un margen visible, al lado derecho del contenido del editor.
6969
7070Este 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.
7171
7272Para cambiar su posición:
7373
7474``` pascal
7575 SynEdit1.RightEdge:= 100; //en pixeles
7676```
7777
7878Para ocultarlo:
7979
8080``` pascal
8181 SynEdit1.Options := SynEdit1.Options + [eoHideRightMargin];
8282```
8383
8484### Coordenadas Lógicas y Físicas
8585
8686La 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).
8787
8888La relación:
8989
9090(Caracter en pantalla) \<---\> (Byte de información)
9191
9292No es una relación de 1 a 1:
9393
9494- Un caracter en pantalla puede estar representado por más de un byte, (efecto de la codificación UTF-8)
9595- Un byte de datos puede representar más de un caracter en pantalla (efecto de las tabulaciones).
9696
9797Para manejar esta falta de correspondencia, SynEdit maneja dos tipos de coordenadas para el cursor de texto (Caret):
9898
9999- Física: Corresponde a la posición visible del cursor en la pantalla.
100100- Lógica: Corresponde a la posición del cursor dentro de la cadena de texto real.
101101
102102La 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).
103103
104104La coordenada física es la posición en la grilla de la pantalla (ignorando los desplazamientos). Esto significa que:
105105
106106
107107Las 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.
108108
109109El 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.
110110
111111La coordenada lógica está referida a la posición que ocupan los bytes que representan a un caracter, dentro de toda la cadena.
112112
113113
114114La letra "a" tiene un byte de ancho, e incrementa la coordenada lógica en 1.
115115
116116La letra "á" tiene dos byte de ancho, e incrementa la coordenada lógica en 2.
117117
118118El caracter de tabulación tiene un byte de ancho e incrementa la coordenada lógica en 1.
119119
120120La coordenada X física es siempre contabilizada desde la izquierda del texto, aún si hay desplazamiento en la visualización.
121121
122122Para obtener la celda-X actual desplazada en SynEdit se debe hacer:
123123
124124
125125grid-X-in-visible-part-of-synedit := PhysicalX - SynEdit.LeftChar + 1
126126
127127Para obtener la celda-Y actual desplazada en SynEdit se debe hacer:
128128
129129
130130grid-y-in-visible-part-of-synedit := SynEdit.RowToScreenRow(PhysicalY); // incluye plegado
131131
132132### Búsqueda y Reemplazo
133133
134134Para realizar las operaciones de búsqueda y reemplazo sobre SynEdit, existen dos métodos especiales:
135135
136136``` pascal
137137function SearchReplace(const ASearch, AReplace: string;
138138 AOptions: TSynSearchOptions): integer;
139139
140140function SearchReplaceEx(const ASearch, AReplace: string;
141141 AOptions: TSynSearchOptions; AStart: TPoint): integer;
142142```
143143
144144La función SearchReplaceEx(), es similar a SearchReplace(), excepto que permite definir la posición inicial desde donde se realizará la búsqueda.
145145
146146Las opciones que se pueden usar en 'AOptions' son:
147147
148148- ssoMatchCase
149149- ssoWholeWord
150150- ssoBackwards
151151- ssoEntireScope
152152- ssoSelectedOnly
153153- ssoReplace
154154- ssoReplaceAll
155155- ssoPrompt
156156- ssoSearchInReplacement
157157- ssoRegExpr
158158- ssoRegExprMultiLine
159159- ssoFindContinue
160160
161161En búsqueda, la función SearchReplace() puede devolver los siguientes valores:
162162
1631630 -\> Elemento no encontrado 1 -\> Se encontró al menos un elemento.
164164
165165En reemplazo, la función SearchReplace() puede devolver los siguientes valores:
166166
1671670 -\> Elemento no encontrado n -\> Se reemplazó “n” elementos
168168
169169Ejemplo de búsqueda simple:
170170
171171``` pascal
172172var
173173 encontrado : integer;
174174 buscado : string;
175175
176176...
177177 buscado := 'texto a buscar';
178178 encontrado := editor.SearchReplace(buscado,'',[]);
179179 if encontrado = 0 then
180180 ShowMessage('No se encuentra: ' + buscado);
181181...
182182```
183183
184184Si 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.
185185
186186Por defecto, la búsqueda se hace desde la posición del cursor hacia adelante, ignorando las mayúsculas/minúsculas.
187187
188188Con el siguiente código, se realiza la búsqueda en sentido contrario:
189189
190190``` pascal
191191 encontrado := editor.SearchReplace(buscado,'',[ssoBackwards]);
192192```
193193
194194Para realizar reemplazo, se debe indicar la opción 'ssoReplace':
195195
196196``` pascal
197197var
198198 encontrado : integer;
199199 buscado : string;
200200begin
201201 buscado := 'texto a buscar';
202202 encontrado := editor.SearchReplace(buscado,'texto a reemplazar',[ssoReplace]);
203203 if encontrado = 0 then
204204 ShowMessage('No se encuentra: ' + buscado);
205205...
206206```
207207
208208Si es que se encuentra alguna coincidencia, se reemplaza el texto, y se hace visible en el editor.
209209
210210### Remarcado de texto
211211
212212SynEdit soporta diversos tipos de remarcados para el contenido:
213213
214214Se puede cambiar el color de fondo de una línea implementando el evento 'OnSpecialLineMarkup'.
215215
216216``` pascal
217217procedure TForm1.SynEdit1SpecialLineMarkup(Sender: TObject;
218218 Line: integer; var Special: boolean;
219219 Markup: TSynSelectedColor);
220220begin
221221 if Line = 5 then begin //línea a marcar
222222 Special := True ;
223223 Markup.Background := clGreen; //color de fondo
224224 end;
225225end;
226226```
227227
228228Para marcar ciertos bloques de texto, se puede usar el método 'SetHighlightSearch':
229229
230230``` pascal
231231uses ..., SynEditTypes;
232232...
233233SynEdit1.HighlightAllColor.Background := clRed;
234234SynEdit1.SetHighlightSearch('xyz', [ssoSelectedOnly]) ;
235235```
236236
237237Con 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.
238238
239239Para información sobre remarcados complejos, ver:
240240
241241<http://forum.lazarus.freepascal.org/index.php/topic,17415.msg95964.html>
242242
243243<http://forum.lazarus.freepascal.org/index.php/topic,17485.msg96510.html>
244244
245245### Marcadores de texto (BookMarks)
246246
247247Los marcadores de texto permiten mostrar un ícono en el panel vertical del editor (Gutter).
248248
249249El siguiente ejemplo, muestra como crear un marcador de texto y hacerlo visible en la línea 2:
250250
251251``` pascal
252252uses ... , SynEditMarks;
253253var
254254 marcador: TSynEditMark;
255255...
256256
257257marcador := TSynEditMark.Create(SynEdit1); //nuevo marcador
258258marcador.ImageList:=ImageList1;
259259marcador.ImageIndex:=1; //elige su ícono
260260marcador.Line:=1; //línea 2
261261marcador.Visible:=true;
262262SynEdit1.Marks.Add(marcador); //agrega el marcador
263263```
264264
265265La lista de imágenes ImageList1, debe conteenr el ícono que aparecerá en el panel vertical del editor.
266266
267267## Modificando el texto por código
268268
269269Para fijar o leer el contenido de SynEdit, se puede acceder a la propiedad 'Text'.
270270
271271La información del texto que muestra SynEdit, se guarda internamente en un TStrigList, visible en la propiedad 'Lines'.
272272
273273Así, para acceder a la primera línea de SynEdit, se accede a:
274274
275275SynEdit1.Lines\[0\]
276276
277277Para modificar el contenido de SynEdit, existen diversos métodos:
278278
279279- 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'.
280280- 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.
281281- 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.
282282
283283- 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.
284284
285285### Menus con Duplicar e intercambiar líneas
286286
287287``` pascal
288288 //Duplicar Línea
289289 procedure TForm1.MenuDuplicarLinea(Sender: TObject);
290290 begin
291291 SynEdit1.Lines.Insert(CustSynEdit().CaretY,CustSynEdit().LineText);
292292 end;
293293
294294 //Intercambiar Línea hacia Arriba
295295 procedure TForm1.MenuLineaArriba(Sender: TObject);
296296 begin
297297 if CustSynEdit.CaretY -1 >= 1 then
298298 begin
299299 CustSynEdit.Lines.Exchange(CustSynEdit.CaretY -1 ,CustSynEdit.CaretY-2);
300300 CustSynEdit.CaretY:=CustSynEdit.CaretY-1;
301301 end;
302302 end;
303303
304304 //Intercambiar Línea hacia Abajo
305305 procedure TForm1.MenuLineaAbajo(Sender: TObject);
306306 begin
307307 if ( CustSynEdit.CaretY + 1 <= CustSynEdit.Lines.Count) then
308308 begin
309309 CustSynEdit.Lines.Exchange(CustSynEdit.CaretY-1,CustSynEdit.CaretY);
310310 CustSynEdit.CaretY:=CustSynEdit.CaretY+1;
311311 end;
312312 end;
313313```
314314
315315### Insertar caracteres en la posición actual
316316
317317``` pascal
318318 procedure TForm1.Button1Click(Sender: TObject);
319319 begin
320320 SynEdit1.CommandProcessor(ecChar,'a', nil); //Inserta a
321321 SynEdit1.SetFocus;
322322 end;
323323```
324324
325325## Portapapeles
326326
327327   SynEdit soporta complétamente las operaciones "Cortar", "Copiar" y "Pegar"
328328
329329   Las operaciones con el protapapeles se implementan con los siguientes métodos:
330330
331331``` pascal
332332 SynEdit1.CopyToClipboard;
333333 SynEdit1.CutToClipboard;
334334 SynEdit1.PasteFromClipboard;
335335```
336336
337337    Para obtener las coordenadas del bloque de selección, usar las propiedades: BlockBegin y BlockEnd.
338338
339339    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':
340340
341341``` pascal
342342 uses
343343 ...
344344 SynEdit, SynEditKeyCmds;
345345
346346 procedure TfrmPrincipal.HandleCodigoKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
347347 begin
348348 if (Shift = [ssCtrl]) then
349349 begin
350350 case Key of
351351 VK_C: synCodigo.CommandProcessor(ecCopy, ' ', nil);
352352 VK_V: synCodigo.CommandProcessor(ecPaste, ' ', nil);
353353 VK_X: synCodigo.CommandProcessor(ecCut, ' ', nil);
354354 end;
355355 end;
356356 end;
357357```
358358
359359### Menú con Deshacer y Rehacer
360360
361361``` pascal
362362 procedure TForm1.MenuRehacer(Sender: TObject);
363363 begin
364364 SynEdit1.Redo;
365365 end;
366366
367367 procedure TForm1.MenuDeshacer(Sender: TObject);
368368 begin
369369 SynEdit1.Undo;
370370 end;
371371```
372372
373373## Resaltado de sintaxis
374374
375375SynEdit soporta el resaltado de sintaxis, usando atributos de texto como el color o el tipo de letra.
376376
377377Para 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.
378378
379-<img src="SynEdit_con_res_Python.png" title="Control SynEdit con resaltador de Python." width="355" />
379+![](/wiki-images/e/e8/SynEdit_con_res_Python.png)
380380
381381Para 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.
382382
383383Luego, 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.
384384
385385También se pueden encontrar resaltadores adicionales en [Highlighter for SynEdit](http://bugs.freepascal.org/view.php?id=18248)
386386
387387Si 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).
388388
389389Otra 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).
390390
391391## Completado de Código
392392
393393SynEdit 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.
394394
395395Existen 3 complementos de completado para SynEdit:
396396
397397- TSynCompletion
398398 - Ofrece una lista de palabras en un menú contextual.
399399 - Usado en la IDE par el completado de identificadores.
400400 - Incluido en los ejemplos.
401401 - Disponible en la paleta de componentes desde la versión 0.9.31
402402- TSynAutoComplete
403403 - Reemplaza la palabra actual (si es identificada) con un texto pre-definido. **No** es interactivo ni incluye menú contextual.
404404 - Incluido en los ejemplos.
405405 - Disponible en la paleta de componentes.
406406- TSynEditAutoComplete
407407 - Módulo Básico de plantillas. **No** es interactivo ni incluye menú contextual.
408408 - Es usado por la IDE para el completamiento de codigo usando plantillas. La IDE contiene código adicional que extiende sus características.
409409 - **Not** incluido en los ejemplos.
410410
411411Los tipos TSynAutoComplete y TSynEditAutoComplete no están muy bien diferenciados y probablemente se fusionen.
412412
413413Se recomienda ver los ejemplos que vienen con Lazarus.
414414
415415### Completado de Código con SynCompletion
416416
417417``` pascal
418418 Uses
419419 ... ...
420420 LCLType,//Para poder usar VK_SPACE
421421 syncompletion;
422422
423423 ... ... ....
424424 var
425425 Completion:TSynCompletion;
426426 begin
427427 Completion:=TSynCompletion.Create(Self);
428428 Completion.Editor:=SynEdit;
429429 Completion.ShortCut:=Menus.ShortCut(VK_SPACE, [ssCtrl]);
430430 Completion.ItemList.add('Arc( )');
431431 Completion.ItemList.add('Axes( )');
432432 Completion.ItemList.add('Bezier( )');
433433 Completion.ItemList.add('Cercle( )');
434434 end;
435435```
436436
437437### Desplegar TSynCompletion en la posición actual
438438
439439``` pascal
440440 procedure TForm1.Button1Click(Sender: TObject);
441441 var p:TPoint;
442442 begin
443443 with SynEdit1 do
444444 begin
445445 P := Point(CaretXPix,CaretYPix + LineHeight);
446446 P.X:=Max(0,Min(P.X,ClientWidth-Completion.Width));
447447 P := ClientToScreen(p);
448448 end;
449449 Completion.Execute('',p.x,p.y);
450450 end;
451451```
452452
453453## SynEdit en el IDE
454454
455455    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.
456456
457457    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.
458458
459459![](/wiki-images/b/b2/Lazarus_Editor_Codigo_Fuente.png)
460460
461461## Synedit 2.0.5 port
462462
463463    Existe una versión alterna de SynEdit, portada desde la versión más reciente del original SynEdit 2.0.5:
464464
465465<http://wiki.lazarus.freepascal.org/SynEdit/port>
466466
467467code: <https://github.com/rnapoles/>
468468
469469## Documentación
470470
471471   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)
472472
473473   Sobre resaltado de sintaxis (en ingles): [[SynEdit Highlighter]]
474474
475475## Más desarrollos, discusiones
476476
477477- RTL (de derecha a izquierda (Right-To-Left)): comenzado por Mazen
478478- 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.
479479- 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)).
480480- [[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.
481481
482482---
483483*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).*
484484Category: Castellano
485485Category: Español

Back to history