You are not logged in.

#51 2012-05-15 14:42:36

djp
Member
Registered: 2012-02-11
Posts: 12

Re: Dmenu Hacking Thread

One more: I really liked that mpc wrapper... but mpd doesn't work on my laptop, so I remade it around mplayer.  It's a little longer, but it has built in controls (instead of selecting an artist, select "**").  This also assumes you have your directories set up as Artist/Album/Track.ogg

#!/bin/bash
# Change this in case I missed an music file extension (space delimited)
ext_list="mp3 ogg oga aac m4a flac wav wma aif aiff ape mpc shn"

# If you have a band called "Control Panel", you might want to change this
control_string="**"

# Make sure you have write permissions on all of these files/directories
music_dir="$HOME/Music"
mpl_in=/tmp/mpl-menu.in
mpl_out=/tmp/mpl-menu.out

# If you have different aliases for mplayer to use different sound cards,
# set them here
prog_name=`echo $0 | awk 'BEGIN {FS="/"}; {print $NF}'`
if [[ "$prog_name" == "mpl-menu-speak" ]]; then
  speak=speak
else
  unset speak
fi
# /alias

# A file named ".playlist" will be created that contains the list of files to be
# played. No other write operations happen here
cd $music_dir

if [[ -f "$HOME/.dmenurc" ]]; then
  . "$HOME/.dmenurc"
else
  DMENU="dmenu -i"
fi

ext_list=`echo $ext_list | tr ' ' '|'`
IFS=$'\n'
art_list="$(find . -regextype posix-extended -regex '.*\.('"$ext_list"')'\
  | awk 'BEGIN {FS="/"}; { print $2 }')"
art_list=`echo -e "$art_list\n$control_string"`
art_list=`echo "$art_list" | sort`
art_list=`echo "$art_list" | uniq`
unset IFS
ARTIST=`echo "$art_list" | $DMENU`
IFS=$'\n'
case $ARTIST in
  "$control_string")
    while true; do
      choices=`echo -e "Next\nPaus/Play\nPrev\nStop\nInfo" | sort`
      unset IFS
      cont_choice=`echo -e "$choices" | $DMENU`
      IFS=$'\n'
      case $cont_choice in
        Next)
          echo -e 'pt_step 1\n' > $mpl_in
          ;;
        Prev)
          echo -e 'pt_step -1\n' > $mpl_in
          ;;
        "Paus/Play")
          echo -e 'pause\n' > $mpl_in
          ;;
        Stop)
          echo -e 'quit\n' > $mpl_in
          if [ -e $music_dir/.playlist ]; then
            rm $music_dir/.playlist
          fi
          exit
          ;;
        Info)
          echo -n "" > $mpl_out
          echo -e 'get_meta_title\n' > $mpl_in
          echo -e 'get_meta_artist\n' > $mpl_in
          echo -e 'get_meta_album\n' > $mpl_in
          sleep .5
          inf_str=`cat $mpl_out | awk 'BEGIN {FS="="}; {print $2}'`
          inf_str=`echo -e "$inf_str" | sed "s/'//g"`
          inf_str=`echo "$inf_str" | tr '\n' '|'`
          inf_str=`echo "$inf_str" | sed   's/^/Title:  /'`
          inf_str=`echo "$inf_str" | sed 's/|/\nArtst:  /'`
          inf_str=`echo "$inf_str" | sed 's/|/\nAlbum:  /'`
          inf_str=`echo "$inf_str" | sed 's/|/\n/'`
          unset IFS
          echo "$inf_str" | $DMENU -l 3 -p "Now Playing:"
          exec $0
          ;;
        "")
          break
          ;;
      esac
    done
    exit
    ;;
  "")
    exit
    ;;
  *)
    # Check to see if the artist exists
    if [[ ! -e $ARTIST ]]; then
      exec $0
    fi
    ;;
esac
alb_list="$(find $ARTIST -regextype posix-extended -regex '.*\.('"$ext_list"')'\
             | awk 'BEGIN {FS="/"}; { print $2 }')"
