Search code examples
eventsdialogfish

Unix Dialog utility fails in fish shell when reacting to an emitted event


I have this function (known to work OK)

function problem_open -e on_problem_open -d "select from existing problems"
    set matches (find $FD_PROB_HOME/ -maxdepth 1 -mindepth 1 -type d ! -name ".git")

    if test 1 -eq (count $matches)
        if test -d $matches
            set -U FD_PROB_CURRENT $matches[1]
            echo "chose option 1"
            return
        end
    end
    set -g dcmd "dialog --stdout --no-tags --menu 'select the file to edit' 20 60 20 "
    set c 1
    for option in $matches
        set l (basename "$option")
        set -g dcmd "$dcmd $c '$l'"
        set c (math $c + 1)
    end
    set choice (eval "$dcmd") 
    #clear
    if test $status -eq 0
        echo "edit option $choice"
        set -U FD_PROB_CURRENT $matches[$choice]
    end
end

when I invoke problem_open directly, the dialog shows fine. When I invoke the function indirectly, via emit on_problem_open the dialog doesn't display.

Any ideas why this is happening? Is it expected behaviour with events?

I can work around the issue, but it would be a warty hack.


Solution

  • After discussing with the fish dev team member Fabian Homborg (@faho), it seems that the desired functionality will not work (not ever), for reasons similar to the venerable "contended access to screen updates in a UI thread" issue in windows et al. Not only that, the dev team intends to actually move event invocation off into another thread in future, so there's no hope for interacting with the terminal from an event handler.

    What I ended up doing was creating a different API that, when user IO is expected, uses direct function invocation instead. See function _define_subcommand_nonevented for the implementation.