Welcome to Vifm Q&A, where you can ask questions about using Vifm. Registration is optional, anonymous posts are moderated. E-mail and GitHub logins are enabled.
0 votes
in vifm by

Are there some kind of file limit to the creation of custom view? I unsuccessfully tried to create one from a selection of 1300 files from fzf, the custom view didn't popup after the selection, even after trying to wait some time.
But if I try the same fzf selection with few files it works.

1 Answer

0 votes
by
selected by
 
Best answer

Just created one with 100'000 files with no trouble. What's the exact command you're using? You might be hitting limit on the length of command-line.

by

this is the command (the second one), can you replicate?

sorry for the double thread

by

Try using cat/cmd <<< "$var" instead of echo like this:

command! fzff : set noquickview
    \| let $FZF_PICK = system("fd --hidden -t f | fzf --multi --height 10 --header '
    \This is the first line of the header\n
    \This is the second line of the header' 2>/dev/tty")
    \| let $FZF_COUNT = system('wc -l <<< "$FZF_PICK"')
    \| if $FZF_COUNT == 1
    \|   execute 'goto' fnameescape($FZF_PICK)
    \| elseif $FZF_COUNT > 1
    \|   execute '!cat <<< "$FZF_PICK" %%n%%u'
    \| endif
by

it gives me the same result. But I think that's something related some filename in my list. The list is composed by ~1500 .eml files, so the filenames have all sort of special characters and random lenght. One (or more) of those filenames breaks the \| execute '!echo "$FZF_PICK" %%n%%u' part of script somehow. I did some test by selecting random content of that list and regardless of selected number sometimes it fails and sometimes not. In that scenario how could I pass those special characters as literal string?

edit: when the selection fails, vifm command output "too few arguments error"

by

That might depend on characters, I'm not sure what can break variable expansion in a shell. After running fzff a failed, you can try doing :!env %m to see value of $FZF_PICK, maybe it will clarify something.

"too few arguments" probably comes from the line with :goto, which suggests that $FZF_PICK is empty.

by

I tried this shell command

FZFPICK=$(fd --hidden -t f | fzf --multi --bind='ctrl-a:select-all') && echo $FZF_PICK > /tmp/fzfpick.txt

and it correctly outputs all the 1567 .eml filenames, one per line. It's the same selection on the same dataset that I do with that vifm script but somehow it fails when executed from vifm.

I ruled out even the special character theory or the selection number; when I was testing that I noticed that if I selected 1193 .eml files it wasn't failing, on the 1194 it failed. But that was not something related to that file subset, because I could swap files at random (with the remaining 374) and the results was more or less the same: it would fail at 1115, at 1194 etc without a patter I could recognize.
I cannot wrap my head around what's wrong.

by

What's the size of that /tmp/fzfpick.txt file?

by
edited by

that file output size is 179K

by

Turns out creating a huge environment variable prevents creation of any child processes. That's why $FZF_PICK ends up empty.

Doing this in a shell:

export a="$(perl -e 'print "a"x(128*1024)')"

achieves the same (can't execute any command after that due to Argument list too long), while this works:

export a="$(perl -e 'print "a"x(128*1024 - 3)')"

Didn't realize that argument length limitation applies to environment variables as well.

The only thing that comes to mind right now is storing data in some temporary file to avoid creation of a large environment variable. Haven't tried it yet.

by

awesome work, thank you!
so to cover all scenario, instead of doing a variable declaration (FZF_PICK) I have to use a system maketemp command and fill it with the fzf command? or maybe there's a cleaner way to do that?

by

Yes, need a temporary file:

command! fzff : set noquickview
    \| let $FZF_FILE = system('mktemp /tmp/vifm-fzf-XXX')
    \| let $FZF_COUNT = system("fd --hidden -t f | fzf --multi --bind='ctrl-a:select-all' --height 10 --header '
    \This is the first line of the header\n
    \This is the second line of the header' 2>/dev/tty | tee \"$FZF_FILE\" | wc -l")
    \| if $FZF_COUNT == 1
    \|   execute 'goto' fnameescape(system('cat "$FZF_FILE"'))
    \| elseif $FZF_COUNT > 1
    \|   execute '!cat "$FZF_FILE" %%n%%u'
    \| endif
    \| execute '!rm -f "$FZF_FILE" %%i'

Things would be prettier in a Lua plugin, but current API won't let implementing this behaviour.

by

I cannot thank you enough for your time, that snippet works flawlessly!

If you would like to make a bug report or feature request consider using GitHub, SourceForge or e-mail. Posting such things here is acceptable, but this is not a perfect place for them.
...