WelcomeWelcome | FAQFAQ | DownloadsDownloads | WikiWiki

Author Topic: Using dmenu to load extensions  (Read 9497 times)

Offline althalus

  • Sr. Member
  • ****
  • Posts: 351
Using dmenu to load extensions
« on: July 16, 2010, 12:20:29 AM »
So ondemand is nice, but it still requires interaction with the mouse, and I can type firefox far faster than I can identify it in a list. Since I already mostly use either dmenu or tablaunch for launching apps, I wrote the following simple little wrapper for dmenu that I set up on a hotkey to quickly and easily load extensions with just a couple of keystrokes. (shouldn't need to say that it requires dmenu.tcz loaded)

Code: [Select]
#!/bin/sh
cd `cat /opt/.tce_dir`/optional
tcz=`ls *.tcz | dmenu -p "load extension: "` && exec tce-load -i $tcz

Mayhap anyone else using dmenu will find it useful.

Offline Misalf

  • Hero Member
  • *****
  • Posts: 1702
Re: Using dmenu to load extensions
« Reply #1 on: January 09, 2016, 07:06:03 PM »
I'm using a slightly less simple script which makes dmenu show a list of extensions and indicate which ones are already loaded.

Code: [Select]
#!/bin/sh
[ -e "/usr/local/tce.installed/dmenu" ] || tce-load -i dmenu.tcz >/dev/null 2>&1
TCZS="$(ls -1 /etc/sysconfig/tcedir/optional/*.tcz 2>/dev/null | sed 's:^/etc/sysconfig/tcedir/optional/::g;s/.tcz$//g' | sort -f)"
INSTALLED="$(for i in `ls -1 /usr/local/tce.installed/` ; do echo "$i" ; done)"
for i in $INSTALLED ; do TCZS="$(echo "${TCZS}" | sed "s/^\b$i\b$/:: $i/")" ; done
tce-load -i $(echo "$TCZS" | dmenu  -b -w 300 -h 300 -y 19 -c -p "*.tcz" -i -xs -nb '#0D0D0C' -nf '#D4D0C8' -sb '#050503' -sf '#ffb000') >/dev/null 2>&1 &


The only issue I have is that this loop is relatively slow.
Code: [Select]
for i in $INSTALLED ; do TCZS="$(echo "${TCZS}" | sed "s/^\b$i\b$/:: $i/")" ; done

It can take a few seconds to complete depending on how many extensions are available.
Would be great if anyone could think of a faster way.
Download a copy and keep it handy: Core book ;)

Offline curaga

  • Administrator
  • Hero Member
  • *****
  • Posts: 11044
Re: Using dmenu to load extensions
« Reply #2 on: January 10, 2016, 05:30:22 AM »
Code: [Select]
INSTALLED="$[for i in `ls -1 /usr/local/tce.installed/` ; do echo "$i" ; done)"
This loop is unnecessary. The shell will break them the same way either way, so just use INSTALLED="/usr/local/tce.installed/*".

String operations and forks are in general slow. You might be able to replace the echo/sed pair with the shell's string replacement operator, but if that's still too slow, the approach needs rethinking.
The only barriers that can stop you are the ones you create yourself.

Offline Misalf

  • Hero Member
  • *****
  • Posts: 1702
Re: Using dmenu to load extensions
« Reply #3 on: January 10, 2016, 07:55:52 AM »
The loop for the INSTALLED variable was a workaround as I couldn't get the subsequent loop to succeed without  sed  complaining about "bad option in substitution expression". Maybe sed doesn't like the path containing a dot.

Still, your suggestion to remove that loop led to some simplification. It now cd into respective directories like the OPs script does.
Code: [Select]
#!/bin/sh
[ -e "/usr/local/tce.installed/dmenu" ] || tce-load -i dmenu.tcz >/dev/null 2>&1

cd /etc/sysconfig/tcedir/optional
TCZS="$(ls -1 *.tcz 2>/dev/null | sed 's/.tcz$//g' | sort -f)"
cd /usr/local/tce.installed
for i in * ; do TCZS="$(echo "${TCZS}" | sed "s/^\b$i\b$/:: $i/")" ; done