alb_list=`echo "$alb_list" | sort`
alb_list=`echo "$alb_list" | uniq`
unset IFS
ALBUM=`echo -e "Play All\n$alb_list" | $DMENU`
IFS=$'\n'

case $ALBUM in
  "Play All")
    song_list="$(find $ARTIST/ -regextype posix-extended\
      -regex '.*\.('"$ext_list"')')"
    song_list=`echo "$song_list" | sort`
    echo "$song_list" > $music_dir/.playlist
    if [ -e $mpl_in ]; then
      unset IFS
      echo "It looks like an instance of mpl-menu is already running!" | $DMENU
      exit
    fi
    mkfifo $mpl_in
    mplayer${speak} -quiet -slave -input file=$mpl_in -playlist "./.playlist"\
      >> $mpl_out
    rm $mpl_in
    rm $mpl_out
    rm $music_dir/.playlist
    ;;
  "")
    exec $0
    ;;
  *)
    # Check to see if the album exists
    if [[ ! -e $ARTIST/$ALBUM ]]; then
      exec $0
    fi
    
    song_list="$(find $ARTIST/$ALBUM/ -regextype posix-extended\
      -regex '.*\.('"$ext_list"')')"
    song_list=`echo "$song_list" | sort`
    echo "$song_list" > $music_dir/.playlist
    unset IFS
    if [ -e $mpl_in ]; then
      unset IFS
      echo "It looks like an instance of mpl-menu is already running!" | $DMENU
      exit
    fi
    mkfifo $mpl_in
    mplayer${speak} -quiet -slave -input file=$mpl_in -playlist "./.playlist"\
      >> $mpl_out
    rm $mpl_in
    rm $mpl_out
    rm $music_dir/.playlist
    ;;
esac

Last edited by djp (2012-06-09 09:36:36)

Offline

#52 2012-05-22 17:32:20

leafo
Member
Registered: 2007-01-12
Posts: 14
Website

Re: Dmenu Hacking Thread

I just stated using dmenu with vim as a way to open files quickly. I wrote about it here: http://leafo.net/posts/using_dmenu_to_open_quickly.html

It's really fast compared to other stuff like FuzzyFinder.

Essentially it boils down to this tiny snippet in your vimrc:

function! Chomp(str)
  return substitute(a:str, '\n$', '', '')
endfunction

function! DmenuOpen(cmd)
  let fname = Chomp(system("git ls-files | dmenu -i -l 20 -p " . a:cmd))
  if empty(fname)
    return
  endif
  execute a:cmd . " " . fname
endfunction

" use ctrl-t to open file in a new tab
" use ctrl-f to open file in current buffer
map <c-t> :call DmenuOpen("tabe")<cr>
map <c-f> :call DmenuOpen("e")<cr>

Offline

#53 2012-05-22 17:45:57

Cloudef
Member
Registered: 2010-10-12
Posts: 636

Re: Dmenu Hacking Thread

leafo wrote:

I just stated using dmenu with vim as a way to open files quickly. I wrote about it here: http://leafo.net/posts/using_dmenu_to_open_quickly.html

It's really fast compared to other stuff like FuzzyFinder.

Essentially it boils down to this tiny snippet in your vimrc:
*snip*

This is really really awesome. Thank you!
Edit: Once again, this is just awesome. Beats nerdtree and such just like that.
I really should use dmenu more.

Last edited by Cloudef (2012-05-22 17:47:34)

Offline

#54 2012-05-22 20:44:38

Runiq
Member
From: Germany
Registered: 2008-10-29
Posts: 1,053

Re: Dmenu Hacking Thread

leafo wrote:

I just stated using dmenu with vim as a way to open files quickly. I wrote about it here: http://leafo.net/posts/using_dmenu_to_open_quickly.html

It's really fast compared to other stuff like FuzzyFinder.

This is awesome. It's one of those things I wish I had thought of myself.

Thank you, leafo.

Edit: Grammar.

Last edited by Runiq (2012-05-28 09:20:07)

Offline

#55 2012-05-24 10:43:13

Runiq
Member
From: Germany
Registered: 2008-10-29
Posts: 1,053

