Advertisement
theoriginalbit

Custom Read w/ Limit & Opt. No Termination (backward compat)

Apr 26th, 2013
404
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 3.38 KB | None | 0 0
  1. function read( _mask, _history, _limit, _noTerminate )
  2.   if _mask and type(_mask) ~= "string" then
  3.     error("Invalid parameter #1: Expected string, got "..type(_mask), 2)
  4.   end
  5.   if _history and type(_history) ~= "table" then
  6.     error("Invalid parameter #2: Expected table, got "..type(_history), 2)
  7.   end
  8.   if _limit and type(_limit) ~= "number" then
  9.     error("Invalid parameter #3: Expected number, got "..type(_limit), 2)
  10.   end
  11.   if _noTerminate and type(_noTerminate) ~= "boolean" then
  12.     error("Invalid argument #3: Expected boolean, got "..nativeType(_noTerminate), 2)
  13.   end
  14.  
  15.   term.setCursorBlink(true)
  16.  
  17.   local input = ""
  18.   local pos = 0
  19.   local historyPos = nil
  20.   local pullEvent = _noTerminate and os.pullEventRaw or os.pullEvent
  21.  
  22.   local sw, sh = term.getSize()
  23.   local sx, sy = term.getCursorPos()
  24.  
  25.   local function redraw( _special )
  26.     local scroll = (sx + pos >= sw and (sx + pos) - sw or 0)
  27.     local replace = _special or _mask
  28.     local output = replace and (string.rep( replace, math.ceil(#input / #replace) - scroll )):sub(1, #input) or input:sub(scroll + 1)
  29.     term.setCursorPos( sx, sy )
  30.     term.write( output )
  31.     term.setCursorPos( sx + pos - scroll, sy )
  32.   end
  33.  
  34.   local nativeScroll = term.scroll
  35.   term.scroll = function( _n ) local ok, err = pcall( function() return nativeScroll( _n ) end ) if ok then sy = sy - _n return err end error( err, 2 ) end
  36.  
  37.   while true do
  38.     local event, code = pullEvent()
  39.     if event == "char" and (not _limit or #input < _limit) then
  40.       input = input:sub(1, pos)..code..input:sub(pos+1)
  41.       pos = pos + 1
  42.     elseif event == "paste" then
  43.       input = input:sub(1, pos)..code..input:sub(pos+1)
  44.       pos = pos + #code
  45.     elseif event == "key" then
  46.       if code == keys.enter or code == keys.numPadEnter then
  47.         break
  48.       elseif code == keys.backspace and pos > 0 then
  49.         redraw(' ')
  50.         input = input:sub(1, math.max(pos-1, 0))..input:sub(pos+1)
  51.         pos = math.max(pos-1, 0)
  52.       elseif code == keys.delete and pos < #input then
  53.         redraw(' ')
  54.         input = input:sub(1, pos)..input:sub(pos+2)
  55.       elseif code == keys.home then
  56.         pos = 0
  57.       elseif code == keys["end"] then
  58.         pos = #input
  59.       elseif code == keys.left and pos > 0 then
  60.         pos = math.max(pos-1, 0)
  61.       elseif code == keys.right and pos < #input then
  62.         pos = math.min(pos+1, #input)
  63.       elseif _history and code == keys.up or code == keys.down then
  64.         redraw(' ')
  65.         if code == keys.up then
  66.           if not historyPos then
  67.             historyPos = #_history
  68.           elseif historyPos > 1 then
  69.             historyPos = historyPos - 1
  70.           end
  71.         else
  72.           if historyPos ~= nil and historyPos < #_history then
  73.             historyPos = math.max(historyPos+1, #_history)
  74.           elseif historyPos == #_history then
  75.             historyPos = nil
  76.           end
  77.         end
  78.  
  79.         if historyPos and #_history > 0 then
  80.           input = string.sub(_history[historyPos], 1, _limit) or ""
  81.           pos = #input
  82.         else
  83.           input = ""
  84.           pos = 0
  85.         end
  86.       end
  87.     end
  88.  
  89.     redraw(_mask)
  90.   end
  91.  
  92.   term.scroll = nativeScroll
  93.  
  94.   term.setCursorBlink(false)
  95.  
  96.   if sy + 1 > sh then
  97.     term.scroll(sy + 1 - sh)
  98.     term.setCursorPos(1, sy)
  99.   else
  100.     term.setCursorPos(1, sy + 1)
  101.   end
  102.  
  103.   return input
  104. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement