elkowar / eww

ElKowars wacky widgets
https://elkowar.github.io/eww
MIT License
9.3k stars 382 forks source link

[BUG] `deflisten` only keeps last line while `defpoll` keeps all lines #546

Closed danjenson closed 2 years ago

danjenson commented 2 years ago

Checklist before submitting an issue

Description of the bug

I have a widget that displays my todos in a nice table format: image Right now, I'm using defpoll to define the todos content: (defpoll todos :interval "15s" "./neww todos")

However, this content rarely changes, so I set up a simple script to simply update when there are changes to the file: todos.sh

#!/bin/bash
nu --config ~/.config/eww/eww.nu -c todos
inotifywait -q -m -e close_write ~/todos.txt |
while read -r filename event; do
  nu --config ~/.config/eww/eww.nu -c todos
done

I tried to listen to this with (deflisten todos "./todos.sh"), but it only ever grabs the last line of output image

Reproducing the issue

  1. Print something with multiple lines
  2. Record it with defpoll
  3. Record it with deflisten

Notice that deflisten only takes the most recent line.

Expected behaviour

deflisten would be able to capture all output since last change

Additional context

No response

viandoxdev commented 2 years ago

Not a bug, See the Listening variables paragraph of the documentation. In your case I'd recommend making your script return a json array of todos instead and use a for special widget to render each line.

You could try substituting the newline character in the command for another (i.e by piping tr '\n' '\f') and using the replace function, but this line seems to make replacing with new lines impossible.

Edit: using the replace trick seems to work, you just need a character you're sure won't be returned by the command:

danjenson commented 2 years ago

It's hacky but it works! It might be nice to capture all output since last change, instead of only the last line since the last change. It would be really useful for files you are watching with inotify. Nonetheless, grateful for the help!

elkowar commented 2 years ago

It's hacky but it works! It might be nice to capture all output since last change, instead of only the last line since the last change. It would be really useful for files you are watching with inotify. Nonetheless, grateful for the help!

How would eww know what the "last change" is? as in, how would eww differenciate between the program outputting 7 lines as one value and outputting 7 lines because 7 changes happened?

xyangst commented 9 months ago

Not a bug, See the Listening variables paragraph of the documentation. In your case I'd recommend making your script return a json array of todos instead and use a for special widget to render each line.

You could try substituting the newline character in the command for another (i.e by piping tr '\n' '\f') and using the replace function, but this line seems to make replacing with new lines impossible.

Edit: using the replace trick seems to work, you just need a character you're sure won't be returned by the command:

  • add | tr '\\n' ' ' to the end of your command in the deflisten (the character in the second quotes isn't a space but this)
  • instead of using {variable_name} use:
;           use special character here v
(whatever ... {replace(variable_name, " ", "
")} ... ) ; the new line is intended

how could i use such a for loop widget over json? any example? the docs dont have anything like that..