Re: Dmenu Hacking Thread

So I caved in and uploaded the dmenu-xft-height package to the AUR.

Offline

#56 2012-05-28 04:49:01

x_fausto
Member
Registered: 2011-11-12
Posts: 18
Website

Re: Dmenu Hacking Thread

I write this quick script, to search the web with dmenu, but uses xclip as "history". I made it thinking of a similar feature I have on surf, but I wanted it on Opera. After a while, I thought it was better if the script can select the browser from a variable, xdg-open or gnome-open. So, here it is:

#!/bin/bash
# Search script with history using dmenu, xclip and your browser
# Author: Heinrich Faust <fausto17@gmail.com>
URL="https://duckduckgo.com/?q=`xclip -o -selecton primary | dmenu -i -fn 'Open Sans-12' -p 'Search' `"
[[ -x $BROWSER ]] && exec "$BROWSER" "$URL"
path=$(which xdg-open || which gnome-open) && exec "$path" "$URL"
echo "Can't find browser" 

I use DuckDuckgo, but you can change the URL, and the definitions of dmenu. I will keep updating as I learn more about shell scripting.


Fork me on Github  |  Eri  @  Arch Linux i686

Offline

#57 2012-06-08 13:01:38

mnzaki
Member
Registered: 2012-06-08
Posts: 13

Re: Dmenu Hacking Thread

dmenu-recent: DMenu Launcher that keeps track of recently used commands and also which commands should be run in the terminal.

Army wrote:

I've been using this one for many months now and I can't live without it anymore (on the computer). It was written by Dieter Plaetinck and posted somewhere here in the forums. I had to make it depend on dmenu-path-c because of changes in dmenu. Maybe someone capable can make it use stest like dmenu_run does? I'll try it myself again, maybe this time I'll succeed.
Anyways, here's this little perl
It's a drop-in replacement for dmenu_run and adds the ability to either run the application in the background (e.g. web browsers, libreoffice, etc.) or in the terminal (mutt, ranger, ncmpcpp, etc.). You'll have to tell it the first time you launch an application, if it's supposed to be run in the background or in a terminal. After that it won't ask again.

That deservers much more love that it's getting! I was JUST about to write something similar, so I based it off of this. It now uses stest and doesn't rebuild the caches unless necessary. Also the 'recent' command keeping is a little better. The old way would arrange commands by number of uses; now I just keep a reverse chronologically sorted list of recent commands, which I think makes more sense. Also it won't drop commands from the list if other commands are used repeatedly.

#!/bin/bash

# Originally based on code by Dieter Plaetinck.
# Pretty much re-written by Mina Nagy (mnzaki)

dmenu_cmd="dmenu $DMENU_OPTIONS"
terminal="urxvtc -e"
max_recent=199 # Number of recent commands to track

cache_dir="${XDG_CACHE_HOME:-$HOME/.cache}/dmenu-recent"
recent_cache="$cache_dir/recent"
rest_cache="$cache_dir/all"
known_types=" background terminal terminal_hold "

config_dir="${XDG_CONFIG_HOME:-$HOME/.config}/dmenu-recent"
mkdir -p "$cache_dir"
mkdir -p "$config_dir"
touch "$recent_cache"

IFS=:
if stest -dqr -n "$rest_cache" $PATH 2>/dev/null; then
     stest -flx $PATH | sort -u | grep -vf "$recent_cache" > "$rest_cache"
fi

IFS=" "
cmd=$(cat "$recent_cache" "$rest_cache" | $dmenu_cmd -p Execute: "$@") || exit

if ! grep -qx "$cmd" "$recent_cache" &> /dev/null; then
    grep -vx "$cmd" "$rest_cache" > "$rest_cache.$$"
    mv "$rest_cache.$$" "$rest_cache"
fi

echo "$cmd" > "$recent_cache.$$"
grep -vx "$cmd" "$recent_cache" | head -n "$max_recent" >> "$recent_cache.$$"
mv "$recent_cache.$$"  "$recent_cache"

# Figure out how to run the command based on the command name, disregarding
# arguments, if any.
word0=${cmd%% *}
match="^$word0$"

