Advertisement
Shiranuit

ByteEditor

Aug 27th, 2017
160
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 65.89 KB | None | 0 0
  1. -------------------------------------------------------------------------
  2. --                         Programme de Shiranuit                      --
  3. --      Copyright © 2018 Propriétés intellectuelles de Shiranuit       --
  4. --             Toutes tentatives visant à s'approprier                 --
  5. --      le travail de Shiranuit ne sont donc pas acceptable,           --
  6. --           et seront passible de sanction/amende pour                --
  7. --       dédommagement et intérêts envers le créateur du Programme     --
  8. -------------------------------------------------------------------------
  9.  
  10. local args = {...}
  11. local mode = {
  12.     byte={
  13.         char=function(...)
  14.             local argschar={...}
  15.             local t = ""
  16.             for i=1,#argschar do
  17.                 local v = tonumber(argschar[i]) or 0
  18.                 if v<0 then
  19.                     v=0
  20.                 end
  21.                 if v>255 then
  22.                     v=0
  23.             end
  24.             t=t..string.char(v)
  25.             end
  26.             return t
  27.         end,
  28.        
  29.         byte=string.byte,
  30.         auth="0123456789"
  31.         },
  32.     hex={
  33.         byte=function(c)
  34.             local c=string.byte(c)
  35.             local hex = "0123456789abcdef"
  36.             local r=""
  37.             while c>16 do
  38.                 local l=c%16+1
  39.                 c=(c-(c%16))/16
  40.                 r=r..hex:sub(l,l)
  41.             end
  42.             r=r..hex:sub(c+1,c+1)
  43.             r=string.reverse(r)
  44.             return r
  45.         end,
  46.        
  47.         char=function(...)
  48.             local argschar={...}
  49.             local t = ""
  50.             for i=1,#argschar do
  51.                 local v = tonumber("0x"..argschar[i]) or 0
  52.                 if v<0 then
  53.                     v=0
  54.                 end
  55.                 if v>255 then
  56.                     v=0
  57.                 end
  58.                 t=t..string.char(v)
  59.             end
  60.             return t
  61.         end,
  62.         auth="0123456789abcdef"
  63.         },
  64.     bits={
  65.         byte=function(c)
  66.             local num=string.byte(c)
  67.             local t={}
  68.             while num>0 do
  69.                 rest=math.fmod(num,2)
  70.                 t[#t+1]=rest
  71.                 num=(num-rest)/2
  72.             end
  73.             return string.reverse(table.concat(t,""))
  74.         end,
  75.        
  76.         char=function(...)
  77.             local argschar={...}
  78.             local t = ""
  79.             for i=1,#argschar do
  80.                 local v = tonumber(argschar[i],2) or 0
  81.                 if v<0 then
  82.                     v=0
  83.                 end
  84.                 if v>255 then
  85.                     v=0
  86.                 end
  87.                 t=t..string.char(v)
  88.             end
  89.             return t
  90.         end,
  91.         auth="01"
  92.     },
  93.     base3={
  94.         byte=function(c)
  95.             local num=string.byte(c)
  96.             local t={}
  97.             while num>0 do
  98.                 rest=math.fmod(num,3)
  99.                 t[#t+1]=rest
  100.                 num=(num-rest)/3
  101.             end
  102.             return string.reverse(table.concat(t,""))
  103.         end,
  104.        
  105.         char=function(...)
  106.             local argschar={...}
  107.             local t = ""
  108.             for i=1,#argschar do
  109.                 local v = tonumber(argschar[i],3) or 0
  110.                 if v<0 then
  111.                     v=0
  112.                 end
  113.                 if v>255 then
  114.                     v=0
  115.                 end
  116.                 t=t..string.char(v)
  117.             end
  118.             return t
  119.         end,
  120.         auth="012"
  121.     },
  122.     base4={
  123.         byte=function(c)
  124.             local num=string.byte(c)
  125.             local t={}
  126.             while num>0 do
  127.                 rest=math.fmod(num,4)
  128.                 t[#t+1]=rest
  129.                 num=(num-rest)/4
  130.             end
  131.             return string.reverse(table.concat(t,""))
  132.         end,
  133.        
  134.         char=function(...)
  135.             local argschar={...}
  136.             local t = ""
  137.             for i=1,#argschar do
  138.                 local v = tonumber(argschar[i],4) or 0
  139.                 if v<0 then
  140.                     v=0
  141.                 end
  142.                 if v>255 then
  143.                     v=0
  144.                 end
  145.                 t=t..string.char(v)
  146.             end
  147.             return t
  148.         end,
  149.         auth="01234"
  150.     }
  151. }
  152. if term.isColor() then
  153.     _colors={select=colors.red,
  154.     multiselect=colors.blue,
  155.     border=colors.red,
  156.     background=colors.black,
  157.     text=colors.white,
  158.     actioninfo=colors.green,
  159.     highlight=colors.gray,
  160.     info=colors.yellow}
  161. else
  162.     _colors={select=colors.gray,
  163.     multiselect=colors.lightGray,
  164.     border=colors.white,
  165.     background=colors.black,
  166.     text=colors.white,
  167.     actioninfo=colors.white,
  168.     highlight=colors.gray,
  169.     info=colors.white}
  170. end
  171. local lang = {
  172.     en = {
  173.         loading="Loading file",
  174.         time="Time estimated",
  175.         paste="Pasted",
  176.         internalpaste="Internal pasted",
  177.         deletebyte="Byte deleted",
  178.         deletesel="Selection deleted",
  179.         clipboard="Clipboarded",
  180.         clearsel="Selection cleared",
  181.         clearbyte="Byte cleared",
  182.         bytesel="Byte(s) selected",
  183.         byteinsert="Byte(s) inserted",
  184.         undo="Undo",
  185.         found="Sequence found",
  186.         notfound="Sequence not found",
  187.         redo="Redo",
  188.         save="Saved",
  189.         saveas="Saved as",
  190.         clipboardset="Clipboard set",
  191.         mode="Mode",
  192.         langset="Language",
  193.         help="Help",
  194.         usage="Usage",
  195.         list="List",
  196.         docs={
  197.             insert="Insert specified byte(s) or char(s) right to the cursor pos",
  198.             help="Display the help for a command",
  199.             bindlist="Show the list of binds",
  200.             lang="Set the language of the editor",
  201.             color="Change the color of a component",
  202.             deleteAll="Delete all bytes",
  203.             redraw="Force the redraw of the editor",
  204.             mode="Change the mode of the editor for this file",
  205.             undo="Undo the previous action",
  206.             redo="Cancel the previous undo",
  207.             setClipboard="Set the internal clipboard",
  208.             save="Save the file",
  209.             exit="exit the editor",
  210.             gotoLn="Go to a specified line",
  211.             find="Find specified byte(s) or char(s) in the file",
  212.             editmode="Leave the command-line and  return in editmode",
  213.             clearHistory="Clear the actions history",
  214.         },
  215.         usages={
  216.             insert={"insert byte <bytes...>","insert char <chars...>"},
  217.             help={"help <command>"},
  218.             bindlist={"bindlist"},
  219.             lang={"lang <language>"},
  220.             color={"color <component> <color>"},
  221.             deleteAll={"deleteAll"},
  222.             redraw={"redraw"},
  223.             mode={"mode <mode>"},
  224.             undo={"undo <count>","undo"},
  225.             redo={"redo <count>","redo"},
  226.             setClipboard={"setClipboard <text...>"},
  227.             save={"save","save <filename>"},
  228.             exit={"exit"},
  229.             gotoLn={"gotoLn <line>"},
  230.             find={"find byte <bytes...>","find char <chars...>"},
  231.             editmode={"editmode"},
  232.             clearHistory={"clearHistory"},
  233.         },
  234.         binds={
  235.             ["Paste"]="CTRL+V",
  236.             ["Copy"]="CTRL+C",
  237.             ["Find selected sequence"]="CTRL+F",
  238.             ["Internal Paste"]="CTRL+P",
  239.             ["Delete selected byte(s)"]="CTRL+DEL",
  240.             ["Select all"]="CTRL+A",
  241.             ["Insert byte"]="CTRL+INSER",
  242.             ["Jump to the next byte"]="TAB",
  243.             ["Increase selection to the left"]="SHIFT+LEFT",
  244.             ["Increase selection to the right"]="SHIFT+RIGHT"
  245.         }
  246.     },
  247.     fr = {
  248.         loading="Chargement du fichier",
  249.         time="Temps estimé",
  250.         paste="Coller",
  251.         internalpaste="Collage interne",
  252.         deletebyte="Byte supprimer",
  253.         deletesel="Selection supprimer",
  254.         clipboard="Copier",
  255.         clearsel="Selection effacer",
  256.         clearbyte="Byte effacer",
  257.         bytesel="Byte(s) selectionner",
  258.         byteinsert="Byte(s) inserer",
  259.         undo="Annuler",
  260.         found="Trouver",
  261.         notfound="Non trouver",
  262.         redo="Refaire",
  263.         save="Enregistrer",
  264.         saveas="Enregistrer sous",
  265.         clipboardset="Presse-papiers",
  266.         mode="Mode",
  267.         langset="Langue",
  268.         help="Aide",
  269.         usage="Utilisation",
  270.         list="Liste",
  271.         docs={
  272.             insert="Insere un/des byte(s) ou caractere(s) a droite du curseur",
  273.             help="Affiche l'aide",
  274.             bindlist="Affiche la liste des raccourcis clavier",
  275.             lang="Change la langue de l'editeur",
  276.             color="Change la couleur d'un composant de l'editeur",
  277.             deleteAll="Supprime tous les bytes",
  278.             redraw="Force la mise a jour de l'ecran",
  279.             mode="Change le mode de l'editeur pour ce fichier",
  280.             undo="Annule la precedente action",
  281.             redo="Refait l'action precedente",
  282.             setClipboard="Definit le Presse-papiers",
  283.             save="Enregistre le fichier",
  284.             exit="quitte l'editeur",
  285.             gotoLn="Va a la ligne specifier",
  286.             find="trouve une sequence de byte(s) ou de caractere(s) dans le fichier",
  287.             editmode="Quitte la console et reviens en mode edition",
  288.             clearHistory="Efface l'historique des actions",
  289.         },
  290.         usages={
  291.             insert={"insert byte <bytes...>","insert char <chars...>"},
  292.             help={"help <commande>"},
  293.             bindlist={"bindlist"},
  294.             lang={"lang <langue>"},
  295.             color={"color <composant> <couleur>"},
  296.             deleteAll={"deleteAll"},
  297.             redraw={"redraw"},
  298.             mode={"mode <mode>"},
  299.             undo={"undo <nombre>","undo"},
  300.             redo={"redo <nombre>","redo"},
  301.             setClipboard={"setClipboard <texte...>"},
  302.             save={"save","save <nom du fichier>"},
  303.             exit={"exit"},
  304.             gotoLn={"gotoLn <ligne>"},
  305.             find={"find byte <bytes...>","find char <chars...>"},
  306.             editmode={"editmode"},
  307.             clearHistory={"clearHistory"},
  308.         },
  309.         binds={
  310.             ["Colle"]="CTRL+V",
  311.             ["Copie"]="CTRL+C",
  312.             ["Trouve la sequence selectionner"]="CTRL+F",
  313.             ["Collage interbe"]="CTRL+P",
  314.             ["Supprime les bytes selectionner"]="CTRL+DEL",
  315.             ["Selectionne tout"]="CTRL+A",
  316.             ["Insere un byte"]="CTRL+INSER",
  317.             ["Saute au byte suivant"]="TAB",
  318.             ["Selectionne vers la gauche"]="SHIFT+LEFT",
  319.             ["Selectionne vers la droite"]="SHIFT+RIGHT"
  320.         }
  321.     }
  322. }
  323. local w,h = term.getSize()
  324. local buff = window.create(term.current(),1,1,w,h,false)
  325. buff.clear()
  326.  
  327. local revcolor = {[1]="white",[2]="orange",[4]="magenta",[8]="lightBlue",[16]="yellow",[32]="lime",[64]="pink",[128]="gray",[256]="lightGray",[512]="cyan",[1024]="purple",[2048]="blue",[4096]="brown",[8192]="green",[16384]="red",[32768]="black"}
  328. local language = lang["en"]
  329. local name = "ByteEditor"
  330. if fs.exists("."..name) then
  331.     local h=fs.open("."..name,"r")
  332.     local dt=h.readAll()
  333.     h.close()
  334.     local info = textutils.unserialise(dt)
  335.     language=info.lang or lang["en"]
  336.     _colors=info.colors or _colors
  337. else
  338.     local dt = {colors=_colors, lang=language}
  339.     local h=fs.open("."..name,"w")
  340.     h.write(textutils.serialise(dt))
  341.     h.close()
  342. end
  343. function drawProgressBar(x,y,w,progress,message,message2)
  344.     term.clear()
  345.     term.setCursorPos(x,y)
  346.     term.write("[")
  347.     term.setCursorPos(x+w+1,y)
  348.     term.write("]")
  349.     local size = math.floor((w-1)*progress/100)
  350.     for i=x+1, x+size+1 do
  351.         term.setCursorPos(i,y)
  352.         term.write("=")
  353.     end
  354.     message = string.format(message or "", math.floor(progress))
  355.     local mlen = math.floor(#message/2)
  356.     local mid = x+math.floor(w/2)
  357.     term.setCursorPos(mid-mlen,y-2)
  358.     term.write(message)
  359.     message2=message2 or ""
  360.     local mlen2 = math.floor(#message2/2)
  361.     term.setCursorPos(mid-mlen2,y-1)
  362.     term.write(message2)
  363. end
  364. w=w-2
  365. local apercent = 0
  366. local atime = os.clock()
  367. if #args>=1 then
  368.     local fname = args[1]
  369.     local code = ""
  370.     local nread = args[3] or "rb"
  371.     if fname then
  372.         if fs.exists(fname) and not fs.isDir(fname) then
  373.             local len = fs.getSize(fname)
  374.             if nread ~= "r" then
  375.                 local handle = fs.open(args[1],"rb")
  376.                 code=""
  377.                 local count = 0
  378.                 while true do
  379.                     char = handle.read()
  380.                     if char then
  381.                         code=code..string.char(char)
  382.                     else
  383.                         break
  384.                     end
  385.                     count = count+1
  386.                     if math.floor(count/len*100) ~= math.floor(apercent) then
  387.                         local t = os.clock()
  388.                         local timePassed = t-atime
  389.                         local prog = count/len*100 - apercent
  390.                         local delta = prog/timePassed
  391.                         local estimated = (100-count/len*100)/delta
  392.                         drawProgressBar(1,h,w,count/len*100,language.loading.." : "..fname.." - %d%%",language.time.." : "..estimated.."s")
  393.                         apercent = count/len*100
  394.                         atime = os.clock()
  395.                     end
  396.                     if count%10000==0 then
  397.                         sleep(0.01)
  398.                     end
  399.                 end
  400.                 handle.close()
  401.             else
  402.                 local handle = fs.open(args[1],"r")
  403.                 code=handle.readAll()
  404.                 handle.close()
  405.             end
  406.         end
  407.     end
  408.     local _type = mode[args[2] or "byte"] or mode["byte"]
  409.     local size = #tostring(_type.byte("\255"))
  410.     local function conv(c)
  411.         local r=_type.byte(c)
  412.         return string.rep("0",size-#tostring(r))..r
  413.     end
  414.     local sep=math.floor(w/2+w/4)
  415.     for i=1, w-3 do
  416.         if i*(size+1)+i <= w-3 then
  417.             sep=w-i-1
  418.         else
  419.             break
  420.         end
  421.     end
  422.     local drawcount = h-4
  423.     local function calc(code)
  424.         local bytes={}
  425.         for i=1,#code do
  426.             local char=code:sub(i,i)
  427.             local bt =conv(char)
  428.             bytes[i]=bt
  429.         end
  430.         local lines = {}
  431.         local txt={}
  432.         local n=1
  433.         for i=1, #bytes do
  434.             if n*(size+1)<=sep-1 and #txt+1+sep<w then
  435.                 txt[#txt+1]=bytes[i]
  436.                 n=n+1
  437.             else
  438.                 lines[#lines+1]=txt
  439.                 txt={bytes[i]}
  440.                 n=2
  441.             end
  442.         end
  443.         lines[#lines+1]=#txt>0 and txt or nil
  444.         return lines
  445.     end
  446.     local lines = calc(code)
  447.     local offset=1
  448.     local _bytepos = 3
  449.     local select = true
  450.     local multiselect = false
  451.     local sStart={line=1, byte=1}
  452.     local sEnd
  453.     local _byte = 1
  454.     local _line = 1
  455.     local internalX = 1
  456.     local ctrl=false
  457.     local shift=false
  458.     local alt=false
  459.     local altgr=false
  460.     local xPos, yPos, down=1,1,false
  461.     local aSep
  462.     local history={}
  463.     local clipboard=""
  464.     local hpos=1
  465.     local editmode = true
  466.     local cmd = ""
  467.     local poscmd=0
  468.     local tCompletions
  469.     local nCompletion
  470.     local tCompletionInfo = {}
  471.     local docs = {}
  472.     local modeinfo = false
  473.     local paged=false
  474.     local infodt = {}
  475.     local infooffset = 1
  476.     local wind = window.create(buff,3,3,sep-3,drawcount,false)
  477.     local function charPos(line, byte)
  478.         if lines[1] and line and byte then
  479.             return (line-1)*#lines[1]+byte
  480.         end
  481.     end
  482.     local function bytePos(charPos)
  483.         if lines[1] then
  484.             local _line=((charPos-1)-((charPos-1)%#lines[1]))/#lines[1]+1
  485.             local _byte=(charPos-1)%#lines[1]+1
  486.             return _line, _byte
  487.         end
  488.     end
  489.     function draw(lines,offset,movesep)
  490.         local ascii = true
  491.         if _HOST then
  492.             ascii=false
  493.         end
  494.         buff.setCursorBlink(false)
  495.         movesep = movesep or false
  496.         buff.setBackgroundColor(_colors.background)
  497.         buff.setTextColor(_colors.text)
  498.         buff.clear()
  499.         buff.setCursorPos(2,1)
  500.         buff.write(name..">")
  501.         for i=3,drawcount+2 do
  502.             buff.setCursorPos(3,i)
  503.             buff.write(table.concat(lines[offset+i-3] or {}," "))
  504.             buff.setCursorPos(sep+1,i)
  505.             buff.write(_type.char(unpack(lines[offset+i-3] or {})))
  506.         end
  507.         buff.setBackgroundColor(_colors.background)
  508.         buff.setTextColor(_colors.border)
  509.         for i=2,w do
  510.             buff.setCursorPos(i,drawcount+3)
  511.             buff.write(ascii and "-" or "\140")
  512.         end
  513.         buff.setBackgroundColor(_colors.background)
  514.         buff.setTextColor(_colors.border)
  515.         for i=2,w do
  516.             buff.setCursorPos(i,2)
  517.             buff.write(ascii and "-" or "\131")
  518.         end
  519.         buff.setBackgroundColor(_colors.background)
  520.         buff.setTextColor(_colors.border)
  521.         for i=2,drawcount+3 do
  522.             local char
  523.             if ascii then
  524.                 char="|"
  525.                 if i==2 or i==drawcount+3 then
  526.                     char="*"
  527.                 end
  528.             else
  529.                 char = "\149"
  530.                 if i==2 then
  531.                     char="\151"
  532.                 elseif i==drawcount+3 then
  533.                     char="\141"
  534.                 end
  535.             end
  536.             buff.setCursorPos(2,i)
  537.             buff.write(char)
  538.         end
  539.         for i=2,drawcount+3 do
  540.             local char
  541.             if movesep then
  542.                 buff.setBackgroundColor(_colors.background)
  543.                 buff.setTextColor(_colors.separateurselect)
  544.             else
  545.                 buff.setBackgroundColor(_colors.background)
  546.                 buff.setTextColor(_colors.border)
  547.             end
  548.             if ascii then
  549.                 char="|"
  550.                 if i==2 or i==drawcount+3 then
  551.                     char="*"
  552.                 end
  553.             else
  554.                 char = "\149"
  555.                 if i==2 then
  556.                     char="\151"
  557.                     buff.setBackgroundColor(_colors.background)
  558.                     buff.setTextColor(_colors.border)
  559.                 elseif i==drawcount+3 then
  560.                     char="\141"
  561.                     buff.setBackgroundColor(_colors.background)
  562.                     buff.setTextColor(_colors.border)
  563.                 end
  564.             end
  565.             buff.setCursorPos(sep,i)
  566.             buff.write(char)
  567.         end
  568.  
  569.         for i=2,drawcount+3 do
  570.             local char
  571.             if ascii then
  572.                 buff.setBackgroundColor(_colors.background)
  573.                 buff.setTextColor(_colors.border)
  574.                 char="|"
  575.                 if i==2 or i==drawcount+3 then
  576.                     char="*"
  577.                 end
  578.             else
  579.                 buff.setBackgroundColor(_colors.border)
  580.                 buff.setTextColor(_colors.background)
  581.                 char = "\149"
  582.                 if i==2 then
  583.                     char="\148"
  584.                 elseif i==drawcount+3 then
  585.                     char="\142"
  586.                     buff.setBackgroundColor(_colors.background)
  587.                     buff.setTextColor(_colors.border)
  588.                 end
  589.             end
  590.             buff.setCursorPos(w,i)
  591.             buff.write(char)
  592.         end
  593.         local aff="Ln:"..(_line or 0).."/"..#lines.." Col:"..(_byte or 0).." Byte:"..(charPos(_line,_byte) or 0).."/"..#code
  594.         buff.setCursorPos(w-#aff+1,drawcount+4)
  595.         buff.setTextColor(_colors.info)
  596.         buff.setBackgroundColor(_colors.background)
  597.         buff.write(aff)
  598.     end
  599.     local function mSelPos()
  600.         if sStart and sEnd then
  601.             local sStartLine, sEndLine, sStartByte, sEndByte
  602.             if sStart.line == sEnd.line then
  603.                 sStartLine=math.min(sStart.line,sEnd.line)
  604.                 sEndLine=math.max(sStart.line,sEnd.line)
  605.                 sStartByte=math.min(sStart.byte,sEnd.byte)
  606.                 sEndByte=math.max(sStart.byte,sEnd.byte)
  607.             else
  608.                 sStartLine=math.min(sStart.line,sEnd.line)
  609.                 sEndLine=math.max(sStart.line,sEnd.line)
  610.                 if sStartLine == sStart.line then
  611.                     sStartByte=sStart.byte
  612.                     sEndByte=sEnd.byte
  613.                 else
  614.                     sStartByte=sEnd.byte
  615.                     sEndByte=sStart.byte
  616.                 end
  617.             end
  618.             return sStartLine, sEndLine, sStartByte, sEndByte
  619.         end
  620.     end
  621.     local function clear()
  622.         if #code<1 then
  623.             draw(lines,offset)
  624.             return
  625.         end
  626.         buff.setCursorBlink(false)
  627.         if lines[_line] and lines[_line][_byte] then
  628.             if _line+2-offset+1 > 2 and _line+2-offset+1 < drawcount+3 then
  629.                 buff.setCursorPos(_bytepos,_line+2-offset+1)
  630.                 buff.setBackgroundColor(_colors.background)
  631.                 buff.setTextColor(_colors.text)
  632.                 buff.write(lines[_line][_byte])
  633.                 buff.setCursorPos(sep+_byte,_line+2-offset+1)
  634.                 buff.setBackgroundColor(_colors.background)
  635.                 buff.setTextColor(_colors.text)
  636.                 buff.write(_type.char(lines[_line][_byte]))
  637.             end
  638.         else
  639.             select = false
  640.         end
  641.         if multiselect then
  642.             buff.setBackgroundColor(_colors.background)
  643.             buff.setTextColor(_colors.text)
  644.             local sStartLine, sEndLine, sStartByte, sEndByte = mSelPos()
  645.             if sStartLine then
  646.                 if sStart.line == sEnd.line then
  647.                     for i=sStartByte, sEndByte do
  648.                         if lines[sStartLine] and lines[sStartLine][i] then
  649.                             if sStartLine+2-offset+1 > 2 and sStartLine+2-offset+1 < drawcount+3 then
  650.                                 local _bytepos = 3+(i-1)*size+i-1
  651.                                 buff.setCursorPos(_bytepos,sStartLine+2-offset+1)
  652.                                 buff.write(lines[sStartLine][i])
  653.                                 buff.setCursorPos(sep+i,sStartLine+2-offset+1)
  654.                                 buff.write(_type.char(lines[sStartLine][i]))
  655.                             end
  656.                         end
  657.                     end
  658.                 else
  659.                     if lines[sStartLine] then
  660.                         for i=sStartByte, #lines[sStartLine] do
  661.                             if lines[sStartLine] and lines[sStartLine][i] then
  662.                                 if sStartLine+2-offset+1 > 2 and sStartLine+2-offset+1 < drawcount+3 then
  663.                                     local _bytepos = 3+(i-1)*size+i-1
  664.                                     buff.setCursorPos(_bytepos,sStartLine+2-offset+1)
  665.                                     buff.write(lines[sStartLine][i])
  666.                                     buff.setCursorPos(sep+i,sStartLine+2-offset+1)
  667.                                     buff.write(_type.char(lines[sStartLine][i]))
  668.                                 end
  669.                             end
  670.                         end
  671.                     end
  672.                    
  673.                     for j=sStartLine+1, sEndLine-1 do
  674.                         if lines[j] then
  675.                             for i=1, #lines[j] do
  676.                                 if j-offset+3 > 2 and j-offset+3 < drawcount+3 then
  677.                                     local _bytepos = 3+(i-1)*size+i-1
  678.                                     buff.setCursorPos(_bytepos,j-offset+3)
  679.                                     buff.write(lines[j][i])
  680.                                     buff.setCursorPos(sep+i,j-offset+3)
  681.                                     buff.write(_type.char(lines[j][i]))
  682.                                 end
  683.                             end
  684.                         end
  685.                     end
  686.                    
  687.                     for i=1, sEndByte do
  688.                         if lines[sEndLine] and lines[sEndLine][i] then
  689.                             if sEndLine+2-offset+1 > 2 and sEndLine+2-offset+1 < drawcount+3 then
  690.                                 local _bytepos = 3+(i-1)*size+i-1
  691.                                 buff.setCursorPos(_bytepos,sEndLine+2-offset+1)
  692.                                 buff.write(lines[sEndLine][i])
  693.                                 buff.setCursorPos(sep+i,sEndLine+2-offset+1)
  694.                                 buff.write(_type.char(lines[sEndLine][i]))
  695.                             end
  696.                         end
  697.                     end
  698.                 end
  699.             end
  700.         end
  701.         local aff="Ln:"..(_line or 0).."/"..#lines.." Col:"..(_byte or 0).." Byte:"..(charPos(_line,_byte) or 0).."/"..#code
  702.         buff.setCursorPos(w-#aff+1,drawcount+4)
  703.         buff.setTextColor(_colors.info)
  704.         buff.setBackgroundColor(_colors.background)
  705.         buff.clearLine()
  706.         buff.setCursorPos(w-#aff+1,drawcount+4)
  707.         buff.write(aff)
  708.         buff.setTextColor(_colors.text)
  709.         buff.setBackgroundColor(_colors.background)
  710.         if _line+3-offset > 2 and _line+3-offset < drawcount+3 then
  711.             if lines[_line] and lines[_line][_byte] then
  712.                 buff.setCursorPos(_bytepos+internalX-1,_line+3-offset)
  713.                 buff.setCursorBlink(select)
  714.             end
  715.         end
  716.         if #code<1 then
  717.             select=false
  718.             buff.setCursorBlink(false)
  719.         end
  720.     end
  721.     local function update()
  722.         buff.setCursorBlink(false)
  723.         if lines[_line] and lines[_line][_byte] then
  724.             if _line+2-offset+1 > 2 and _line+2-offset+1 < drawcount+3 then
  725.                 buff.setCursorPos(_bytepos,_line+2-offset+1)
  726.                 buff.setBackgroundColor(_colors.select)
  727.                 buff.setTextColor(_colors.text)
  728.                 buff.write(lines[_line][_byte])
  729.                 buff.setCursorPos(sep+_byte,_line+2-offset+1)
  730.                 buff.setBackgroundColor(_colors.select)
  731.                 buff.setTextColor(_colors.text)
  732.                 buff.write(_type.char(lines[_line][_byte]))
  733.                 select=true
  734.             end
  735.         else
  736.             select = false
  737.         end
  738.         if multiselect then
  739.             buff.setBackgroundColor(_colors.multiselect)
  740.             buff.setTextColor(_colors.text)
  741.             local sStartLine, sEndLine, sStartByte, sEndByte = mSelPos()
  742.             if sStartLine then
  743.                 if sStart.line == sEnd.line then
  744.                     for i=sStartByte, sEndByte do
  745.                         if lines[sStartLine] and lines[sStartLine][i] then
  746.                             if sStartLine+2-offset+1 > 2 and sStartLine+2-offset+1 < drawcount+3 then
  747.                                 local _bytepos = 3+(i-1)*size+i-1
  748.                                 buff.setCursorPos(_bytepos,sStartLine+2-offset+1)
  749.                                 buff.write(lines[sStartLine][i])
  750.                                 buff.setCursorPos(sep+i,sStartLine+2-offset+1)
  751.                                 buff.write(_type.char(lines[sStartLine][i]))
  752.                             end
  753.                         end
  754.                     end
  755.                 else
  756.                     if lines[sStartLine] then
  757.                         for i=sStartByte, #lines[sStartLine] do
  758.                             if lines[sStartLine] and lines[sStartLine][i] then
  759.                                 if sStartLine-offset+3 > 2 and sStartLine-offset+3 < drawcount+3 then
  760.                                     local _bytepos = 3+(i-1)*size+i-1
  761.                                     buff.setCursorPos(_bytepos,sStartLine-offset+3)
  762.                                     buff.write(lines[sStartLine][i])
  763.                                     buff.setCursorPos(sep+i,sStartLine-offset+3)
  764.                                     buff.write(_type.char(lines[sStartLine][i]))
  765.                                 end
  766.                             end
  767.                         end
  768.                     end
  769.                     for j=sStartLine+1, sEndLine-1 do
  770.                         if lines[j] then
  771.                             for i=1, #lines[j] do
  772.                                 if j-offset+3 > 2 and j-offset+3 < drawcount+3 then
  773.                                     local _bytepos = 3+(i-1)*size+i-1
  774.                                     buff.setCursorPos(_bytepos,j-offset+3)
  775.                                     buff.write(lines[j][i])
  776.                                     buff.setCursorPos(sep+i,j-offset+3)
  777.                                     buff.write(_type.char(lines[j][i]))
  778.                                 end
  779.                             end
  780.                         end
  781.                     end
  782.                     for i=1, sEndByte do
  783.                         if lines[sEndLine] and lines[sEndLine][i] then
  784.                             if sEndLine-offset+3 > 2 and sEndLine-offset+3 < drawcount+3 then
  785.                                 local _bytepos = 3+(i-1)*size+i-1
  786.                                 buff.setCursorPos(_bytepos,sEndLine-offset+3)
  787.                                 buff.write(lines[sEndLine][i])
  788.                                 buff.setCursorPos(sep+i,sEndLine-offset+3)
  789.                                 buff.write(_type.char(lines[sEndLine][i]))
  790.                             end
  791.                         end
  792.                     end
  793.                 end
  794.             end
  795.         end
  796.         local aff="Ln:"..(_line or 0).."/"..#lines.." Col:"..(_byte or 0).." Byte:"..(charPos(_line,_byte) or 0).."/"..#code
  797.         buff.setCursorPos(w-#aff+1,drawcount+4)
  798.         buff.setTextColor(_colors.info)
  799.         buff.setBackgroundColor(_colors.background)
  800.         buff.clearLine()
  801.         buff.setCursorPos(w-#aff+1,drawcount+4)
  802.         buff.write(aff)
  803.         buff.setTextColor(_colors.text)
  804.         buff.setBackgroundColor(_colors.background)
  805.         if _line+3-offset > 2 and _line+3-offset < drawcount+3 then
  806.             if lines[_line] and lines[_line][_byte] then
  807.                 buff.setCursorPos(_bytepos+internalX-1,_line+3-offset)
  808.                 buff.setCursorBlink(select)
  809.             end
  810.         end
  811.         if #code<1 then
  812.             select=false
  813.             buff.setCursorBlink(false)
  814.         end
  815.     end
  816.     local function skipLeft()
  817.         if lines[_line] then
  818.             local min,max=1,#lines[_line]
  819.             if _byte-1 >= 1 then
  820.                 internalX=size
  821.                 clear()
  822.                 multiselect=false
  823.                 _byte=_byte-1
  824.                 _bytepos = 3+(_byte-1)*size+_byte-1
  825.                 update()
  826.             else
  827.                 if _line-offset>=1 then
  828.                     if _line-1 >= 1 then
  829.                         clear()
  830.                         multiselect=false
  831.                         _byte=max
  832.                         _line=_line-1
  833.                         _bytepos = 3+(_byte-1)*size+_byte-1
  834.                         update()
  835.                     end
  836.                 else
  837.                     if offset > 1 then
  838.                         if _line-1 >= 1 then
  839.                             clear()
  840.                             multiselect=false
  841.                             offset=offset-1
  842.                             _line=_line-1
  843.                             _byte=max
  844.                             _bytepos = 3+(_byte-1)*size+_byte-1
  845.                             internalX=size
  846.                             draw(lines,offset)
  847.                             update()
  848.                         end
  849.                     end
  850.                 end
  851.             end
  852.             sStart = {line=_line, byte=_byte}
  853.             sEnd=nil
  854.         end
  855.         clear()
  856.         draw(lines,offset)
  857.         update()
  858.     end
  859.     local function skipRight()
  860.         if lines[_line] then
  861.             local min,max=1,#lines[_line]
  862.             if _byte+1 <= max then
  863.                 internalX=1
  864.                 clear()
  865.                 multiselect=false
  866.                 _byte=_byte+1
  867.                 _bytepos = 3+(_byte-1)*size+_byte-1
  868.                 update()
  869.             else
  870.                 if _line+2-offset<=drawcount then
  871.                     if _line+1 < #lines then
  872.                         clear()
  873.                         multiselect=false
  874.                         _byte=1
  875.                         _line=_line+1
  876.                         _bytepos = 3+(_byte-1)*size+_byte-1
  877.                         update()
  878.                     end
  879.                 else
  880.                     if offset+drawcount <= #lines then
  881.                         if _line+1 < #lines then
  882.                             clear()
  883.                             multiselect=false
  884.                             offset=offset+1
  885.                             _line=_line+1
  886.                             _byte=1
  887.                             _bytepos = 3+(_byte-1)*size+_byte-1
  888.                             internalX=1
  889.                             draw(lines,offset)
  890.                             update()
  891.                         end
  892.                     end
  893.                 end
  894.             end
  895.             sStart = {line=_line, byte=_byte}
  896.             sEnd=nil
  897.         end
  898.         clear()
  899.         draw(lines,offset)
  900.         update()
  901.     end
  902.     local function cursorLeft()
  903.         if internalX-1>=1 then
  904.             clear()
  905.             multiselect=false
  906.             internalX=internalX-1
  907.             update()
  908.         else
  909.             skipLeft()
  910.         end
  911.         clear()
  912.         update()
  913.         sStart = {line=_line, byte=_byte}
  914.         sEnd=nil
  915.     end
  916.     local function cursorRight()
  917.         local min,max=1,(lines and lines[_line] and #lines[_line]) or 0
  918.         if internalX+1 <= size then
  919.             clear()
  920.             multiselect=false
  921.             internalX=internalX+1
  922.             update()
  923.         else
  924.             skipRight()
  925.         end
  926.         clear()
  927.         update()
  928.         sStart = {line=_line, byte=_byte}
  929.         sEnd=nil
  930.     end
  931.     local function dispInfo(txt)
  932.         buff.setBackgroundColor(_colors.background)
  933.         buff.setTextColor(_colors.actioninfo)
  934.         local aff="Ln:"..(_line or 0).." Col:"..(_byte or 0).." Byte:"..(charPos(_line,_byte) or 0)
  935.         buff.setCursorPos(w-#aff,drawcount+4)
  936.         buff.setTextColor(_colors.info)
  937.         buff.setBackgroundColor(_colors.background)
  938.         buff.clearLine()
  939.         buff.setCursorPos(w-#aff,drawcount+4)
  940.         buff.write(aff)
  941.         buff.setCursorPos(2,drawcount+4)
  942.         buff.setTextColor(_colors.actioninfo)
  943.         buff.setBackgroundColor(_colors.background)
  944.         buff.write(txt)
  945.         buff.setTextColor(_colors.text)
  946.         buff.setBackgroundColor(_colors.background)
  947.         if editmode then
  948.             buff.setCursorPos(_bytepos+internalX-1,_line+3-offset)
  949.         else
  950.             local s=name.."> "
  951.             local sx = 2+#s
  952.             local nScroll = 0
  953.             if sx + poscmd >= w then
  954.                 nScroll = (sx + poscmd) - w
  955.             end
  956.             buff.setCursorPos( sx + poscmd - nScroll, 1 )
  957.         end
  958.         buff.setCursorBlink(true)
  959.     end
  960.     local function copy(tb)
  961.         local t={}
  962.         for k, v in pairs(tb) do
  963.             t[k]=v
  964.         end
  965.         return t
  966.     end
  967.     local function updatecmd(_bClear)
  968.         buff.setTextColor(_colors.text)
  969.         buff.setBackgroundColor(_colors.background)
  970.         buff.setCursorBlink(true)
  971.         buff.setCursorPos(2,1)
  972.         buff.clearLine()
  973.         local s=name.."> "
  974.         local nScroll = 0
  975.         local sx = 2+#s
  976.         local size = w-sx
  977.         if sx + poscmd >= w then
  978.             nScroll = (sx + poscmd) - w
  979.         end
  980.         buff.write(s..string.sub( cmd, nScroll + 1, nScroll+1+size))
  981.         if nCompletion then
  982.             local sCompletion = tCompletions[ nCompletion ]
  983.             local oldText, oldBg
  984.             if not _bClear then
  985.                 oldText = buff.getTextColor()
  986.                 oldBg = buff.getBackgroundColor()
  987.                 buff.setTextColor( _colors.text )
  988.                 buff.setBackgroundColor( _colors.highlight )
  989.             end
  990.             buff.write( sCompletion )
  991.             if not _bClear then
  992.                 buff.setTextColor( oldText )
  993.                 buff.setBackgroundColor( oldBg )
  994.             end
  995.         end
  996.         buff.setCursorPos( sx + poscmd - nScroll, 1 )
  997.         buff.setCursorBlink(true)
  998.     end
  999.     local function completeMultipleChoice( sText, tOptions, bAddSpaces )
  1000.         local tResults = {}
  1001.         for n=1,#tOptions do
  1002.             local sOption = tOptions[n]
  1003.             if #sOption + (bAddSpaces and 1 or 0) > #sText and string.sub( sOption, 1, #sText ) == sText then
  1004.                 local sResult = string.sub( sOption, #sText + 1 )
  1005.                 if bAddSpaces then
  1006.                     table.insert( tResults, sResult .. " " )
  1007.                 else
  1008.                     table.insert( tResults, sResult )
  1009.                 end
  1010.             end
  1011.         end
  1012.         return tResults
  1013.     end
  1014.     local function tokenise( ... )
  1015.         local sLine = table.concat( { ... }, " " )
  1016.         local tWords = {}
  1017.         local bQuoted = false
  1018.         for match in string.gmatch( sLine .. "\"", "(.-)\"" ) do
  1019.             if bQuoted then
  1020.                 table.insert( tWords, match )
  1021.             else
  1022.                 for m in string.gmatch( match, "[^ \t]+" ) do
  1023.                     table.insert( tWords, m )
  1024.                 end
  1025.             end
  1026.             bQuoted = not bQuoted
  1027.         end
  1028.         return tWords
  1029.     end
  1030.     local function completeCommand(sLine)
  1031.         local t = {}
  1032.         for k, v in pairs(tCompletionInfo) do
  1033.             if #k>#sLine and k:sub(1,#sLine) == sLine then
  1034.                 t[#t+1]=k:sub(#sLine+1, #k)
  1035.             end
  1036.         end
  1037.         table.sort(t)
  1038.         return t
  1039.     end
  1040.     local function completeProgramArgument( sProgram, nArgument, sPart, tPreviousParts )
  1041.         local tInfo = tCompletionInfo[ sProgram ]
  1042.         if tInfo then
  1043.             return tInfo.fnComplete( shell, nArgument, sPart, tPreviousParts )
  1044.         end
  1045.         return nil
  1046.     end
  1047.     local function complete( sLine )
  1048.         if #sLine > 0 then
  1049.             local tWords = tokenise( sLine )
  1050.             local nIndex = #tWords
  1051.             if string.sub( sLine, #sLine, #sLine ) == " " then
  1052.                 nIndex = nIndex + 1
  1053.             end
  1054.             if nIndex == 1 then
  1055.                 local sBit = tWords[1] or ""
  1056.                 local sPath = sBit
  1057.                 if tCompletionInfo[ sPath ] then
  1058.                     return { " " }
  1059.                 else
  1060.                     local tResults = completeCommand(sBit)
  1061.                     for n=1,#tResults do
  1062.                         local sResult = tResults[n]
  1063.                         local sPath = sBit .. sResult
  1064.                         if tCompletionInfo[ sPath ] then
  1065.                             tResults[n] = sResult .. " "
  1066.                         end
  1067.                     end
  1068.                     return tResults
  1069.                 end
  1070.  
  1071.             elseif nIndex > 1 then
  1072.                 local sPath = tWords[1]
  1073.                 local sPart = tWords[nIndex] or ""
  1074.                 local tPreviousParts = tWords
  1075.                 tPreviousParts[nIndex] = nil
  1076.                 return completeProgramArgument( sPath , nIndex - 1, sPart, tPreviousParts )
  1077.             end
  1078.         end
  1079.         return nil
  1080.     end
  1081.     local function addCommand( cmd, args, bAddSpaces)
  1082.         tCompletionInfo[ cmd ] = {
  1083.         fnComplete = function( shell, nIndex, sText, tPreviousText ) return completeMultipleChoice( sText, args[nIndex] or {}, bAddSpaces) end
  1084.     }
  1085.     end
  1086.     local function recomplete()
  1087.         if complete and poscmd == string.len(cmd) then
  1088.             tCompletions = complete( cmd )
  1089.             if tCompletions and #tCompletions > 0 then
  1090.                 nCompletion = 1
  1091.             else
  1092.                 nCompletion = nil
  1093.             end
  1094.         else
  1095.             tCompletions = nil
  1096.             nCompletion = nil
  1097.         end
  1098.     end
  1099.     local function uncomplete()
  1100.         tCompletions = nil
  1101.         nCompletion = nil
  1102.     end
  1103.     local function acceptCompletion()
  1104.         if nCompletion then
  1105.             updatecmd( true )
  1106.             local sCompletion = tCompletions[ nCompletion ]
  1107.             local sFirstLetter = string.sub( sCompletion, 1, 1 )
  1108.             local sCommonPrefix = sCompletion
  1109.             for n=1,#tCompletions do
  1110.                 local sResult = tCompletions[n]
  1111.                 if n ~= nCompletion and string.find( sResult, sFirstLetter, 1, true ) == 1 then
  1112.                     while #sCommonPrefix > 1 do
  1113.                         if string.find( sResult, sCommonPrefix, 1, true ) == 1 then
  1114.                             break
  1115.                         else
  1116.                             sCommonPrefix = string.sub( sCommonPrefix, 1, #sCommonPrefix - 1 )
  1117.                         end
  1118.                     end
  1119.                 end
  1120.             end
  1121.             cmd = cmd .. sCommonPrefix
  1122.             poscmd = string.len( cmd )
  1123.         end
  1124.  
  1125.         recomplete()
  1126.         updatecmd()
  1127.     end
  1128.     local function writemode()
  1129.         select=false
  1130.         update()
  1131.         poscmd=#cmd
  1132.         recomplete()
  1133.         updatecmd()
  1134.         editmode = false
  1135.     end
  1136.     local function termwrite( sText , term)
  1137.         local w,h = term.getSize()        
  1138.         local x,y = term.getCursorPos()
  1139.        
  1140.         local nLinesPrinted = 0
  1141.         local function newLine()
  1142.             if y + 1 <= h then
  1143.                 term.setCursorPos(1, y + 1)
  1144.             else
  1145.                 term.setCursorPos(1, h)
  1146.                 term.scroll(1)
  1147.             end
  1148.             x, y = term.getCursorPos()
  1149.             nLinesPrinted = nLinesPrinted + 1
  1150.         end
  1151.        
  1152.        
  1153.         while string.len(sText) > 0 do
  1154.             local whitespace = string.match( sText, "^[ \t]+" )
  1155.             if whitespace then
  1156.        
  1157.                 term.write( whitespace )
  1158.                 x,y = term.getCursorPos()
  1159.                 sText = string.sub( sText, string.len(whitespace) + 1 )
  1160.             end
  1161.            
  1162.             local newline = string.match( sText, "^\n" )
  1163.             if newline then
  1164.            
  1165.                 newLine()
  1166.                 sText = string.sub( sText, 2 )
  1167.             end
  1168.            
  1169.             local text = string.match( sText, "^[^ \t\n]+" )
  1170.             if text then
  1171.                 sText = string.sub( sText, string.len(text) + 1 )
  1172.                 if string.len(text) > w then
  1173.            
  1174.                     while string.len( text ) > 0 do
  1175.                         if x > w then
  1176.                             newLine()
  1177.                         end
  1178.                         term.write( text )
  1179.                         text = string.sub( text, (w-x) + 2 )
  1180.                         x,y = term.getCursorPos()
  1181.                     end
  1182.                 else
  1183.  
  1184.                     if x + string.len(text) - 1 > w then
  1185.                         newLine()
  1186.                     end
  1187.                     term.write( text )
  1188.                     x,y = term.getCursorPos()
  1189.                 end
  1190.             end
  1191.         end
  1192.        
  1193.         return nLinesPrinted
  1194.     end
  1195.  
  1196.     local function termprint(term, ... )
  1197.         local nLinesPrinted = 0
  1198.         for n,v in ipairs( { ... } ) do
  1199.             nLinesPrinted = nLinesPrinted + termwrite( tostring( v ) , term)
  1200.         end
  1201.         nLinesPrinted = nLinesPrinted + termwrite( "\n", term)
  1202.         return nLinesPrinted
  1203.     end
  1204.    
  1205.     function updateInfo()
  1206.         wind.setVisible(true)
  1207.         wind.setBackgroundColor(_colors.background)
  1208.         wind.setTextColor(_colors.text)
  1209.         wind.clear()
  1210.         wind.setCursorPos(1,1)
  1211.         local n=1
  1212.         for k, v in pairs(infodt) do
  1213.             if n>infooffset+drawcount-2 then
  1214.                 break
  1215.             end
  1216.             if n>=infooffset then
  1217.                 termprint(wind,"- "..k.." : "..v)
  1218.             end
  1219.             n=n+1
  1220.         end
  1221.         modeinfo=true
  1222.         if not editmode then
  1223.             updatecmd()
  1224.         end
  1225.     end
  1226.    
  1227.     -- Command Completion
  1228.     addCommand("insert",{{"byte","char"}})
  1229.     addCommand("save",{{}})
  1230.     addCommand("exit",{{}})
  1231.     addCommand("deleteAll",{{}})
  1232.     addCommand("clearHistory",{{}})
  1233.     addCommand("redraw",{{}})
  1234.     addCommand("gotoLn",{{}})
  1235.     tCompletionInfo[ "help" ] = { fnComplete = function( shell, nIndex, sText, tPreviousText ) local cmd={} for k, v in pairs(tCompletionInfo) do cmd[#cmd+1]=k end local args={cmd} return completeMultipleChoice( sText, args[nIndex] or {}, false) end }
  1236.     addCommand("bindlist",{{}})
  1237.     addCommand("editmode",{{}})
  1238.     addCommand("setClipboard",{{}})
  1239.     addCommand("undo",{{}})
  1240.     addCommand("redo",{{}})
  1241.     addCommand("find",{{"byte","char"}},true)
  1242.     local modes={}
  1243.     for k, v in pairs(mode) do
  1244.         modes[#modes+1]=k
  1245.     end
  1246.     addCommand("mode",{modes})
  1247.     local langs={}
  1248.     for k, v in pairs(lang) do
  1249.         langs[#langs+1]=k
  1250.     end
  1251.     addCommand("lang",{langs})
  1252.     local keycolor = {}
  1253.     for k, v in pairs(_colors) do
  1254.         keycolor[#keycolor+1]=k
  1255.     end
  1256.     if term.isColor() then
  1257.         addCommand("color",{keycolor,{"white","red","green","blue","lime","gray","lightGray","grey","lightGrey","black","purple","brown","cyan","lightBlue","magenta","orange","yellow","pink"}},true)
  1258.     else
  1259.         addCommand("color",{keycolor,{"white","gray","lightGray","grey","lightGrey","black"}},true)
  1260.     end
  1261.     -- Draw
  1262.     draw(lines,offset)
  1263.     writemode()
  1264.     while true do
  1265.         buff.setVisible(true)
  1266.         buff.setVisible(false)
  1267.         local event, p1,p2,p3,p4,p5 = os.pullEvent()
  1268.         if modeinfo then
  1269.             if event == "mouse_drag" or event=="mouse_click" or event=="mouse_up" then
  1270.                 draw(lines,offset)
  1271.                 update()
  1272.                 if not editmode then
  1273.                     updatecmd()
  1274.                 end
  1275.                 modeinfo=false
  1276.                 event = ""
  1277.             end
  1278.         end
  1279.         if event=="mouse_click" then
  1280.             local x, y = p2,p3
  1281.             if x>2 and x<sep and y>2 and y<drawcount+3 then
  1282.                 editmode = true
  1283.                 clear()
  1284.                 multiselect=false
  1285.                 local a,b,c = _byte, _line, _bytepos
  1286.  
  1287.                 local _x = x-3
  1288.                 _byte=(_x-(_x%(size+1)))/(size+1)+1
  1289.                 _line = y-2+offset-1
  1290.                 _bytepos = 3+(_byte-1)*size+_byte-1
  1291.  
  1292.                 if lines[_line] and lines[_line][_byte] and x>=_bytepos and x<= _bytepos+size-1 then
  1293.                     internalX = x-_bytepos+1
  1294.                     update()
  1295.                 else
  1296.                     internalX=1
  1297.                     select = true
  1298.                     update()
  1299.                 end
  1300.                 xPos,yPos,down=x,y,true
  1301.                 sStart = {line=_line, byte=_byte}
  1302.                 sEnd=nil
  1303.             elseif x>sep and x<w and y>2 and y<drawcount+3 then
  1304.                 editmode = true
  1305.                 local line = y-2+offset-1
  1306.                 local byte = x-sep
  1307.                 if lines[line] and lines[line][byte] then
  1308.                     clear()
  1309.                     multiselect=false
  1310.                     _line=y-2+offset-1
  1311.                     local _x=x-sep
  1312.                     _byte = _x
  1313.                     _bytepos = 3+(_byte-1)*size+_byte-1
  1314.                     internalX = 1
  1315.                     update()
  1316.                     xPos,yPos,down=x,y,true
  1317.                     sStart = {line=_line, byte=_byte}
  1318.                     sEnd=nil
  1319.                 else
  1320.                     writemode()
  1321.                 end
  1322.             else
  1323.                 local s=name.."> "
  1324.                 local t=s..cmd
  1325.                 if editmode then
  1326.                     writemode()
  1327.                 end
  1328.             end
  1329.         elseif event == "mouse_up" then
  1330.             down=false
  1331.             if xPos==aSep and yPos>=2 and yPos<=drawcount+3 then
  1332.                 draw(lines,offset)
  1333.                 update()
  1334.             end
  1335.         elseif event=="mouse_drag" then
  1336.             if down==true and xPos<sep and yPos>2 and yPos<drawcount+3 then -- Bytes
  1337.                 editmode = true
  1338.                 local x, y = p2, p3
  1339.                 if x>2 and x<sep and y>2 and y<drawcount+3 then
  1340.                     local a,b,c = _byte, _line, _bytepos
  1341.                     multiselect=true
  1342.                     clear()
  1343.                     _line=y-2+offset-1
  1344.                     local _x = x-3
  1345.                     _byte=(_x-(_x%(size+1)))/(size+1)+1
  1346.                     _bytepos = 3+(_byte-1)*size+_byte-1
  1347.                    
  1348.                     if lines[_line] and lines[_line][_byte] and x>=_bytepos and x<= _bytepos+size-1 then
  1349.                         internalX = x-_bytepos+1
  1350.                         sEnd = {byte=_byte, line=_line}
  1351.                     else
  1352.                         _byte=a
  1353.                         _line=b
  1354.                         _bytepos=c
  1355.                     end
  1356.                     update()
  1357.                 end
  1358.             elseif down==true and xPos>sep and xPos<w and yPos>2 and yPos<drawcount+3 then -- Chars
  1359.                 editmode = true
  1360.                 local x, y = p2, p3
  1361.                 if x>sep and x<w and y>2 and y<drawcount+3 then
  1362.                     local a,b,c = _byte, _line, _bytepos
  1363.                     clear()
  1364.                     multiselect=true
  1365.                     _line=y-2+offset-1
  1366.                     local _x=x-sep
  1367.                     _byte = _x
  1368.                     _bytepos = 3+(_byte-1)*size+_byte-1
  1369.                     internalX=1
  1370.                     if lines[_line] and lines[_line][_byte] then
  1371.                         sEnd = {byte=_byte, line=_line}
  1372.                     else
  1373.                         _byte=a
  1374.                         _line=b
  1375.                         _bytepos=c
  1376.                     end
  1377.                     update()
  1378.                 end
  1379.             end
  1380.         elseif event == "paste" then
  1381.             if editmode then
  1382.                     if #clipboard>0 then
  1383.                     local olines={}
  1384.                     for k, v in pairs(lines) do
  1385.                         olines[k]=copy(v)
  1386.                     end
  1387.                     local pos=(_line-1)*#lines[1]+_byte
  1388.                     if multiselect then
  1389.                         local sStartLine, sEndLine, sStartByte, sEndByte = mSelPos()
  1390.                         local startPos = (sStartLine-1)*#lines[1]+sStartByte
  1391.                         local endPos = (sEndLine-1)*#lines[1]+sEndByte
  1392.                         code=code:sub(1,startPos-1)..clipboard..code:sub(endPos+1)
  1393.                         _line=((startPos+#clipboard-1)-((startPos+#clipboard-1)%#lines[1]))/#lines[1]+1
  1394.                         _byte=(startPos+#clipboard-1)%#lines[1]+1
  1395.                     else
  1396.                         code=code:sub(1,pos-1)..clipboard..code:sub(pos+#clipboard)
  1397.                         _line=((pos+#clipboard-1)-((pos+#clipboard-1)%#lines[1]))/#lines[1]+1
  1398.                         _byte=(pos+#clipboard-1)%#lines[1]+1
  1399.                     end
  1400.                     _bytepos = 3+(_byte-1)*size+_byte-1
  1401.                     internalX=1
  1402.                     lines=calc(code)
  1403.                     local nlines = {}
  1404.                     for k, v in pairs(lines) do
  1405.                         nlines[k]=copy(v)
  1406.                     end
  1407.                     history[hpos]={type="byte",info={oldlines=olines, newlines=nlines, line=_line, byte=_byte, bytepos=_bytepos, internalX=internalX,offset=offset, drawcount=drawcount}}
  1408.                     hpos=hpos+1
  1409.                     multiselect=false
  1410.                     draw(lines,offset)
  1411.                     update()
  1412.                     sStart={line=_line,byte=_byte}
  1413.                     sEnd=nil
  1414.                     dispInfo(language.paste)
  1415.                 end
  1416.             else
  1417.                 cmd=cmd:sub(1,poscmd)..p1..cmd:sub(poscmd+1)
  1418.                 poscmd=poscmd+#p1
  1419.                 recomplete()
  1420.                 updatecmd()
  1421.                 dispInfo(language.paste)
  1422.             end
  1423.         elseif event == "mouse_scroll" then
  1424.             if modeinfo then
  1425.                 if not paged then
  1426.                     if p1==1 then
  1427.                         local c = 0
  1428.                         for k, v in pairs(infodt) do
  1429.                             c=c+1
  1430.                         end
  1431.                         if infooffset+drawcount-1<=c then
  1432.                             infooffset=infooffset+1
  1433.                             updateInfo()
  1434.                         end
  1435.                     elseif p1==-1 then
  1436.                         if infooffset-1>=1 then
  1437.                             infooffset=infooffset-1
  1438.                             updateInfo()
  1439.                         end
  1440.                     end
  1441.                 end
  1442.             else
  1443.                 if p1==1 then
  1444.                     if offset+drawcount <= #lines then
  1445.                         clear()
  1446.                         offset=offset+1
  1447.                         draw(lines,offset)
  1448.                         update()
  1449.                         if not editmode then
  1450.                             updatecmd()
  1451.                         end
  1452.                     end
  1453.                 elseif p1==-1 then
  1454.                     if offset-1 >= 1 then
  1455.                         clear()
  1456.                         offset=offset-1
  1457.                         draw(lines,offset)
  1458.                         update()
  1459.                         if not editmode then
  1460.                             updatecmd()
  1461.                         end
  1462.                     end
  1463.                 end
  1464.             end
  1465.         elseif event=="key_up" then
  1466.             if p1==29 then -- Ctrl
  1467.                 ctrl=false
  1468.             elseif p1==42 then -- Shift
  1469.                 shift=false
  1470.             elseif p1==56 then -- Alt
  1471.                 alt=false
  1472.             elseif p1==184 then  -- AltGr
  1473.                 altgr=false
  1474.             end
  1475.         elseif event=="key" then
  1476.             if p1==29 then -- Ctrl
  1477.                 ctrl=true
  1478.             elseif p1==42 then -- Shift
  1479.                 shift=true
  1480.             elseif p1==56 then -- Alt
  1481.                 alt=true
  1482.                 if editmode then
  1483.                     writemode()
  1484.                 else
  1485.                     editmode=true
  1486.                     update()
  1487.                 end
  1488.             elseif p1==184 then -- AltGr
  1489.                 altgr=true
  1490.             end
  1491.             if editmode then
  1492.                 if #code>0 then
  1493.                     if p1==211 then -- Delete
  1494.                         if ctrl then
  1495.                             local olines={}
  1496.                             for k, v in pairs(lines) do
  1497.                                 olines[k]=copy(v)
  1498.                             end
  1499.                             if multiselect then
  1500.                                 local sStartLine, sEndLine, sStartByte, sEndByte = mSelPos()
  1501.                                 local startPos = charPos(sStartLine, sStartByte)
  1502.                                 local endPos = charPos(sEndLine, sEndByte)
  1503.                                 code=code:sub(1,startPos-1)..code:sub(endPos+1)
  1504.                                 local olines={}
  1505.                                 for k, v in pairs(lines) do
  1506.                                     olines[k]=copy(v)
  1507.                                 end
  1508.                                 local nlines = calc(code)
  1509.                                 history[hpos]={type="byte",info={oldlines=olines, newlines=nlines, line=sStartLine, byte=sStartByte, bytepos=3+(sStartByte-1)*size+sStartByte-1, internalX=internalX,offset=offset, drawcount=drawcount}}
  1510.                                 hpos=hpos+1
  1511.                                 lines=nlines
  1512.                                 _byte=sStartByte
  1513.                                 _line=sStartLine
  1514.                                 _bytepos = 3+(_byte-1)*size+_byte-1
  1515.                             else
  1516.                                 if lines and lines[_line] then
  1517.                                     table.remove(lines[_line],_byte)
  1518.                                     local code=""
  1519.                                     for i=1, #lines do
  1520.                                         for j=1, #lines[i] do
  1521.                                             code=code.._type.char(lines[i][j])
  1522.                                         end
  1523.                                     end
  1524.                                     lines=calc(code)
  1525.                                     local nlines = {}
  1526.                                     for k, v in pairs(lines) do
  1527.                                         nlines[k]=copy(v)
  1528.                                     end
  1529.                                     history[hpos]={type="byte",info={oldlines=olines, newlines=nlines, line=_line, byte=_byte, bytepos=_bytepos, internalX=internalX,offset=offset, drawcount=drawcount}}
  1530.                                     hpos=hpos+1
  1531.                                 end
  1532.                             end
  1533.                             if offset+drawcount-1>#lines then
  1534.                                 offset=#lines-drawcount+1
  1535.                             end
  1536.                             if offset<1 then
  1537.                                 offset=1
  1538.                             end
  1539.                             skipLeft()
  1540.                             local msel = multiselect
  1541.                             multiselect=false
  1542.                             draw(lines,offset)
  1543.                             update()
  1544.                             if #code<1 then
  1545.                                 writemode()
  1546.                             end
  1547.                             if msel then
  1548.                                 dispInfo(language.deletesel)
  1549.                             else
  1550.                                 dispInfo(language.deletebyte)
  1551.                             end
  1552.                         else
  1553.                             local bt = lines and lines[_line] and lines[_line][_byte]
  1554.                             if bt then
  1555.                                 if multiselect then
  1556.                                     local sStartLine, sEndLine, sStartByte, sEndByte = mSelPos()
  1557.                                     local startPos = charPos(sStartLine, sStartByte)
  1558.                                     local endPos = charPos(sEndLine, sEndByte)
  1559.                                     code=code:sub(1,startPos-1)..string.rep("\0",endPos-startPos+1)..code:sub(endPos+1)
  1560.                                     local olines={}
  1561.                                     for k, v in pairs(lines) do
  1562.                                         olines[k]=copy(v)
  1563.                                     end
  1564.                                     local nlines = calc(code)
  1565.                                     history[hpos]={type="byte",info={oldlines=olines, newlines=nlines, line=_line, byte=_byte, bytepos=_bytepos, internalX=internalX,offset=offset, drawcount=drawcount}}
  1566.                                     hpos=hpos+1
  1567.                                     lines=nlines
  1568.                                     draw(lines,offset)
  1569.                                     dispInfo(language.clearsel)
  1570.                                 else
  1571.                                     bt=bt:sub(1,internalX-1).."0"..bt:sub(internalX+1)
  1572.                                     history[hpos]={type="char",info={line=_line,byte=_byte,old=lines[_line][_byte], new=bt, internalX=internalX, bytepos=_bytepos,offset=offset, drawcount=drawcount}}
  1573.                                     hpos=hpos+1
  1574.                                     lines[_line][_byte]=bt
  1575.                                     cursorRight()
  1576.                                     dispInfo(language.clearbyte)
  1577.                                 end
  1578.                             end
  1579.                         end
  1580.                     elseif p1==46 then -- c
  1581.                         if ctrl then
  1582.                             if multiselect then
  1583.                                 local sStartLine, sEndLine, sStartByte, sEndByte = mSelPos()
  1584.                                 local startPos = (sStartLine-1)*#lines[1]+sStartByte
  1585.                                 local endPos = (sEndLine-1)*#lines[1]+sEndByte
  1586.                                 local code=""
  1587.                                 for i=1, #lines do
  1588.                                     for j=1, #lines[i] do
  1589.                                         code=code.._type.char(lines[i][j])
  1590.                                     end
  1591.                                 end
  1592.                                 clipboard=code:sub(startPos,endPos)
  1593.                             else
  1594.                                 clipboard=_type.char(lines[_line][_byte])
  1595.                             end
  1596.                             dispInfo(language.clipboard)
  1597.                         end
  1598.                     elseif p1==30 then -- a
  1599.                         if ctrl then
  1600.                             multiselect=true
  1601.                             clear()
  1602.                             local drawcount = drawcount
  1603.                             drawcount = drawcount<=#lines and drawcount or #lines
  1604.                             _byte = #lines[drawcount+offset-1]
  1605.                             _line=drawcount+offset-1
  1606.                             _bytepos = 3+(_byte-1)*size+_byte-1
  1607.                             sStart={line=1,byte=1}
  1608.                             sEnd={line=#lines,byte=#lines[#lines]}
  1609.                             update()
  1610.                             dispInfo(language.bytesel)
  1611.                         end
  1612.                     elseif p1==210 then -- insert
  1613.                         if ctrl then
  1614.                             local olines={}
  1615.                             for k, v in pairs(lines) do
  1616.                                 olines[k]=copy(v)
  1617.                             end
  1618.                             table.insert(lines[_line],_byte+1,string.rep("0",size))
  1619.                             local code=""
  1620.                             for i=1, #lines do
  1621.                                 for j=1, #lines[i] do
  1622.                                     code=code.._type.char(lines[i][j])
  1623.                                 end
  1624.                             end
  1625.                             local nlines=calc(code)
  1626.                             history[hpos]={type="byte",info={oldlines=olines, newlines=nlines, line=_line, byte=_byte, bytepos=_bytepos, internalX=internalX,offset=offset, drawcount=drawcount}}
  1627.                             lines=nlines
  1628.                             hpos=hpos+1
  1629.                             draw(lines,offset)
  1630.                             update()
  1631.                             dispInfo(language.byteinsert)
  1632.                         end
  1633.                     elseif p1==14 then -- Backspace
  1634.                         local bt = lines[_line] and lines[_line][_byte]
  1635.                         if bt then
  1636.                             cursorLeft()
  1637.                             bt=bt:sub(1,internalX-1).."0"..bt:sub(internalX+1)
  1638.                             history[hpos]={type="char",info={line=_line,byte=_byte,old=lines[_line][_byte], new=bt, internalX=internalX, bytepos=_bytepos,offset=offset, drawcount=drawcount}}
  1639.                             hpos=hpos+1
  1640.                             lines[_line][_byte]=bt
  1641.                             update()
  1642.                         end
  1643.                     elseif p1==44 then -- z
  1644.                         if ctrl then
  1645.                             local h=history[hpos-1]
  1646.                             if h then
  1647.                                 hpos=hpos-1
  1648.                                 if h.type == "char" then
  1649.                                     clear()
  1650.                                     _line=h.info.line
  1651.                                     _byte=h.info.byte
  1652.                                     internalX=h.info.internalX
  1653.                                     offset=h.info.offset
  1654.                                     _bytepos=h.info.bytepos
  1655.                                     drawcount=h.info.drawcount
  1656.                                     lines[_line][_byte]=h.info.old
  1657.                                     draw(lines,offset)
  1658.                                     update()
  1659.                                 elseif h.type == "byte" then
  1660.                                     lines=h.info.oldlines
  1661.                                     _line=h.info.line
  1662.                                     _byte=h.info.byte
  1663.                                     internalX=h.info.internalX
  1664.                                     _bytepos=h.info.bytepos
  1665.                                     offset=h.info.offset
  1666.                                     drawcount=h.info.drawcount
  1667.                                     code=""
  1668.                                     for i=1, #lines do
  1669.                                         for j=1, #lines[i] do
  1670.                                             code=code.._type.char(lines[i][j])
  1671.                                         end
  1672.                                     end
  1673.                                     draw(lines,offset)
  1674.                                     update()
  1675.                                 end
  1676.                                 dispInfo(language.undo)
  1677.                             end
  1678.                         end
  1679.                     elseif p1==33 then -- f
  1680.                             local txt
  1681.                             if multiselect then
  1682.                                 local sStartLine, sEndLine, sStartByte, sEndByte = mSelPos()
  1683.                                 if sStartLine and sEndLine and sStartByte and sEndByte and lines and lines[1] then
  1684.                                     local startPos = (sStartLine-1)*#lines[1]+sStartByte
  1685.                                     local endPos = (sEndLine-1)*#lines[1]+sEndByte
  1686.                                     local code=""
  1687.                                     for i=1, #lines do
  1688.                                         for j=1, #lines[i] do
  1689.                                             code=code.._type.char(lines[i][j])
  1690.                                         end
  1691.                                     end
  1692.                                     txt=code:sub(startPos,endPos)
  1693.                                 end
  1694.                             else
  1695.                                 if (lines and lines[_line] and lines[_line][_byte]) then
  1696.                                     txt=_type.char(lines[_line][_byte])
  1697.                                 end
  1698.                             end
  1699.                             txt=(txt and #txt>0 and txt) or "\0"
  1700.                             local pos = charPos(_line,_byte)
  1701.                             local _s, _e = string.find(code,txt,pos+1)
  1702.                             if not _s then
  1703.                                 _s, _e = string.find(code,txt,1)
  1704.                             end
  1705.                             if _s then
  1706.                                 local line1, byte1 = bytePos(_s)
  1707.                                 local line2, byte2 = bytePos(_e)
  1708.                                 _byte=byte2
  1709.                                 _line=line2
  1710.                                 _bytepos = 3+(_byte-1)*size+_byte-1
  1711.                                 offset=_line
  1712.                                 local drawcount = drawcount
  1713.                                 drawcount=drawcount<=#lines and drawcount or #lines
  1714.                                 if offset+drawcount-1>#lines then
  1715.                                     offset=#lines-drawcount+1
  1716.                                 end
  1717.                                 if offset<1 then
  1718.                                     offset=1
  1719.                                 end
  1720.                                 sStart={line=line1,byte=byte1}
  1721.                                 sEnd={line=line2,byte=byte2}
  1722.                                 multiselect=true
  1723.                                 draw(lines,offset)
  1724.                                 update()
  1725.                                 if not editmode then
  1726.                                     updatecmd()
  1727.                                 end
  1728.                                 dispInfo(language.found)
  1729.                             else
  1730.                                 dispInfo(language.notfound)
  1731.                             end
  1732.                     elseif p1==21 then -- y
  1733.                         if ctrl then
  1734.                             local h=history[hpos]
  1735.                             if h then
  1736.                                 hpos=hpos+1
  1737.                                 if h.type == "char" then
  1738.                                     clear()
  1739.                                     _line=h.info.line
  1740.                                     _byte=h.info.byte
  1741.                                     internalX=h.info.internalX
  1742.                                     _bytepos=h.info.bytepos
  1743.                                     offset=h.info.offset
  1744.                                     drawcount=h.info.drawcount
  1745.                                     lines[_line][_byte]=h.info.new
  1746.                                     draw(lines,offset)
  1747.                                     update()
  1748.                                 elseif h.type == "byte" then
  1749.                                     code=""
  1750.                                     for i=1, #lines do
  1751.                                         for j=1, #lines[i] do
  1752.                                             code=code.._type.char(lines[i][j])
  1753.                                         end
  1754.                                     end
  1755.                                     lines=h.info.newlines
  1756.                                     _line=h.info.line
  1757.                                     _byte=h.info.byte
  1758.                                     internalX=h.info.internalX
  1759.                                     _bytepos=h.info.bytepos
  1760.                                     offset=h.info.offset
  1761.                                     drawcount=h.info.drawcount
  1762.                                     draw(lines,offset)
  1763.                                     update()
  1764.                                 end
  1765.                                 dispInfo(language.redo)
  1766.                             end
  1767.                         end
  1768.                     elseif p1==15 then -- Tab
  1769.                         local sx = internalX
  1770.                         skipRight()
  1771.                         internalX=sx
  1772.                         update()
  1773.                     elseif p1==203 then -- Left
  1774.                         if shift then
  1775.                             multiselect=true
  1776.                             clear()
  1777.                             sEnd=sEnd or copy(sStart or {line=1,byte=1})
  1778.                             if sEnd.byte-1<1 then
  1779.                                 if sEnd.line-1 >= 1 then
  1780.                                     sEnd.line=sEnd.line-1
  1781.                                     _line=_line-1
  1782.                                     sEnd.byte=#lines[_line]
  1783.                                     _byte=#lines[_line]
  1784.                                     if _line<offset then
  1785.                                         if _line-1 >= 1 then
  1786.                                             offset=_line
  1787.                                             _byte=#lines[_line]
  1788.                                             _bytepos = 3+(_byte-1)*size+_byte-1
  1789.                                             internalX=size
  1790.                                             draw(lines,offset)
  1791.                                         end
  1792.                                     end
  1793.                                 end
  1794.                             else
  1795.                                 _byte=_byte-1
  1796.                                 sEnd.byte=sEnd.byte-1
  1797.                             end
  1798.                             if _line<offset then
  1799.                                 offset=_line
  1800.                                 draw(lines,offset)
  1801.                             end
  1802.                             _bytepos = 3+(_byte-1)*size+_byte-1
  1803.                             update()
  1804.                         else
  1805.                             cursorLeft()
  1806.                         end
  1807.                     elseif p1==205 then -- Right
  1808.                         if shift then
  1809.                             multiselect=true
  1810.                             clear()
  1811.                             sEnd=sEnd or copy(sStart or {line=1,byte=1})
  1812.                             if lines and lines[sEnd.line] then
  1813.                                 if sEnd.byte+1>#lines[sEnd.line] then
  1814.                                     if sEnd.line+1 <= #lines then
  1815.                                         sEnd.line=sEnd.line+1
  1816.                                         sEnd.byte=1
  1817.                                         _line=_line+1
  1818.                                         _byte=1
  1819.                                         if offset+drawcount <= #lines then
  1820.                                             if _line+1-offset>drawcount then
  1821.                                                 offset=offset+1
  1822.                                                 _byte=1
  1823.                                                 _bytepos = 3+(_byte-1)*size+_byte-1
  1824.                                                 internalX=1
  1825.                                                 draw(lines,offset)
  1826.                                             end
  1827.                                         end
  1828.                                     end
  1829.                                 else
  1830.                                     _byte=_byte+1
  1831.                                     sEnd.byte=sEnd.byte+1
  1832.                                 end
  1833.                             end
  1834.                             if _line+1-offset>drawcount then
  1835.                                 offset=_line
  1836.                                 local drawcount = drawcount
  1837.                                 drawcount=drawcount<=#lines and drawcount or #lines
  1838.                                 if offset+drawcount-1>#lines then
  1839.                                     offset=#lines-drawcount+1
  1840.                                 end
  1841.                                 if offset<1 then
  1842.                                     offset=1
  1843.                                 end
  1844.                                 draw(lines,offset)
  1845.                             end
  1846.                             _bytepos = 3+(_byte-1)*size+_byte-1
  1847.                             update()
  1848.                         else
  1849.                             cursorRight()
  1850.                         end
  1851.                     elseif p1==200 then -- Up
  1852.                         if _line-offset>=1 then
  1853.                             if _line-1 >= 1 then
  1854.                                 clear()
  1855.                                 multiselect=false
  1856.                                 _line=_line-1
  1857.                                 update()
  1858.                             end
  1859.                         else
  1860.                             if offset-1 >= 1 then
  1861.                                 if _line-1 >= 1 then
  1862.                                     clear()
  1863.                                     multiselect=false
  1864.                                     offset=offset-1
  1865.                                     _line=_line-1
  1866.                                     draw(lines,offset)
  1867.                                     update()
  1868.                                 end
  1869.                             end
  1870.                         end
  1871.                         sStart={line=_line,byte=_byte}
  1872.                         sEnd=nil
  1873.                     elseif p1==208 then -- Down
  1874.                         if _line+2-offset<=drawcount then
  1875.                             if _line+1 < #lines then
  1876.                                 clear()
  1877.                                 multiselect=false
  1878.                                 _line=_line+1
  1879.                                 if lines[_line] and _byte> #lines[_line] then
  1880.                                     _byte=#lines[_line]
  1881.                                     _bytepos = 3+(_byte-1)*size+_byte-1
  1882.                                 end
  1883.                                 update()
  1884.                             end
  1885.                         else
  1886.                             if offset+drawcount <= #lines then
  1887.                                 if _line+1 <= #lines then
  1888.                                     clear()
  1889.                                     multiselect=false
  1890.                                     offset=offset+1
  1891.                                     _line=_line+1
  1892.                                     if _byte> #lines[_line] then
  1893.                                         _byte=#lines[_line]
  1894.                                         _bytepos = 3+(_byte-1)*size+_byte-1
  1895.                                     end
  1896.                                     draw(lines,offset)
  1897.                                     update()
  1898.                                 end
  1899.                             end
  1900.                         end
  1901.                         sStart={line=_line,byte=_byte}
  1902.                         sEnd=nil
  1903.                     end
  1904.                 else
  1905.                     writemode()
  1906.                 end
  1907.             else
  1908.                 if p1==14 then -- Backspace
  1909.                     if poscmd>0 then
  1910.                         cmd=cmd:sub(1,poscmd-1)..cmd:sub(poscmd+1)
  1911.                         poscmd=poscmd-1
  1912.                         recomplete()
  1913.                         updatecmd()
  1914.                     end
  1915.                 elseif p1==203 then -- Left
  1916.                     if poscmd>0 then
  1917.                         poscmd=poscmd-1
  1918.                         recomplete()
  1919.                         updatecmd()
  1920.                     end
  1921.                 elseif p1==205 then -- Right
  1922.                     if poscmd<#cmd then
  1923.                         poscmd=poscmd+1
  1924.                         recomplete()
  1925.                         updatecmd()
  1926.                     else
  1927.                         acceptCompletion()
  1928.                     end
  1929.                 elseif p1==211 then -- Delete
  1930.                     if poscmd<#cmd then
  1931.                         cmd=cmd:sub(1,poscmd)..cmd:sub(poscmd+2)
  1932.                         recomplete()
  1933.                         updatecmd()
  1934.                     end
  1935.                 elseif p1 == 200 or p1 == 208 then -- Up, Down
  1936.                     if nCompletion then
  1937.                         updatecmd( true )
  1938.                         if p1 == 200 then
  1939.                             nCompletion = nCompletion - 1
  1940.                             if nCompletion < 1 then
  1941.                                 nCompletion = #tCompletions
  1942.                             end
  1943.                         elseif p1 == 208 then
  1944.                             nCompletion = nCompletion + 1
  1945.                             if nCompletion > #tCompletions then
  1946.                                 nCompletion = 1
  1947.                             end
  1948.                         end
  1949.                         updatecmd()
  1950.                     end
  1951.                 elseif p1 == 15 then -- Tab
  1952.                     acceptCompletion()
  1953.                 elseif p1 == 199 then -- Start
  1954.                     poscmd=0
  1955.                     recomplete()
  1956.                     updatecmd()
  1957.                 elseif p1 == 207 then -- End
  1958.                     poscmd=#cmd
  1959.                     recomplete()
  1960.                     updatecmd()
  1961.                 elseif p1 == 25 then -- p
  1962.                     if ctrl then
  1963.                         cmd=cmd:sub(1,poscmd)..clipboard..cmd:sub(poscmd+1)
  1964.                         poscmd=poscmd+#clipboard
  1965.                         recomplete()
  1966.                         updatecmd()
  1967.                         dispInfo(language.internalpaste)
  1968.                     end
  1969.                 elseif p1 == 28 then -- Enter
  1970.                     poscmd=0
  1971.                     os.queueEvent("command",tokenise(cmd))
  1972.                     cmd=""
  1973.                     recomplete()
  1974.                     updatecmd()
  1975.                 end
  1976.             end
  1977.         elseif event == "char" then
  1978.             if editmode then
  1979.                 if _type.auth:find(p1) then
  1980.                     local bt = lines[_line] and lines[_line][_byte]
  1981.                     if bt then
  1982.                         bt=bt:sub(1,internalX-1)..p1..bt:sub(internalX+1)
  1983.                         history[hpos]={type="char",info={line=_line,byte=_byte,old=lines[_line][_byte], new=bt, internalX=internalX, bytepos=_bytepos, offset=offset, drawcount=drawcount}}
  1984.                         hpos=hpos+1
  1985.                         lines[_line][_byte]=bt
  1986.                         cursorRight()
  1987.                         code=""
  1988.                         for i=1, #lines do
  1989.                             for j=1, #lines[i] do
  1990.                                 code=code.._type.char(lines[i][j])
  1991.                             end
  1992.                         end
  1993.                     end
  1994.                 end
  1995.             else
  1996.                 cmd=cmd:sub(1,poscmd)..p1..cmd:sub(poscmd+1)
  1997.                 poscmd=poscmd+1
  1998.                 recomplete()
  1999.                 updatecmd()
  2000.             end
  2001.         elseif event == "command" then
  2002.             local command = p1[1]
  2003.             table.remove(p1,1)
  2004.             local args=p1
  2005.             if command == "insert" then
  2006.                 local mode = args[1] or "char"
  2007.                 local olines={}
  2008.                 for k, v in pairs(lines) do
  2009.                     olines[k]=copy(v)
  2010.                 end
  2011.                 if code and #code>0 then
  2012.                     local pos=(_line-1)*#lines[1]+_byte
  2013.                     if mode == "byte" then
  2014.                         table.remove(args,1)
  2015.                         local txt=_type.char(unpack(args))
  2016.                         txt=#txt>0 and txt or "\0"
  2017.                         code=code:sub(1,pos)..txt..code:sub(pos+1)
  2018.                         local nlines=calc(code)
  2019.                         history[hpos]={type="byte",info={oldlines=olines, newlines=nlines, line=_line, byte=_byte, bytepos=_bytepos, internalX=internalX,offset=offset, drawcount=drawcount}}
  2020.                         lines=nlines
  2021.                         hpos=hpos+1
  2022.                     elseif mode == "char" then
  2023.                         table.remove(args,1)
  2024.                         local txt=table.concat(args,"")
  2025.                         txt=#txt>0 and txt or "\0"
  2026.                         code=code:sub(1,pos)..txt..code:sub(pos+1)
  2027.                         local nlines=calc(code)
  2028.                         history[hpos]={type="byte",info={oldlines=olines, newlines=nlines, line=_line, byte=_byte, bytepos=_bytepos, internalX=internalX,offset=offset, drawcount=drawcount}}
  2029.                         lines=nlines
  2030.                         hpos=hpos+1
  2031.                     end
  2032.                     offset=_line
  2033.                     local drawcount = drawcount
  2034.                     drawcount=drawcount<=#lines and drawcount or #lines
  2035.                     if offset+drawcount-1>#lines then
  2036.                         offset=#lines-drawcount+1
  2037.                     end
  2038.                     if offset<1 then
  2039.                         offset=1
  2040.                     end
  2041.                     draw(lines,offset)
  2042.                     update()
  2043.                     if not editmode then
  2044.                         updatecmd()
  2045.                     end
  2046.                 else
  2047.                     if mode == "byte" then
  2048.                         table.remove(args,1)
  2049.                         local txt=_type.char(unpack(args))
  2050.                         txt=#txt>0 and txt or "\0"
  2051.                         code = txt
  2052.                         local nlines=calc(code)
  2053.                         history[hpos]={type="byte",info={oldlines=olines, newlines=nlines, line=_line, byte=_byte, bytepos=_bytepos, internalX=internalX,offset=offset, drawcount=drawcount}}
  2054.                         lines=nlines
  2055.                         _line=1
  2056.                         _byte=1
  2057.                         _bytepos = 3+(_byte-1)*size+_byte-1
  2058.                         hpos=hpos+1
  2059.                     elseif mode == "char" then
  2060.                         table.remove(args,1)
  2061.                         local txt=table.concat(args,"")
  2062.                         txt=#txt>0 and txt or "\0"
  2063.                         code=txt
  2064.                         local nlines=calc(code)
  2065.                         history[hpos]={type="byte",info={oldlines=olines, newlines=nlines, line=_line, byte=_byte, bytepos=_bytepos, internalX=internalX,offset=offset, drawcount=drawcount}}
  2066.                         lines=nlines
  2067.                         _line=1
  2068.                         _byte=1
  2069.                         _bytepos = 3+(_byte-1)*size+_byte-1
  2070.                         hpos=hpos+1
  2071.                     end
  2072.                     offset=_line
  2073.                     local drawcount = drawcount
  2074.                     drawcount=drawcount<=#lines and drawcount or #lines
  2075.                     if offset+drawcount-1>#lines then
  2076.                         offset=#lines-drawcount+1
  2077.                     end
  2078.                     if offset<1 then
  2079.                         offset=1
  2080.                     end
  2081.                     draw(lines,offset)
  2082.                     update()
  2083.                     if not editmode then
  2084.                         updatecmd()
  2085.                     end
  2086.                 end
  2087.             elseif command == "save" then
  2088.                 if #args>0 then
  2089.                     h=fs.open(args[1],"w")
  2090.                     h.write(code)
  2091.                     h.close()
  2092.                 else
  2093.                     h=fs.open(fname,"w")
  2094.                     h.write(code)
  2095.                     h.close()
  2096.                 end
  2097.                 if not editmode then
  2098.                     updatecmd()
  2099.                 end
  2100.                 if #args>0 then
  2101.                     dispInfo(language.saveas.." "..args[1])
  2102.                 else
  2103.                     dispInfo(language.save)
  2104.                 end
  2105.             elseif command == "exit" then
  2106.                 buff.setVisible(false)
  2107.                 term.clear()
  2108.                 term.setCursorPos(1,1)
  2109.                 break
  2110.             elseif command == "deleteAll" then
  2111.                 code=""
  2112.                 sEnd=nil
  2113.                 multiselect=false
  2114.                 lines=calc(code)
  2115.                 draw(lines,offset)
  2116.                 if not editmode then
  2117.                     updatecmd()
  2118.                 end
  2119.             elseif command == "clearHistory" then
  2120.                 history={}
  2121.                 hpos=1
  2122.             elseif command == "redraw" then
  2123.                 local drawcount = drawcount
  2124.                 drawcount=drawcount<=#lines and drawcount or #lines
  2125.                 if offset+drawcount-1>#lines then
  2126.                     offset=#lines-drawcount+1
  2127.                 end
  2128.                 if offset<1 then
  2129.                     offset=1
  2130.                 end
  2131.                 draw(lines,offset)
  2132.                 update()
  2133.                 if not editmode then
  2134.                     updatecmd()
  2135.                 end
  2136.             elseif command == "gotoLn" then
  2137.                 local ln = tonumber(args[1] or 1)
  2138.                 if lines[ln] then
  2139.                     offset=ln
  2140.                     local drawcount = drawcount
  2141.                     drawcount=drawcount<=#lines and drawcount or #lines
  2142.                     if offset+drawcount-1>#lines then
  2143.                         offset=#lines-drawcount+1
  2144.                     end
  2145.                     if offset<1 then
  2146.                         offset=1
  2147.                     end
  2148.                     multiselect=false
  2149.                     _line=ln
  2150.                     sStart={line=_line,byte=_byte}
  2151.                     draw(lines,offset)
  2152.                     update()
  2153.                     if not editmode then
  2154.                         updatecmd()
  2155.                     end
  2156.                 end
  2157.             elseif command == "color" then
  2158.                 local color = _colors[args[1]]
  2159.                 if color then
  2160.                     local v = colors[args[2]] or color
  2161.                     _colors[args[1]]=v
  2162.                     draw(lines,offset)
  2163.                     update()
  2164.                     if not editmode then
  2165.                         updatecmd()
  2166.                     end
  2167.                     local dt = {colors=_colors, lang=language}
  2168.                     local h=fs.open("."..name,"w")
  2169.                     h.write(textutils.serialise(dt))
  2170.                     h.close()
  2171.                     dispInfo(args[1].." : "..revcolor[v])
  2172.                 end
  2173.             elseif command == "editmode" then
  2174.                 editmode=true
  2175.                 select=true
  2176.                 draw(lines,offset)
  2177.                 update()
  2178.                 if not editmode then
  2179.                     updatecmd()
  2180.                 end
  2181.             elseif command == "setClipboard" then
  2182.                 clipboard=args[1] or ""
  2183.                 dispInfo(language.clipboardset)
  2184.             elseif command == "undo" then
  2185.                 local count = tonumber(args[1]) or 1
  2186.                 for i=1,  count do
  2187.                     local h=history[hpos-1]
  2188.                     if h then
  2189.                         hpos=hpos-1
  2190.                         if h.type == "char" then
  2191.                             clear()
  2192.                             _line=h.info.line
  2193.                             _byte=h.info.byte
  2194.                             internalX=h.info.internalX
  2195.                             offset=h.info.offset
  2196.                             _bytepos=h.info.bytepos
  2197.                             drawcount=h.info.drawcount
  2198.                             lines[_line][_byte]=h.info.old
  2199.                         elseif h.type == "byte" then
  2200.                             lines=h.info.oldlines
  2201.                             _line=h.info.line
  2202.                             _byte=h.info.byte
  2203.                             internalX=h.info.internalX
  2204.                             _bytepos=h.info.bytepos
  2205.                             offset=h.info.offset
  2206.                             drawcount=h.info.drawcount
  2207.                             code=""
  2208.                             for i=1, #lines do
  2209.                                 for j=1, #lines[i] do
  2210.                                     code=code.._type.char(lines[i][j])
  2211.                                 end
  2212.                             end
  2213.                         end
  2214.                     end
  2215.                 end
  2216.                 draw(lines,offset)
  2217.                 update()
  2218.                 if not editmode then
  2219.                     updatecmd()
  2220.                 end
  2221.                 dispInfo(language.undo.." "..count)
  2222.             elseif command == "redo" then
  2223.                 local count = tonumber(args[1]) or 1
  2224.                 for i=1,  count do
  2225.                     local h=history[hpos]
  2226.                     if h then
  2227.                         hpos=hpos+1
  2228.                         if h.type == "char" then
  2229.                             clear()
  2230.                             _line=h.info.line
  2231.                             _byte=h.info.byte
  2232.                             internalX=h.info.internalX
  2233.                             _bytepos=h.info.bytepos
  2234.                             offset=h.info.offset
  2235.                             drawcount=h.info.drawcount
  2236.                             lines[_line][_byte]=h.info.new
  2237.                             draw(lines,offset)
  2238.                             update()
  2239.                         elseif h.type == "byte" then
  2240.                             code=""
  2241.                             for i=1, #lines do
  2242.                                 for j=1, #lines[i] do
  2243.                                     code=code.._type.char(lines[i][j])
  2244.                                 end
  2245.                             end
  2246.                             lines=h.info.newlines
  2247.                             _line=h.info.line
  2248.                             _byte=h.info.byte
  2249.                             internalX=h.info.internalX
  2250.                             _bytepos=h.info.bytepos
  2251.                             offset=h.info.offset
  2252.                             drawcount=h.info.drawcount
  2253.                         end
  2254.                     end
  2255.                 end
  2256.                 draw(lines,offset)
  2257.                 update()
  2258.                 if not editmode then
  2259.                     updatecmd()
  2260.                 end
  2261.                 dispInfo(language.redo.." "..count)
  2262.             elseif command == "mode" then
  2263.                 _type = mode[args[1] or "byte"] or mode["byte"]
  2264.                 size = #tostring(_type.byte("\255"))
  2265.                 sep=math.floor(w/2+w/4)
  2266.                 for i=1, w-3 do
  2267.                     if i*(size+1)+i <= w-3 then
  2268.                         sep=w-i-1
  2269.                     else
  2270.                         break
  2271.                     end
  2272.                 end
  2273.                 if #code>0 then
  2274.                     local pos = charPos(_line, _byte)
  2275.                     local md = args[1] or "byte"
  2276.                     md = mode[md] and md or "byte"
  2277.  
  2278.                     lines=calc(code)
  2279.                     _line, _byte = bytePos(pos)
  2280.                     if _line then
  2281.                         offset=_line
  2282.                         local drawcount = drawcount
  2283.                         drawcount=drawcount<=#lines and drawcount or #lines
  2284.                         if offset+drawcount-1>#lines then
  2285.                             offset=#lines-drawcount+1
  2286.                         end
  2287.                         if offset<1 then
  2288.                             offset=1
  2289.                         end
  2290.                         _bytepos = 3+(_byte-1)*size+_byte-1
  2291.                         draw(lines,offset)
  2292.                         update()
  2293.                         if not editmode then
  2294.                             updatecmd()
  2295.                         end
  2296.                         dispInfo(language.mode..":"..md)
  2297.                     end
  2298.                 end
  2299.             elseif command == "find" then
  2300.                 local mode = args[1] or "char"
  2301.                 local olines={}
  2302.                 for k, v in pairs(lines) do
  2303.                     olines[k]=copy(v)
  2304.                 end
  2305.                 if #code>0 then
  2306.                     local pos=(_line-1)*#lines[1]+_byte
  2307.                     if mode == "byte" then
  2308.                         table.remove(args,1)
  2309.                         local txt=_type.char(unpack(args))
  2310.                         txt=#txt>0 and txt or "\0"
  2311.                         local pos = charPos(_line,_byte)
  2312.                         local _s, _e = string.find(code,txt,pos)
  2313.                         if not _s then
  2314.                             _s, _e = string.find(code,txt,1)
  2315.                         end
  2316.                         if _s then
  2317.                             local line1, byte1 = bytePos(_s)
  2318.                             local line2, byte2 = bytePos(_e)
  2319.                             _byte=byte2
  2320.                             _line=line2
  2321.                             _bytepos = 3+(_byte-1)*size+_byte-1
  2322.                             sStart={line=line1,byte=byte1}
  2323.                             sEnd={line=line2,byte=byte2}
  2324.                             offset=_line
  2325.                             local drawcount = drawcount
  2326.                             drawcount=drawcount<=#lines and drawcount or #lines
  2327.                             if offset+drawcount-1>#lines then
  2328.                                 offset=#lines-drawcount+1
  2329.                             end
  2330.                             if offset<1 then
  2331.                                 offset=1
  2332.                             end
  2333.                             multiselect=true
  2334.                             draw(lines,offset)
  2335.                             update()
  2336.                             if not editmode then
  2337.                                 updatecmd()
  2338.                             end
  2339.                             dispInfo(language.found)
  2340.                         else
  2341.                             dispInfo(language.notfound)
  2342.                         end
  2343.                     elseif mode == "char" then
  2344.                         table.remove(args,1)
  2345.                         local txt=table.concat(args,"")
  2346.                         txt=#txt>0 and txt or "\0"
  2347.                         local pos = charPos(_line,_byte)
  2348.                         local _s, _e = string.find(code,txt,pos)
  2349.                         if not _s then
  2350.                             _s, _e = string.find(code,txt,1)
  2351.                         end
  2352.                         if _s then
  2353.                             local line1, byte1 = bytePos(_s)
  2354.                             local line2, byte2 = bytePos(_e)
  2355.                             _byte=byte2
  2356.                             _line=line2
  2357.                             _bytepos = 3+(_byte-1)*size+_byte-1
  2358.                             offset=_line
  2359.                             local drawcount = drawcount
  2360.                             drawcount=drawcount<=#lines and drawcount or #lines
  2361.                             if offset+drawcount-1>#lines then
  2362.                                 offset=#lines-drawcount+1
  2363.                             end
  2364.                             if offset<1 then
  2365.                                 offset=1
  2366.                             end
  2367.                             sStart={line=line1,byte=byte1}
  2368.                             sEnd={line=line2,byte=byte2}
  2369.                             multiselect=true
  2370.                             draw(lines,offset)
  2371.                             update()
  2372.                             if not editmode then
  2373.                                 updatecmd()
  2374.                             end
  2375.                             dispInfo(language.found)
  2376.                         else
  2377.                             dispInfo(language.notfound)
  2378.                         end
  2379.                     end
  2380.                 end
  2381.             elseif command == "lang" then
  2382.                 local langname = args[1] or "en"
  2383.                 language = lang[langname] or lang["en"]
  2384.                 langname = lang[langname] and langname or "en"
  2385.                 local dt = {colors=_colors, lang=language}
  2386.                 local h=fs.open("."..name,"w")
  2387.                 h.write(textutils.serialise(dt))
  2388.                 h.close()
  2389.                 dispInfo(language.langset.." "..langname)
  2390.             elseif command == "help" then
  2391.                 if language.docs[args[1]] then
  2392.                     wind.setVisible(true)
  2393.                     wind.setBackgroundColor(_colors.background)
  2394.                     wind.setTextColor(_colors.text)
  2395.                     wind.clear()
  2396.                     wind.setCursorPos(1,1)
  2397.                     termprint(wind, language.help.." : "..language.docs[args[1]])
  2398.                     termprint(wind,"")
  2399.                     for k, v in pairs(language.usages[args[1]]) do
  2400.                         termprint(wind,language.usage.." : "..v)
  2401.                     end
  2402.                     paged=true
  2403.                     modeinfo=true
  2404.                     if not editmode then
  2405.                         updatecmd()
  2406.                     end
  2407.                 else
  2408.                     local cmd={}
  2409.                     for k, v in pairs(tCompletionInfo) do
  2410.                         cmd[#cmd+1]=k
  2411.                     end
  2412.                     table.sort(cmd)
  2413.                     infodt = cmd
  2414.                     updateInfo()
  2415.                 end
  2416.             elseif command == "bindlist" then
  2417.                 local lst = {}
  2418.                 for k, v in pairs(language.binds) do
  2419.                     lst[v]=k
  2420.                 end
  2421.                 paged=false
  2422.                 infodt=lst
  2423.                 updateInfo()
  2424.             end
  2425.         end
  2426.     end
  2427. else
  2428.     local t={}
  2429.     for k, v in pairs(mode) do
  2430.         t[#t+1]=k
  2431.     end
  2432.     term.clear()
  2433.     term.setCursorPos(1,1)
  2434.     table.sort(t)
  2435.     print("Usage: "..shell.getRunningProgram().." <filename> <mode["..table.concat(t,",").."]> <readMode[rb,r]>")
  2436. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement