Module Scintilla
Publié : ven. 23/juin/2017 9:13
Bonjour à tous,
j'ai complété ce code créé par GPI du forum allemand qu'il avait fait pour LUA et moi pour PB
J'aimerais utiliser ce code avec un EditorGadget, comment pourrais-je faire ?
j'ai complété ce code créé par GPI du forum allemand qu'il avait fait pour LUA et moi pour PB
J'aimerais utiliser ce code avec un EditorGadget, comment pourrais-je faire ?
Code : Tout sélectionner
;D'après un programme créé par GPI
DeclareModule Scintilla
EnableExplicit
;-** Structure
Structure Color
fore.i
back.i
EndStructure
Structure FontStyle
fore.i
back.i
FontStyle.i; Formulaire de combinaison #pb_font_bold, #pb_font_italic, #pb_font_underline. #PB_Font_StrikeOut est utilisé pour "eol"
font.s
size.i
EndStructure
Structure ColorAlpha
color.i
alpha.i
EndStructure
Structure LexerStyle; Utilisé pour stocker le Style pour le lexer
None.FontStyle
String.FontStyle
SingleString.FontStyle
StringBlock.FontStyle
CommentBlock.FontStyle
Comment.FontStyle
Number.FontStyle
AlphaNum.FontStyle
MotCle.FontStyle
SpecialMotCle.FontStyle
LineNumber.FontStyle
Label.FontStyle
FolderMark.Color
RepeatedSelection.ColorAlpha
Brace.ColorAlpha
BadBrace.ColorAlpha
Currentline.ColorAlpha
Pliage.i
AutoIndention.i
TabSize.i
MinLinenumberSize.i
EndStructure
Prototype prot_LexerCallback(gadget,*scinotify.SCNotification)
Prototype prot_LexerInit(gadget,*LexerStyle.LexerStyle)
Structure LexerInfo; pour le lexer - Commande use()
callback.prot_LexerCallback
init.prot_LexerInit
EndStructure
;-** Declarations des procédures
Declare init()
Declare GetDefault(*Lexer.LexerStyle)
Declare SetStyle(Gadget,*lexer.LexerStyle)
Declare Gadget(id,x,y,cx,cy,*lexer=0,*style.lexerstyle=0)
Declare SetText(gadget,text.s)
Declare AppendText(gadget,text.s)
Declare.s GetText(gadget)
;pour utiliser dans le Lexer
Prototype prot_FindWordStart(gadget,endpos)
Declare _Autocomplete(gadget,FindStart.prot_findwordstart,Map special())
Declare _CallBack(Gadget, *scinotify.SCNotification)
Declare _fastUTF8(string.s="")
CompilerIf #PB_Compiler_Debugger
Declare _SetProperty(gadget,Key,Value)
CompilerEndIf
Declare _GetPropertyFlag(gadget,Key)
Declare _SetPropertyFlag(gadget,Key,Value)
Declare _Indention(gadget)
Declare _MarkBrace(gadget,brace.s)
;-** Constantes
;-{ AutoIndention
Enumeration 0
#AutoIndention_none
#AutoIndention_simple
#AutoIndention_complex
EndEnumeration
;}
;-{ Propriétés
Enumeration #STYLE_MAX -1
#Property_flag
#Property_MinLinenumberSize
#Property_AutoIndention
EndEnumeration
EnumerationBinary
#PropertyFlag_Fold
#PropertyFlag_RepeatedSelection
#PropertyFlag_Brace
EndEnumeration
; container-lexer Ne prend pas en charge sci_set / getporperty - donc j'ai utilisé un style pour enregistrer certains drapeaux/valeurs en tant que style
;}
;-{ Style
Enumeration 1
;#Style_Default - mis par PB
#style_String
#style_SingleString
#style_StringBlock
#style_CommentBlock
#style_Comment
#style_Number
#style_AlphaNum
#style_MotCle
#style_SpecialMotCle
#style_Label
EndEnumeration
;}
;-{ Indicateurs
Enumeration 1
#indicator_selection
#indicator_brace
#indicator_badbrace
EndEnumeration
;}
;-{ état de la ligne
; 12345678
#linestate_submask =$00ff0000
#linestate_subshift =16
#linestate_start =$01000000
#linestate_CommentBlock =$02000000
#linestate_QuoteBlock =$04000000
#linestate_IndentBeforeMask =$0000F000
#linestate_IndentBeforeShift=4+4+4
#linestate_IndentAfterMask =$00000F00
#linestate_IndentAfterShift =4+4
#linestate_IndentBase =$7
#linestate_IndentLevelMask =$000000FF
; les flags commentblock et quoteblock sont utilisés pour marquer les lignes. En combinaison avec start, il indique la première ligne du bloc
; submask est utilisé pour masquer un sous-compteur - en pb le bloc devis/commentaires ont des "Niveaux" par exemple [[]] [= [] =]
; le sous-compteur indiquent le niveau du bloc
; Le retrait avant et après est identique à celui de l'éditeur purebasic et peut aller de -7 à 7 (IndentBase est ajouté avant le stockage)
; IndentLevelMask est utilisé pour stocker l'indentation dans une plage de 0 à 255
;}
;-{ Marge
Enumeration 0
#margin_linenumber
#margin_fold
EndEnumeration
;-** macros globales
Macro _GetProperty(gadget,Key)
sci(gadget,#SCI_STYLEGETFORE,key)
EndMacro
CompilerIf Not #PB_Compiler_Debugger
Macro _SetProperty(gadget,key,value)
sci(gadget,#SCI_STYLESETFORE,key,value)
EndMacro
CompilerEndIf
EndDeclareModule
Module Scintilla
;-** Macros
Macro SCI(Gadget,Msg,a=0,b=0)
ScintillaSendMessage(Gadget,Msg,a,b)
EndMacro
Macro __SetStyle(name,vFore=-1,vBack=-1,vFontstyle=-1,vFont="",vSize=0)
name\fore=vFore
name\back=vBack
name\FontStyle=vFontStyle
name\font=vFont
name\size=vSize
EndMacro
;-** routines internes
Procedure __SetFontStyle(id,style,*FontStyle.FontStyle)
If *FontStyle\fore>=0
sci(id,#SCI_STYLESETFORE,style,*FontStyle\fore)
EndIf
If *FontStyle\back>=0
sci(id,#SCI_STYLESETBACK,style,*FontStyle\back)
EndIf
If *FontStyle\FontStyle>=0
sci(id,#SCI_STYLESETBOLD,style,Bool(*FontStyle\FontStyle & #PB_Font_Bold))
sci(id,#SCI_STYLESETITALIC,style,Bool(*FontStyle\FontStyle & #PB_Font_Italic))
sci(id,#SCI_STYLESETUNDERLINE,style,Bool(*FontStyle\FontStyle & #PB_Font_Underline))
sci(id,#SCI_STYLESETEOLFILLED,style,Bool(*FontStyle\FontStyle & #PB_Font_StrikeOut))
EndIf
If *FontStyle\size>0
sci(id,#SCI_STYLESETSIZE,style,*FontStyle \size)
EndIf
If *FontStyle\font<>""
sci(id,#SCI_STYLESETFONT,style,_fastUTF8(*FontStyle\font))
EndIf
EndProcedure
Procedure __setLineWidth(gadget)
Protected maxlines,width,digit,min
maxlines=sci(gadget,#SCI_GETLINECOUNT)
min=_GetProperty(gadget,#Property_MinLinenumberSize)
While maxlines>0
maxlines/10
digit+1
Wend
If digit<min
digit=min
EndIf
width=sci(gadget,#SCI_TEXTWIDTH,#STYLE_LINENUMBER, @"9");Parce que j'envoie seulement un caractère, unicode = ascii
width*(digit+1)
If sci(Gadget,#SCI_GETMARGINWIDTHN,#margin_linenumber)<>width
sci(gadget,#SCI_SETMARGINWIDTHN,#margin_linenumber,width)
EndIf
EndProcedure
Procedure __RepeatedSelection(gadget)
Static indicator_set,startPos,endPos
Protected *buf.ascii,buflength,size,i
size=sci(gadget,#SCI_GETLENGTH)
sci(gadget,#SCI_SETINDICATORCURRENT,#indicator_selection)
If indicator_set
sci(gadget, #SCI_INDICATORCLEARRANGE,0,size)
indicator_set=#False
EndIf
startPos=sci(gadget,#SCI_GETSELECTIONSTART)
endpos=sci(gadget,#SCI_GETSELECTIONEND)
If startPos=sci(gadget,#SCI_WORDSTARTPOSITION,startpos,#True) And endpos=sci(gadget,#SCI_WORDENDPOSITION,startPos,#True)
buflength=sci(gadget,#SCI_GETSELTEXT)
If buflength>2
*buf=AllocateMemory(buflength)
If *buf
sci(gadget,#SCI_GETSELTEXT,0,*buf)
sci(gadget,#SCI_SETTARGETSTART,0)
sci(gadget,#SCI_SETTARGETEND, size )
sci(gadget,#SCI_SETSEARCHFLAGS, #SCFIND_MATCHCASE|#SCFIND_WHOLEWORD)
Repeat
i= sci(gadget,#SCI_SEARCHINTARGET,buflength-1,*buf)
If i<0
Break
EndIf
If i<>startPos
sci(gadget,#SCI_INDICATORFILLRANGE,i,buflength-1)
EndIf
sci(gadget,#SCI_SETTARGETSTART,i+buflength-1)
sci(gadget,#SCI_SETTARGETEND, size )
ForEver
indicator_set=#True
FreeMemory(*buf)
EndIf
EndIf
EndIf
EndProcedure
;-** procédures
Procedure init()
; Avec Debugger - copier Scintilla.dll dans le répertoire principal
; Initaliser le gadget scintilla en chargeant le scintilla32/scintilla64 dll ou scintilla.dll/scilexer.dll comme alternative
CompilerIf #PB_Compiler_OS=#PB_OS_Windows
CompilerIf #PB_Compiler_Processor=#PB_Processor_x86
#DLL_Scintilla="Scintilla32.dll"
CompilerElse
#DLL_Scintilla="Scintilla64.dll"
CompilerEndIf
CompilerIf #PB_Compiler_Debugger
If FileSize(#DLL_Scintilla)<>FileSize(#PB_Compiler_Home+"Compilers\Scintilla.dll")
CopyFile(#PB_Compiler_Home+"Compilers\Scintilla.dll",#DLL_Scintilla)
EndIf
CompilerEndIf
If InitScintilla(#DLL_Scintilla)=0
If InitScintilla("Scintilla.dll")=0
If InitScintilla("SciLexer.dll")=0
ProcedureReturn #False
EndIf
EndIf
EndIf
CompilerEndIf
ProcedureReturn #True
EndProcedure
Procedure SetText(Gadget,text.s)
;Méthode rapide (et sale) pour définir un texte long, car SetGadgetText ne fonctionne pas
sci(Gadget,#SCI_SETTEXT,0,_fastUTF8(text))
_fastUTF8()
EndProcedure
Procedure AppendText(Gadget,text.s)
;Ajouter le texte sans le faire défiler jusqu'à la position
sci(Gadget,#SCI_APPENDTEXT,StringByteLength(text,#PB_UTF8),_fastUTF8(text))
_fastUTF8()
EndProcedure
Procedure.s GetText(Gadget)
;GetGadgetText ne fonctionne pas (car il utilise unicode pas ascii)
Protected *buf,bufsize,ret.s
bufsize=sci(gadget,#SCI_GETLENGTH)+1
*buf=AllocateMemory(bufsize)
If *buf
sci(Gadget,#SCI_GETTEXT,bufsize,*buf)
ret=PeekS(*buf,-1,#PB_UTF8)
FreeMemory(*buf)
EndIf
ProcedureReturn ret
EndProcedure
Procedure GetDefault(*Lexer.LexerStyle)
;Obtenir le style par défaut
Protected back=$DFFFFF
Protected backMargin=$dfefef
Protected backgrey=$DFDFDF
__SetStyle(*Lexer\None ,$000000,back,0,"Arial",12)
__SetStyle(*Lexer\String ,$ff)
__SetStyle(*lexer\SingleString ,$ff7f00)
__SetStyle(*lexer\StringBlock ,$ff7f00,backgrey,#PB_Font_StrikeOut)
__SetStyle(*Lexer\Comment ,$AAAA00)
__SetStyle(*Lexer\CommentBlock ,$AAAA00,backgrey,#PB_Font_StrikeOut)
__SetStyle(*Lexer\Number ,$333300)
__SetStyle(*Lexer\AlphaNum ,$000000)
__SetStyle(*Lexer\MotCle ,$FF0000,back,#PB_Font_Bold)
__SetStyle(*Lexer\SpecialMotCle,$996900,back,#PB_Font_Italic)
__SetStyle(*Lexer\LineNumber ,$666666,backMargin)
__SetStyle(*Lexer\Label ,$ff00ff)
*Lexer\FolderMark\fore=$ffffff
*Lexer\FolderMark\back=$000000
*Lexer\RepeatedSelection\color=$006600
*Lexer\RepeatedSelection\alpha=50
*Lexer\Brace\color=$006600
*lexer\brace\alpha=50
*Lexer\BadBrace\color=$0000ff
*lexer\BadBrace\alpha=128
*lexer\Pliage=#True
*lexer\AutoIndention=#AutoIndention_complex
*Lexer\TabSize=2
*Lexer\Currentline\color=$afFFFF
*Lexer\Currentline\alpha=#SC_ALPHA_NOALPHA
*lexer\MinLinenumberSize=3
EndProcedure
Procedure SetStyle(Gadget,*lexer.LexerStyle)
;Définir le style d'un gadget Scintilla
Protected width
With *lexer
__SetFontStyle(Gadget,#STYLE_DEFAULT,\None)
ScintillaSendMessage(Gadget,#SCI_STYLECLEARALL)
__SetFontStyle(Gadget,#style_String,\string)
__SetFontStyle(Gadget,#style_SingleString,\SingleString)
__setFontStyle(Gadget,#style_StringBlock,\StringBlock)
__SetFontStyle(Gadget,#style_CommentBlock,\CommentBlock)
__SetFontStyle(Gadget,#style_Comment,\Comment)
__SetFontStyle(Gadget,#style_Number,\Number)
__SetFontStyle(Gadget,#style_AlphaNum,\AlphaNum)
__SetFontStyle(Gadget,#style_MotCle,\MotCle)
__SetFontStyle(Gadget,#style_SpecialMotCle,\SpecialMotCle)
__SetFontStyle(Gadget,#STYLE_LINENUMBER,\LineNumber)
__SetFontStyle(Gadget,#style_Label,\Label)
sci(Gadget,#SCI_SETFOLDMARGINCOLOUR,#margin_fold,\LineNumber\back)
sci(Gadget,#SCI_SETFOLDMARGINHICOLOUR,#margin_fold,\LineNumber\back)
sci(Gadget, #SCI_MARKERSETFORE, #SC_MARKNUM_FOLDER,\FolderMark\fore)
sci(Gadget, #SCI_MARKERSETBACK, #SC_MARKNUM_FOLDER, \FolderMark\back)
sci(Gadget, #SCI_MARKERSETFORE, #SC_MARKNUM_FOLDEROPEN,\FolderMark\fore)
sci(Gadget, #SCI_MARKERSETBACK, #SC_MARKNUM_FOLDEROPEN, \FolderMark\back)
sci(Gadget, #SCI_MARKERSETFORE, #SC_MARKNUM_FOLDEROPENMID, \FolderMark\fore)
sci(Gadget, #SCI_MARKERSETBACK, #SC_MARKNUM_FOLDEROPENMID, \FolderMark\back)
sci(Gadget, #SCI_MARKERSETFORE, #SC_MARKNUM_FOLDERSUB, \FolderMark\fore)
sci(Gadget, #SCI_MARKERSETBACK, #SC_MARKNUM_FOLDERSUB, \FolderMark\back)
sci(Gadget, #SCI_MARKERSETFORE, #SC_MARKNUM_FOLDERTAIL, \FolderMark\fore)
sci(Gadget, #SCI_MARKERSETBACK, #SC_MARKNUM_FOLDERTAIL, \FolderMark\back)
sci(Gadget, #SCI_MARKERSETFORE, #SC_MARKNUM_FOLDERMIDTAIL,\FolderMark\fore)
sci(Gadget, #SCI_MARKERSETBACK, #SC_MARKNUM_FOLDERMIDTAIL, \FolderMark\back)
sci(gadget,#SCI_INDICSETSTYLE,#indicator_selection,#INDIC_STRAIGHTBOX);fullbox
sci(gadget,#SCI_INDICSETFORE,#indicator_selection,\RepeatedSelection\color)
sci(gadget,#SCI_INDICSETALPHA,#indicator_selection,\RepeatedSelection\alpha)
sci(gadget,#SCI_INDICSETUNDER,#indicator_selection,#True)
sci(gadget,#SCI_INDICSETSTYLE,#indicator_brace,#INDIC_STRAIGHTBOX);fullbox
sci(gadget,#SCI_INDICSETFORE,#indicator_brace,\Brace\color)
sci(gadget,#SCI_INDICSETALPHA,#indicator_brace,\Brace\alpha)
sci(gadget,#SCI_INDICSETUNDER,#indicator_brace,#True)
sci(gadget,#SCI_INDICSETSTYLE,#indicator_badbrace,#INDIC_STRAIGHTBOX);fullbox
sci(gadget,#SCI_INDICSETFORE,#indicator_badbrace,\badBrace\color)
sci(gadget,#SCI_INDICSETALPHA,#indicator_badbrace,\badBrace\alpha)
sci(gadget,#SCI_INDICSETUNDER,#indicator_badbrace,#True)
_SetPropertyFlag(gadget,#PropertyFlag_Fold,\Pliage)
_SetPropertyFlag(gadget,#PropertyFlag_RepeatedSelection,Bool(\RepeatedSelection\alpha))
If \Pliage
width=sci(gadget,#SCI_TEXTWIDTH,#STYLE_LINENUMBER,@"9")*2
ScintillaSendMessage(Gadget,#SCI_SETMARGINWIDTHN,#margin_fold, width)
Else
ScintillaSendMessage(Gadget,#SCI_SETMARGINWIDTHN,#margin_fold, 0)
EndIf
_SetPropertyFlag(gadget,#PropertyFlag_Brace,Bool(\Brace\alpha Or \BadBrace\alpha))
_SetProperty(gadget,#Property_AutoIndention,\AutoIndention)
_SetProperty(gadget,#Property_MinLinenumberSize,\MinLinenumberSize)
sci(gadget,#SCI_SETTABWIDTH,\TabSize)
sci(gadget,#SCI_SETCARETLINEVISIBLE,Bool( \Currentline\alpha))
sci(gadget,#SCI_SETCARETLINEBACK,\Currentline\color)
sci(Gadget,#SCI_SETCARETLINEBACKALPHA,\Currentline\alpha)
EndWith
EndProcedure
Procedure Gadget(id,x,y,cx,cy,*lexer.LexerInfo=0,*style.lexerstyle=0)
;Créer un gadget Scintilla. * Lexer-info devrait être lexer.use()-call
Protected Gadget , MotCle.s
Protected defaultstyle.lexerstyle,defaultlexer.lexerinfo
Protected ret
If *style=0
GetDefault(defaultstyle)
*style=defaultstyle
EndIf
If *lexer=0
defaultlexer\callback=@_CallBack()
*lexer\callback=defaultlexer
EndIf
ret = ScintillaGadget(id,x,y,cx,cy,*lexer\callback)
If id <> #PB_Any
Gadget = id
Else
Gadget = ret
EndIf
; Indicateurs d'utilisation pour Brace-Highlight
sci(gadget,#SCI_BRACEHIGHLIGHTINDICATOR,#True,#indicator_brace)
sci(gadget,#SCI_BRACEBADLIGHTINDICATOR,#True,#indicator_badbrace)
; Fixer la barre de défilement horizontale
sci(gadget,#SCI_SETSCROLLWIDTHTRACKING,#True)
sci(gadget,#SCI_SETSCROLLWIDTH,100)
; Faire défiler avant que le Curseur n'atteigne le bord
sci(gadget,#SCI_SETXCARETPOLICY,#CARET_SLOP|#CARET_EVEN|#CARET_STRICT ,100)
sci(gadget,#SCI_SETYCARETPOLICY,#CARET_SLOP|#CARET_EVEN|#CARET_STRICT ,3)
; Définir la marge du pliage
ScintillaSendMessage(Gadget,#SCI_SETMARGINTYPEN, #margin_fold, #SC_MARGIN_SYMBOL )
ScintillaSendMessage(Gadget,#SCI_SETMARGINMASKN, #margin_fold, #SC_MASK_FOLDERS)
ScintillaSendMessage(Gadget,#SCI_SETMARGINSENSITIVEN, #margin_fold, #True)
; Symboles de pliage
ScintillaSendMessage(Gadget,#SCI_MARKERDEFINE, #SC_MARKNUM_FOLDEROPEN , #SC_MARK_BOXMINUS)
ScintillaSendMessage(Gadget,#SCI_MARKERDEFINE, #SC_MARKNUM_FOLDER , #SC_MARK_BOXPLUS)
ScintillaSendMessage(Gadget,#SCI_MARKERDEFINE, #SC_MARKNUM_FOLDERSUB , #SC_MARK_VLINE)
ScintillaSendMessage(Gadget,#SCI_MARKERDEFINE, #SC_MARKNUM_FOLDERTAIL , #SC_MARK_LCORNER)
ScintillaSendMessage(Gadget,#SCI_MARKERDEFINE, #SC_MARKNUM_FOLDEREND , #SC_MARK_BOXPLUSCONNECTED)
ScintillaSendMessage(Gadget,#SCI_MARKERDEFINE, #SC_MARKNUM_FOLDEROPENMID , #SC_MARK_BOXMINUSCONNECTED)
ScintillaSendMessage(Gadget,#SCI_MARKERDEFINE, #SC_MARKNUM_FOLDERMIDTAIL , #SC_MARK_TCORNER)
; Manipulation automatique des plis
sci(Gadget,#SCI_SETAUTOMATICFOLD,#SC_AUTOMATICFOLD_SHOW|#SC_AUTOMATICFOLD_CLICK|#SC_AUTOMATICFOLD_CHANGE)
If ret And *lexer\init
*lexer\init(gadget,*style)
EndIf
ProcedureReturn ret
EndProcedure
;-** Procédures pour le Lexer
Procedure _fastUTF8(str.s="")
; Méthode facile pour convertir en UTF8 sans allocation et libération de mémoire pour chaque appel
Static *buf,bufsize
Protected needed
If str=""
If *buf
FreeMemory(*buf)
*buf=0
EndIf
ProcedureReturn 0
EndIf
needed=StringByteLength(str,#PB_UTF8)+1;null-terminated
If *buf=0 Or bufsize<needed
If *buf
FreeMemory(*buf)
EndIf
bufsize=needed:If bufsize<1024:bufsize=1024:EndIf
*buf=AllocateMemory(bufsize)
EndIf
If *buf
PokeS(*buf,str,-1,#PB_UTF8)
EndIf
ProcedureReturn *buf
EndProcedure
;Fausse propriété, car le conteneur-lexer ne prend pas en charge les propriétés
CompilerIf #PB_Compiler_Debugger
Procedure _SetProperty(gadget,key,value)
;Variante de procédure pour la macro _SetProperty pour ajouter un contrôle de plage pour la valeur
If value<0 Or value>$ffffff
Debug "ATTENTION: SetProperty - la valeur n'est pas dans la fourchette 0-$ffffff ("+Hex(value)+")"
EndIf
ProcedureReturn sci(gadget,#SCI_STYLESETFORE,key,value)
EndProcedure
CompilerEndIf
Procedure _GetPropertyFlag(gadget,key)
;Obtenir un drapeau dans le "style" #property_flag
ProcedureReturn Bool(_GetProperty(gadget,#Property_flag)&key)
EndProcedure
Procedure _SetPropertyFlag(gadget,key,value)
;Définir un drapeau dans le "style" #property_flag
Protected store=_GetProperty(gadget,#Property_flag)
If value
store | key
Else
store & ~key
EndIf
_SetProperty(gadget,#Property_flag,store)
EndProcedure
Procedure _CallBack(Gadget, *scinotify.SCNotification)
;Rappel par défaut pour gadget scintilla. Le rappel de Lexer devrait appeler ceci pour faire quelques choses de base comme la sélection
;répétée, le changement de largeur de la colonne de numéro de ligne
Protected lineNumber,width
Select *scinotify\nmhdr\code
Case #SCN_UPDATEUI
If *scinotify\updated=#SC_UPDATE_SELECTION
If _GetPropertyFlag(gadget,#PropertyFlag_RepeatedSelection)
__RepeatedSelection(gadget)
EndIf
EndIf
Case #SCN_ZOOM
;Corriger le numéro de ligne et la marge de repli
__setLineWidth(gadget)
If _GetPropertyFlag(gadget,#PropertyFlag_Fold)
width=sci(gadget,#SCI_TEXTWIDTH,#STYLE_LINENUMBER,@"9")*2
ScintillaSendMessage(Gadget,#SCI_SETMARGINWIDTHN, #margin_fold, width)
EndIf
Case #SCN_MODIFIED
;Vérifier si la marge du numéro de ligne est assez large
If (*scinotify\modificationType & (#SC_MOD_INSERTTEXT|#SC_MOD_DELETETEXT)) And *scinotify\linesAdded
__setLineWidth(gadget)
EndIf
Case #SCN_MARGINCLICK
;Désactivé par le traitement automatique
; Debug "Marginclick:"+*scinotify\margin
; If *scinotify\margin = #margin_fold
; lineNumber = ScintillaSendMessage(Gadget,#SCI_LINEFROMPOSITION,*scinotify\position)
; ScintillaSendMessage(Gadget,#SCI_TOGGLEFOLD, lineNumber, 0)
; EndIf
EndSelect
EndProcedure
Procedure _Indention(gadget)
;Méthode simple pour ajouter un retrait automatique. Copie simple de l'indentation de la ligne précédente
; devrait être appelé après un caractère cr / lf est ajouté au document / rappel
Protected lineNumber,mode,*buf,bufsize,*buf2.ascii,pos
pos=sci(gadget,#SCI_GETCURRENTPOS)
lineNumber=sci(gadget,#SCI_LINEFROMPOSITION,pos)
If lineNumber>0
bufsize=sci(gadget,#SCI_GETLINE,lineNumber-1,0)+1
*buf=AllocateMemory(bufsize)
If *buf
sci(gadget,#SCI_GETLINE,lineNumber-1,*buf)
*buf2=*buf
While *buf2\a=32 Or *buf2\a=9 ;barre espace et tab
*buf2+1
Wend
*buf2\a=0
sci(gadget,#SCI_REPLACESEL,0,*buf)
FreeMemory (*buf)
EndIf
EndIf
EndProcedure
Procedure _MarkBrace(gadget,brace.s)
;Vérifier si sous la position actuelle est une orthèse et le mettre en évidence
; une combinaison de "(){}[]<>"
Protected pos,char,findpos
Static doRemove
pos=sci(gadget,#SCI_GETCURRENTPOS)
If pos=sci(gadget,#SCI_GETANCHOR)
char=sci(gadget,#SCI_GETCHARAT,pos)
If FindString(brace,Chr(char))
findpos=sci(gadget,#SCI_BRACEMATCH,pos)
If findpos>=0
sci(gadget,#SCI_BRACEHIGHLIGHT,pos,findpos)
Else
sci(gadget,#SCI_BRACEBADLIGHT,pos)
EndIf
doremove=#True
ElseIf doremove
sci(gadget,#SCI_BRACEHIGHLIGHT,-1,-1)
sci(gadget,#SCI_BRACEBADLIGHT,-1)
doRemove=#False
EndIf
ElseIf doremove
sci(gadget,#SCI_BRACEHIGHLIGHT,-1,-1)
sci(gadget,#SCI_BRACEBADLIGHT,-1)
doRemove=#False
EndIf
EndProcedure
Procedure _Autocomplete(gadget,FindStart.prot_findwordstart,Map special())
; Utilisé depuis le lexer pour la boite d'autocompletion
; Special est un MAP, la mapkey contient les mots pour la liste.
; Une Map est utilisée, car avec cette Map, il est plus facile de détecter, si un mot est un mot spécial pour le style
Protected startPos,endPos,i,char,range.ScTextRange,word.s
NewList words.s()
Protected wordlist.s
If sci(gadget,#SCI_AUTOCACTIVE)=#False
endPos=sci(gadget,#SCI_GETCURRENTPOS)
startPos=FindStart(gadget,endpos)
If endpos-startPos>1
range\chrg\cpMin=startpos
range\chrg\cpMax=endPos
range\lpstrText=AllocateMemory(endpos-startpos+1)
sci(gadget,#SCI_GETTEXTRANGE,0,range)
word=PeekS(range\lpstrText,-1,#PB_UTF8)
FreeMemory(range\lpstrText)
ForEach special()
If Left(MapKey(special()),Len(word))=word
AddElement(words())
words()=MapKey(special())
EndIf
Next
If ListSize(words())>0 ; And ListSize(words())<30
SortList(words(),#PB_Sort_Ascending)
ForEach words()
wordlist+" "+words()
Next
sci(gadget,#SCI_AUTOCSHOW,endpos-startpos,_fastUTF8(Mid(wordlist,2)))
_fastUTF8()
EndIf
EndIf
EndIf
EndProcedure
EndModule
;-
;- Lexer PB
;-
DeclareModule PB_Lexer
EnableExplicit
Declare use()
EndDeclareModule
Module PB_Lexer
UseModule scintilla
Declare Highlight(Gadget,startPos,endPos)
Global NewMap MotCle()
Global NewMap DebutPliage()
Global NewMap FinPliage()
Global NewMap special()
Global NewMap avant()
Global NewMap apres()
;-{ Constantes lex
Enumeration
#lex_None
#lex_Alpha
#lex_Space
#lex_NewLine
#lex_Misc
#lex_Quote
#lex_Slash
#lex_Bracket
#lex_SingleQuote
#lex_Label
EndEnumeration
;}
;-{ Constantes force
Enumeration
#force_None
#force_Comment
#force_Quote
#force_SingleQuote
#force_QuoteBlock
#force_CommentBlock
EndEnumeration
;}
;-{ Constantes Num
Enumeration
#num_none
#num_ok
#num_point
#num_exp
EndEnumeration
;}
Macro SCI(Gadget,Msg,a=0,b=0)
ScintillaSendMessage(Gadget,Msg,a,b)
EndMacro
Procedure IsPBNumber(*word.character)
;Vérifie, si la chaîne (unicode) est un numéro PB valide
Protected i,point,exp,lastEXP,num
Protected hex,c
Protected ok=#num_ok
If *word\c='0'
*word+SizeOf(character)
If *word\c='x' Or *word\c='X'
*word+SizeOf(character)
hex=#True
EndIf
EndIf
While *word\c
c=*word\c
If (c>='0' And c<='9') Or ( hex=#True And ((c>='a' And c<='f') Or (c>='A' And c<='F')) )
LastExp=#False
num=#True
ElseIf c='.'
If point
ok=#num_none
Break
EndIf
point=#True
ElseIf (c='+' Or c='-')
If lastexp=#False
ok=#num_none
Break
EndIf
lastexp=#False
ElseIf c='E' Or c='e' Or ( Hex=#True And (c='P' Or c='p')); en hexadécimal pour obtenir ici de toute façon
If exp Or num=#False
ok=#num_none
Break
EndIf
exp=#True
point=#True
lastEXP=#True
Else
ok=#num_none
Break
EndIf
*word+SizeOf(character)
Wend
If ok
If lastEXP
ProcedureReturn #num_exp
ElseIf Point
ProcedureReturn #num_point
EndIf
EndIf
ProcedureReturn ok
EndProcedure
Procedure CheckLine(gadget,lineNumber)
;Vérifie que l'indentation de la ligne est correcte et la corrige
Protected mode,pos,currentpos,char
Protected indentlevel,indentafter,indentbefore,word.s
Protected linestate
Protected spaces,tabsize
pos=sci(gadget,#SCI_POSITIONFROMLINE,lineNumber)
tabsize=sci(gadget,#SCI_GETTABWIDTH)
currentpos=pos
Repeat
char=sci(gadget,#SCI_GETCHARAT,currentpos)
currentpos+1
If char=32
spaces+1
ElseIf char=9
spaces+(tabsize-(spaces%tabsize))
Else
Break
EndIf
ForEver
linestate= sci(Gadget,#SCI_GETLINESTATE,lineNumber)
If lineState & (#linestate_QuoteBlock|#linestate_CommentBlock)=0 Or lineState & #linestate_start
IndentLevel=(linestate&#linestate_IndentLevelMask)
If spaces<>tabsize*indentlevel
sci(gadget,#SCI_SETTARGETSTART,pos)
sci(gadget,#SCI_SETTARGETEND,currentpos-1)
word=LSet("",indentlevel,Chr(9))
sci(gadget,#SCI_REPLACETARGET,StringByteLength(word,#PB_UTF8),_fastUTF8(word))
EndIf
EndIf
EndProcedure
Procedure PBIndention(gadget)
; la routine auto indentation "complex" pour pb
Protected lineNumber,pos
Protected indentlevel,indentafter,word.s
Protected linestate
Protected spaces,tabsize
pos=sci(gadget,#SCI_GETCURRENTPOS)
Highlight(gadget,pos,pos)
lineNumber=sci(gadget,#SCI_LINEFROMPOSITION,pos)
CheckLine(gadget,lineNumber-1)
If lineNumber>0
linestate= sci(Gadget,#SCI_GETLINESTATE,lineNumber)
;Debug Hex(linestate)
IndentAfter=((lineState&#linestate_IndentAfterMask)>>#linestate_IndentAfterShift) - #linestate_IndentBase
IndentLevel=(linestate&#linestate_IndentLevelMask)
;Debug Hex(linestate&(#linestate_CommentBlock|#linestate_QuoteBlock))+" "+Hex(linestate&#linestate_end)
If linestate&(#linestate_CommentBlock|#linestate_QuoteBlock)=0 ; Or linestate&#linestate_end
;indentlevel+indentafter
word=LSet("",indentlevel,Chr(9))
sci(gadget,#SCI_REPLACESEL,StringByteLength(word,#PB_UTF8),_fastUTF8(word))
EndIf
EndIf
EndProcedure
Procedure Highlight(Gadget,startPos,endPos)
;Formulaire de style de startpos à endpos
Protected lineNumber,lineNumber2,foldLevel
Protected thisLevel,nextLevel
Protected currentPos
Protected State,oldState
Protected word.s,char,charnext,stylePos,style
Protected force
Protected ignoreNext
Protected i, achar.s
Protected forceLabel
Protected lineStateSubCount,EndMark.s
Protected lineState
Protected doFold
Protected IndentLevel,IndentBefore,IndentAfter
Protected eolchar
linenumber = SCI(Gadget, #SCI_LINEFROMPOSITION, startpos)
doFold=_GetPropertyFlag(gadget,#PropertyFlag_Fold)
If sci(gadget,#SCI_GETEOLMODE)=#SC_EOL_CR
eolchar=13
Else
eolchar=10
EndIf
If linenumber = 0
foldlevel = #SC_FOLDLEVELBASE
lineStateSubCount=0
Else
linenumber - 1
foldlevel = SCI(Gadget, #SCI_GETFOLDLEVEL, linenumber) & #SC_FOLDLEVELNUMBERMASK
linestate= sci(Gadget,#SCI_GETLINESTATE,lineNumber)
If lineState & (#linestate_start|#linestate_CommentBlock)=#linestate_CommentBlock
lineStateSubCount=(lineState & #linestate_submask)>>#linestate_subshift
endmark="--]"+RSet("]",lineStateSubCount,"=")
force=#force_CommentBlock
EndIf
If lineState & (#linestate_start|#linestate_QuoteBlock)=#linestate_QuoteBlock
lineStateSubCount=(lineState & #linestate_submask)>>#linestate_subshift
endmark="]"+RSet("]",lineStateSubCount,"=")
force=#force_QuoteBlock
EndIf
IndentBefore=((lineState&#linestate_IndentBeforeMask)>>#linestate_IndentBeforeShift) - #linestate_IndentBase
IndentLevel=(linestate&#linestate_IndentLevelMask) - IndentBefore
IndentBefore=0
EndIf
thisLevel=foldLevel
nextLevel=foldLevel
linestate=0
currentPos = SCI(Gadget, #SCI_POSITIONFROMLINE, linenumber)
stylePos=currentPos
SCI(gadget, #SCI_STARTSTYLING, currentpos)
oldState=#lex_None
charnext= Sci(Gadget, #SCI_GETCHARAT, currentpos)
While currentpos <= endpos
char = charnext
charnext=Sci(Gadget, #SCI_GETCHARAT, currentpos+1)
Select char
Case ':'
If oldState=#lex_alpha And ((charnext>='a' And charnext<='z') Or (charnext>='A' And charnext<='Z') Or charnext='_')
state=#lex_Alpha
Else
state=#lex_Label
EndIf
Case 'a' To 'z','A' To 'Z','0' To '9','_'
If Left(word,2)="::"
state=#lex_Label
Else
state=#lex_Alpha
EndIf
Case '(', ')'
state=#lex_bracket
Case '"'
state=#lex_Quote
Case 39 ;'
state=#lex_SingleQuote
Case '/'
state=#lex_Slash
Case 0 To 32, 127 ;espaces blancs et caractères eol
If char=eolchar
state=#lex_NewLine
Else
state=#lex_Space
EndIf
;Pour détecter les numéros de poste
Case '+','-'
If oldState=#lex_Alpha And IsPBNumber(@word)=#num_exp;doit suivre une exp!
state=#lex_Alpha
Else
state=#lex_misc
EndIf
Case '.'
If oldState=#lex_Alpha And IsPBNumber(@word)=#num_ok ;ne doit avoir ni le point ni exp, juste ok!
state=#lex_Alpha
ElseIf oldState=#lex_Alpha And ((charnext>='a' And charnext<='z') Or (charnext>='A' And charnext<='Z') Or charnext='_')
state=#lex_Alpha
Else
state=#lex_Misc
EndIf
Default
state=#lex_Misc
EndSelect
If oldstate=#lex_NewLine Or state<>oldState
Select force
Case #force_CommentBlock;{
lineState|#linestate_CommentBlock
style=#style_CommentBlock
If oldState=#lex_misc And Right(word,Len(EndMark))=EndMark
force=#force_None
;linestate|#linestate_end
EndIf
;}
Case #force_QuoteBlock;{
linestate|#linestate_QuoteBlock
style=#style_StringBlock
If oldState=#lex_misc And Right(word,Len(EndMark))=EndMark
force=#force_None
;linestate|#linestate_end
EndIf
;}
Case #force_Quote;{
style=#style_String
Select oldState
Case #lex_Slash
ignoreNext=#True
Case #lex_Quote
If ignoreNext=#False
force=#force_None
Else
ignoreNext=#False
EndIf
Case #lex_NewLine
force=#force_None
Default
ignoreNext=#False
EndSelect
;}
Case #force_SingleQuote;{
style=#style_SingleString
Select oldState
Case #lex_Slash
ignoreNext=#True
Case #lex_SingleQuote
If ignoreNext=#False
force=#force_None
Else
ignoreNext=#False
EndIf
Case #lex_NewLine
force=#force_None
Default
ignoreNext=#False
EndSelect
;}
Case #force_None;{
Select oldState
Case #lex_SingleQuote
ignoreNext=#False
force=#force_SingleQuote
style=#style_SingleString
forceLabel=#False
Case #lex_Quote
ignoreNext=#False
force=#force_Quote
style=#style_String
forceLabel=#False
Case #lex_bracket
style=#STYLE_DEFAULT
forceLabel=#False
Case #lex_Space
style=#STYLE_DEFAULT
Case #lex_Slash,#lex_NewLine
style=#STYLE_DEFAULT
forceLabel=#False
Case #lex_Label
If Left(word,2)="::" And FindString(Mid(word,3,Len(word)-4),":")=0
style=#STYLE_label
Else
style=#STYLE_DEFAULT
EndIf
forceLabel=#False
Case #lex_Alpha
If FindMapElement(MotCle(),word)
style=#style_MotCle
If word="Goto"
forceLabel=#True
Else
forceLabel=0
EndIf
ElseIf FindMapElement(special(),word)
style=#style_SpecialMotCle
ElseIf IsPBNumber(@word)
style=#style_Number
forceLabel=#False
ElseIf forceLabel
forceLabel=#False
style=#style_label
Else
style=#style_AlphaNum
EndIf
;Folding
If FindMapElement(DebutPliage(),word)
thislevel | #SC_FOLDLEVELHEADERFLAG
nextlevel + 1
EndIf
If FindMapElement(FinPliage(),word)
nextlevel - 1
If nextlevel < #SC_FOLDLEVELBASE
nextlevel = #SC_FOLDLEVELBASE
EndIf
EndIf
;Indention
If FindMapElement(apres(),word)
IndentAfter+apres()
EndIf
If FindMapElement(avant(),word)
If avant()<0 And IndentAfter=>-avant()
IndentAfter+avant()
Else
IndentBefore+avant()
EndIf
EndIf
Case #lex_Misc
style=#STYLE_DEFAULT
If Left(word,1)="["
lineStateSubCount=1
For i=2 To Len(word)
achar=Mid(word,i,1)
If achar="="
lineStateSubCount+1
ElseIf achar="["
If lineStateSubCount>255
lineStateSubCount=255
EndIf
endmark="]"+RSet("]",lineStateSubCount,"=")
lineState|#linestate_start|#linestate_QuoteBlock
force=#force_QuoteBlock
style=#style_StringBlock
Break
Else
Break
EndIf
Next
If force<>#force_QuoteBlock
lineStateSubCount=0
EndIf
ElseIf Left(word,2)="--"
style=#style_Comment
force=#force_Comment
If Mid(word,3,1)="["
lineStateSubCount=1
For i=4 To Len(word)
achar=Mid(word,i,1)
If achar="="
lineStateSubCount+1
ElseIf achar="["
If lineStateSubCount>255
lineStateSubCount=255
EndIf
endmark="--]"+RSet("]",lineStateSubCount,"=")
lineState|#linestate_start|#linestate_CommentBlock
force=#force_CommentBlock
style=#style_CommentBlock
Break
Else
Break
EndIf
Next
If force<>#force_CommentBlock
lineStateSubCount=0
EndIf
EndIf
EndIf
forceLabel=#False
Default
; le premier appel n'a pas de style
style=0
forceLabel=#False
EndSelect
;}
Case #force_Comment;{
If oldstate=#lex_NewLine
force=#force_None
EndIf
style=#style_Comment
;}
EndSelect
If style
SCI(Gadget, #SCI_SETSTYLING, currentpos - stylePos, style)
stylePos = currentpos
EndIf
word=""
oldState=state
EndIf
word+Chr(char)
If state=#lex_NewLine Or currentpos=endPos
;Coller des guillemets et commenter
If linestate &(#linestate_QuoteBlock|#linestate_CommentBlock)=0
lineStateSubCount=0
Else
lineState+ (lineStateSubCount<<#linestate_subshift)
EndIf
;indentaion
lineState+ ((IndentAfter+#linestate_IndentBase)<<#linestate_IndentAfterShift)&#linestate_IndentAfterMask
lineState+ ((IndentBefore+#linestate_IndentBase)<<#linestate_IndentbeforeShift)&#linestate_IndentBeforeMask
IndentLevel+IndentBefore:If IndentLevel<0:IndentLevel=0:ElseIf IndentLevel>255:IndentLevel=255:EndIf
linestate+ IndentLevel&#linestate_IndentLevelMask
Indentlevel+IndentAfter:If IndentLevel<0:IndentLevel=0:ElseIf IndentLevel>255:IndentLevel=255:EndIf
sci(gadget,#SCI_SETLINESTATE,linenumber,lineState)
linestate=0
IndentAfter=0
IndentBefore=0
;pliage
If doFold
Sci(Gadget, #SCI_SETFOLDLEVEL, linenumber, thislevel)
EndIf
thislevel = nextlevel
lineNumber+1
EndIf
currentpos+1
Wend
If _GetProperty(Gadget,#Property_AutoIndention)=#AutoIndention_complex
Protected startline,endline,currentline
startline=sci(gadget,#SCI_LINEFROMPOSITION,startpos)
endline=sci(gadget,#SCI_LINEFROMPOSITION,endpos)
currentpos=sci(gadget,#SCI_GETCURRENTPOS)
currentline=sci(gadget,#SCI_LINEFROMPOSITION,currentPos)
For i=startline To endline
If i<>currentline
CheckLine(gadget,i)
EndIf
Next
EndIf
EndProcedure
Procedure FindWordStart(gadget,endpos)
;Utilisé pour trouver le mot courant sous la position (position = dernier caractère dans le mot).
;et détecter les mots liés avec . ou :
Protected startpos,char,i
startpos=endpos
Repeat
startpos=sci(gadget,#SCI_WORDSTARTPOSITION,startpos,#True)
char=sci(gadget,#SCI_GETCHARAT,startpos-1)
If char='.' Or char=':'
startpos-1
Else
Break
EndIf
ForEver
ProcedureReturn startpos
EndProcedure
Procedure PBCallback(Gadget, *scinotify.SCNotification)
;rappel scintilla pour le lexer
Protected startPos,lineNumber,mode
Select *scinotify\nmhdr\code
Case #SCN_UPDATEUI
If *scinotify\updated=#SC_UPDATE_SELECTION
If _GetPropertyFlag(gadget,#PropertyFlag_Brace)
_MarkBrace(gadget,"()[]{}")
EndIf
EndIf
Case #SCN_MODIFIED
If *scinotify\modificationType & (#SC_MOD_DELETETEXT)
If _GetPropertyFlag(gadget,#PropertyFlag_Brace)
_MarkBrace(gadget,"()[]{}")
EndIf
EndIf
If *scinotify\length=1 And (*scinotify\modificationType&#SC_MOD_DELETETEXT) And *scinotify\position=sci(gadget,#SCI_GETCURRENTPOS)
_Autocomplete(gadget,@FindWordStart(),special())
EndIf
Case #SCN_CHARADDED
If (*scinotify\ch>='a' And *scinotify\ch<='z') Or (*scinotify\ch>='A' And *scinotify\ch<='Z') Or (*scinotify\ch>='0' And *scinotify\ch<='9') Or *scinotify\ch='_' Or *scinotify\ch='.' Or *scinotify\ch=':'
_Autocomplete(gadget,@FindWordStart(),special())
EndIf
If _GetPropertyFlag(gadget,#PropertyFlag_Brace)
_MarkBrace(gadget,"()[]{}")
EndIf
If (*scinotify\ch=10 Or *scinotify\ch=13)
mode=sci(gadget,#SCI_GETEOLMODE)
If (mode=#SC_EOL_CR And *scinotify\ch=13) Or (mode<>#SC_EOL_CR And *scinotify\ch=10)
Select _GetProperty(gadget,#property_AutoIndention)
Case #AutoIndention_simple: _indention(gadget)
Case #AutoIndention_complex: PBIndention(gadget)
EndSelect
;parenthèses, crochets ou accolades corrects
If _GetPropertyFlag(gadget,#PropertyFlag_Brace)
_MarkBrace(gadget,"()[]{}")
EndIf
EndIf
EndIf
Case #SCN_AUTOCCHARDELETED
_Autocomplete(gadget,@FindWordStart(),special())
Case #SCN_STYLENEEDED
startPos =SCI(Gadget,#SCI_GETENDSTYLED)
;Le lexer pb a toujours le style de la ligne avant de commencer - donc nous n'avons pas besoin
;lineNumber = SCI(Gadget,#SCI_LINEFROMPOSITION,startPos)
;startPos = SCI(Gadget,#SCI_POSITIONFROMLINE,lineNumber)
Highlight(Gadget,startPos, *scinotify\position)
EndSelect
ProcedureReturn _callback(gadget,*scinotify)
EndProcedure
Procedure PBinit(gadget,*style.lexerstyle)
;Cette routine est appelée à partir du gadget scintilla ::, après la création du gadget
Protected word.s,i
;{ Lire des listes de mots pour le style, le pliage, l'indentation
If MapSize(special())=0
Restore special
Repeat
Read.s word
If word<>""
special(word)=#True
Else
Break
EndIf
ForEver
EndIf
If MapSize(MotCle())=0
Restore MotCle
Repeat
Read.s word
If word<>""
MotCle(word)=#True
Else
Break
EndIf
ForEver
EndIf
If MapSize(DebutPliage())=0
Restore DebutPliage
Repeat
Read.s word
If word<>""
DebutPliage(word)=#True
Else
Break
EndIf
ForEver
EndIf
If MapSize(FinPliage())=0
Restore FinPliage
Repeat
Read.s word
If word<>""
FinPliage(word)=#True
Else
Break
EndIf
ForEver
EndIf
If MapSize(apres())=0
Restore apres
Repeat
Read.s word
Read.i i
If word<>""
apres(word)=i
Else
Break
EndIf
ForEver
EndIf
If MapSize(avant())=0
Restore avant
Repeat
Read.s word
Read.i i
If word<>""
avant(word)=i
Else
Break
EndIf
ForEver
EndIf
;}
;Définir le Lexer sur le conteneur
ScintillaSendMessage(Gadget,#SCI_SETLEXER,#SCLEX_CONTAINER)
;Caractères pour la détection des mots
sci(gadget,#SCI_SETWORDCHARS,0, _fastUTF8("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"))
;Autocompletion des mots sélectionnés
sci(gadget,#SCI_AUTOCSETFILLUPS,0,_fastUTF8(~".:[("))
;le style
SetStyle(Gadget,*style)
ProcedureReturn #True