This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Cranium's profile picture

shell.resolve information

Started by Cranium, 13 February 2013 - 06:40 AM
Cranium #1
Posted 13 February 2013 - 07:40 AM
So, I have just started messing about in the filesystem, and I am having trouble understanding the shell.resolve() function. Unfortunately, there is no documentation ont his function in the wiki. I want to be able to make a miniature file browser, where after selecting the name of a folder, it opens that folder and lists its contents. So far, I can't go any further than one folder in, and it will always keep going into folders deeper into the directory.
Take this filetree for example:

Dir1
    Dir2
	    program1
    program2
    program3
I want to be able to return the filepath of Dir1/Dir2/program1, but I don't quite know how to.
Kingdaro #2
Posted 13 February 2013 - 07:44 AM
The function shell.resolve(text) takes the current shell.dir() and fs.combine()s it with text. It makes it so that the current shell directory is treated as root.


local filepath1 = 'foo'
local filepath2 = 'bar'

-- so if our current directory is "apps"
shell.resolve(filepath1) --> apps/foo
shell.resolve(filepath2) --> apps/bar

You can set the current shell directory with shell.setDir(), however in your case, it'd be better to simply keep a local variable for your directory, instead of using shell's internal directory.
Lyqyd #3
Posted 13 February 2013 - 07:58 AM
It does more than that, IIRC. It should also check through the path variables if the file isn't in the current directory and use one of those paths if it finds it. That's why you can type `edit filename` instead of `rom/programs/edit filename`.
Cranium #4
Posted 13 February 2013 - 07:59 AM
So if I want to go to program1, and I am looping to iterate through the list, I want to do this:

local dir = "/"
while true do
	local fileList = fs.list(dir)
	for i = 1, #fileList do
		--generic selection with os.pullEvent()
		if fs.isDir(fileList[i]) then
			--append dir to be (dir..fileList[i])
		else
			--open file
			--break from loop
		end
	end
end
BigSHinyToys #5
Posted 13 February 2013 - 08:23 AM
This is a test ver of mouseFB testing out how icons would work and simplifying some functions before adding them to the main.
http://pastebin.com/YZYJpihT
I do not use shell to store the current path because I wanted a program that could run independent of the shell environment. I store the location in a table called "path" and use that to generate the string with the function "stringPath()" I personally don't think a file browser should change the shells directory but that is just me. You could store the path in a string and use some pattern to separate remove folders when moving back.
Cranium #6
Posted 13 February 2013 - 08:27 AM
Yeah, I am going to do the concatenation of variables to achieve the filepath. The only problem I am having is when I want to go 'up' a directory. I can go all the way to Dir2, but if I wanted to go back to Dir1, I need to use a string.sub or string.gsub command, right?
How would I have it match the string to remove a previous directory?
Lyqyd #7
Posted 13 February 2013 - 08:36 AM
If you have the directory string as foo/bar/baz,

string.match(pathVar, "(.-)/[^/]$")
BigSHinyToys #8
Posted 13 February 2013 - 08:44 AM
String functions specifically patterns are not my strong suite that is why I when with a table actually I will mess with it a bit but I don't know If I can solve this for you.
Cranium #9
Posted 13 February 2013 - 10:05 AM
Hmmm….didn't think about tables. I might just go ahead and add each new directory into a table, and when going back, just use table.remove to remove the last listing. That would actually work well. No faffing about with the strings.
KaoS #10
Posted 13 February 2013 - 05:14 PM
there is a much simpler method in fact. all you do is substitute "../" for the filename. the following code inserts the "up one level" option to the top of the list, normally you would include an if statement like
if shell.resolve(dir)~="" then
so you do not show up one level if they are at the top level


local dir = ""
local running=true
while running do
  local fileList = fs.list(dir)
  table.insert(fileList,1,"../") --insert the "up one" option to the list
  for i = 1, #fileList do
    --generic selection with os.pullEvent()
    local targ=shell.resolve(dir.."/"..fileList[i])
    if fs.isDir(targ) then --you had fileList[i] here and that would not work because you would need the full path
      dir=targ
    else
      shell.run(targ)
      running=false
      break
    end
  end
end
Cranium #11
Posted 14 February 2013 - 02:46 AM
there is a much simpler method in fact. all you do is substitute "../" for the filename. the following code inserts the "up one level" option to the top of the list, normally you would include an if statement like
if shell.resolve(dir)~="" then
so you do not show up one level if they are at the top level


local dir = ""
local running=true
while running do
  local fileList = fs.list(dir)
  table.insert(fileList,1,"../") --insert the "up one" option to the list
  for i = 1, #fileList do
	--generic selection with os.pullEvent()
	local targ=shell.resolve(dir.."/"..fileList[i])
	if fs.isDir(targ) then --you had fileList[i] here and that would not work because you would need the full path
	  dir=targ
	else
	  shell.run(targ)
	  running=false
	  break
	end
  end
end
Well, I finally figured it out on how to navigate through the files fairly easily. I actually did end up going with tables, as it was much easier for me to work with. Here's my unfinished function that I am working on, with the completed navigation:

local function newPaste()
    for i = 3, y do
	    paintutils.drawLine(1,i,x,i,colors.lightBlue)
    end
    term.setBackgroundColor(colors.lightBlue)
    term.setCursorPos(2, 4)
    term.setTextColor(colors.black)
    write("File")
    term.setCursorPos(19, 4)
    write("Type")
    term.setCursorPos(30, 4)
    write("File Size")
    term.setCursorPos(2, 14)
    term.setBackgroundColor(colors.lightBlue)
    term.setTextColor(colors.black)
    write("Selected File Info:")
    for k = 15, y do
	    paintutils.drawLine(2,k,25,k,colors.lightGray)
    end
    term.setTextColor(colors.black)
    term.setBackgroundColor(colors.green)
    term.setCursorPos(11,18)
    write("Upload")
    local scroll = 1
    local dirTab = {""}
    while true do
	    local listTable = fs.list(table.concat(dirTab, "/"))
	    local typeTable = {}
	    local sizeTable = {}
	    for i = 1, #listTable do
		    if fs.isDir(table.concat(dirTab, "/").."/"..listTable[i]) then
			    table.insert(listTable, 1, listTable[i])
			    table.remove(listTable, i + 1)
			    table.insert(typeTable, 1, "Folder")
			    table.insert(sizeTable, 1, "")
		    else
			    table.insert(typeTable, "File")
			    table.insert(sizeTable, fs.getSize(table.concat(dirTab, "/").."/"..listTable[i]).." Bytes")
		    end
	    end
	    table.insert(listTable, 1, "Return")
	    table.insert(typeTable, 1, "")
	    table.insert(sizeTable, 1, "")
	    for i = 1,8 do
		    if i > #listTable then break end
		    if scroll <= 8 then
			    paintutils.drawLine(1,i + 4,x,i + 4,colors.lightBlue)
			    term.setCursorPos(1, 4 + i)
			    term.setBackgroundColor(colors.lightBlue)
			    term.setTextColor(colors.white)
			    if fs.isDir(table.concat(dirTab, "/").."/"..listTable[i]) then
				    term.setTextColor(colors.lime)
				    write(" "..listTable[i])
			    elseif listTable[i] == "Return" then
				    term.setTextColor(colors.green)
				    write(" "..listTable[i])
			    else
				    term.setTextColor(colors.white)
				    write(" "..listTable[i])
			    end
			    term.setCursorPos(19,4 + i)
			    write(typeTable[i])
			    term.setCursorPos(30,4 + i)
			    write(sizeTable[i])
			    term.setCursorPos(1, 4 + scroll)
			    term.setTextColor(colors.red)
			    write(">"..listTable[scroll])
		    else
			    paintutils.drawLine(1,i + 4,x,i + 4,colors.lightBlue)
			    term.setCursorPos(1, 4 + i)
			    term.setBackgroundColor(colors.lightBlue)
			    if fs.isDir(table.concat(dirTab, "/").."/"..listTable[scroll + (i - 8)]) then
				    term.setTextColor(colors.lime)
				    write(" "..listTable[scroll + (i - 8)])
			    elseif listTable[scroll + (i - 8)] == "Return" then
				    term.setTextColor(colors.green)
				    write(" "..listTable[i])
			    else
				    term.setTextColor(colors.white)
				    write(" "..listTable[scroll + (i - 8)])
			    end
			    term.setCursorPos(19, 4 + i)
			    write(typeTable[scroll + (i - 8)])
			    term.setCursorPos(30, 4 + i)
			    write(sizeTable[scroll + (i - 8)])
			    term.setCursorPos(1, 12)
			    term.setTextColor(colors.red)
			    write(">"..listTable[scroll])
		    end
		    paintutils.drawLine(3,16,24,16,colors.white)
		    term.setBackgroundColor(colors.white)
		    term.setTextColor(colors.blue)
		    term.setCursorPos(4,16)
		    if string.len(listTable[scroll]) > 17 then
			    write(listTable[scroll] == "Return" and "" or string.sub(listTable[scroll], 1,17).."...")
		    else
			    write(listTable[scroll] == "Return" and "" or listTable[scroll])
		    end
	    end
		    local events = {os.pullEvent()}
	    if events[1] == "mouse_scroll" then
		    if events[2] == 1 then
			    if scroll >= #listTable then
				    scroll = #listTable
			    elseif scroll >= 1 and scroll < #listTable then
				    scroll = scroll + 1
			    end
		    elseif events[2] == -1 then
			    if scroll <= 1 then
				    scroll = 1
			    elseif scroll >= 1 then
				    scroll = scroll - 1
			    end
		    end
	    elseif events[1] == "key" then
		    if events[2] == 208 then
			    if scroll >= #listTable then
				    scroll = #listTable
			    elseif scroll >= 1 and scroll < #listTable then
				    scroll = scroll + 1
			    end
		    elseif events[2] == 200 then
			    if scroll <= 1 then
				    scroll = 1
			    elseif scroll >= 1 then
				    scroll = scroll - 1
			    end
		    elseif events[2] == 28 then
			    if scroll == 1 and dir ~= "/" then
				    table.remove(dirTab)
				    scroll = 1
				    for i = 5,13 do
					    paintutils.drawLine(1,i,x,i,colors.lightBlue)
				    end
			    else
				    if fs.isDir(table.concat(dirTab, "/").."/"..listTable[scroll]) then
					    table.insert(dirTab, listTable[scroll])
					    scroll = 1
					    for i = 5,13 do
						    paintutils.drawLine(1,i,x,i,colors.lightBlue)
					    end
				    else
					    if logged then
						    --add logged upload
					    else
						    --not logged upload
					    end
				    end
			    end
		    end
	    end
    end
end