get_type () {
    while type=$(echo $known_types | xargs -n1 | $dmenu_cmd -p Type:); do
        [[ $known_types =~ " $type " ]] || continue
        echo "$word0" >> "$config_dir/$type"
        break
    done
    echo $type
}

if ! type=$(grep -lx "$match" -R "$config_dir"); then
    type=$(get_type)
else 
    type=${type##*/}
    if ! [[ $known_types =~ " $type " ]]; then
        rm "$config_dir/$type"
        type=$(get_type)
    fi
fi

[[ "$type" = "background" ]] && exec $cmd
[[ "$type" = "terminal" ]] && exec $terminal "$cmd"
[[ "$type" = "terminal_hold" ]] &&
    exec $terminal sh -c "$cmd && echo Press Enter to kill me... && read line"

Update 1:
Changed the type names and added 'terminal_hold' type, which will run a command and hold the terminal after it exits.
Fixed a bug with recent program list keeping.
Cleaned up the code; thanks to steve___ for the helpful pointers!
Update 2:
Exit if user presses escape during type choosing
Update 3:
Fix bug with cache update when new executables are installed in $PATH

Last edited by mnzaki (2012-06-29 13:39:23)

Offline

#58 2012-06-08 13:10:27

mnzaki
Member
Registered: 2012-06-08
Posts: 13

Re: Dmenu Hacking Thread

dcalculator: Quick and dirty calculator for dmenu. Keeps track of previous values. Depends on the 'calc' utility.

Inspired by Procyon's post.
This will prompt for more calculations and keep track of all previous values.

#!/bin/bash

while inp=$(echo -e "$oup" | dmenu -p Calculate:)
do
    if oup2=$(calc -pd "$inp"); then
        echo -n "$oup2" | xsel -i
        oup="$oup2\n$oup"
    fi
done

Update: Copy the last answer into the primary X selection.

Last edited by mnzaki (2012-06-08 19:43:41)

Offline

#59 2012-06-08 15:16:51

Army
Member
Registered: 2007-12-07
Posts: 1,784

Re: Dmenu Hacking Thread

mnzaki wrote:

dmenu-recent: DMenu Launcher that keeps track of recently used commands and also which commands should be run in the terminal.

Awesome, thanks! I'll give it a shot!

Offline

#60 2012-06-09 09:47:54

djp
Member
Registered: 2012-02-11
Posts: 12

Re: Dmenu Hacking Thread

Another calculator - it's a little bulkier than the others, but it constantly loops (you can press escape to quit) and it keeps track of all commands entered.  The first value is taken from xclip (primary), and the last value is stored in xclip. Requires python, xsel, and vertical patch.

EDIT: if contents of primary aren't a valid calculation, first item in history will be "False"

#!/bin/bash
DMENU="dmenu -i"
if [[ -f "$HOME/.dmenurc" ]]; then
  . $HOME/.dmenurc
fi
DMENU="$DMENU -l 10"

pystr="from math import *; print"

hist="$(xsel -o)"
(echo "$pystr $hist" | python 2>/dev/null) || hist=False

calc=$(echo $hist | $DMENU -p Calculate:)
prev="$calc"
while true; do
  case $calc in
    ""|"exit")
      break
      ;;
    *)
      prev="$calc"
      hist="$prev\n$hist"
      calc=$(echo "$pystr $calc; print \"\n$hist\"" | python 2>/dev/null\
        | $DMENU -p "Calculate:")
      ;;
  esac
done
echo "$pystr $prev" | python 2>/dev/null | xsel -i

Last edited by djp (2012-06-10 22:15:19)

Offline

#61 2012-06-09 10:17:46

mnzaki
Member
Registered: 2012-06-08
Posts: 13

Re: Dmenu Hacking Thread

dmenu-dict: Look up words in dictionaries using the dict utility. Prompt for corrections if word not found. Display definitions in a transient terminal.

#!/bin/sh
terminal="urxvtc --transient-for 0 -e"
tmpfile="/tmp/ddict.lookup.$$"

