Welcome to Vifm Q&A, where you can ask questions about Vifm usage. Registration is optional, anonymous posts are moderated. GitHub or Google logins are enabled.
0 votes
in vifm by

Is it possible to copy the path of all currently selected files/folders to the clipboard by running a command?

Currently I'm using

nnoremap yf :!echo %c:p | xclip -selection clipboard %i<cr>

but this gives me only the path of one single item (the current one).

1 Answer

0 votes
by
selected by
 
Best answer

If you replace %c with %f

nnoremap yf :!echo %c:p | xclip -selection clipboard %i<cr>

you'll get all files in the selection, but they will be on the same line. You probably want something like this

nnoremap yf :!printf "\n%%s" %f:p | tail -c+2 | xclip -selection clipboard %i<cr>

which will put each path on a separate line.

by

Thank you a lot, it works!

by

Wouldn't %%s\n avoid the need for the tail?

by

Yes, it would, but there is a trailing new line character with %%\n.

by

This works great. Thank you. Is there a way to change it so that it adds / at the end of directories?

by

Only via a shell loop (xsel is used in this case):

nnoremap <silent> yf :!for f in %f:p; do if [ -d "$f" ]; then echo "$f/"; else echo "$f"; fi; done | xsel --input --clipboard %i<cr>

Also tried to do this via Lua:

local M = { }

local function append(sel, entry)
    local line = entry.location .. "/" .. entry.name
    if entry.type == 'dir' then
        line = line .. '/'
    end
    sel[#sel + 1] = line
end

local function yf(info)
    local view = vifm.currview()
    local selection = { }

    for i = 1, view.entrycount do
        local entry = view:entry(i)
        if entry.selected then
            append(selection, entry)
        end
    end

    if #selection == 0 then
        local entry = view:entry(view.currententry)
        append(selection, entry)
    end

    local job = vifm.startjob {
        cmd = "xsel --clipboard --input",
        iomode = "w",
    }

    local pipe = job:stdin()
    pipe:write(table.concat(selection, '\n'))
    pipe:close()

    if job:exitcode() ~= 0 then
        vifm.errordialog("plugin: " .. vifm.plugin.name,
                         "Failed to copy selection to clipboard")
    else
        vifm.sb.info(string.format("Yanked paths to %d file(s)", #selection))
    end
end

local added = vifm.keys.add {
    shortcut = "yf",
    modes = { "normal" },
    description = "yank selection to clipboard",
    handler = yf,
}
if not added then
    vifm.sb.error("Failed to register `yf` key")
end

return M
by

It works great. Thank you

by

Just to add that this is useful to do in visual mode:

" yank currently selected filenames with path
vnoremap yf :!printf "\n%%s" %f:p | tail -c+2 | xclip -selection clipboard %i<cr>

" yank currently selected filenames without path
vnoremap yn :!printf "\n%%s" %f | tail -c+2 | xclip -selection clipboard %i<cr>

" yank currently selected filenames
vnoremap yy :yank<cr>

The last one is just to skip the waiting period otherwise.

...