tce-load -i $(echo "$TCZS" | dmenu  -b -w 300 -h 300 -y 19 -c -p "*.tcz" -i -xs -nb '#0D0D0C' -nf '#D4D0C8' -sb '#050503' -sf '#ffb000') >/dev/null 2>&1 &

Download a copy and keep it handy: Core book ;)

Offline Misalf

  • Hero Member
  • *****
  • Posts: 1702
Re: Using dmenu to load extensions
« Reply #4 on: January 10, 2016, 08:26:21 AM »
Quote
You might be able to replace the echo/sed pair with the shell's string replacement operator
In case you meant something like this
Code: [Select]
for i in * ; do TCZS="${TCZS//$i/:: $i}" ; done
it's either incredibly slow so that I loose the patients to wait for it to finish, or I'm doing something wrong.
Download a copy and keep it handy: Core book ;)

Offline curaga

  • Administrator
  • Hero Member
  • *****
  • Posts: 11044
Re: Using dmenu to load extensions
« Reply #5 on: January 10, 2016, 03:46:56 PM »
Yes, I meant that, perhaps it is that slow in bb ash.

You can always write it in C++ and have it done in O(log n) time ;)
The only barriers that can stop you are the ones you create yourself.

Offline Misalf

  • Hero Member
  • *****
  • Posts: 1702
Re: Using dmenu to load extensions
« Reply #6 on: January 10, 2016, 04:06:15 PM »
So, not being smart enough to write proper shell scripts means one has to learn C++. q:

BTW, the script currently looks like this, showing an extra dmenu while generating the list of tczs to prevent confusion.
Code: [Select]
#!/bin/sh
[ -e "/usr/local/tce.installed/dmenu" ] || tce-load -i dmenu.tcz >/dev/null 2>&1

cd /etc/sysconfig/tcedir/optional
TCZS="$(ls -1 *.tcz 2>/dev/null | sed 's/.tcz$//g' | sort -f)"
cd /usr/local/tce.installed
echo "Building menu..." | dmenu  -b -w 300 -h 300 -y 19 -p "*.tcz" -i -xs -nb '#0D0D0C' -nf '#D4D0C8' -sb '#050503' -sf '#ffb000' >/dev/null 2>&1 &
for i in * ; do TCZS="$(echo "${TCZS}" | sed "s/^\b$i\b$/:: $i/")" ; done
killall dmenu

tce-load -i $(echo "$TCZS" | dmenu  -b -w 300 -h 300 -y 19 -c -p "*.tcz" -i -xs -nb '#0D0D0C' -nf '#D4D0C8' -sb '#050503' -sf '#ffb000') >/dev/null 2>&1 &


Having 517 tczs on 7.x it takes about one second on my netbook. My 6.x install has 1139 tczs.

I just can't find a way to batch-replace several strings without a for loop and echo, which I think is the main for the delay.
Download a copy and keep it handy: Core book ;)

Offline mocore

  • Hero Member
  • *****
  • Posts: 641
  • ~.~
Re: Using dmenu to load extensions
« Reply #7 on: January 10, 2016, 06:34:19 PM »
I just can't find a way to batch-replace several strings without a for loop and echo, which I think is the main for the delay.

" just can't find"  probably " have not yet found"   ;)

Maby awk can replace tha strings  ? at least i hear its good for those sorts of things !


Offline Misalf

  • Hero Member
  • *****
  • Posts: 1702
Re: Using dmenu to load extensions
« Reply #8 on: January 10, 2016, 06:55:25 PM »
Yeah, thanks for the suggestion. I'm trying all day using awk which I'm not good at. I try to improve this scripts speed from time to time whenever the delay bugs me too much. I keep reading the same search results on the web about awk though. Maybe because I don't how to search for what I don't understand. Doh.
Download a copy and keep it handy: Core book ;)

Offline coreplayer2

  • Hero Member
  • *****
  • Posts: 3020