word=$(xsel -o | dmenu -p 'Dict Lookup:') || exit
while [[ $word != "" ]]; do
    oup=$(dict "$word" 2>&1)
    if [[ $? -eq 21 ]]; then
        word=$(echo -e "$oup" | cut -d: -f2 | xargs -n1 | sort -u -f | dmenu -p 'Did you mean:') || exit
    else
        echo -e "$oup" > "$tmpfile"
        break
    fi
done

$terminal less "$tmpfile"\; rm "$tmpfile"

Last edited by mnzaki (2012-07-02 16:30:58)

Offline

#62 2012-06-14 22:01:35

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,422
Website

Re: Dmenu Hacking Thread

I'm thinking of writing a color patch for dmenu (much like colorstatus patch for dwm).  It seems much of the drawing code is shared with dwm, so many of the changes can probably be taken from the colorstatus patch.

Before I dive into this though, I was wondering if anyone else has tinkered with this or heard of such coloring options for dmenu.  I googled quite a bit, but I have been surprised to find nothing on it.  Either my google-fu is very weak, or maybe no one else would be interested in this but me.

To clarify, this would be useful for dmenu using scripts like many in this thread.  It wouldn't have any use in the normal dmenu-run type script.  But as many users use dmenu in creative ways to display information and get input, being able to color that display would be nice.

So, the question: has anyone seen such color patches, or tinkered with this yet?


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#63 2012-06-15 06:35:02

Runiq
Member
From: Germany
Registered: 2008-10-29
Posts: 1,053

Re: Dmenu Hacking Thread

Trilby wrote:

So, the question: has anyone seen such color patches, or tinkered with this yet?

No, and no. But I do have some suggestions once you have a working draft ready. wink

Offline

#64 2012-06-16 20:45:46

skanky
Member
From: WAIS
Registered: 2009-10-23
Posts: 1,847

Re: Dmenu Hacking Thread

I have a question about dmenu_run (and dmenu_recent) and stest.

When I run

stest -flx $PATH

as is in both the dmenu_run and dmenu_recent scripts, I get no output, yet dmenu_run works as expected when I run it with no cache file - and it builds a cache file.
Looking at the stest manual, I'd expect no output, so that's fine but that's how dmenu_run uses it.

However, dmenu_recent doesn't ever build up the rest_cache file - as I would expect seeing as the above code produces no output.

However, the following code runs and produces a list of files as expected (ignore the fact that there are probably better ways to do this, I just wanted something that works):

echo $PATH | sed 's/:/\n/g' | awk '{system("stest -flx " $1)}'

so I know I don't have an empty $PATH wink

Can anyone point out the very obvious thing I must be missing?


"...one cannot be angry when one looks at a penguin."  - John Ruskin
"Life in general is a bit shit, and so too is the internet. And that's all there is." - scepticisle

Offline

#65 2012-06-16 21:06:58

mnzaki
Member
Registered: 2012-06-08
Posts: 13

Re: Dmenu Hacking Thread

The not at all obvious thing is

IFS         The Internal Field Separator that is used for word splitting after expansion and
              to split lines into words with the read builtin command.  The default  value  is
              ``<space><tab><newline>''.

In both dmenu_recent and dmenu_run, there's a line that does "IFS=:", so this way $PATH expands to "/usr/bin /bin /usr/local/bin...." instead of "/usr/bin:/bin:/usr/local/bin..."

Offline

#66 2012-06-16 21:28:24

skanky
Member
From: WAIS
Registered: 2009-10-23
Posts: 1,847

Re: Dmenu Hacking Thread

mnzaki wrote:

The not at all obvious thing is

IFS         The Internal Field Separator that is used for word splitting after expansion and
              to split lines into words with the read builtin command.  The default  value  is
              ``<space><tab><newline>''.

In both dmenu_recent and dmenu_run, there's a line that does "IFS=:", so this way $PATH expands to "/usr/bin /bin /usr/local/bin...." instead of "/usr/bin:/bin:/usr/local/bin..."

Actually yes it is obvious and I really should have spotted that. Thank you.
The problem was, once I'd got the stest line outside the scripts I was dealing with it isolation and I completely forgot about IFS.

