I want to poll something and then pipe results to FZF, such that it gets updated there. Here is an example using CURL:
while true; do curl google.com -s; sleep 2; done | fzf
This stacks-up all the outputs like:
</BODY></HTML>
<A HREF="http://www.google.com/">here</A>.
The document has moved
<H1>301 Moved</H1>
<TITLE>301 Moved</TITLE></HEAD><BODY>
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
</BODY></HTML>
<A HREF="http://www.google.com/">here</A>.
The document has moved
<H1>301 Moved</H1>
<TITLE>301 Moved</TITLE></HEAD><BODY>
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
</BODY></HTML>
<A HREF="http://www.google.com/">here</A>.
The document has moved
<H1>301 Moved</H1>
<TITLE>301 Moved</TITLE></HEAD><BODY>
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
But I want it to just list one output
</BODY></HTML>
<A HREF="http://www.google.com/">here</A>.
The document has moved
<H1>301 Moved</H1>
<TITLE>301 Moved</TITLE></HEAD><BODY>
> <HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
and update it if it changes.
A simple way of dealing with this is with a key-press-reload command:
curl google.com | fzf --bind 'ctrl-r:reload(curl google.com)'
But that requires pressing CTRL-R to refresh. To make it automated... can wrap the desired command and FZF, and use FZF with fzf -f <query>
to only get the results to display. Eg, with node create fzf-watch.js:
const { exec } = require("child_process");
const cmd = process.argv[2];
let query = "";
let timeout;
let commandRes = "";
if (!cmd) {
console.log("A command must be provided as the second argument");
process.exit(1);
}
function runCommand(cb) {
exec(cmd, function (error, stdout, stderr) {
if (stderr) {
console.log("standard error", stderr);
}
commandRes = stdout;
cb();
});
}
function printOut(/** @type {string} */ str) {
console.clear();
console.log(str);
process.stdout.write(`Query: ${query}`);
}
function runFzf() {
if (!query) {
printOut(commandRes);
return;
}
exec(
`echo '${commandRes}' | fzf -f "${query}"`,
function (error, stdout, stderr) {
if (!error) {
printOut(stdout);
} else {
printOut("");
}
}
);
}
function runQuery() {
// Run fzf on existing result in the meantime
runFzf();
// Start running the command
runCommand(runFzf);
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(runQuery, 5000);
}
const readline = require("readline");
readline.emitKeypressEvents(process.stdin);
process.stdin.setRawMode(true);
process.stdin.on("keypress", (k, key) => {
if (key.name === "backspace") {
query = query.substring(0, query.length - 1);
}
else if (key.sequence === "\u0003") {
process.exit();
} else {
query = `${query}${k}`;
}
runQuery();
});
runQuery();
Call it like this to watch the results (called every 5 seconds):
node ./fzf-watch.js 'curl google.com'