feh icon indicating copy to clipboard operation
feh copied to clipboard

Feature request: logging or printing of current filename

Open gwern opened this issue 6 months ago • 1 comments

I would like a feature or extension of an existing feature which, as far as I can tell, does not exist: a way to have feh log to a file or stdout/stderr the current filename being viewed.

My usecase is I would like to curate my backlog of photographs, which is far too large to go through in a single sitting, with multiple sessions, where I resume where I left off. For ease of use, this needs to track the current position automatically. So using the --actions to do something like "%f" would be bad: I'd need to remember to use that specially in the curation mode, as opposed to just running feh_resume. I cannot seem to find any existing feh feature which would enable this.

One logical place would be to expand the definition of --verbose:

     -V, --verbose
             output useful information, progress bars, etc.

It is not clear to me what --verbose actually does (at least with Feh v3.3), because when I run feh --verbose on some random image directories, I don't see any output at all; but taking the man page at face value, printing the 'current image filename' seems to me like it would be 'useful information', and it's very much in the spirit of 'progress bars' (printing out the current file name would let you create a progress bar by combining it with a file list, for example).

Compatibility-wise, presumably anyone parsing or otherwise using the verbose output is grepping for just the parts they need, so adding in filename printing should not break any code which was not already hopelessly fragile.


A fragile proof of concept, which uses strace because I can't see any way to get last-image-viewed out of feh, and then has to parse filenames from strace's default octal output back into UTF-8:

function feh_resume() {
    local -r target_directory="$1"
    local -r last_seen_file="${target_directory}/.last_seen_image"
    local -r temp_file="$(mktemp)"

    if ! command -v feh &>/dev/null || ! command -v strace &>/dev/null; then
        echo "Error: Required command 'feh' or 'strace' not found."
        return 1
    fi

    if [[ -z "$target_directory" ]]; then
        echo "Error: No target directory provided."
        return 1
    fi

    local last_seen_image=""
    if [[ -f "$last_seen_file" ]]; then
        read -r last_seen_image < "$last_seen_file"
    fi

    local start_at_option=""
    if [[ -n "$last_seen_image" ]]; then
        start_at_option="--start-at $last_seen_image"
        echo "Starting at: $last_seen_image"
    fi

    local last_image_accessed
    last_image_accessed=$(strace -e trace=openat feh $start_at_option "$target_directory"/* 2>&1 \
                          | grep 'openat' | awk -F'"' '{print $2}' \
                          | grep -F "$target_directory" | tail -1 \
                          | xargs -0 printf '%b\n')

    if [[ -n "$last_image_accessed" ]]; then
        echo "Last image: $last_image_accessed"
        echo "$last_image_accessed" >> "$temp_file" && mv "$temp_file" "$last_seen_file"
    fi
}

gwern avatar Dec 30 '23 00:12 gwern