LoganDark

Input

Jan 30th, 2018
188
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 6.67 KB | None | 0 0
  1. return function(_sCensor, _tHistory, _fnAutocomp, _sDefault, _nMaxlen, _bPrintAfter,  _nStartPos, _fnColorizer)
  2.     local nStartX, nStartY = term.getCursorPos()
  3.     nStartX = nStartX - 1
  4.     nStartY = nStartY - 1
  5.     _sCensor = _sCensor and _sCensor:sub(1, 1) or nil
  6.     _tHistory = _tHistory or {}
  7.     _fnAutocomp = _fnAutocomp or function() end
  8.     _nMaxlen = _nMaxlen or term.getSize() - nStartX
  9.     _bPrintAfter = _bPrintAfter or true
  10.     _fnColorizer = _fnColorizer or function(_sLine, _nPos, _nScroll, _bLast, _sCompletion)
  11.         if _sCompletion then
  12.             return ('0'):rep(#_sLine) .. ('f'):rep(#_sCompletion), ('f'):rep(#_sLine) .. ('7'):rep(#_sCompletion)
  13.         else
  14.             return ('0'):rep(#_sLine), ('f'):rep(#_sLine)
  15.         end
  16.     end
  17.  
  18.     local sLine = _sDefault or ''
  19.     local nPos = _nStartPos and math.max(1, math.min(#sLine, _nStartPos)) or #sLine
  20.     local nScroll = math.max(0, nPos - _nMaxlen + 1)
  21.     local nMark = nPos
  22.     local bShift = false
  23.     local tCompletions = nil
  24.     local nCompletion = nil
  25.     local nHistoryPos = nil
  26.  
  27.     local function getMarks()
  28.         local nMarkStart, nMarkEnd
  29.  
  30.         if nMark ~= nPos then
  31.             if nMark < nPos then
  32.                 nMarkStart = nMark
  33.                 nMarkEnd = nPos
  34.             else
  35.                 nMarkStart = nPos
  36.                 nMarkEnd = nMark
  37.             end
  38.         end
  39.  
  40.         return nMarkStart, nMarkEnd
  41.     end
  42.  
  43.     local function draw(_bLast)
  44.         local nStartIndex = nScroll + 1
  45.         local nEndIndex = nScroll + _nMaxlen
  46.  
  47.         local sCensored = _sCensor and _sCensor:rep(#sLine) or sLine
  48.         local sCompletion = ''
  49.  
  50.         if not _bLast then
  51.             sCompletion = nCompletion and tCompletions[nCompletion] or ''
  52.         end
  53.  
  54.         sCensored = sCensored .. sCompletion
  55.  
  56.         if nScroll < nPos - _nMaxlen + math.max(1, sCompletion:len()) then
  57.             nScroll = nPos - _nMaxlen + math.max(1, sCompletion:len())
  58.         end
  59.  
  60.         local sClippedText = sCensored:sub(nStartIndex, nEndIndex)
  61.         sClippedText = sClippedText .. string.rep(' ', math.max(0, _nMaxlen - #sClippedText))
  62.  
  63.         local sFg, sBg = _fnColorizer(sLine, nPos, nScroll, _bLast, sCompletion)
  64.         local nMarkStart, nMarkEnd = getMarks()
  65.  
  66.         if nMarkStart then
  67.             local sOldFg, sOldBg = sFg, sBg
  68.  
  69.             sFg = sOldFg:sub(1, nMarkStart) .. sOldBg:sub(nMarkStart + 1, nMarkEnd) .. sOldFg:sub(nMarkEnd + 1)
  70.             sBg = sOldBg:sub(1, nMarkStart) .. sOldFg:sub(nMarkStart + 1, nMarkEnd) .. sOldBg:sub(nMarkEnd + 1)
  71.         end
  72.  
  73.         local sClippedFg = sFg:sub(nStartIndex, nEndIndex)
  74.         local sClippedBg = sBg:sub(nStartIndex, nEndIndex)
  75.         sClippedFg = sClippedFg .. string.rep('0', math.max(0, _nMaxlen - #sClippedFg))
  76.         sClippedBg = sClippedBg .. string.rep('f', math.max(0, _nMaxlen - #sClippedBg))
  77.  
  78.         term.setCursorPos(nStartX + 1, nStartY + 1)
  79.         term.blit(sClippedText, sClippedFg, sClippedBg)
  80.         term.setCursorPos(nStartX + nPos - nScroll + 1, nStartY + 1)
  81.     end
  82.  
  83.     local function setCursor(_nX, _bSetMark)
  84.         nPos = math.max(0, math.min(#sLine, _nX))
  85.  
  86.         if _bSetMark then
  87.             nMark = nPos
  88.         end
  89.     end
  90.  
  91.     local function deleteMarked()
  92.         local nMarkStart, nMarkEnd = getMarks()
  93.  
  94.         if nMarkStart then
  95.             sLine = sLine:sub(1, nMarkStart) .. sLine:sub(nMarkEnd + 1)
  96.  
  97.             setCursor(nMarkStart, true)
  98.         end
  99.     end
  100.  
  101.     local function recomplete()
  102.         if nPos == #sLine then
  103.             tCompletions = _fnAutocomp(sLine)
  104.  
  105.             if tCompletions then
  106.                 nCompletion = 1
  107.             else
  108.                 nCompletion = nil
  109.             end
  110.         else
  111.             tCompletions = nil
  112.             nCompletion = nil
  113.         end
  114.     end
  115.  
  116.     term.setCursorBlink(true)
  117.  
  118.     local bRecomplete = true
  119.  
  120.     while true do
  121.         if bRecomplete then
  122.             recomplete()
  123.         end
  124.  
  125.         bRecomplete = true
  126.  
  127.         draw(false)
  128.  
  129.         local sEvent, vArg, vArg2, vArg3 = os.pullEvent()
  130.  
  131.         if sEvent == 'char' or sEvent == 'paste' then
  132.             deleteMarked()
  133.             sLine = sLine:sub(1, nPos) .. vArg .. sLine:sub(nPos + 1)
  134.             setCursor(nPos + 1, true)
  135.         elseif sEvent == 'key' then
  136.             if vArg == keys.enter then
  137.                 break
  138.             elseif vArg == keys.left then
  139.                 if nPos > 0 then
  140.                     setCursor(nPos - 1, not bShift)
  141.                 end
  142.             elseif vArg == keys.right then
  143.                 if nPos < #sLine then
  144.                     setCursor(nPos + 1, not bShift)
  145.                 end
  146.             elseif vArg == keys.up then
  147.                 if nCompletion then
  148.                     if nCompletion == 1 then
  149.                         nCompletion = #tCompletions
  150.                     else
  151.                         nCompletion = nCompletion - 1
  152.                     end
  153.                 elseif _tHistory and #_tHistory > 0 then
  154.                     if nHistoryPos == nil then
  155.                         nHistoryPos = #_tHistory
  156.                     elseif nHistoryPos > 1 then
  157.                         nHistoryPos = nHistoryPos - 1
  158.                     end
  159.  
  160.                     if nHistoryPos then
  161.                         sLine = _tHistory[nHistoryPos]
  162.                         setCursor(#sLine, true)
  163.                     end
  164.                 end
  165.  
  166.                 bRecomplete = false
  167.             elseif vArg == keys.down then
  168.                 if nCompletion then
  169.                     if nCompletion == #tCompletions then
  170.                         nCompletion = 1
  171.                     else
  172.                         nCompletion = nCompletion + 1
  173.                     end
  174.                 elseif _tHistory and #_tHistory > 0 then
  175.                     if nHistoryPos == #_tHistory then
  176.                         nHistoryPos = nil
  177.                     elseif nHistoryPos ~= nil then
  178.                         nHistoryPos = nHistoryPos + 1
  179.                     end
  180.  
  181.                     if nHistoryPos then
  182.                         sLine = _tHistory[nHistoryPos]
  183.                         setCursor(#sLine, true)
  184.                     end
  185.                 end
  186.  
  187.                 bRecomplete = false
  188.             elseif vArg == keys.tab then
  189.                 if nCompletion then
  190.                     sLine = sLine .. tCompletions[nCompletion]
  191.                     setCursor(#sLine, not bShift)
  192.                 end
  193.             elseif vArg == keys.backspace then
  194.                 if getMarks() then
  195.                     deleteMarked()
  196.                 else
  197.                     if nPos > 0 then
  198.                         sLine = sLine:sub(1, nPos - 1) .. sLine:sub(nPos + 1)
  199.                         setCursor(nPos - 1, not bShift)
  200.                     end
  201.                 end
  202.             elseif vArg == keys.delete then
  203.                 if getMarks() then
  204.                     deleteMarked()
  205.                 else
  206.                     if nPos < #sLine then
  207.                         sLine = sLine:sub(1, nPos) .. sLine:sub(nPos + 2)
  208.                     end
  209.                 end
  210.             elseif vArg == keys.home then
  211.                 setCursor(0, not bShift)
  212.             elseif vArg == keys['end'] then
  213.                 setCursor(#sLine, not bShift)
  214.             elseif vArg == keys.leftShift then
  215.                 bShift = true
  216.             end
  217.         elseif sEvent == 'key_up' then
  218.             if vArg == keys.leftShift then
  219.                 bShift = false
  220.             else
  221.                 bRecomplete = false
  222.             end
  223.         elseif sEvent == 'mouse_click' then
  224.             if vArg == 1 then
  225.                 local nX, nY = vArg2 - 1, vArg3 - 1
  226.  
  227.                 if nY == nStartY then
  228.                     if nX >= nStartX and nX < nStartX + _nMaxlen then
  229.                         setCursor(nScroll + (nX - nStartX), not bShift)
  230.                     end
  231.                 end
  232.             end
  233.         elseif sEvent == 'mouse_drag' then
  234.             if vArg == 1 then
  235.                 local nX, nY = vArg2 - 1, vArg3 - 1
  236.  
  237.                 if nY == nStartY then
  238.                     if nX >= nStartX and nX < nStartX + _nMaxlen then
  239.                         setCursor(nScroll + (nX - nStartX), false)
  240.                     end
  241.                 end
  242.             end
  243.         end
  244.  
  245.         if nScroll < nPos - _nMaxlen + 1 then
  246.             nScroll = nPos - _nMaxlen + 1
  247.         elseif nScroll > nPos - 2 then
  248.             nScroll = math.max(0, nPos - 2)
  249.         end
  250.     end
  251.  
  252.     draw(true)
  253.     term.setCursorBlink(false)
  254.     term.setCursorPos(nStartX + _nMaxlen + 1, nStartY + 1)
  255.  
  256.     if _bPrintAfter then
  257.         print()
  258.     end
  259.  
  260.     return sLine
  261. end
Advertisement
Add Comment
Please, Sign In to add comment