local separators = " ()[],-+*/=<>" local function split_by_last_separator(s) for i = #s, 1, -1 do local c = s:sub(i, i) if separators:find(c, 1, true) then if i == #s then -- Separador al final return s, "" end -- Separador en medio return s:sub(1, i), s:sub(i + 1) end end -- Sin separadores return "", s end local function split_by_last_dot(s) local last = s:match(".*()%.") -- devuelve la posición DESPUÉS del último punto if not last then -- No hay puntos: primera parte = cadena completa, segunda = "" return "", s end -- Si el punto está al final, la segunda parte es "" if last > #s then return s, "" end -- Primera parte incluye el punto local first = s:sub(1, last - 1) local second = s:sub(last+1) return first, second end function get_by_path(path) local current = _G for segment in path:gmatch("[^%.]+") do if type(current) ~= "table" then return nil end current = current[segment] if current == nil then --print("get_by_path: " ..segment.." es nil") return nil end end --print("get_by_path: ok") return current end function entries_starting_with(s, t) if not t then return nil end local result = {} for k, v in pairs(t) do if type(k) == "string" and k:sub(1, #s) == s then result[#result+1] = k end end return result end console = { command = "", history = {}, history_pos = 0, cursor = 50, autocomplete_list = {}, autocomplete_prefix = "", autocomplete_index = 1, enable = function() app.push(console.update) console.command = "" end, update = function() surf.target(0) draw.rrectf(0, 92, 160, 108, 4, 1) draw.rrect(0, 92, 160, 108, 4, 13) draw.text(">", 2, 96, 13) draw.text(console.command, 6, 96, 13) if console.autocomplete_list and #console.autocomplete_list>0 then --local num = math.min(5, #console.autocomplete_list) --local base_y = 92-num*7 --draw.rectf(3+#console.command*4, base_y, 80, num*7, 1) --draw.rect(3+#console.command*4, base_y, 80, num*7, 13) --for i=1,num do -- draw.text(console.autocomplete_list[i], 6+#console.command*4, base_y+i*7, 13) --end local sufix = console.autocomplete_list[console.autocomplete_index]:sub(#console.autocomplete_prefix+1) draw.text(sufix, 6+#console.command*4, 96, 6) end if console.cursor > 24 then draw.text("_", 6+#console.command*4, 96, 13) end console.cursor = console.cursor - 1 if console.cursor == 0 then console.cursor = 50 end if key.press(key.ESCAPE) then app.pop() return end local should_update = false if #console.history>0 then if key.press(key.UP) and console.history_pos > 1 then console.history_pos = console.history_pos - 1 console.command = console.history[console.history_pos] should_update = true elseif key.press(key.DOWN) and console.history_pos < #console.history then console.history_pos = console.history_pos + 1 console.command = console.history[console.history_pos] should_update = true end end local k = key.press() if k ~= key.UNKNOWN then should_update = true if k >= key.A and k <= key.Z then if key.down(key.LSHIFT) or key.down(key.RSHIFT) then console.command = console.command .. string.char(k+61) else console.command = console.command .. string.char(k+93) end elseif k == key.N0 then if key.down(key.LSHIFT) or key.down(key.RSHIFT) then console.command = console.command .. '=' elseif key.down(key.RALT) then console.command = console.command .. '}' else console.command = console.command .. '0' end elseif k == key.N1 then if key.down(key.LSHIFT) or key.down(key.RSHIFT) then console.command = console.command .. '!' elseif key.down(key.RALT) then console.command = console.command .. '|' else console.command = console.command .. '1' end elseif k == key.N2 then if key.down(key.LSHIFT) or key.down(key.RSHIFT) then console.command = console.command .. '"' elseif key.down(key.RALT) then console.command = console.command .. '@' else console.command = console.command .. '2' end elseif k == key.N3 then if key.down(key.LSHIFT) or key.down(key.RSHIFT) then console.command = console.command .. '·' elseif key.down(key.RALT) then console.command = console.command .. '#' else console.command = console.command .. '3' end elseif k == key.N4 then if key.down(key.LSHIFT) or key.down(key.RSHIFT) then console.command = console.command .. '$' elseif key.down(key.RALT) then console.command = console.command .. '~' else console.command = console.command .. '4' end elseif k == key.N5 then if key.down(key.LSHIFT) or key.down(key.RSHIFT) then console.command = console.command .. '%' elseif key.down(key.RALT) then console.command = console.command .. ' ' else console.command = console.command .. '5' end elseif k == key.N6 then if key.down(key.LSHIFT) or key.down(key.RSHIFT) then console.command = console.command .. '&' elseif key.down(key.RALT) then console.command = console.command .. ' ' else console.command = console.command .. '6' end elseif k == key.N7 then if key.down(key.LSHIFT) or key.down(key.RSHIFT) then console.command = console.command .. '/' elseif key.down(key.RALT) then console.command = console.command .. ' ' else console.command = console.command .. '7' end elseif k == key.N8 then if key.down(key.LSHIFT) or key.down(key.RSHIFT) then console.command = console.command .. '(' elseif key.down(key.RALT) then console.command = console.command .. ' ' else console.command = console.command .. '8' end elseif k == key.N9 then if key.down(key.LSHIFT) or key.down(key.RSHIFT) then console.command = console.command .. ')' elseif key.down(key.RALT) then console.command = console.command .. ' ' else console.command = console.command .. '9' end elseif k == key.PERIOD then if key.down(key.LSHIFT) or key.down(key.RSHIFT) then console.command = console.command .. ':' else console.command = console.command .. '.' end elseif k == key.COMMA then if key.down(key.LSHIFT) or key.down(key.RSHIFT) then console.command = console.command .. ';' else console.command = console.command .. ',' end elseif k == key.GRAVE then if key.down(key.LSHIFT) or key.down(key.RSHIFT) then console.command = console.command .. ' ' elseif key.down(key.RALT) then console.command = console.command .. '\\' else console.command = console.command .. ' ' end elseif k == key.EQUALS then if key.down(key.LSHIFT) or key.down(key.RSHIFT) then console.command = console.command .. '¿' else console.command = console.command .. '¡' end elseif k == key.SLASH then if key.down(key.LSHIFT) or key.down(key.RSHIFT) then console.command = console.command .. '_' elseif key.down(key.RALT) then console.command = console.command .. ' ' else console.command = console.command .. '-' end elseif k == key.APOSTROPHE then if key.down(key.LSHIFT) or key.down(key.RSHIFT) then console.command = console.command .. '"' elseif key.down(key.RALT) then console.command = console.command .. '{' else console.command = console.command .. '\'' end elseif k == key.SEMICOLON then if key.down(key.LSHIFT) or key.down(key.RSHIFT) then console.command = console.command .. 'Ñ' elseif key.down(key.RALT) then console.command = console.command .. ' ' else console.command = console.command .. 'ñ' end elseif k == key.BACKSLASH then if key.down(key.LSHIFT) or key.down(key.RSHIFT) then console.command = console.command .. 'Ç' elseif key.down(key.RALT) then console.command = console.command .. '}' else console.command = console.command .. 'ç' end elseif k == key.RIGHTBRACKET then if key.down(key.LSHIFT) or key.down(key.RSHIFT) then console.command = console.command .. '*' elseif key.down(key.RALT) then console.command = console.command .. ']' else console.command = console.command .. '+' end elseif k == key.LEFTBRACKET then if key.down(key.LSHIFT) or key.down(key.RSHIFT) then console.command = console.command .. '^' elseif key.down(key.RALT) then console.command = console.command .. '[' else console.command = console.command .. '`' end elseif k == key.NONUSBACKSLASH then if key.down(key.LSHIFT) or key.down(key.RSHIFT) then console.command = console.command .. '>' elseif key.down(key.RALT) then console.command = console.command .. ' ' else console.command = console.command .. '<' end elseif k == key.MINUS then if key.down(key.LSHIFT) or key.down(key.RSHIFT) then console.command = console.command .. '?' else console.command = console.command .. '\'' end elseif k == key.SPACE then console.command = console.command .. ' ' elseif k == key.BACKSPACE then console.command = console.command:sub(1, #console.command - 1) elseif k == key.TAB then local sufix = console.autocomplete_list[console.autocomplete_index]:sub(#console.autocomplete_prefix+1) console.command = console.command .. sufix elseif k == key.RETURN then table.insert(console.history, console.command) console.history_pos = #console.history+1 local f,err = load(console.command) if not f then print("Error al compilar:", err) else print(f()) app.pop() end end end if should_update then local a, b = split_by_last_separator(console.command) if b ~= "" then local ba, bb = split_by_last_dot(b) console.autocomplete_prefix = bb if ba ~= "" then console.autocomplete_list = entries_starting_with(bb, get_by_path(ba)) --print(bb..":"..ba) --print(#console.autocomplete_list) else console.autocomplete_list = entries_starting_with(bb, _G) --print(bb..":".."golbal") --print(#console.autocomplete_list) end else console.autocomplete_prefix = "" console.autocomplete_list = entries_starting_with("", _G) --print(""..":".."golbal") --print(#console.autocomplete_list) end end end, }