EDIT: don't know why dmenu_recent didn't populate the rest_cache, but running that line on its own build it and now the script runs as expected, many thanks.
I probably did something wrong initially and ended up with an empty file that stopped subsequent runs filling it.

Last edited by skanky (2012-06-16 21:36:34)


"...one cannot be angry when one looks at a penguin."  - John Ruskin
"Life in general is a bit shit, and so too is the internet. And that's all there is." - scepticisle

Offline

#67 2012-06-16 21:50:00

skanky
Member
From: WAIS
Registered: 2009-10-23
Posts: 1,847

Re: Dmenu Hacking Thread

So here's my addition, it's a modification of the dmenu_edit script mentioned here.

It now lists shortened files in the menu and allows strings to be inserted before the editor - mainly sudo, but I'm sure there are other uses.

#!/bin/sh
#
# dedit: Use dmenu to open and edit a file from a given list.

# Global variables:
FILES="$XDG_CONFIG_HOME/dmenu/edit-list"

if [ -f $XDG_CONFIG_HOME/dmenu/dmenurc ]; then
  . $XDG_CONFIG_HOME/dmenu/dmenurc
else
  DMENU='dmenu -i -l 8'
fi

# Get list of options
OPTS=$(awk '{print $1}' $FILES)

choice=$(echo "$OPTS" | $DMENU -p "File to edit:")
if [[ $choice ]]; then
    # use eval as get vim error is use awk's system
    eval $(awk '/'$choice'/ {printf("%s '$EDITOR' %s", $3, $2);exit}' $FILES)
fi

The file is in the format:

bashrc ~/.bashrc
bash_profile ~/.bash_profile
xinitrc ~/.xinitrc
Xdefaults ~/.Xdefaults
vimrc ~/.config/vim/vimrc
rc.conf /etc/rc.conf sudo
editlist ~/.config/dmenu/edit-list

Obviously you'll need to quote spaces.
I might make it more generic and have the path passed in (use an alias or function to wrap it) and have a fourth column to enable passing in a non-default editor.
But that will probably be Monday, now.

EDIT: removed unnecessary $sudo from script.

Last edited by skanky (2012-06-18 10:48:05)


"...one cannot be angry when one looks at a penguin."  - John Ruskin
"Life in general is a bit shit, and so too is the internet. And that's all there is." - scepticisle

Offline

#68 2012-06-17 10:39:58

theGunslinger
Member
Registered: 2011-05-20
Posts: 300

Re: Dmenu Hacking Thread

@mnzaki
I'm using your modified dmenu-recent and i have to say it's become invaluable in my daily work. However it won't work if i set my panel transparent (using awesomewm), do you know what the problem could be?

Offline

#69 2012-06-17 11:04:12

mnzaki
Member
Registered: 2012-06-08
Posts: 13

Re: Dmenu Hacking Thread

theGunslinger wrote:

@mnzaki
I'm using your modified dmenu-recent and i have to say it's become invaluable in my daily work. However it won't work if i set my panel transparent (using awesomewm), do you know what the problem could be?

Could you be more specific? In what way does it not work? Does it not show up in the first place? Do other dmenu utilities work? Can you run it from a terminal (as opposed to from the WM using a shortcut) and see if there's any error output?

Offline

#70 2012-06-17 13:01:35

theGunslinger
Member
Registered: 2011-05-20
Posts: 300

Re: Dmenu Hacking Thread

Other utilites worked, and it could be ran from a terminal so I've checked my rc.lua and fixed the error ( I've made). Works great, thanks again for this great tool.

Offline

#71 2012-06-18 20:40:25

skanky
Member
From: WAIS
Registered: 2009-10-23
Posts: 1,847

Re: Dmenu Hacking Thread

Here's an updated version of my edit script:

#!/bin/sh
#
# dedit: Use dmenu to open and edit a file from a given list.

# Global variables:
FILES=${1:-"$HOME/.config/dmenu/edit-list"}

if [ -f $XDG_CONFIG_HOME/dmenu/dmenurc ]; then
  . $XDG_CONFIG_HOME/dmenu/dmenurc