Re: Using dmenu to load extensions
« Reply #9 on: January 10, 2016, 07:15:02 PM »
I sure that both awk and sed are as slow as Molasses   :o

for speed, I'd use
Code: [Select]
for f in *.tcz; do echo "${f%%.*}"; done
which is faster and better that using ls
« Last Edit: January 10, 2016, 07:26:28 PM by coreplayer2 »

Offline Misalf

  • Hero Member
  • *****
  • Posts: 1702
Re: Using dmenu to load extensions
« Reply #10 on: January 10, 2016, 08:15:26 PM »
Thanks. Applied with a small adjustment to not mess up filenames containing dots (f.e. Xorg-7.7.tcz).
Code: [Select]
TCZS="$(for f in *.tcz; do echo "${f%%.tcz}" ; done | sort -f)"
Download a copy and keep it handy: Core book ;)

Offline coreplayer2

  • Hero Member
  • *****
  • Posts: 3020
Re: Using dmenu to load extensions
« Reply #11 on: January 10, 2016, 10:11:29 PM »
Oh well in that case you should take the shortest pattern from the end of $var  (use one % instead of %%)

Code: [Select]
for f in *.tcz; do echo "${f%.*}"; done
:p

« Last Edit: January 10, 2016, 10:14:19 PM by coreplayer2 »

Offline Misalf

  • Hero Member
  • *****
  • Posts: 1702
Re: Using dmenu to load extensions
« Reply #12 on: January 11, 2016, 01:29:54 AM »
I always forget that syntax. o.O
Download a copy and keep it handy: Core book ;)

Offline Misalf

  • Hero Member
  • *****
  • Posts: 1702
Re: Using dmenu to load extensions
« Reply #13 on: January 11, 2016, 03:54:17 AM »
Thanks coreplayer2. Your suggestion to use a loop for the tczs got me thinking - Why not reusing that loop.

Code: [Select]
#!/bin/sh
[ -e "/usr/local/tce.installed/dmenu" ] || tce-load -i dmenu >/dev/null 2>&1

PROMPT="*.tcz"
OPTS="-b -w 300 -h 300 -y 19 -nb #0D0D0C -nf #D4D0C8 -sb #050503 -sf #FFB000"

cd /etc/sysconfig/tcedir/optional
TCZS="$(for f in $PROMPT ; do [ -e "/usr/local/tce.installed/${f%.*}" ] && echo ":: ${f%.*}" || echo "${f%.*}" ; done | sort -f)"

TCZ="$(echo "$TCZS" | dmenu -i -xs -c -p "$PROMPT" $OPTS 2>/dev/null)" \
&& tce-load -i "$TCZ"


This makes code execution almost instantaneously!

As it is right now, the only problem is the  sort  part. I can't get it to ignore the leading  ":: " .
Download a copy and keep it handy: Core book ;)

Offline Misalf

  • Hero Member
  • *****
  • Posts: 1702
Re: Using dmenu to load extensions
« Reply #14 on: January 11, 2016, 04:19:55 AM »
Yay! found a way I'm quite happy with. Thanks everyone!

Code: [Select]
#!/bin/sh
[ -e "/usr/local/tce.installed/dmenu" ] || tce-load -i dmenu >/dev/null 2>&1

PROMPT="*.tcz"
OPTS="-i -xs -c -b -w 300 -h 300 -y 19 -nb #0D0D0C -nf #D4D0C8 -sb #050503 -sf #FFB000"

cd /etc/sysconfig/tcedir/optional
TCZS="$(for f in $PROMPT ; do [ -e "/usr/local/tce.installed/${f%.*}" ] && echo " ${f%.*}" || echo "${f%.*}" ; done | sort -bf | sed 's/ /:: /')"

TCZ="$(echo "$TCZS" | dmenu -p "$PROMPT" $OPTS 2>/dev/null)" \
&& tce-load -i "$TCZ" &


Code: [Select]
time dmenu-tce-load
real 0m 0.04s
user 0m 0.03s
sys 0m 0.02s
Download a copy and keep it handy: Core book ;)