Well, it's 2020 and sublime still can't (won't?) read from stdin. None of the answers in this thread were working satisfactorily for me due to the program I was having pass input to sublime.
In my case, I wanted to take advantage of the "paste current selection to program" capability of the kitty terminal emulator. That functionality takes the current selection in the terminal and pipes it into a program for you when you press the keyboard shortcut. For some reason, the developer of kitty decided to pass the selection as an argument rather than via stdin.
To remedy this, I wrote a small C script that can handle both scenarios. In order to run the script, you'll need to install TCC. You may want to check your repo first. I know on debian you can install it with apt: sudo apt install tcc
. Alternatively, you can compile the following code with GCC, just remove the first line.
#!/usr/bin/tcc -run
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char **argv)
{
uint64_t randVal = 0;
FILE *fp = fopen("/dev/urandom", "rb");
fread((char *) &randVal, 8, 1, fp);
fclose(fp);
char tmpfile[512] = {0};
sprintf(tmpfile, "/tmp/piped_input_%llu.txt", randVal);
fp = fopen(tmpfile, "wb");
if(!fp)
{
fprintf(stderr, "Could not open temporary file: '%s'\n", tmpfile);
return -1;
}
if(argc == 2)
fprintf(fp, "%s", argv[1]);
if(argc == 1)
{
uint8_t tmpBuf[4096] = {0};
memset(tmpBuf, 0, 4096); // Old habit... ¯\_(ツ)_/¯
while(!feof(stdin))
{
int32_t numRead = fread((char *) tmpBuf, 1, 4096, stdin);
if(numRead > 0)
fwrite((char *) tmpBuf, numRead, 1, fp);
else
break;
}
}
fflush(fp);
fclose(fp);
char cmdStr[512] = {0};
sprintf(cmdStr, "subl %s", tmpfile);
system(cmdStr);
// Give sublime some time to open the file
usleep(1000 * 250);
unlink(tmpfile);
return 0;
}
The above script will read from stdin unless an argument is passed to the program. In either case, it simply reads the input (stdin
or argv[1]
) into a temporary file, opens the file with sublime, waits ~250ms to give time for sublime to open the file, and deletes the temporary file.
You can copy the above code to a location in your path (like /usr/local/bin/subl_pipe). Make sure set the permissions: chmod 755 /usr/local/bin/subl_pipe
.
Anyway, I hope this is useful to somebody else eventually... ^_^