--[[LuaCS, by Yatto]] --[[LuaColorationSytaxique, ou LuaCodeSource]] --[[ compile avec Luna-0.2a, de ExtendeD http://ndlessly.wordpress.com ]] --Utilise un bout de Universal Menu, de Spirikoi --[[Merci a: Critor, Adriweb, Levak, Excale, Monstercrunch, Laurae et ses NYAN et YATTOFLOW, et tous ceux que j'oublie, pour m'avoir supporte, aide, trouve des bugs, proposer des ameliorations, des idees quand j'avais des problemes, bref, merci pour tout ce qui a fait de cette idee un programme. =) ]] z=0 i=0 j=0 isColor=true cutCalled=false isSelection=false selx=0 sely=0 tmp="" copy="" x = 0 y = 1 fontSize = 11 undoIndex = 0 undoQueue = 1 maxUndo = 255 UndoTable={} for i = 1, maxUndo do UndoTable[i] = {} end buffer = {""} sep = '[ %,%;%:%-%+%*%/%.%(%)%[%]=%<%>%~%#]' -- cs{{"pattern", "color", [size, ["font"]]}, ...} cs={ {"%-%-%[%[.-%]%]", "gray", 6, "i"}, {"%[%[.-%]%]", "purple", 4, "i"}, {"%-%-.*$", "gray", 2, "i"}, {'%b""', "purple", 2, "i"}, {"%b''", "purple", 2, "i"}, {'and', "blue"}, {'break', "blue"}, {'do', "blue"}, {'else', "blue"}, {'elseif', "blue"}, {'end', "blue"}, {'false', "blue"}, {'for', "blue"}, {'function', "blue"}, {'if', "blue"}, {'in', "blue"}, {'local', "blue"}, {'nil', "pink"}, {'not', "blue"}, {'or', "blue"}, {'repeat', "blue"}, {'return', "blue"}, {'then', "blue"}, {'true', "blue"}, {'until', "blue"}, {'while', "blue"}, {'assert', "pink"}, {'collectgarbage', "pink"},{'error', "pink"}, {'gcinfo', "blue"}, {'loadstring', "pink"}, {'print', "pink"}, {'tonumber', "pink"}, {'tostring', "blue"}, {'type', "pink"}, {'unpack', "pink"}, {'foreach', "blue"}, {'foreachi', "blue"}, {'rawget', "pink"}, {'rawset', "pink"}, {'require', "blue"}, {'_G', "blue"}, {'getfenv', "pink"}, {'getmetatable', "pink"}, {'ipairs', "pink"}, {'next', "blue"}, {'pairs', "pink"}, {'pcall', "pink"}, {'rawegal', "pink"}, {'setfenv', "blue"}, {'setmetatable', "pink"}, {'xpcall', "blue"}, {"%d+", "green", 1}, {"==", "brown"}, {"=", "brown"}, {"<", "brown"}, {">", "brown"}, {"platform.window:invalidate", "blue"}, } function test(arg) return arg and 1 or 0 end function addChar(ch, oldx, oldy) buffer[oldy] = buffer[oldy]:sub(0, oldx)..ch..buffer[oldy]:sub(oldx + 1) x = oldx + 1 y = oldy end function delChar(_, oldx, oldy) buffer[oldy] = buffer[oldy]:sub(0, oldx - 1)..buffer[oldy]:sub(oldx + 1) x = oldx - 1 y = oldy end function addLine(oldx, oldy) table.insert(buffer, oldy + 1, string.sub(buffer[oldy], oldx + 1)) buffer[oldy] = string.sub(buffer[oldy], 0, oldx) x = oldx y = oldy + 1 end function delLine(oldx, oldy) buffer[oldy-1] = buffer[oldy-1]..buffer[oldy] table.remove(buffer, oldy) x = oldx y = oldy - 1 end function addString(chaine, oldx, oldy, oldselx, oldsely) if oldselx and oldsely then if oldy > oldsely then x = oldselx y = oldsely selx = oldx sely = oldy else x = oldx y = oldy selx = oldselx sely = oldsely end isSelection = true else x = oldx y = oldy selx = oldx sely = oldy end prex = string.sub(buffer[y], 0, x) postx = string.sub(buffer[y], x + 1) chaine = string.gsub(chaine, string.char(13), '') if string.find(chaine, '\n') then local lines = string.split(chaine, '\n') local n = 0 for i, line in ipairs(lines) do if i == 1 then buffer[y] = prex..line elseif i < #lines then table.insert(buffer, y + n + 1, line) n = n + 1 else buffer[y + n + 1] = line..postx x = x + #line end end y = y + n + 1 else buffer[y] = prex..chaine..postx x = x + #chaine end end function delString(_, oldx, oldy, oldselx, oldsely) x = oldx y = oldy selx = oldselx sely = oldsely deleteSelection() end HistoryMap = { [delChar]=addChar, [addChar]=delChar, [addLine]=delLine, [delLine]=addLine, [addString]=delString, [delString]=addString, } function addUndo(fonct, params) local i = (undoIndex % maxUndo) + 1 while i ~= undoQueue and #UndoTable[i] > 0 do UndoTable[i] = {} collectgarbage() i = (i % maxUndo) + 1 end if undoIndex > 0 then undoIndex = (undoIndex % maxUndo) + 1 if undoIndex == undoQueue then undoQueue = (undoQueue % maxUndo) + 1 end else undoIndex = undoQueue end UndoTable[undoIndex] = {fonct, params} end function getSelection() local copy = "" if sely == y then if selx ~= x then if selx < x then x, selx = selx, x end copy = buffer[y]:sub(x + 1, selx) end else if sely < y then x, y, selx, sely = selx, sely, x, y end copy = buffer[y]:sub(x + 1).."\n" k = y while k < sely - 1 do k = k + 1 copy = copy..buffer[k].."\n" end copy = copy..buffer[sely]:sub(0, selx) end return copy end function deleteSelection() if sely == y then if selx < x then buffer[y] = buffer[y]:sub(0, selx)..buffer[y]:sub(x + 1) end if selx > x then buffer[y] = buffer[y]:sub(0, x)..buffer[y]:sub(selx + 1) -- selx exclu x = selx end else if sely < y then selx, sely, x, y = x, y, selx, sely end buffer[y] = buffer[y]:sub(0, x)..buffer[sely]:sub(selx + 1) while y < sely do sely = sely - 1 table.remove(buffer, y + 1) end end end -- string.find iterator -> for loops -- for a, b in str:gfind(pattern) do print (a, b) end function string:gfind(pattern, max) local i = 0 return function() if #self >= #pattern or (max and #self >= max) then local a, b = self:find(sep..pattern..sep, i) if a then i = b+1 return a + 1, b - 1 else a, b = self:find("^"..pattern..sep, i) if a then i = b return a, b - 1 else a, b = self:find(sep..pattern.."$", i) if a then i = b + 1 return a + 1, b else a, b = self:find("^"..pattern.."$", i) if a then i = b + 1 return a, b elseif pattern:find(sep) then a, b = self:find(pattern, i) if a then i = b + 1 return a, b end end end end end end end end function setColor(theColor) -- It's a "Better lua API" script that Spirikoi have modified, in his "Universal Menu", thanks to him theColor = string.lower(theColor) platform.gc():setColorRGB(0,0,0) -- set black as default is nothing else valid is found if theColor == "blue" then platform.gc():setColorRGB(0,0,255) elseif theColor == "brown" then platform.gc():setColorRGB(165,42,42) elseif theColor == "cyan" then platform.gc():setColorRGB(0,255,255) elseif theColor == "darkblue" then platform.gc():setColorRGB(0,0,139) elseif theColor == "darkred" then platform.gc():setColorRGB(139,0,0) elseif theColor == "fuchsia" then platform.gc():setColorRGB(255,0,255) elseif theColor == "gold" then platform.gc():setColorRGB(255,215,0) elseif theColor == "gray" or theColor == "grey" then platform.gc():setColorRGB(127,127,127) elseif theColor == "green" then platform.gc():setColorRGB(0,128,0) elseif theColor == "lightblue" then platform.gc():setColorRGB(173,216,230) elseif theColor == "lightgreen" then platform.gc():setColorRGB(144,238,144) elseif theColor == "magenta" then platform.gc():setColorRGB(255,0,255) elseif theColor == "maroon" then platform.gc():setColorRGB(128,0,0) elseif theColor == "navyblue" then platform.gc():setColorRGB(159,175,223) elseif theColor == "orange" then platform.gc():setColorRGB(255,125,0) elseif theColor == "palegreen" then platform.gc():setColorRGB(152,251,152) elseif theColor == "pink" then platform.gc():setColorRGB(204,45,204) elseif theColor == "purple" then platform.gc():setColorRGB(128,0,128) elseif theColor == "red" then platform.gc():setColorRGB(255,0,0) elseif theColor == "royalblue" then platform.gc():setColorRGB(65,105,225) elseif theColor == "salmon" then platform.gc():setColorRGB(250,128,114) elseif theColor == "seagreen" then platform.gc():setColorRGB(46,139,87) elseif theColor == "silver" then platform.gc():setColorRGB(192,192,192) elseif theColor == "turquoise" then platform.gc():setColorRGB(64,224,208) elseif theColor == "violet" then platform.gc():setColorRGB(238,130,238) elseif theColor == "white" then platform.gc():setColorRGB(255,255,255) elseif theColor == "yellow" then platform.gc():setColorRGB(255,255,0) elseif theColor == "paleyellow" then platform.gc():setColorRGB(255,255,150) end end function on.charIn(ch) if isSelection then deleteSelection() end prex = string.sub(buffer[y], 0, x) postx = string.sub(buffer[y], x + 1) buffer[y] = prex..ch..postx --insert char x = x + 1 -- pos. char suivant addUndo(delChar,{ch, x, y}) platform.window:invalidate() end function on.resize() local gc = platform.gc() gc:begin() x, y = 0, 1 lineSpacing = gc:getStringHeight("1") * 0.7 startLine, endLine = 1, platform.window:height() / lineSpacing gc:finish() end on.resize() function string:highlight(gc, i, x, y) if i <= #cs then local oldB, oldX = 0, x for a, b in self:gfind(cs[i][1], cs[i][3]) do local previousString = self:sub(oldB, a - 1) local subString = self:sub(a, b) previousString:highlight(gc, i + 1, oldX, y) oldX = oldX + gc:getStringWidth(previousString) setColor(cs[i][2]) if cs[i][4] then gc:setFont("sansserif", cs[i][4], fontSize) end gc:drawString(subString, oldX, y, "top") oldB = b + 1 oldX = oldX + gc:getStringWidth(subString) end return self:sub(oldB):highlight(gc, i + 1, oldX, y) else setColor("black") gc:setFont("sansserif", "r", fontSize) gc:drawString(self, x, y, "top") end end function on.paint(gc) local pwh = platform.window:height() local pww = platform.window:width() gc:setFont("sansserif", "r", fontSize) local maxLineNumber = #tostring(#buffer) local maxLineNumberWidth = maxLineNumber * gc:getStringWidth(maxLineNumber) -- Rectangle des n°lignes setColor("silver") gc:fillRect(0, 0, maxLineNumberWidth, pwh) setColor("black") gc:drawLine(maxLineNumberWidth, 0, maxLineNumberWidth, pwh) -- Rectangle de la ligne actuelle setColor("paleyellow") gc:fillRect(maxLineNumberWidth + 1, (y - startLine + 0.2) * lineSpacing, pww, 1.2 * lineSpacing) -- Rectangle du curseur setColor("black") gc:fillRect(maxLineNumberWidth + 3 + gc:getStringWidth(buffer[y]:sub(0, x)), (y - startLine + 0.2) * lineSpacing, 1, 1.2 * lineSpacing) -- affichage n°ligne + ligne local beginX = maxLineNumberWidth + 3 local beginY = 0 setColor("black") --local isMultiLine = false for i = startLine, math.min(#buffer, endLine + startLine - 1) do beginY = (i - startLine) * lineSpacing if i == y then setColor("darkred") end gc:drawString(i, maxLineNumberWidth - gc:getStringWidth(i), beginY, "top") if isColor then --if isMultiLine then -- setColor("black") -- gc:setFont("sansserif", "r", fontSize) -- gc:drawString(buffer[i], beginX, beginY, "top") --else buffer[i]:gsub("\\.", " "):highlight(gc, 1, beginX, beginY) --end else setColor("black") gc:setFont("sansserif", "r", fontSize) gc:drawString(buffer[i], beginX, beginY, "top") end end -- affichage de l'assenseur local scrollBarStartY = 10 local scrollBarStartX = pww - 10 local scrollBarLength = pwh - 20 local scrollBarWidth = 10 local scrollBarHeight = math.min((endLine - startLine + 1) * scrollBarLength / #buffer, scrollBarLength) local scrollBarY = (startLine - 1) * scrollBarLength / #buffer + scrollBarStartY setColor("white") gc:fillRect(scrollBarStartX, scrollBarStartY, scrollBarWidth, scrollBarLength) setColor("black") gc:drawRect(scrollBarStartX, scrollBarStartY, scrollBarWidth, scrollBarLength) gc:fillRect(scrollBarStartX+2, scrollBarY+2, scrollBarWidth-4, math.max(scrollBarHeight-4, 4)) --[[ setColor("black") --prex = string.sub(buffer[y], 0, x) --postx = string.sub(buffer[y], x + 1) width=(13+(math.floor(math.log10(y))+1)*8) i=i-j --i: var de la ligne de debut d'ecriture l=#buffer if y>i+14 then --si le curseur sort de l'ecran par le bas i=y-14 end if yy+1 do --y+1 pour traiter la derniere ligne a part. k=k-1 gc:fillRect(((math.floor(math.log10(k))+1)*8)+9+z, (k-1)*15, gc:getStringWidth(buffer[k])+2,15) end end -- comme on a une ligne colore sur la position y, on traitera sely=y aprs qu'on ait dessine la ligne jaune. setColor("black") end while iy then gc:fillRect((math.floor(math.log10(y))+1)*8+9 + gc:getStringWidth(string.sub(buffer[y],0,x))+z, (y-1)*15, gc:getStringWidth(string.sub(buffer[y],x+test(x~=0))) +2 , 15) end if sely == y then if selxx then gc:fillRect(((math.floor(math.log10(y))+1)*8)+9+z + gc:getStringWidth(string.sub(buffer[y],0,x)) , (y-1)*15, gc:getStringWidth(string.sub(buffer[y],x+test(x~=0),selx))+2, 15) end end end setColor("black") end -- j2 sera reutilise plus tard... if gc:getStringWidth(chainy)>289 then -- si la chaine depasse l'ecran (la place pour le texte est d'environ 289 px) if i==y then sub=string.sub(chainy,0,x+math.floor(math.log10(y))+1+2) la ligne ci-dessus est un peu bizarre, mais logique au fond. On veut trouver la longueur de la ligne avec les caractere pretapes: le numero de la ligne et les deux espaces. Or le numero de ligne change! si la ligne est dans les dizaines, elle a deux chiffres, dans les centaines, trois... D'ou l'arrondi du logarithme: il permet de recuperer 0 s'il n'y a qu'une unite, 1 s'il y a des dizaines, 2 avec les centaines... On rajoute a cela "+1" pour avoir le nombre correct (1 pour unite, 2 pour dizaines...) et on rajoute enfin "+2" qui correspondent aux deux espaces entre le numero et la ligne proprement dite. if gc:getStringWidth(sub)>289 then z=289-gc:getStringWidth(sub) else z=0 end else z=0 end end gc:drawString(chainy,z,j*15) --coloration syntaxique if isColor then e=1 a=1 t=1 preligne = math.floor(math.log10(i))+1+2 -- le nombre de caracteres dans le preligne (nombre+.+%s%s) while t<=#cs do e,a=0,1 testcs=cs[t] while not(a==nil) do a,b=string.find(chainy,testcs[1],e) prechar=nil postchar=nil if testcs[3] then -- si le mot doit etre isole... if a~=nil then --si a existe, a est forcement apres le preligne... donc il vaut au moins 5 !! prechar=chainy:sub(a-1,a-1) if prechar==" " then prechar=true else prechar=false end if b~=#chainy then --si b n'est pas en fin de ligne (pas besoin de tester si b existe: si a existe, b existe.) postchar=chainy:sub(b+1,b+1) -- on regarde le caractere suivant if postchar==" " then postchar=true else postchar=false end else -- si b existe mais b==fin de ligne postchar=true end end end -- a existe, et ( pas besoin d'isoler OU (prechar ET postchar sont conformes à l'isolation) if a~=nil and ( not(testcs[3]) or (prechar and postchar)) then -- on colorie! m=gc:getStringWidth(string.sub(chainy,0,a-1 )) setColor(testcs[2]) gc:drawString(string.sub(chainy,a,b),m+z,j*15) -- setColor("black") e=b -- on test a partir de la fin du mot end e=e+1 end t=t+1 end end end -- endWhile: fin de la boucle d'affichage du texte --curseur fantome sub2=string.sub(buffer[y],0,x) lsub2=gc:getStringWidth(sub2)+ gc:getStringWidth(y..". ")+2 if lsub2>294 then lsub2=294 end gc:drawString("|",lsub2,j2*15) --ascenceur gc:drawString("#",305,((201*(y-1))/l)+15) -- cadre de l'ascenseur gc:setPen("medium", "smooth") gc:drawLine(304, 0, 304, ((201*(l-1))/l)+10) gc:drawLine(303, ((201*(l-1))/l)+12,320,((201*(l-1))/l)+12) ]] -- affichage d'aide pendant les versions WIP -- gc:drawString("x:"..x,10,200) --pos x -- gc:drawString("sx:"..selx,40,200) --gc:drawString("w:"..width,80,200) -- gc:drawString("y:"..y,120,200) -- pos y -- gc:drawString("sy:"..sely,150,200) -- gc:drawString("undo:"..undoIndex.."/"..maxUndo..":"..undoQueue,200,200) -- pos de l'index des Undo if isSelection then gc:drawString("Select",120,200) -- ça fait tres "version beta" mais ca reste simple et clair... end end function on.backspaceKey() if isSelection then deleteSelection() else if x == 0 and y > 1 then x = #buffer[y - 1] buffer[y - 1] = buffer[y - 1]..buffer[y] table.remove(buffer,y) y = y - 1 if startLine > 1 and y > 1 then startLine = startLine - 1 endLine = endLine - 1 end addUndo(addLine,{x, y}) elseif x > 0 then addUndo(addChar,{string.sub(buffer[y], x, x), x, y}) buffer[y] = string.sub(buffer[y], 0, x - 1)..string.sub(buffer[y], x + 1) x = x - 1 end end platform.window:invalidate() end function on.enterKey() if isSelection then addUndo(addString,{getSelection(), selx, sely, x, y}) deleteSelection() -- on suppr. la selection isSelection = false end prex = string.sub(buffer[y], 0, x) postx = string.sub(buffer[y], x + 1) buffer[y] = prex table.insert(buffer, y + 1, postx) local tabul = prex:match("^ *") -- on capture tous les espaces en début de ligne buffer[y + 1] = tabul..buffer[y + 1] y = y + 1 if y > endLine then startLine = startLine + 1 endLine = endLine + 1 end addUndo(delLine,{x, y}) x = #tabul platform.window:invalidate() end function on.arrowUp() if y > 1 then y = y - 1 if x > #buffer[y] then x = #buffer[y] end if y < startLine then startLine = startLine - 1 endLine = endLine - 1 end else x = 0 end platform.window:invalidate() end function on.arrowDown() if y < #buffer then y = y + 1 if x > #buffer[y] then x = #buffer[y] end if y > endLine then startLine = startLine + 1 endLine = endLine + 1 end else x = #buffer[y] end platform.window:invalidate() end function on.arrowLeft() if x > 0 then x = x - 1 elseif y > 1 then y = y - 1 x = #buffer[y] end platform.window:invalidate() end function on.arrowRight() if x < #buffer[y] then x = x + 1 elseif y < #buffer then x = 0 y = y + 1 end platform.window:invalidate() end function on.mouseDown(mx, my) width = (13+(math.floor(math.log10(y))+1)*8) length = platform.gc():getStringWidth(buffer[y]) a = i - j b = math.floor(a + (my/15))+1 if b <= #buffer then y = b -- +1 parce que ca arrondit (math.floor) 1 ligne en dessous end local k = 0 b=true mx = mx - width while k <= #buffer[y] and b do sub = string.sub(buffer[y], 0, k) a = platform.gc():getStringWidth(sub) if a + z >= mx then -- "-z":= si la fenetre est decalee x = k b = false end k = k + 1 end if width + length < mx then x = #buffer[y] end platform.window:invalidate() end function on.backtabKey() undo() end function on.clearKey() redo() end function on.tabKey() if not(isSelection) then isSelection=true selx, sely = x, y else isSelection=false end end function undo() isSelection = false -- si la liste des actions effectuees n'est pas vide && si on peut encore annuler (s'il existe des actions au dessous de l'index) if undoIndex > 0 then local elt = UndoTable[undoIndex] elt[1](unpack(elt[2])) -- on execute la fonction contraire a celle faite (n UndoIndex), avec ses parametres (table) if undoIndex == undoQueue then undoIndex = 0 else undoIndex = ((undoIndex - 2) % maxUndo) + 1 end platform.window:invalidate() end end function redo() isSelection = false local nextIndex = (undoIndex == 0) and undoQueue or (undoIndex % maxUndo) + 1 -- Si on a fait au moins un Undo if (nextIndex ~= undoQueue or undoIndex == 0) and #UndoTable[nextIndex] > 0 then undoIndex = nextIndex local elt = UndoTable[undoIndex] --on prend l'action qu'on vient d'annuler HistoryMap[elt[1]](unpack(elt[2])) -- on fait l'inverse du Undo qu'on retrouve avec la table de correspondance HistoryMap platform.window:invalidate() end end function on.copy() if isSelection then clipboard.addText(getSelection()) isSelection = false end platform.window:invalidate() end function on.cut() if isSelection then on.copy() addUndo(addString,{copy, selx, sely, x, y}) deleteSelection() isSelection=false end platform.window:invalidate() end function on.paste() if isSelection then addUndo(addString, {getSelection(), selx, sely, x, y}) deleteSelection() end copy = clipboard.getText() addString(copy, x, y) addUndo(delString, {copy, selx, sely, x, y}) platform.window:invalidate() end function selectAll() x, y, selx, sely = 0, 1, #buffer[#buffer], #buffer isSelection = true platform.window:invalidate() end function on.varChange(varlist) vary = var.recall("y") if vary <= #buffer and vary > 0 then y = vary platform.window:invalidate() end end function sauver() tmp = table.concat(buffer,string.uchar(10)):gsub('"', '""') var.store("txt", tmp) end function charger() selx, sely, x, y = 0, 1, #buffer[#buffer], #buffer addUndo(addString, {getSelection(), selx, sely, x, y}) deleteSelection() local txt = var.recall("txt"):gsub('""', '"') buffer = {} collectgarbage() buffer = txt:split(string.uchar(10)) selx, sely, x, y = 0, 1, #buffer[#buffer], #buffer addUndo(delString, {txt, selx, sely, x, y}) y = #buffer x = #buffer[y] platform.window:invalidate() end function testCode() local osx, osy, ox, oy = selx, sely, x, y selx, sely, x, y = 0, 1, #buffer[#buffer], #buffer isSelection = true on.copy() selx, sely, x, y = osx, osy, ox, oy if not var.recall("s__code") then var.store("s__code", 0) else var.store("s__code", var.recall("s__code") + 1) end end function on.create() var.store("y", 1) var.monitor("y") end function ecrire(mot, h) if isSelection then addUndo(addString, {getSelection(), selx, sely, x, y}) deleteSelection() end addUndo(delString, {mot, selx, sely, x, y}) prex = string.sub(buffer[y], 0, x) postx = string.sub(buffer[y], x + 1) buffer[y] = prex..mot..postx x = x + h -- on positionne le curseur la ou on veut dans l'expression qu'on a rajoute platform.window:invalidate() end function fIfThen() ecrire("if then", 3) end function fElse() ecrire("else", 5) end function fEnd() ecrire("end", 3) end function fWhileDo() ecrire("while do",6) end function fForDo() ecrire("for do", 4) end function fPWI() ecrire("platform.window:invalidate()",28) end function fVarMonit() ecrire("var.monitor()", 12) end function fVarUnmonit() ecrire("var.unmonitor()", 14) end function fVarRecall() ecrire("var.recall()", 11) end function fVarRecallstr() ecrire("var.recallstr()", 14) end function fVarStore() ecrire("var.store(,)",10) end function fVarList() ecrire("var.list()",9) end function fFunction() ecrire("function",8) end function fReturn() ecrire("return",6) end function fAccol() ecrire("{}",1) end function fBrackets() ecrire("[]",1) end function fColorSyntax() isColor = not isColor platform.window:invalidate() end menu = { {"Fichier...", {"Tester avec Oclua", testCode}, {"Sauvegarder", sauver}, {"Charger", charger}, {"Selectionner tout", selectAll}, }, {"Blocs conditionnels/boucles", {"if then", fIfThen}, {"else", fElse}, {"end", fEnd}, {"while do", fWhileDo}, {"for do", fForDo}, }, {"fonction/termes usuels", {"function", fFunction}, {"return", fReturn}, {"platform.window:invalidate()", fPWI}, }, {"Var. -->", {"var.monitor()", fVarMonit}, {"var.unmonitor()", fVarUnmonit}, {"var.recall()", fVarRecall}, {"var.recallstr()", fVarRecallstr}, {"var.store()", fVarStore}, {"var.list()", fVarList}, }, {"Caractères spéciaux", {"{}", fAccol}, {"[]", fBrackets}, }, {"Options", {"Activer/desactiver la coloration syntaxique", fColorSyntax}, } } toolpalette.register(menu) toolpalette.enablePaste(true) toolpalette.enableCut(true) toolpalette.enableCopy(true)s