Operating system for OpenComputers
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

267 lignes
6.5KB

  1. local ed = package.loaded.ed or {}
  2. ed.bfunc = ed.bfunc or {}
  3. ed.ifunc = ed.ifunc or setmetatable({},{__index=ed.bfunc})
  4. ed.buffers = ed.buffers or {}
  5. function ed.bfunc:load(fpath)
  6. local f = io.open(fpath,"rb")
  7. if not f then return false, "unable to open file" end
  8. for line in f:lines() do
  9. self[#self+1] = line
  10. end
  11. f:close()
  12. self.path = fpath
  13. return true, #self
  14. end
  15. function ed.bfunc:save(fpath)
  16. local path = fpath or self.path
  17. if not path then return false, "no path" end
  18. self.path = path
  19. local f = io.open(path,"wb")
  20. if not f then return false, "unable to open file" end
  21. for k,v in ipairs(self) do
  22. f:write(v.."\n")
  23. end
  24. f:close()
  25. self.dirty = false
  26. return true
  27. end
  28. function ed.bfunc:close(discard)
  29. if not discard and self.dirty then
  30. local saved = self:save()
  31. if not saved then return false, "unable to save buffer" end
  32. end
  33. for k,v in pairs(ed.buffers) do
  34. if v == self then
  35. table.remove(ed.buffers,k)
  36. return true
  37. end
  38. end
  39. return false, "unable to find buffer handle"
  40. end
  41. function ed.bfunc:range(start,finish)
  42. start, finish = math.max(1,tonumber(start) or 1), math.min(#self,tonumber(finish) or #self)
  43. local rt = {}
  44. for i = start, finish do
  45. rt[#rt+1] = self[i]
  46. end
  47. return rt
  48. end
  49. function ed.bfunc:checkCursor()
  50. self.y = math.max(self.y,1)
  51. self.y = math.min(self.y,#self)
  52. self.x = math.max(self.x,1)
  53. self.x = math.min(self.x,math.max(self[self.y]:len()+1,1))
  54. end
  55. function ed.ifunc.buffers()
  56. for k,v in pairs(ed.buffers) do
  57. print(string.format("\27[31m%4i\27[0m %s",k,v.path or "?"))
  58. end
  59. end
  60. function ed.ifunc.help()
  61. print("Available commands:")
  62. for k,v in pairs(ed.bfunc) do
  63. print(k)
  64. end
  65. for k,v in pairs(ed.ifunc) do
  66. print(k)
  67. end
  68. end
  69. function ed.ifunc:list(start,finish)
  70. start, finish = math.max(1,tonumber(start) or 1), math.min(#self,tonumber(finish) or #self)
  71. local lt = self:range(start,finish)
  72. for k,v in pairs(lt) do
  73. print(string.format("\27[31m%4d\27[0m %s",k+start-1,v))
  74. end
  75. end
  76. function ed.ifunc:insert(p,o)
  77. ed.ifunc.pointer(self,p)
  78. while true do
  79. io.write(string.format("\27[31m%4d\27[0m ",self.y + (o or 0)))
  80. local line = io.read()
  81. if line == "." then break end
  82. table.insert(self,self.y + (o or 0),line)
  83. self.dirty = true
  84. self.y = self.y + 1
  85. end
  86. end
  87. function ed.ifunc:append(p)
  88. ed.ifunc.insert(self,p,1)
  89. end
  90. function ed.ifunc:pointer(n)
  91. self.y = math.max(1,tonumber(n) or 1)
  92. self.y = math.min(#self,self.y)
  93. print(self.y)
  94. end
  95. function ed.newBuffer()
  96. local nb = setmetatable({},{__index=ed.bfunc})
  97. nb.x,nb.y = 1, 1
  98. ed.buffers[#ed.buffers+1] = nb
  99. return nb
  100. end
  101. function ed.open(buffer)
  102. if ed.buffers[buffer] then
  103. buffer = ed.buffers[buffer]
  104. end
  105. if type(buffer) == "string" then
  106. nb = ed.newBuffer()
  107. nb:load(buffer)
  108. buffer = nb
  109. end
  110. if type(buffer) ~= "table" then buffer = ed.newBuffer() buffer[1] = "" end
  111. return buffer
  112. end
  113. function ed.interactive(buffer)
  114. buffer=ed.open(buffer)
  115. while true do
  116. io.write("\27[34mced:\27[0m ")
  117. local line = io.read()
  118. local words = {}
  119. for word in line:gmatch("[^%s]+") do
  120. words[#words+1] = word
  121. end
  122. local cmd = table.remove(words,1)
  123. if ed.ifunc[cmd] then
  124. print(ed.ifunc[cmd](buffer,table.unpack(words)))
  125. elseif cmd == "quit" then
  126. break
  127. else
  128. print("Unknown command.")
  129. end
  130. if cmd == "close" then
  131. break
  132. end
  133. end
  134. end
  135. function ed.visual(buffer)
  136. buffer=ed.open(buffer)
  137. local mx, my = 40, 13
  138. local cx,cy = math.max(1,buffer.x-mx//2), math.max(1,buffer.y-my//2)
  139. local ox, oy
  140. local mode = "c"
  141. local mult, multstr = 1, ""
  142. local resized = false
  143. io.write("\27[999;999H\27[6n")
  144. local function drawBuffer(force)
  145. if cx ~= ox or cy ~= oy or force then
  146. io.write("\27[2J\27[H")
  147. for i = cy, cy+my do
  148. print(string.format("\27[31m%4i \27[0m%s",i,(buffer[i] or "\27[36m~"):sub(cx,cx+mx-6)))
  149. end
  150. elseif mode == "i" then
  151. print(string.format("\27[2K\27[999D\27[31m%4i \27[0m%s",buffer.y,(buffer[buffer.y] or "\27[36m~"):sub(cx,cx+mx-6)))
  152. end
  153. io.write(string.format("\27[1;%iH\27[0;36;%im\27[2K[%s] ced visual: %i,%i/%i, %iK free %i",my+2,(mode == "c" and 7) or 0, mode, buffer.x, buffer.y, #buffer, computer.freeMemory()//1024,mult))
  154. io.write(string.format("\27[%i;%iH\27[0m",buffer.x+6-cx,buffer.y-cy+1))
  155. end
  156. os.setTimeout(0.0005)
  157. while true do
  158. drawBuffer()
  159. ox, oy = cx, cy
  160. io.write("\27[100;101m")
  161. local c=io.read(1)
  162. if c == "\27" then
  163. local b = ""
  164. repeat
  165. c=io.read(1)
  166. b=b..c
  167. until c:match("%a")
  168. dprint(b)
  169. local nx, ny = b:match("%[(%d+);(%d+)")
  170. if nx and ny then
  171. mx, my = math.max(mx, tonumber(nx)), math.max(my, tonumber(ny)-2)
  172. drawBuffer(true)
  173. end
  174. end
  175. if mode == "c" then
  176. if c == "q" then
  177. io.write("\27[0m\27[2J\27[H")
  178. break
  179. elseif c == "h" then
  180. buffer.x = buffer.x - mult
  181. elseif c == "l" then
  182. buffer.x = buffer.x + mult
  183. elseif c == "j" then
  184. buffer.y = buffer.y + mult
  185. elseif c == "k" then
  186. buffer.y = buffer.y - mult
  187. elseif c == "d" then
  188. for i = 1, mult do
  189. table.remove(buffer,buffer.y)
  190. end
  191. drawBuffer(true)
  192. elseif c == "i" or c == "\t" then
  193. mode = "i"
  194. elseif c == "a" then
  195. buffer.x = buffer.x + 1
  196. mode = "i"
  197. elseif c == ":" then
  198. io.write("\27[1;999H\27[2K")
  199. ed.interactive(buffer)
  200. drawBuffer(true)
  201. elseif c == "w" then
  202. buffer:save()
  203. elseif c:match("%d") then
  204. multstr = multstr .. c
  205. mult = tonumber(multstr)
  206. end
  207. if c:match("%D") then
  208. multstr = ""
  209. mult = 1
  210. end
  211. else
  212. if c == "\t" then
  213. mode = "c"
  214. elseif c == "\8" and buffer.x == 1 and buffer.y > 1 then
  215. local lblen = buffer[buffer.y-1]:len()
  216. buffer[buffer.y-1] = buffer[buffer.y-1] .. table.remove(buffer,buffer.y)
  217. buffer.x, buffer.y = lblen+1, buffer.y - 1
  218. drawBuffer(true)
  219. elseif c == "\8" then
  220. buffer[buffer.y] = buffer[buffer.y]:sub(1,buffer.x - 2)..buffer[buffer.y]:sub(buffer.x)
  221. buffer.x = buffer.x - 1
  222. else
  223. buffer[buffer.y] = buffer[buffer.y]:sub(1,buffer.x-1)..c..buffer[buffer.y]:sub(buffer.x)
  224. buffer.x = buffer.x + 1
  225. local fh,sh = buffer[buffer.y]:match("(.*)\n(.*)")
  226. if fh and sh then
  227. buffer[buffer.y] = fh
  228. table.insert(buffer,buffer.y+1,sh)
  229. buffer.x, buffer.y = 1, buffer.y + 1
  230. drawBuffer(true)
  231. end
  232. end
  233. end
  234. buffer:checkCursor()
  235. local ax, amx = buffer.x + 5, mx - 5
  236. if cy + my < buffer.y + 3 then
  237. cy = math.min(#buffer-my,buffer.y + 6 - my)
  238. end
  239. if cy + 3 > buffer.y then
  240. cy = math.max(1,buffer.y - 6)
  241. end
  242. if buffer.x + 5 > cx + mx - 4 then
  243. cx = math.max(1,(buffer.x + 6) - (mx - 6))
  244. end
  245. if buffer.x < cx + 3 then
  246. cx = math.max(1,buffer.x - 6)
  247. end
  248. end
  249. end
  250. return ed