Advertisement
GopherAtl

edit+

Mar 4th, 2015
255
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 20.75 KB | None | 0 0
  1. --[===============================================]
  2.  
  3. --edit+
  4.  
  5. os.unloadAPI("hilight")
  6. os.loadAPI("hilight")
  7.  
  8. if hilight==nil then
  9.   error("hilight not loaded?")
  10. end
  11.  
  12. local args={...}
  13.  
  14. local filename=args[1]
  15.  
  16. if not filename then
  17.   print("usage:\nedit+ <filename>")
  18.   return
  19. end
  20.  
  21. local filePath=shell.dir().."/"..filename
  22. local lines={}
  23.  
  24. local prevState
  25.  
  26. do
  27.   local prevState={}
  28.   local file=io.open(filePath,"r")
  29.   if file~=nil then
  30.     for line in file:lines() do
  31.       lines[#lines+1]=hilight.hilightToSpans(line,prevState)
  32.       prevState=lines[#lines].state
  33.     end
  34.     file:close()
  35.   else
  36.     lines[1]={rawText="",state={}}
  37.   end
  38. end
  39.  
  40.  
  41.  
  42.  
  43. term.clear()
  44.  
  45. local running=true
  46. local w,h=term.getSize()
  47. local scrollPos={x=1,y=1}
  48. local curPos={x=1,y=1}
  49. local selectBounds
  50. local lastClickPos={x=1,y=1}
  51. local clipboard
  52.  
  53. local function curToTextPos(curPos)
  54.   local lineNum=curPos.y+scrollPos.y-1
  55.   local index
  56.   if lineNum>#lines then
  57.     lineNum=#lines
  58.     index=#lines[#lines].rawText+1
  59.   else
  60.     index=math.min(curPos.x+scrollPos.x-1,#lines[lineNum].rawText+1)
  61.   end
  62.   return {x=index,y=lineNum}
  63. end
  64.  
  65.  
  66. local function drawLineNum()
  67.   lineNum=" "..tostring(scrollPos.y+curPos.y-1).." "
  68.   term.setCursorPos(w-#lineNum+1,h)
  69.   term.setBackgroundColor(colors.white)
  70.   term.setTextColor(colors.black)
  71.   term.write(lineNum)
  72.   term.setBackgroundColor(colors.black)
  73.   term.setTextColor(colors.white)
  74. end
  75.  
  76. local function redrawLine(screenLine)
  77.   local lineNum=screenLine+scrollPos.y-1
  78.   if lineNum<=#lines then
  79.     local selStart,selEnd=0,-1
  80.     local spans=lines[lineNum]
  81.     if selectBounds and selectBounds[1].y<=lineNum and selectBounds[2].y>=lineNum then
  82.       --we'll be doing selecting here
  83.       selStart,selEnd=1,#spans.rawText+1
  84.       if selectBounds[1].y==lineNum then
  85.         selStart=selectBounds[1].x
  86.       end
  87.       if selectBounds[2].y==lineNum then
  88.         selEnd=selectBounds[2].x
  89.       end
  90.     end
  91.  
  92.     term.setCursorPos(2-scrollPos.x,screenLine)
  93.     local index=1
  94.     for i=1,#spans do
  95.       local len=#spans[i].text
  96.       local subStart,subEnd=1,len
  97.       if index>selEnd or index+len-1<selStart then
  98.         subStart,subEnd=len+1,len+1
  99.       else
  100.         if selStart>=index then
  101.           subStart=selStart-index+1
  102.         end
  103.         if selEnd<index+len-1 then
  104.           subEnd=len - (index+len-1 - selEnd)
  105.         end
  106.       end
  107.       if subStart>1 then
  108.         term.setTextColor(spans[i].color)
  109.         term.write(spans[i].text:sub(1,subStart-1))
  110.       end
  111.       if subStart~=len+1 then
  112.         term.setTextColor(term.isColor() and colors.white or colors.black)
  113.         term.setBackgroundColor(term.isColor() and colors.blue or colors.white)
  114.         term.write(spans[i].text:sub(subStart,subEnd))
  115.         term.setBackgroundColor(colors.black)
  116.       end
  117.       if subEnd<len then
  118.         term.setTextColor(spans[i].color)
  119.         term.write(spans[i].text:sub(subEnd+1))
  120.       end
  121.       index=index+len
  122.     end
  123.     if selEnd>#spans.rawText then
  124.       term.setBackgroundColor(term.isColor() and colors.blue or colors.white)
  125.       term.write(" ")
  126.       term.setBackgroundColor(colors.black)
  127.     end
  128.  
  129.     local x,y=term.getCursorPos()
  130.     term.write((" "):rep(math.max(0,w-x+1)))
  131.   else
  132.     term.setCursorPos(1,screenLine)
  133.     term.write((" "):rep(w))
  134.   end
  135.   if screenLine==h then
  136.     drawLineNum()
  137.   end
  138. end
  139.  
  140. local function redrawFrom(index)
  141.   for y=index,h do
  142.     redrawLine(y)
  143.   end
  144. end
  145.  
  146. local function updateSelect(newBounds)
  147.   local startY,endY
  148.   if selectBounds then
  149.     if newBounds then
  150.       startY,endY=math.min(selectBounds[1].y,newBounds[1].y),math.max(selectBounds[2].y,newBounds[2].y)
  151.     else
  152.       startY,endY=selectBounds[1].y,selectBounds[2].y
  153.     end
  154.   elseif newBounds then
  155.     startY,endY=newBounds[1].y,newBounds[2].y
  156.   else
  157.     return
  158.   end
  159.   selectBounds=newBounds
  160.   for i=startY-scrollPos.y+1,endY-scrollPos.y+1 do
  161.     if i>=1 and i<=h then
  162.       redrawLine(i)
  163.     end
  164.   end
  165. end
  166.  
  167.  
  168. local function cursorRow()
  169.   return lines[curPos.y+scrollPos.y-1]
  170. end
  171.  
  172. local function trueCurPos()
  173.   local cx,cy=curPos.x,curPos.y
  174.   local row=cursorRow()
  175.   cx=math.min(cx,#row.rawText-scrollPos.x+2)
  176.   return cx,cy
  177. end
  178.  
  179.  
  180. local function curTextPos()
  181.   local lineNum=curPos.y+scrollPos.y-1
  182.   local index=math.min(curPos.x+scrollPos.x-1,#lines[lineNum].rawText+1)
  183.   return lineNum,index
  184. end
  185.  
  186.  
  187. local function doCursor()
  188.   term.setCursorPos(trueCurPos())
  189.   term.setCursorBlink(true)
  190. end
  191.  
  192. local function setScrollX(pos)
  193.   local lineNum,index=curTextPos()
  194.   local target=math.max(math.min(pos,#lines[lineNum].rawText-w+2),1)
  195.   if target~=scrollPos.x then
  196.     scrollPos.x=target
  197.     redrawFrom(1)
  198.   end
  199. end
  200.  
  201. local function scrollY(offset)
  202.   local didScroll=false
  203.   local target=math.max(math.min(scrollPos.y+offset,#lines-h+1),1)
  204.   if target~=scrollPos.y then
  205.     didScroll=true
  206.     --correct if it was clamped
  207.     offset=target-scrollPos.y
  208.     term.scroll(offset)
  209.     scrollPos.y=target
  210.     for i=1,offset+1 do
  211.       redrawLine(h-i+1)
  212.     end
  213.     for i=-1,offset,-1 do
  214.       redrawLine(-i)
  215.     end
  216.   end
  217.   return didScroll
  218. end
  219.  
  220. local function gotoLine(lineNum)
  221.   local curY=lineNum-scrollPos.y+1
  222.   if curY<1 then
  223.     scrollY(lineNum-scrollPos.y)
  224.     curPos.y=1
  225.     redraw=true
  226.   elseif curY>h then
  227.     scrollY(lineNum-h+1 - scrollPos.y)
  228.     curPos.y=h
  229.     redraw=true
  230.   else
  231.     curPos.y=lineNum-scrollPos.y+1
  232.   end
  233.   if curPos.x~=1 then
  234.     curPos.x=1
  235.     redraw=true
  236.   end
  237.   if redraw then
  238.     redrawFrom(1)
  239.   end
  240. end
  241.  
  242.  
  243. local function cursorDown(amt)
  244.   updateSelect()
  245.   amt=amt or 1
  246.   if #lines<curPos.y+amt+scrollPos.y-1 then
  247.     amt=#lines-curPos.y-scrollPos.y+1
  248.   end
  249.   if amt>0 then
  250.     if curPos.y+amt>h then
  251.       scrollY(amt-(h-curPos.y))
  252.       curPos.y=h
  253.     elseif curPos.y<#lines then
  254.       curPos.y=curPos.y+amt
  255.     end
  256.   end
  257. end
  258.  
  259. local function cursorUp(amt)
  260.   updateSelect()
  261.   amt=amt or 1
  262.   if curPos.y-amt<1 then
  263.     scrollY(curPos.y-1-amt)
  264.     curPos.y=1
  265.   else
  266.     curPos.y=curPos.y-amt
  267.   end
  268.   drawLineNum()
  269. end
  270.  
  271.  
  272. local function updateLine(lineNum,newText,noProp)
  273. local prevLineState={}
  274.   if lineNum>1 then
  275.     prevLineState=lines[lineNum-1].state
  276.   end
  277.   local line=lines[lineNum]
  278.   local prevEndState=line.state
  279.   line=hilight.hilightToSpans(newText,prevLineState)
  280.   lines[lineNum]=line
  281.   redrawLine(curPos.y)
  282.   --check for an end state change and flag to propagate
  283.   if not hilight.compareStates(line.state,prevEndState) then
  284.     local prevState=line.state
  285.     --for now just redoing whole file if needed, will make it incremental and/or deferred later
  286.     if not noProp then
  287.       for i=lineNum+1,#lines do
  288.         prevEndState=lines[i].state
  289.         lines[i]=hilight.hilightToSpans(lines[i].rawText,prevState)
  290.         if i-scrollPos.y+1 <= h then
  291.           redrawLine(i-scrollPos.y+1)
  292.         end
  293.         prevState=lines[i].state
  294.         --stop iterating if the state returns to expected
  295.         if hilight.compareStates(prevState,prevEndState) then
  296.           break
  297.         end
  298.       end
  299.     end
  300.   end
  301. end
  302.  
  303. local function deleteSelection()
  304.   if selectBounds then
  305.     local startY,endY=selectBounds[1].y,selectBounds[2].y
  306.     local selectBounds=selectBounds
  307.     updateSelect()
  308.     if startY==endY then
  309.       local text=lines[startY].rawText
  310.       updateLine(startY,text:sub(1,selectBounds[1].x-1)..text:sub(selectBounds[2].x+1))
  311.     else
  312.       local newText=lines[startY].rawText:sub(1,selectBounds[1].x-1,noProp)..lines[endY].rawText:sub(selectBounds[2].x+1)
  313.       for i=startY+1,endY do
  314.         table.remove(lines,startY+1)
  315.       end
  316.       updateLine(startY,newText)
  317.       redrawFrom(curPos.y+1)
  318.     end
  319.   end
  320. end
  321.  
  322.  
  323. local function save()
  324.   file=io.open(filePath,"w")
  325.   if file then
  326.     for i=1,#lines do
  327.       if i~=1 then
  328.         file:write("\n")
  329.       end
  330.       file:write(lines[i].rawText)
  331.     end
  332.     file:close()
  333.   end
  334. end
  335.  
  336. local function load()
  337.   --TODO: file dialog
  338. end
  339.  
  340. local function new()
  341.   --TODO: file dialog
  342.   --actually, just make new, with filename nil'd, and do
  343.   --file dialog on save if filename is nil.
  344.   --will facilitate saveAs also.
  345. end
  346.  
  347. local function help()
  348.   --not much point for this until advanced mode is added, actually?
  349. end
  350.  
  351. local charKeys={[57]=' ', [43]='\\', [83]='.', [2]='1', [3]='2', [4]='3', [5]='4', [6]='5', [7]='6', [8]='7', [9]='8', [10]='9', [11]='0', [12]='-', [13]='=', [51]=',', [52]='.', [53]='/', [181]='/', [55]='*', [26]='[', [27]=']', [71]='7', [72]='8', [73]='9', [74]='-', [75]='4', [76]='5', [77]='6', [78]='+', [79]='1', [80]='2', [81]='3', [39]=';', [40]='"', [41]='`', [82]='0', [30]='a', [48]='b', [46]='c', [32]='d', [18]='e', [33]='f', [34]='g', [35]='h', [23]='i', [36]='j', [37]='k', [38]='l', [50]='m', [49]='n', [24]='o', [25]='p', [16]='q', [19]='r', [31]='s', [20]='t', [22]='u', [47]='v', [17]='w', [45]='x', [21]='y', [44]='z', }
  352.  
  353. local runEnv={shell=shell, multishell=multishell}
  354. setmetatable(runEnv,{__index=_G})
  355.  
  356. local function run()
  357.   --save changes first
  358.   save()
  359.   term.setTextColor(colors.white)
  360.   term.setBackgroundColor(colors.black)
  361.   term.clear()
  362.   term.setCursorPos(1,1)
  363.  
  364.   local succ,err
  365.   local func=loadfile(filePath)
  366.   if not func then
  367.     succ,err=pcall(dofile,filePath)
  368.   else
  369.     setfenv(func,runEnv)
  370.     succ,err=pcall(func)
  371.   end
  372.  
  373.   term.setTextColor(colors.white)
  374.   term.setBackgroundColor(colors.black)
  375.   term.setCursorPos(1,h)
  376.   term.scroll(1)
  377.   if not succ and err then
  378.     print("Program '"..filePath.."' crashed with error:")
  379.     printError(err)
  380.   else
  381.     print("program exited normally")
  382.   end
  383.   write("press a key to return to editor")
  384.   e={os.pullEvent("key")}
  385.   if charKeys[e[2]] then os.pullEvent() end
  386.   if not succ then
  387.     local lineNum,text=err:match(filename..":(%d+):(.-)")
  388.     if lineNum then
  389.       gotoLine(tonumber(lineNum))
  390.     end
  391.   end
  392.   term.clear()
  393.   redrawFrom(1)
  394.   doCursor()
  395. end
  396.  
  397. local function exit()
  398.   return true
  399. end
  400.  
  401. local function copy()
  402.   if selectBounds then
  403.     local startY,endY=selectBounds[1].y,selectBounds[2].y
  404.     local selectBounds=selectBounds
  405.     clipboard={}
  406.     if startY==endY then
  407.       clipboard[1]=lines[startY].rawText:sub(selectBounds[1].x,selectBounds[2].x)
  408.     else
  409.       clipboard[1]=lines[startY].rawText:sub(selectBounds[1].x)
  410.       for y=startY+1,endY-1 do
  411.         clipboard[#clipboard+1]=lines[y].rawText
  412.       end
  413.       clipboard[#clipboard+1]=lines[endY].rawText:sub(1,selectBounds[2].x)
  414.     end
  415.   end
  416. end
  417.  
  418. local function cut()
  419.   copy()
  420.   deleteSelection()
  421. end
  422.  
  423. local function paste()
  424.   if clipboard then
  425.     local lineNum,index=curTextPos()
  426.     --delete selection, if any, as we'll replace
  427.     deleteSelection()
  428.     --split this line at cursor
  429.     local before,after=lines[lineNum].rawText:sub(1,index-1),lines[lineNum].rawText:sub(index)
  430.     local newLines={}
  431.     --append first cb line to before for first line
  432.     newLines[1]=before..clipboard[1]
  433.     --rest will be new lines
  434.     for i=2,#clipboard do
  435.       newLines[i]=clipboard[i]
  436.     end
  437.     --append after to last
  438.     local newX=#newLines[#newLines]+1
  439.     newLines[#newLines]=newLines[#newLines]..after
  440.  
  441.     --ok, update first line
  442.     updateLine(lineNum,newLines[1],true)
  443.     --insert rest
  444.     for i=2,#newLines do
  445.       table.insert(lines,lineNum+i-1,{state={}})
  446.       updateLine(lineNum+i-1,newLines[i],i==#newLines)
  447.     end
  448.     redrawFrom(lineNum)
  449.     --new cursor pos will be in that last line
  450.     if #newLines>1 then
  451.       cursorDown(#newLines-1)
  452.     end
  453.     curPos.x=newX
  454.   end
  455. end
  456.  
  457.  
  458. local basicMenu={
  459.     "&save",
  460. --    "&load",
  461. --    "&new",
  462. --    "help-&?",
  463.     "&run",
  464.     "&exit",
  465. --    "&advanced",
  466.     "&copy",
  467.     "cut-&x",
  468.     "paste-&v",
  469.     funcs={
  470.       save=save,
  471.       load=load,
  472.       new=new,
  473.       help=help,
  474.       run=run,
  475.       exit=exit,
  476.  
  477.       copy=copy,
  478.       cut=cut,
  479.       paste=paste
  480.     },
  481. }
  482.  
  483. redrawFrom(1)
  484. term.setCursorBlink(true)
  485. doCursor()
  486.  
  487. local function writeMenuLabel(menuItem,selected)
  488.   local pre,pk,hk,post=menuItem:match("^(%a*)(%-?)&(.)(%a*)")
  489.   if not pre then
  490.     error("malformed menu label - '"..menuItem.."'")
  491.   end
  492.   local label=" "
  493.   local func=pre
  494.   term.setBackgroundColor(selected and colors.blue or colors.gray)
  495.   term.setTextColor(colors.white)
  496.   term.write(" "..pre)
  497.   if pk~="-" then
  498.     func=func..hk..post
  499.     term.setTextColor(colors.yellow)
  500.     term.write(hk)
  501.     term.setTextColor(colors.white)
  502.     term.write(post)
  503.     label=label..pre..hk..post
  504.   else
  505.     term.write("-")
  506.     term.setTextColor(colors.yellow)
  507.     term.write(hk)
  508.     label=label..pre.."-"..hk
  509.   end
  510.   term.write(" ")
  511.   label=label.." "
  512.   return func,hk,label
  513. end
  514.  
  515. local function doMenu()
  516.   --root menu
  517.   --          |15                      |40(26)       |54(39)
  518.   local buttonMap={}
  519.   local hkMap={}
  520.   local command
  521.   local selected=1
  522.   local function drawMenu(menu)
  523.     local menuStr=""
  524.     for i=1,#menu do
  525.       local itemStr=(selected==i and "[" or " ")
  526.       local pre,pk,hk,post=menu[i]:match("^(%a*)(%-?)&(.)(%a*)")
  527.       itemStr=itemStr..pre
  528.       local cmd=pre
  529.       if pk=="" then
  530.         itemStr=itemStr.."("..hk..")"..post
  531.         cmd=cmd..hk..post
  532.       else
  533.         itemStr=itemStr.."("..hk..")"
  534.       end
  535.       itemStr=itemStr..(selected==i and "]" or " ")
  536.       for j=1,#itemStr do
  537.         buttonMap[#buttonMap+1]={i,cmd}
  538.       end
  539.       menuStr=menuStr..itemStr
  540.     end
  541.     term.setCursorPos(1,h)
  542.     term.setTextColor(colors.black)
  543.     term.setBackgroundColor(colors.white)
  544.     term.write(menuStr)
  545.     term.setBackgroundColor(colors.black)
  546.   end
  547.   if term.isColor() then
  548.     drawMenu=function(menu)
  549.       term.setCursorPos(1,h)
  550.       for i=1,selected-1 do
  551.         local cmd,hk,label=writeMenuLabel(menu[i])
  552.         for j=1,#label do
  553.           buttonMap[#buttonMap+1]={i,cmd}
  554.           hkMap[hk]=cmd
  555.         end
  556.       end
  557.       local cmd,hk,label=writeMenuLabel(menu[selected],true)
  558.       command=cmd
  559.       for j=1,#label do
  560.         buttonMap[#buttonMap+1]={selected,cmd}
  561.       end
  562.       hkMap[hk]=cmd
  563.       menuStr=""
  564.       for i=selected+1,#menu do
  565.         local cmd,hk,label=writeMenuLabel(menu[i])
  566.         for j=1,#label do
  567.           buttonMap[#buttonMap+1]={i,cmd}
  568.         end
  569.         hkMap[hk]=cmd
  570.       end
  571.       term.setTextColor(colors.black)
  572.       term.setBackgroundColor(colors.lightGray)
  573.       term.write(menuStr)
  574.       term.setBackgroundColor(colors.black)
  575.     end
  576.   end
  577.  
  578.   --           new save load help exit more
  579.   while true do
  580.     drawMenu(basicMenu)
  581.     local e={os.pullEvent()}
  582.     if e[1]=="key" then
  583.       if e[2]==keys.leftCtrl then
  584.         command=nil
  585.         break
  586.       elseif e[2]==keys.right then
  587.         selected=selected%#basicMenu+1
  588.       elseif e[2]==keys.left then
  589.         selected=selected==1 and #basicMenu or selected-1
  590.       elseif e[2]==keys.enter then
  591.         --do the thing
  592.         break
  593.       end
  594.     elseif e[1]=="char" then
  595.       if hkMap[e[2]] then
  596.         command=hkMap[e[2]]
  597.         break
  598.       end
  599.     elseif e[1]=="mouse_click" then
  600.       local _,btn,x,y=unpack(e)
  601.       if y==h and buttonMap[x] then
  602.         selected=buttonMap[x][1]
  603.         if btn==1 then
  604.           command=buttonMap[x][2]
  605.           break
  606.         end
  607.       else
  608.         break
  609.       end
  610.     end
  611.  
  612.   end
  613.  
  614.   if basicMenu.funcs[command] and basicMenu.funcs[command]() then
  615.     running=false
  616.   else
  617.     redrawLine(h)
  618.     doCursor()
  619.   end
  620.  
  621. end
  622.  
  623.  
  624. while running do
  625.  
  626.   local e={os.pullEvent()}
  627.  
  628.   if e[1]=="key" then
  629.     local key=e[2]
  630.     if key==keys.down then
  631.       cursorDown()
  632.       drawLineNum()
  633.       doCursor()
  634.     elseif key==keys.up then
  635.       cursorUp()
  636.       drawLineNum()
  637.       doCursor()
  638.     elseif key==keys.right then
  639.       local lineNum,index=curTextPos()
  640.       if curPos.x>index then
  641.         curPos.x=index
  642.       end
  643.       if curPos.x+scrollPos.x-1>#lines[lineNum].rawText then
  644.         cursorDown()
  645.         drawLineNum()
  646.         setScrollX(1)
  647.         curPos.x=1
  648.       else
  649.         if curPos.x==w then
  650.           setScrollX(scrollPos.x+1)
  651.         else
  652.           curPos.x=curPos.x+1
  653.         end
  654.       end
  655.       updateSelect()
  656.       doCursor()
  657.     elseif key==keys.left then
  658.       if curPos.x==1 then
  659.         cursorUp()
  660.         curPos.x=#cursorRow().rawText+1
  661.         if curPos.x>w then
  662.           setScrollX(curPos.x-w+1)
  663.           curPos.x=w
  664.         end
  665.         drawLineNum()
  666.       else
  667.         curPos.x=curPos.x-1
  668.       end
  669.       updateSelect()
  670.       doCursor()
  671.     elseif key==keys.pageDown then
  672.       if not scrollY(h) then
  673.         curPos.y=math.min(h,#lines)
  674.       end
  675.       updateSelect()
  676.       doCursor()
  677.     elseif key==keys.pageUp then
  678.       if not scrollY(-h) then
  679.         curPos.y=1
  680.       end
  681.       updateSelect()
  682.       doCursor()
  683.     elseif key==keys.leftCtrl then
  684.       doMenu()
  685.     elseif key==keys.enter then
  686.       if selectBounds then
  687.         deleteSelection()
  688.       end
  689.       --carry on with the cr
  690.       local lineNum,index=curTextPos()
  691.       local curText=lines[lineNum].rawText
  692.       local pre,post=curText:sub(1,index-1),curText:sub(index)
  693.       updateLine(lineNum,pre,true)
  694.       table.insert(lines,lineNum+1,{state={}})
  695.       updateLine(lineNum+1,post)
  696.       if curPos.y==h then
  697.         cursorDown()
  698.       else
  699.         curPos.y=curPos.y+1
  700.       end
  701.       curPos.x=1
  702.       redrawFrom(curPos.y-1)
  703.       doCursor()
  704.     elseif key==keys.backspace then
  705.       if selectBounds then
  706.         deleteSelection()
  707.       else
  708.         local lineNum,index=curTextPos()
  709.         if index==1 then
  710.           if lineNum>1 then
  711.             local prevLine=lines[lineNum-1]
  712.             curPos.x=#prevLine.rawText+1
  713.             local curLine=table.remove(lines,lineNum)
  714.  
  715.             updateLine(lineNum-1,prevLine.rawText..curLine.rawText)
  716.             curPos.y=curPos.y-1
  717.             redrawFrom(curPos.y)
  718.             drawLineNum()
  719.           end
  720.         else
  721.           local curText=lines[lineNum].rawText
  722.           local newText=curText:sub(1,index-2)..curText:sub(index)
  723.           updateLine(lineNum,newText)
  724.           curPos.x=index-1
  725.         end
  726.       end
  727.       doCursor()
  728.     elseif key==keys.delete then
  729.       if selectBounds then
  730.         deleteSelection()
  731.       else
  732.         local lineNum,index=curTextPos()
  733.         local curText=lines[lineNum].rawText
  734.         if index==#curText+1 then
  735.           if lineNum<#lines then
  736.             local nextLine=table.remove(lines,lineNum+1)
  737.             updateLine(lineNum,curText..nextLine.rawText)
  738.             redrawFrom(curPos.y)
  739.           end
  740.         else
  741.           local newText=curText:sub(1,index-1)..curText:sub(index+1)
  742.           updateLine(lineNum,newText)
  743.           curPos.x=index
  744.         end
  745.       end
  746.       doCursor()
  747.     elseif key==keys.home then
  748.       setScrollX(1)
  749.       curPos.x=1
  750.       updateSelect()
  751.       doCursor()
  752.     elseif key==keys["end"] then
  753.       local max=#cursorRow().rawText+1
  754.       if max>w then
  755.         local target=max-w+1
  756.         if target>scrollPos.x then
  757.           setScrollX(target)
  758.           curPos.x=w
  759.         else
  760.           curPos.x=max - scrollPos.x
  761.         end
  762.       else
  763.         curPos.x=max
  764.       end
  765.       updateSelect()
  766.       doCursor()
  767.     end
  768.  
  769.   elseif e[1]=="char" then
  770.     local char=e[2]
  771.     if selectBounds then
  772.       deleteSelection()
  773.     end
  774.     --get the affected line and actual x position in line
  775.     local lineNum, index = curTextPos()
  776.     local line=lines[lineNum]
  777.     --insert our char!
  778.     local newText=line.rawText:sub(1,index-1)..char..line.rawText:sub(index)
  779.     curPos.x=index+1
  780.     updateLine(lineNum,newText)
  781.     doCursor()
  782.  
  783.   elseif e[1]=="mouse_scroll" then
  784.     if e[2]>0 then
  785.       cursorDown()
  786.     else
  787.       cursorUp()
  788.     end
  789.     drawLineNum()
  790.     doCursor()
  791.  
  792.   elseif e[1]=="mouse_click" then
  793.     if e[2]==1 then
  794.       local x,y=math.min(math.max(e[3],1),w),math.min(math.max(e[4],1),h)
  795.       if y+scrollPos.y-1 > #lines then
  796.         curPos.y=#lines
  797.         curPos.x=#lines[#lines].rawText+1
  798.       else
  799.         curPos.x=x
  800.         curPos.y=y
  801.       end
  802.       updateSelect()
  803.       drawLineNum()
  804.       doCursor()
  805.       lastClickPos={x=x,y=y}
  806.     elseif e[2]==2 then
  807.  
  808.     elseif e[2]==3 then
  809.  
  810.     end
  811.   elseif e[1]=="mouse_drag" then
  812.     local dragTo=curToTextPos({x=math.min(math.max(e[3],1),w),y=math.min(math.max(e[4],1),h)})
  813.     dragTo.x=math.min(dragTo.x,#lines[dragTo.y].rawText)
  814.     local newBounds
  815.     local dragFrom=lastClickPos
  816.     if dragTo.y<dragFrom.y or (dragTo.y==dragFrom.y and dragTo.x<dragFrom.x) then
  817.       newBounds={dragTo,curToTextPos(dragFrom)}
  818.     else
  819.       newBounds={curToTextPos(dragFrom),dragTo}
  820.     end
  821.     updateSelect(newBounds)
  822.   elseif e[1]=="term_resize" then
  823.     w,h=term.getSize()
  824.     redrawFrom(1)
  825.     doCursor()
  826.   end
  827.  
  828. end
  829.  
  830. term.clear()
  831. term.setCursorPos(1,1)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement