diff --git a/.DS_Store b/.DS_Store index bf3e1cda..2fc6e892 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/Applications.txt b/Applications.txt index c0e00c07..b849f1da 100644 --- a/Applications.txt +++ b/Applications.txt @@ -253,7 +253,7 @@ name="lib/MineOSCore.lua", url="IgorTimofeev/OpenComputers/master/lib/MineOSCore.lua", type="Library", - version=1.45, + version=1.46, }, { name="lib/advancedLua.lua", @@ -300,7 +300,7 @@ name="lib/GUI.lua", url="IgorTimofeev/OpenComputers/master/lib/GUI.lua", type="Library", - version=1.40, + version=1.41, }, { name="lib/windows.lua", @@ -360,7 +360,7 @@ name="lib/syntax.lua", url="IgorTimofeev/OpenComputers/master/lib/syntax.lua", type="Library", - version=1.10, + version=1.11, }, { name="lib/palette.lua", @@ -375,8 +375,8 @@ version=1.19, }, { - name="lib/archive.lua", - url="IgorTimofeev/OpenComputers/master/lib/archive.lua", + name="lib/compressor.lua", + url="IgorTimofeev/OpenComputers/master/lib/compressor.lua", type="Library", version=1.0, }, @@ -470,14 +470,14 @@ url="IgorTimofeev/OpenComputers/master/Applications/Motd/English.txt", type="Script", forceDownload=true, - version=1.02, + version=1.03, }, { name="usr/misc/greetings/Russian.txt", url="IgorTimofeev/OpenComputers/master/Applications/Motd/Russian.txt", type="Script", forceDownload=true, - version=1.02, + version=1.03, }, { name="etc/motd", diff --git a/Applications/.DS_Store b/Applications/.DS_Store index cb90986e..837952ad 100644 Binary files a/Applications/.DS_Store and b/Applications/.DS_Store differ diff --git a/Applications/MineCodeIDE/MineCodeIDE.lua b/Applications/MineCodeIDE/MineCodeIDE.lua index 48b4d5db..bf3528de 100755 --- a/Applications/MineCodeIDE/MineCodeIDE.lua +++ b/Applications/MineCodeIDE/MineCodeIDE.lua @@ -3,7 +3,7 @@ -- "/MineOS/Applications/MineCode IDE.app/MineCode IDE.lua" open OS.lua --- package.loaded.syntax = nil +package.loaded.syntax = nil -- package.loaded.ECSAPI = nil -- package.loaded.GUI = nil -- package.loaded.windows = nil @@ -58,6 +58,7 @@ local config = { doubleClickDelay = 0.4, screenScale = 1, enableAutoBrackets = true, + highlightLuaSyntax = true, } local colors = { @@ -446,6 +447,7 @@ local function selectWord() from = {symbol = from, line = cursor.position.line}, to = {symbol = to, line = cursor.position.line}, } + cursor.position.symbol = to end end @@ -1028,7 +1030,7 @@ end local function createWindow() mainWindow = windows.fullScreen() - mainWindow.codeView = mainWindow:addCodeView(1, 1, 1, 1, {""}, 1, 1, 1, {}, {}, true, 2) + mainWindow.codeView = mainWindow:addCodeView(1, 1, 1, 1, {""}, 1, 1, 1, {}, {}, config.highlightLuaSyntax, 2) mainWindow.codeView.scrollBars.vertical.onTouch = function() mainWindow.codeView.fromLine = mainWindow.codeView.scrollBars.vertical.value end @@ -1227,6 +1229,8 @@ local function createWindow() mainWindow.toggleSyntaxHighlightingButton.switchMode, mainWindow.toggleSyntaxHighlightingButton.pressed = true, true mainWindow.toggleSyntaxHighlightingButton.onTouch = function() mainWindow.codeView.highlightLuaSyntax = not mainWindow.codeView.highlightLuaSyntax + config.highlightLuaSyntax = mainWindow.codeView.highlightLuaSyntax + saveConfig() end mainWindow.runButton = mainWindow.topToolBar:addAdaptiveButton(1, 1, 3, 1, 0x4B4B4B, 0xEEEEEE, 0xCCCCCC, 0x444444, "▷") diff --git a/MineOS/.DS_Store b/MineOS/.DS_Store index 745646e4..f4c1125b 100644 Binary files a/MineOS/.DS_Store and b/MineOS/.DS_Store differ diff --git a/MineOS/Languages/English.lang b/MineOS/Languages/English.lang index d6f1684e..4ed815c5 100755 --- a/MineOS/Languages/English.lang +++ b/MineOS/Languages/English.lang @@ -30,7 +30,7 @@ contextMenuRemoveFromDock = "Remove from Dock", contextMenuMoveRight = "Move right", contextMenuMoveLeft = "Move left", - contextMenuArchive = "Add to archive", + contextMenuArchive = "Compress", contextMenuDelete = "Delete", contextMenuAddToFavourites = "Add to favourites", contextMenuCreateApplication = "Create MineOS application", diff --git a/MineOS/Languages/Russian.lang b/MineOS/Languages/Russian.lang index f341aced..c5bc346e 100755 --- a/MineOS/Languages/Russian.lang +++ b/MineOS/Languages/Russian.lang @@ -30,7 +30,7 @@ contextMenuRemoveFromDock = "Удалить из Dock", contextMenuMoveRight = "Передвинуть правее", contextMenuMoveLeft = "Передвинуть левее", - contextMenuArchive = "Добавить в архив", + contextMenuArchive = "Сжать", contextMenuDelete = "Удалить", contextMenuAddToFavourites = "Добавить в избранное", contextMenuCreateApplication = "Создать приложение MineOS", diff --git a/lib/GUI.lua b/lib/GUI.lua index 5ca1503d..e30a9d3b 100755 --- a/lib/GUI.lua +++ b/lib/GUI.lua @@ -1013,7 +1013,7 @@ local function inputFieldDraw(inputField) end if inputField.highlightLuaSyntax then - require("syntax").highlightString(inputField.x, inputField.y, inputField.text) + require("syntax").highlightString(inputField.x, inputField.y, inputField.text, 2) else buffer.text( inputField.x, diff --git a/lib/MineOSCore.lua b/lib/MineOSCore.lua index 92adca3b..5981567e 100755 --- a/lib/MineOSCore.lua +++ b/lib/MineOSCore.lua @@ -10,8 +10,6 @@ local buffer = require("doubleBuffering") local GUI = require("GUI") local windows = require("windows") local ecs = require("ECSAPI") -local zip = require("archive") -local syntax = require("syntax") local fs = require("filesystem") local unicode = require("unicode") @@ -298,10 +296,10 @@ function MineOSCore.analyzeIconFormat(iconObject) iconObject.launch = function() MineOSCore.safeLaunch(MineOSCore.paths.applications .. "Viewer.app/Viewer.lua", "open", iconObject.path) end - elseif iconObject.format == ".pkg" or iconObject.format == ".zip" then + elseif iconObject.format == ".pkg" then iconObject.iconImage.image = MineOSCore.icons.archive iconObject.launch = function() - zip.unarchive(iconObject.path, (MineOSCore.getFilePath(iconObject.path) or "")) + require("compressor").unpack(iconObject.path, MineOSCore.getFilePath(iconObject.path)) end elseif iconObject.format == ".3dm" then iconObject.iconImage.image = MineOSCore.icons.model3D @@ -633,10 +631,10 @@ function MineOSCore.iconRightClick(icon, eventData) {MineOSCore.localization.contextMenuCopy}, {MineOSCore.localization.contextMenuRename}, {MineOSCore.localization.contextMenuCreateShortcut, icon.format == ".lnk"}, - -- "-", - -- {MineOSCore.localization.contextMenuUploadToPastebin, true}, "-", + {MineOSCore.localization.contextMenuArchive}, {MineOSCore.localization.contextMenuAddToDock}, + "-", {MineOSCore.localization.contextMenuProperties}, {MineOSCore.localization.contextMenuDelete} ):show() @@ -647,6 +645,9 @@ function MineOSCore.iconRightClick(icon, eventData) {MineOSCore.localization.contextMenuRename}, {MineOSCore.localization.contextMenuCreateShortcut, icon.format == ".lnk"}, "-", + {MineOSCore.localization.contextMenuArchive}, + {MineOSCore.localization.contextMenuAddToDock}, + "-", {MineOSCore.localization.contextMenuProperties}, {MineOSCore.localization.contextMenuDelete} ):show() @@ -667,7 +668,6 @@ function MineOSCore.iconRightClick(icon, eventData) ):show() elseif icon.format == ".pic" then action = GUI.contextMenu(eventData[3], eventData[4], - -- {MineOSCore.localization.contextMenuEdit}, {MineOSCore.localization.contextMenuEditInPhotoshop}, {MineOSCore.localization.contextMenuSetAsWallpaper}, "-", @@ -675,10 +675,10 @@ function MineOSCore.iconRightClick(icon, eventData) {MineOSCore.localization.contextMenuCopy}, {MineOSCore.localization.contextMenuRename}, {MineOSCore.localization.contextMenuCreateShortcut, icon.format == ".lnk"}, - -- "-", - -- {MineOSCore.localization.contextMenuUploadToPastebin, true}, "-", + -- {MineOSCore.localization.contextMenuArchive}, {MineOSCore.localization.contextMenuAddToDock}, + "-", {MineOSCore.localization.contextMenuProperties}, {MineOSCore.localization.contextMenuDelete} ):show() @@ -686,7 +686,6 @@ function MineOSCore.iconRightClick(icon, eventData) action = GUI.contextMenu(eventData[3], eventData[4], {MineOSCore.localization.contextMenuEdit}, {MineOSCore.localization.contextMenuFlashEEPROM, (not component.isAvailable("eeprom") or icon.size > 4096)}, - {MineOSCore.localization.contextMenuCreateApplication}, "-", {MineOSCore.localization.contextMenuCut}, {MineOSCore.localization.contextMenuCopy}, @@ -695,23 +694,24 @@ function MineOSCore.iconRightClick(icon, eventData) -- "-", -- {MineOSCore.localization.contextMenuUploadToPastebin, true}, "-", + -- {MineOSCore.localization.contextMenuArchive}, {MineOSCore.localization.contextMenuAddToDock}, + "-", {MineOSCore.localization.contextMenuProperties}, {MineOSCore.localization.contextMenuDelete} ):show() else action = GUI.contextMenu(eventData[3], eventData[4], {MineOSCore.localization.contextMenuEdit}, - -- {MineOSCore.localization.contextMenuCreateApplication}, "-", {MineOSCore.localization.contextMenuCut}, {MineOSCore.localization.contextMenuCopy}, {MineOSCore.localization.contextMenuRename}, {MineOSCore.localization.contextMenuCreateShortcut, icon.format == ".lnk"}, - -- "-", - -- {MineOSCore.localization.contextMenuUploadToPastebin, true}, "-", + -- {MineOSCore.localization.contextMenuArchive}, {MineOSCore.localization.contextMenuAddToDock}, + "-", {MineOSCore.localization.contextMenuProperties}, {MineOSCore.localization.contextMenuDelete} ):show() @@ -760,8 +760,7 @@ function MineOSCore.iconRightClick(icon, eventData) ecs.createShortCut(MineOSCore.getFilePath(icon.path) .. "/" .. ecs.hideFileFormat(MineOSCore.getFileName(icon.path)) .. ".lnk", icon.path) computer.pushSignal("MineOSCore", "updateFileList") elseif action == MineOSCore.localization.contextMenuArchive then - -- ecs.info("auto", "auto", "", "Архивация файлов...") - archive.pack(ecs.hideFileFormat(MineOSCore.getFileName(icon.path))..".pkg", icon.path) + require("compressor").pack(icon.path, MineOSCore.getFilePath(icon.path) .. "Archive.pkg") computer.pushSignal("MineOSCore", "updateFileList") elseif action == MineOSCore.localization.contextMenuSetAsWallpaper then fs.remove(MineOSCore.paths.wallpaper) diff --git a/lib/compressor.lua b/lib/compressor.lua new file mode 100644 index 00000000..a7934d83 --- /dev/null +++ b/lib/compressor.lua @@ -0,0 +1,187 @@ + +local unicode = require("unicode") +local fs = require("filesystem") +local compressor = {} + +------------------------------------------------------------------------------------------------------------------ + +local function numberToByteArray(number) + local byteArray = {} + while number > 0 do + table.insert(byteArray, 1, bit32.band(number, 0xFF)) + number = bit32.rshift(number, 8) + end + return byteArray +end + +local function byteArrayToNumber(byteArray) + local number = byteArray[1] + for i = 2, #byteArray do + number = bit32.bor(byteArray[i], bit32.lshift(number, 8)) + end + return number +end + +local function getFileList(path) + local fileList = {} + for file in fs.list(path) do + table.insert(fileList, path .. file) + end + return fileList +end + +------------------------------------------------------------------------------------------------------------------ + +local function writePath(compressedFile, path) + -- Получаем юникод-байтики названия файла или папки + local pathBytes = {} + for i = 1, unicode.len(path) do + local charBytes = { string.byte(unicode.sub(path, i, i), 1, 6) } + for j = 1, #charBytes do + table.insert(pathBytes, charBytes[j]) + end + end + -- Записываем количество байт, необходимое для записи РАЗМЕРА байт пути + local bytesForCountOfBytesForPath = numberToByteArray(#pathBytes) + compressedFile:write(string.char(#bytesForCountOfBytesForPath)) + -- Записываем количество байт, необходимое для записи самого пути + for i = 1, #bytesForCountOfBytesForPath do + compressedFile:write(string.char(bytesForCountOfBytesForPath[i])) + end + -- Записываем байтики пути + for i = 1, #pathBytes do + compressedFile:write(string.char(pathBytes[i])) + end +end + +local function writeFileSize(compressedFile, path) + local size = fs.size(path) + local bytesForSize = numberToByteArray(size) + -- Записываем количество байт, необходимое для записи РАЗМЕРА байт размера файла + compressedFile:write(string.char(#bytesForSize)) + -- Записываем сами байты размера файла + for i = 1, #bytesForSize do + compressedFile:write(string.char(bytesForSize[i])) + end +end + +local function doCompressionRecursively(fileList, compressedFile) + for file = 1, #fileList do + if fs.name(fileList[file]) ~= "mnt/" and fs.name(fileList[file]) ~= ".DS_Store" then + if fs.isDirectory(fileList[file]) then + -- print("Это папка: " .. fileList[file]) + compressedFile:write("D") + writePath(compressedFile, fileList[file]) + + doCompressionRecursively(getFileList(fileList[file]), compressedFile) + else + -- print("Это файл: " .. fileList[file]) + compressedFile:write("F") + writePath(compressedFile, fileList[file]) + writeFileSize(compressedFile, fileList[file]) + + local compressionFile = io.open(fileList[file], "rb") + compressedFile:write(compressionFile:read("*a")) + compressionFile:close() + end + -- else + -- print("Говно-путь: " .. fileList[file]) + end + end +end + +function compressor.pack(pathToCompress, pathToCompressedFile) + fs.makeDirectory(fs.path(pathToCompressedFile)) + -- Открываем файл со сжатым контентом + local compressedFile, reason = io.open(pathToCompressedFile, "wb") + if not compressedFile then + error("Failed to open file for writing while packing: " .. tostring(reason)) + end + -- Записываем сигнатурку + compressedFile:write("ARCH") + -- Пакуем данные + doCompressionRecursively({ pathToCompress }, compressedFile) + -- Закрываем файл со сжатым контентом + compressedFile:close() +end + +------------------------------------------------------------------------------------------------------------------ + +local function readPath(compressedFile) + local countOfBytesForPathBytes = string.byte(compressedFile:read(1)) + local pathBytes = {} + for i = 1, countOfBytesForPathBytes do + table.insert(pathBytes, string.byte(compressedFile:read(1))) + end + local pathSize = byteArrayToNumber(pathBytes) + local path = compressedFile:read(pathSize) + -- print("Колво байт под байты пути: ", countOfBytesForPathBytes) + -- print("Колво байт под путь: ", pathSize) + -- print("Путь: ", path) + return path +end + +local function readFileSize(compressedFile) + local countOfBytesForFileSize = string.byte(compressedFile:read(1)) + local fileSizeBytes = {} + for i = 1, countOfBytesForFileSize do + table.insert(fileSizeBytes, string.byte(compressedFile:read(1))) + end + local fileSize = byteArrayToNumber(fileSizeBytes) + -- print("Размер файла: ", fileSize) + return fileSize +end + +function compressor.unpack(pathToCompressedFile, pathWhereToUnpack) + if not fs.exists(pathToCompressedFile) then + error("Failed to unpack file \"" .. tostring(pathToCompressedFile) .. "\" because it doesn't exists") + end + fs.makeDirectory(pathWhereToUnpack) + + local compressedFile = io.open(pathToCompressedFile, "rb") + local signature = compressedFile:read(4) + if signature == "ARCH" then + while true do + local type = compressedFile:read(1) + if type == "D" then + -- print("Это папка") + local path = readPath(compressedFile) + fs.makeDirectory(pathWhereToUnpack .. path) + elseif type == "F" then + -- print("Это файл") + local path = readPath(compressedFile) + local size = readFileSize(compressedFile) + + local file, reason = io.open(pathWhereToUnpack .. path, "wb") + if not file then + error("Failed to open file for writing while unpacking: " .. tostring(reason)) + end + file:write(compressedFile:read(size)) + file:close() + elseif not type then + break + else + compressedFile:close() + error("Packed file is corrupted, unknown path type: " .. tostring(type)) + end + end + else + compressedFile:close() + error("Packed file is corrupted, wrong signature: " .. tostring(signature)) + end + + compressedFile:close() +end + +------------------------------------------------------------------------------------------------------------------ + +-- compressor.pack("/etc/", "/test1.pkg") +-- print(" ") +-- compressor.unpack("/test1.pkg", "/papkaUnpacked/") + +------------------------------------------------------------------------------------------------------------------ + +return compressor + + + diff --git a/lib/syntax.lua b/lib/syntax.lua index c6af4f25..7dd16be9 100755 --- a/lib/syntax.lua +++ b/lib/syntax.lua @@ -109,7 +109,7 @@ function syntax.highlightString(x, y, str, indentationWidth) local notSpaceNotFound, indentationSymbolCounter = true, 1 for symbol = 1, stringLength do - if indentationWidth and notSpaceNotFound then + if notSpaceNotFound then if symbols[symbol] == " " then colors[symbol] = syntax.colorScheme.indentation if indentationSymbolCounter == 1 then