bash $ kak <(echo "hello")
# vs
bash $ vim <(echo "hello")
kak: blank on /proc/<pid>/fd/<fd-number>vim: shows "hello" on /proc/self/fd/<fd-number> — is ./self a hint?kak should be able to read from temporary file descriptors as means to plug it into some bash workflow and analyze some intermediate output easily within my favourite (kak) editor. — especially for reading with familiar syntax highlighting.
stdin works: echo "hello" | kak — a valid workaground, not sure if a solution though. It might just be written somewhere editor <(echo "foo"), so compatibility is king.Probably if a file is not seekable, kak should treat it as a fifo buffer, like stdin.
I wasn't familiar with how process substitution worked, so I decided to check it out:
$ python3 -c "import sys; print(sys.argv)" <(echo hello)
['-c', '/dev/fd/63']
On my machine, /dev/fd is a symlink to /proc/self/fd, and /proc/self is a magic symlink that points to the PID of whatever process reads it.
For me, vim <(echo hello) displays /dev/fd/63 on the status line, but the actual buffer name printed by ^G (and displayed in the title bar) is /proc/1175470/fd/63.
For me, kak <(echo hello) produces a buffer named /proc/1176021/fd/63, and 1176021 matches %val{session} so I presume that is the actual correct PID to be reading.
Digging into the source-code, Kakoune calls open_or_create_file_buffer() for every file named on the command-line:
That reads the file content via a type called MappedFile:
https://github.com/mawww/kakoune/blob/ec3d7c31040afaee65afde15832d9b0ed6b2224d/src/file.cc#L207-L226
That function will silently do nothing if the filesystem entry has zero size, which appears to be the case for pipes:
$ stat -L -c %s <(echo hello)
0
Even if that check were removed, it wouldn't work - Kakoune goes on to read the file with mmap(), which doesn't work for pipes and FIFOs.
Sure enough, if we trick Kakoune into editing the file as a FIFO, it works:
$ pipekak () { kak -e "edit -fifo $1 $1"; }
$ pipekak <(echo hello)
Probably the right thing to do here would be to make open_or_create_buffer() check the file type as well as whether the file exists - if the type is S_IFCHR (character device) or S_IFIFO (guess!) it should call create_fifo_buffer() instead.
Most helpful comment
I wasn't familiar with how process substitution worked, so I decided to check it out:
On my machine,
/dev/fdis a symlink to/proc/self/fd, and/proc/selfis a magic symlink that points to the PID of whatever process reads it.For me,
vim <(echo hello)displays/dev/fd/63on the status line, but the actual buffer name printed by^G(and displayed in the title bar) is/proc/1175470/fd/63.For me,
kak <(echo hello)produces a buffer named/proc/1176021/fd/63, and 1176021 matches%val{session}so I presume that is the actual correct PID to be reading.Digging into the source-code, Kakoune calls
open_or_create_file_buffer()for every file named on the command-line:https://github.com/mawww/kakoune/blob/ec3d7c31040afaee65afde15832d9b0ed6b2224d/src/buffer_utils.cc#L95-L108
That reads the file content via a type called
MappedFile:https://github.com/mawww/kakoune/blob/ec3d7c31040afaee65afde15832d9b0ed6b2224d/src/file.cc#L207-L226
That function will silently do nothing if the filesystem entry has zero size, which appears to be the case for pipes:
Even if that check were removed, it wouldn't work - Kakoune goes on to read the file with
mmap(), which doesn't work for pipes and FIFOs.Sure enough, if we trick Kakoune into editing the file as a FIFO, it works:
Probably the right thing to do here would be to make
open_or_create_buffer()check the file type as well as whether the file exists - if the type isS_IFCHR(character device) orS_IFIFO(guess!) it should callcreate_fifo_buffer()instead.