else
  DMENU='dmenu -i -l 8'
fi

# Show list of options
choice=$(awk '{print $1}' $FILES | $DMENU -p "File to edit:")

if [[ $choice ]]; then
    # use eval as get vim error is use awk's system
    eval $(awk '/'$choice'/ && NF == 2 {printf("'$EDITOR' %s",$2); exit}
                /'$choice'/ && NF == 3 {printf("%s %s",$3,$2); exit}' $FILES)
fi

It will assume standard editor for two entry items, and if there is a third entry it will assume that that is a different editor to use. There may be better ways to do that, but after trying a few out, this works best with how I will use it. The label file being consistently the first two items on the line. That way if I want to add other parameters, I won't need to insert them to existing entries.

Sudo is used by using sudoedit as the editor name, see example below.

Here's a couple of example files:

$ cat ~/.config/dmenu/edit-list
bashrc  ~/.bashrc
bash_profile ~/.bash_profile
functions ~/.config/bash/bash_functions
xinitrc ~/.xinitrc
Xdefaults ~/.Xdefaults
vimrc ~/.config/vim/vimrc
rc.conf /etc/rc.conf sudoedit 
editlist $XDG_CONFIG_HOME/dmenu/edit-list
acclist $XDG_CONFIG_HOME/dmenu/edit-list-acc

$ $cat ~/.config/dmenu/edit-list-acc 
Forecast ~/data/Accounting/Forecast11-12.xls gnumeric
Ledgers ~/data/Accounting/Ledgers.xls gnumeric
PPAC ~/data/Accounting/AC20112012.xls gnumeric

Using the second file I wrapped dedit in a function:

acedit () { dedit "$XDG_CONFIG_HOME/dmenu/edit-list-acc" & }

It should be fairly trivial to convert it to a generic command launcher. I haven't done that yet as I'm not sure how much I'll use it.
I'll keep it in mind though.

Nothing overly sophisticated, but does a job.


"...one cannot be angry when one looks at a penguin."  - John Ruskin
"Life in general is a bit shit, and so too is the internet. And that's all there is." - scepticisle

Offline

#72 2012-06-19 11:25:27

skanky
Member
From: WAIS
Registered: 2009-10-23
Posts: 1,847

Re: Dmenu Hacking Thread

Last one for a while I think, again though, nothing overly sophisticated.

This one lists all mounts on /media and /mnt. If you select one, it gets unmounted. If you need to input a password (can be disabled in sudoers), you'll need to run from a terminal.

#!/bin/bash
#
# dumnt: gives a list of mounted external drives for umounting.
#
# depends on dmenu.

# Source generic dmenu
if [ -f $XDG_CONFIG_HOME/dmenu/dmenurc ]; then
  . $XDG_CONFIG_HOME/dmenu/dmenurc
else
  DMENU='dmenu -i -l 8'
fi

# Show options, get choice
choice=$(mount | awk '$3 ~ /\/media\// || /\/mnt\// { print $3 }' | $DMENU -p "Drive to umount:")

if [[ $choice ]]; then
        sudo umount $choice
fi

If there is nothing mounted on those dirs, then you'll get an empty list in dmenu. Hitting enter or escape should clear with no side effects.


"...one cannot be angry when one looks at a penguin."  - John Ruskin
"Life in general is a bit shit, and so too is the internet. And that's all there is." - scepticisle

Offline

#73 2012-06-19 14:09:23

Runiq
Member
From: Germany
Registered: 2008-10-29
Posts: 1,053

Re: Dmenu Hacking Thread

skanky wrote:

Last one for a while I think, again though, nothing overly sophisticated.

This one lists all mounts on /media and /mnt. If you select one, it gets unmounted. If you need to input a password (can be disabled in sudoers), you'll need to run from a terminal.

code!

If there is nothing mounted on those dirs, then you'll get an empty list in dmenu. Hitting enter or escape should clear with no side effects.

Hm… I did something similar using dmenu and udisks. The calling syntax is awkward, but it works fine for me and doesn't need sudo (but it does need udisks and python-dbus):

# Shows mountable volumes in dmenu and mounts them under
# /media/<label>
dmenu_udisks.py -m -- dmenu <dmenu_options>
# Shows mounted volumes in dmenu and unmounts them, destroying the
# /media/<label> directory in the process
dmenu_udisks.py -u -- dmenu <dmenu_options>

By the way, is there a patch somewhere to make dmenu read default options from an environment variable or from a configuration file? I'm tired of having to change the configuration in multiple places if I decide to mix things up again (which reliably happens every few weeks).

Offline

#74 2012-06-19 14:24:12

skanky
Member
From: WAIS
Registered: 2009-10-23
Posts: 1,847

Re: Dmenu Hacking Thread

Runiq wrote:
skanky wrote:

Last one for a while I think, again though, nothing overly sophisticated.

This one lists all mounts on /media and /mnt. If you select one, it gets unmounted. If you need to input a password (can be disabled in sudoers), you'll need to run from a terminal.

code!

If there is nothing mounted on those dirs, then you'll get an empty list in dmenu. Hitting enter or escape should clear with no side effects.

Hm… I did something similar using dmenu and udisks. The calling syntax is awkward, but it works fine for me and doesn't need sudo (but it does need udisks and python-dbus):

# Shows mountable volumes in dmenu and mounts them under
# /media/<label>
dmenu_udisks.py -m -- dmenu <dmenu_options>
# Shows mounted volumes in dmenu and unmounts them, destroying the
# /media/<label> directory in the process
dmenu_udisks.py -u -- dmenu <dmenu_options>

I haven't finalised my unmount method yet (hence I use umount above) but I think using pumount would also mean that sudo isn't required. That would mean requiring pmount package, which was another reason not to use it above.

Runiq wrote:

By the way, is there a patch somewhere to make dmenu read default options from an environment variable or from a configuration file? I'm tired of having to change the configuration in multiple places if I decide to mix things up again (which reliably happens every few weeks).

Haven't seen a patch, though there is one in suckless.org that enables config from the xresources - see xrdb.
Also, that's what the $DMENU method helps to get round. Obviously if you want more than one set-up you can have multiple files and point to different ones when setting it up.


"...one cannot be angry when one looks at a penguin."  - John Ruskin
"Life in general is a bit shit, and so too is the internet. And that's all there is." - scepticisle

Offline

#75 2012-06-19 18:59:21

null
Member
Registered: 2009-05-06
Posts: 398

Re: Dmenu Hacking Thread

Here is my little addition to this thread:

The first ruby script takes XML address books like the ones claws mail uses. They have to look like something like this to work:

<address-book name="leute" >
  <person uid="249410652" first-name="" last-name="" nick-name="" cn="null" >
    <address-list>
      <address uid="249410653" alias="" email="myemail@arch.linux" remarks="" />
    </address-list>
  </person>
</address-book>

Important are the cn and email attribute.

Here's the ruby script:

#!/usr/bin/env ruby
#Encoding: UTF-8

require 'rexml/document'

###### List addressbooks here ######
path = ['/path/to/addrbook-000003.xml',
		'/path/to/addrbook-000006.xml']

###### create address list ######
path.each do |book|
	file = File.open(book, 'r+')
	xml = REXML::Document.new file

	# save all addresses here so that they can be sorted
	@addresses = []
	
	xml.root.elements.each do |elem|
		@addtmp = []

		elem.attributes.each do |attr, val|
			if attr == 'cn'
				val = val.downcase
				@addtmp.push(val)
			end
		end
		
		elem.elements['address-list[1]/address[1]'].attributes.each do |attr, val|
			if attr == 'email'
				@addtmp.push(val)
			end
		end

		@addresses.push(@addtmp)
	end

	# sort and print the stuff!
	@addresses.sort.each do |adds|
		puts adds[0].to_s + ' <' + adds[1].to_s + '>'
	end
end

The ruby script was part of a openbox pipe menu I wrote years ago. Haven't written anything in ruby since, I hope this script works well enough smile

Last edited by null (2016-06-12 12:04:34)

Offline

Board footer

Powered by FluxBB