Continuous writes to fifo buffer causes hanging

I’m confused about the use of fifo buffers. In the following example I’m trying to create such a buffer, and then write to it some lines:

evaluate-commands %sh{
     output=$(mktemp -d -t kak-temp-XXXXXXXX)/fifo
     printf "declare-option str my_fifo %s\n" ${output}
     mkfifo ${output}
     echo "edit! -fifo ${output} -scroll -debug -readonly *buffer-name*
           hook buffer BufClose .* %{ nop %sh{ rm -r $(dirname ${output})} }"
}

nop %sh{
    printf "%s\n" "First Line" >> ${kak_opt_my_fifo}
    printf "%s\n" "Second Line" >> ${kak_opt_my_fifo}
}

Now I want to add more lines and execute the code below, which leads to kakoune hanging:

nop %sh{
    printf "%s\n" "Third Line" >> ${kak_opt_my_fifo}
}

I want to continuously write lines into a buffer and have that buffer automatically scroll down, which is why I thought edit -scroll would be a good idea, but this only works with fifos.

Question: What can I do to prevent kakoune from hanging up. Perhaps I shouldn’t use fifos at all here?

Unfortunately I cannot help you with the buffer.

But it would probably be possible to write a simple command to automatically scroll to the bottom (gj) when the buffer changes. Have you had a look at hooks? BufReload would probably help.

You probably want to disable confirmation for reloading in the same command. Check the autoreload option.

It is because the fifo is closed.
At your “Third Line”, Kakoune stopped to read the fifo, so it hangs.
Check BufCloseFifo on :doc hooks.
You can see when the fifo buffer closes when the [fifo] flag disappears in the status line.

1 Like

@alexherbo2 Is there any way to reopen the fifo buffer without deleting the old content? I tried modifying the last command with:

evaluate-commands %sh{
    printf "%s\n" "edit! -fifo ${kak_opt_my_fifo} -scroll -debug *buffer-name"
    printf "%s\n" "Third Line" >> ${kak_opt_my_fifo}
}

But that still leads to hangups.

The commands in an evaluate-commands %sh{} don’t take effect until after the shell has ended, so what’s happening is:

  • The shell prints an edit command to stdout, and it sits in the buffer
  • The shell tries to open the FIFO in append mode, but nothing is reading the FIFO so it hangs forever
  • The shell never exits, so Kakoune never executes the command in the buffer.

If you want to trickle data into the FIFO over time, you’ll need to keep the writing-end open, so that Kakoune will keep the reading end open. Generally that means a shell whose output is redirected, that executes the actual processes you want to run. Untested code to illustrate the idea:

eval %sh{
temp=$(mktemp -d)/fifo
printf "edit! -fifo %s -scroll *buffer-name*\n" "$temp"
printf "hook buffer BuffClose .* %{ nop %sh{ rm -rf %s }\n" "$temp"

/bin/sh -c "
    echo 'First Line'
    echo 'Second Line'
    sleep 5
    echo 'Third Line'
" </dev/null >"$temp" 2>/dev/null &
    
}
3 Likes

@Screwtapello Thanks for the explanation.