app.path - Path Utilities API
Path parsing, joining, and special directory access.
Path Component Extraction
app.path.basename(path)
Gets the file name (including extension) from a path.
app.path.basename("/path/to/file.txt") -- "file.txt"
app.path.basename("/path/to/folder") -- "folder"
app.path.name(path)
Gets the file name (without extension) from a path.
app.path.name("/path/to/file.txt") -- "file"
app.path.name("/path/to/archive.tar.gz") -- "archive.tar"
app.path.extension(path)
Gets the file extension (without the dot).
app.path.extension("/path/to/file.txt") -- "txt"
app.path.extension("/path/to/archive.tar.gz") -- "gz"
app.path.extension("/path/to/folder") -- ""
app.path.dirname(path)
Gets the parent directory path.
app.path.dirname("/path/to/file.txt") -- "/path/to"
Path Operations
app.path.join(…)
Joins path components.
app.path.join("/path", "to", "file.txt") -- "/path/to/file.txt"
app.path.normalize(path)
Normalizes a path (resolves . and ..).
app.path.normalize("/path/../to/./file") -- "/to/file"
app.path.expandTilde(path)
Expands the tilde to the user’s home directory.
app.path.expandTilde("~/Documents") -- "/Users/username/Documents"
app.path.absolute(path)
Converts to an absolute path (also expands ~).
app.path.absolute("./file.txt") -- "/current/dir/file.txt"
app.path.absolute("~/file.txt") -- "/Users/username/file.txt"
app.path.relative(path, base)
Gets a relative path.
app.path.relative("/a/b/c/file.txt", "/a/b") -- "c/file.txt"
app.path.relative("/a/b/c", "/a/d") -- "../b/c"
Path String Checks
app.path.isAbsolute(path)
Checks whether a path is absolute (starts with / or ~).
app.path.isAbsolute("/path/to/file") -- true
app.path.isAbsolute("~/Documents") -- true
app.path.isAbsolute("./relative/path") -- false
app.path.isRelative(path)
Checks whether a path is relative.
app.path.isRelative("./path/to/file") -- true
app.path.isRelative("/absolute/path") -- false
app.path.hasExtension(path, ext?)
Checks whether a file has an extension. If ext is specified, checks whether it matches (case-insensitive).
app.path.hasExtension("/file.txt") -- true (has extension)
app.path.hasExtension("/file.txt", "txt") -- true
app.path.hasExtension("/file.TXT", "txt") -- true (case-insensitive)
app.path.hasExtension("/file.txt", ".txt") -- true (dot prefix also works)
app.path.hasExtension("/folder") -- false
File System Checks
app.path.exists(path)
Checks whether a path exists.
if app.path.exists("/path/to/file") then
-- File or directory exists
end
app.path.isDirectory(path)
Checks whether a path is a directory.
if app.path.isDirectory("/path/to/folder") then
-- Is a directory
end
app.path.isFile(path)
Checks whether a path is a regular file (not a directory or symbolic link).
if app.path.isFile("/path/to/file.txt") then
-- Is a file
end
app.path.isSymlink(path)
Checks whether a path is a symbolic link.
if app.path.isSymlink("/path/to/link") then
-- Is a symbolic link
end
Path Modification
app.path.withExtension(path, ext)
Changes the extension.
app.path.withExtension("/path/file.txt", "md") -- "/path/file.md"
app.path.withExtension("/path/file.txt", ".md") -- "/path/file.md"
app.path.withName(path, name)
Changes the file name (preserving the extension).
app.path.withName("/path/old.txt", "new") -- "/path/new.txt"
app.path.withBasename(path, basename)
Changes the full file name (including extension).
app.path.withBasename("/path/old.txt", "new.md") -- "/path/new.md"
app.path.withDirname(path, dirname)
Changes the parent directory.
app.path.withDirname("/old/file.txt", "/new") -- "/new/file.txt"
Special Directories
Get system special directory paths:
app.path.home() -- "/Users/username"
app.path.temp() -- "/var/folders/.../T"
app.path.desktop() -- "/Users/username/Desktop"
app.path.documents() -- "/Users/username/Documents"
app.path.downloads() -- "/Users/username/Downloads"
app.path.applications() -- "/Applications"
app.path.caches() -- "/Users/username/Library/Caches"
app.path.library() -- "/Users/username/Library"
app.path.movies() -- "/Users/username/Movies"
app.path.music() -- "/Users/username/Music"
app.path.pictures() -- "/Users/username/Pictures"
Path Analysis
app.path.components(path)
Splits a path into an array of components.
app.path.components("/a/b/c") -- {"/", "a", "b", "c"}
app.path.components("a/b/c") -- {"a", "b", "c"}
app.path.split(path)
Splits into directory and file name.
local parts = app.path.split("/path/to/file.txt")
-- { dirname = "/path/to", basename = "file.txt" }
app.path.splitext(path)
Splits into name and extension.
local parts = app.path.splitext("/path/file.txt")
-- { name = "file", extension = "txt" }
Examples
Batch Change Extensions
function MyPlugin:handleChangeExt(context)
local result = app.dialog.form({
title = "Change Extension",
fields = {
{type = "text", id = "ext", label = "New Extension", default = "md"}
}
})
if not result then return end
for _, file in ipairs(context.selectedFiles) do
local newPath = app.path.withExtension(file, result.ext)
app.file.move(file, newPath)
end
end
Organize Files into Subdirectories
function MyPlugin:handleOrganize(context)
local dir = context.currentDirectory
for _, file in ipairs(context.selectedFiles) do
local ext = app.path.extension(file)
if ext ~= "" then
local subdir = app.path.join(dir, ext:upper())
if not app.path.exists(subdir) then
app.file.mkdir(subdir)
end
local dest = app.path.join(subdir, app.path.basename(file))
app.file.move(file, dest)
end
end
end