Interacting with Marta APIs

Now you know how to create simple Marta plugins. This time let’s touch Marta APIs a bit more. In this tutorial we will create an action that shows a popup with some information about the selected files.

🚩 Create a new single-file plugin, declare a plugin and an action.

Contexts

Marta holds the application state in several kinds of contexts:

  • A GlobalContext (marta.globalContext) provides access to global services (localFileSystem, actionRepository). It is created once during the start-up and exposed as globalContext global.
  • WindowContext is owned by a Marta window. It holds window-local services (paneManager) and allows to run actions.
  • PaneContext is created for each individual pane (tab). It provides access to the pane’s list model. PaneContext also holds a reference to the containing WindowContext.

As we want to get the selected files, we surely need the instance of a PaneContext. How we can access it from our action?

In fact, there is one more context that is passed to actions – an ActionContext.

marta.action {
    ...
    apply = function(actionContext)
        ...
    end
}

ActionContext holds references to PaneContext instances for both active and inactive panes. Let’s use it:

marta.action {
    ....
    apply = function(actionContext)
        -- PaneContext for the active pane
        local activePane = actionContext.activePane

        -- Active pane list model
        local model = activePane.model

        -- Iterate through all selected files
        for _, file in ipairs(model.selectedFiles) do
            martax.alert(file.simpleName)
        end
    end
}

🚩 Put the code above to your action and check if everything works as expected. A popup should be shown for each selected file.

Collecting info

Let’s join the output data so only a single popup alert will be displayed. We can also add some more information about the items: for instance, we can enclose the name into square brackets for directories and print the file size:

[Documents]
[Library]
my-document.txt (4 KB)
script.sh (720 bytes)

Fortunately, martax module already provides a helper function for rendering size:

-- Prints "1 KB"
martax.formatSize(1024)

Instead of showing popups for each file, we collect results to the text variable:

apply = function(context)
    local files = context.activePane.model.selectedFiles
    local text = ""

    for _, file in ipairs(files) do
        local name = file.simpleName
        local entity

        if file.isDirectory then
            entity = "[" .. name .. "]"
        else
            entity = name .. " (" .. martax.formatSize(file.size) .. ")"
        end

        text = text .. entity .. "\n"
    end

    martax.alert("Selected files: \n\n" .. text)
end

Final version

Now everything looks good – except that we do not check if the selection is empty. Now we fix the problem. The listing below is a complete plugin implementation:

plugin { 
    id = "marta.example.fileinfo",
    name = "File information",
    apiVersion = "1.0"
}

action {
    id = "show",
    name = "Show file information",
    apply = function(context)
        local files = context.activePane.model.selectedFiles
        if #files == 0 then
            martax.alert("No selected files.")
            return
        end

        local text = ""
        for _, file in ipairs(files) do
            local name = file.simpleName
            local entity

            if file.isDirectory then
                entity = "[" .. name .. "]"
            else
                entity = name .. " (" .. martax.formatSize(file.size) .. ")"
            end

            text = text .. entity .. "\n"
        end

        martax.alert("Selected files: \n\n" .. text)
    end
}