html/iMPD.pl


   1 #/usr/bin/perl -w
   2 ########################################################################
   3 #
   4 # iMPD - irssi MPD controller
   5 # Copyright (C) 2004 Shawn Fogle (starz@antisocial.com)
   6 #
   7 # This program is free software; you can redistribute it and/or modify
   8 # it under the terms of the GNU General Public License as published by
   9 # the Free Software Foundation; either version 2 of the License, or
  10 # (at your option) any later version.
  11 #
  12 # This program is distributed in the hope that it will be useful,
  13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 # GNU General Public License for more details.
  16 #
  17 # You should have received a copy of the GNU General Public License
  18 # along with this program; if not, write to the Free Software
  19 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  20 #
  21 ########################################################################
  22 #
  23 # iMPD - irssi MPD
  24 #
  25 # Requirements: mpc, mpd (http://musicpd.org) 
  26 #
  27 # Please report b00gs to http://www.musicpd.org/forum/viewtopic.php?t=19
  28 # Get the latest and greatest from pulling the module at musicpd's 
  29 # SVN (module iMPD).
  30 #
  31 # OK, This is the a script for irssi/mpc/mpd for people who want to 
  32 # control mpd from irssi. It's very bloated, and featureful, but this
  33 # is a good thing because it's just a perl script and you really don't 
  34 # ever need to use anything that's in here that doesn't pertain to you.
  35 # If you need it (or want it) it's most likely in here. 
  36 #
  37 # I am up for suggestions, alot of this may not work for you, and
  38 # I will not fix it unless you tell me about it.
  39 #
  40 # I do not believe in backwards compatibility if that means it gets in 
  41 # the way of development, so this is probably needs the latest and 
  42 # greatest due to changes in mpc/mpd.
  43 #
  44 ########################################################################
  45 #                           Changes
  46 ########################################################################
  47 #          
  48 #  0.0.0m->0.0.0n
  49 #
  50 #  - Added Move / Crossfade
  51 #
  52 #  - Fixed problems with finding mpc if it's in your path.
  53 #
  54 #  - Began work on AddNext (Adding next in the queue, unless it's on
  55 #    random or shuffle, don't know if it will ever be added but this
  56 #    release needs to make it out soon to fix path b00g.
  57 #
  58 #  - Finally attached the GPL to make this fully GPLv2 compatible
  59 #
  60 ########################################################################
  61 #           Buglist / Wishlist / Todo (In no particular order)
  62 ########################################################################
  63 #
  64 # - Have to be able to tell if MPD goes down, so it can gracefully 
  65 #   shutdown the statusbar, so it doesn't try and access mpc every
  66 #   5 seconds (gets even worse if mpdbar_refresh is faster than 
  67 #   default). This will more than likely be fixed by the MPD module.
  68 #   Note to self: Script unloading self leads to _bad_problems ;p
  69 #
  70 # - Update issues will go away in 0.11.0 (see musicpd.org) due to 
  71 #   update being non-blocking from there on out (hopefully ;p)
  72 #
  73 ########################################################################
  74 # You don't need to edit below this unless you know what you're doing :)
  75 ########################################################################
  76 
  77 use File::Basename;
  78 use Irssi;
  79 use Irssi::TextUI;
  80 use strict;
  81 use vars qw($VERSION %ENABLED %SAVE_VARS %IRSSI %COUNT %SET);
  82 
  83 $VERSION = '0.0.0n';
  84 %IRSSI = (
  85 	  authors     => 'Santabutthead',
  86 	  contact     => 'starz@antisocial.com',
  87 	  name        => 'iMPD',
  88 	  description => 'This controls Music Player Daemon from the familiar irssi interface',
  89 	  license     => 'GPL v2',
  90 	  url         => 'http://www.musicpd.org'
  91 	  );
  92 
  93 # Create $SET{'mpc_override'}="/outside/path" if mpc's not in your path
  94 
  95 ### DO NOT EDIT THESE! Use /set mpd_host /set mpd_port ### 
  96 
  97 $SET{'port'} = "2100";
  98 $SET{'host'} = "127.0.0.1";
  99 
 100 ### Let's go ahead and set this up, so irssi doesn't have a tantrum ###
 101 
 102 Irssi::signal_add('setup changed' => \&read_settings);
 103 Irssi::settings_add_bool('misc', 'mpdbar_bottom', 0);
 104 Irssi::settings_add_bool('misc', 'mpdbar_top', 0);
 105 Irssi::settings_add_bool('misc', 'mpdbar_window', 0);
 106 Irssi::settings_add_bool('misc', 'current_window', '0');
 107 Irssi::settings_add_int('misc', 'output_window', '1');
 108 Irssi::settings_add_int('misc', 'mpd_port', '2100');
 109 Irssi::settings_add_str('misc', 'mpd_host', '127.0.0.1');
 110 Irssi::signal_add_first('command script unload', \&cleanup);
 111 Irssi::signal_add_first('command script load', \&cleanup);
 112 Irssi::signal_add('setup changed' => \&mpdbar_refresh);
 113 # Keep the $2- to treat spaces right
 114 Irssi::statusbar_item_register('mpdbar', '{sb $0 $1 $2-}', 'mpdbar_setup');
 115 Irssi::statusbars_recreate_items();
 116 
 117 #######################################################################
 118 
 119 print "For usage information on iMPD type /mhelp";
 120 
 121 sub add { 
 122     if ($_[0]) {
 123 	&read_settings;
 124 	my $j;
 125 	&current_window;
 126 	if ($_[0] =~ /^album\s/ or $_[0]=~ /^filename\s/ or $_[0]=~ /^title\s/ or $_[0]=~ /^artist\s/ ) {
 127 	    my @i = split / /, $_[0];
 128 	    $j = $i[0];
 129 	    $_[0] =~ s/^(\w+)\s//;
 130 	} else { 
 131 	    $j = "filename";
 132 	}
 133 	Irssi::command( "$SET{'intrairssi'} search $j \Q$_[0]\E | $SET{'intrashell'} add" );    
 134 	&set_active;
 135     } else {
 136 	print "%W/madd (album|artist|filename|title) {search term} {search term}..%w";
 137 	print " - Search for {search term} and automagically add it to the end of the queue";
 138 	print " - This command does not support play number. (it doesn't make sense)";
 139 	print " - If not specified it will use filename by default";
 140     }
 141 }
 142 
 143 sub addall {
 144     &read_settings;
 145     &current_window;
 146     Irssi::command( "$SET{'intrairssi'} add \"\"" );
 147     &set_active;
 148 }
 149 
 150 sub addallPlay {
 151     &read_settings;
 152     &current_window;
 153     Irssi::command( "$SET{'intrairssi'} add \"\" && $SET{'intrashell'} play" );
 154     &mpdbar_refresh; # Impatience
 155     &set_active;
 156 }
 157 
 158 sub addallShufflePlay {
 159     &read_settings;
 160     &current_window;
 161     Irssi::command( "$SET{'intrairssi'} add \"\" && $SET{'intrashell'} shuffle && $SET{'intrashell'} play" );
 162     &mpdbar_refresh; # Impatience
 163     &set_active;
 164 }
 165 
 166 sub addNext {  # This does not work yet, but doesn't hurt being here until it does :)
 167     if ($_[0]) {
 168 	&read_settings;
 169 	my $j;
 170 	&current_window;
 171 	&song_count;
 172 	if ($_[0] =~ /^album\s/ or $_[0]=~ /^filename\s/ or $_[0]=~ /^title\s/ or $_[0]=~ /^artist\s/ ) {
 173 	    my @i = split / /, $_[0];
 174 	    $j = $i[0];
 175 	    $_[0] =~ s/^(\w+)\s//;
 176 	} else { 
 177 	    $j = "filename";
 178 	}
 179 	Irssi::command( "$SET{'intrairssi'} search $j \Q$_[0]\E | $SET{'intrashell'} add" );    
 180 	my $new_pos =~ $COUNT{'song'}++;
 181 	my $playcount =~ $COUNT{'playlist'}++;
 182 	Irssi::command( "$SET{'intrairssi'} mpc $playcount $new_pos");
 183 	#random detect stuff here;
 184 	&set_active;
 185     } else {
 186 	print "%W/maddnext (album|artist|filename|title) {search term} {search term}..%w";
 187 	print " - Search for {search term} and automagically add it to the next position in";
 188         print " - the queue. This command does not support play number. (it doesn't make sense)";
 189 	print " - If not specified it will use filename by default";
 190     }
 191 }
 192 
 193 sub addPlay { 
 194     if ($_[0]) {
 195 	&read_settings;
 196 	my $j;
 197 	&current_window;
 198 	if ($_[0]=~ /^album\s/ or $_[0]=~ /^filename\s/ or $_[0]=~ /^title\s/ or $_[0]=~ /^artist\s/ ) {
 199 	    my @i = split / /, $_[0];
 200 	    $j = $i[0];
 201 	    $_[0] =~ s/^(\w+)\s//;
 202 	} else { 
 203 	    $j = "filename";
 204 	}
 205 	Irssi::command( "$SET{'intrairssi'} search $j \Q$_[0]\E | $SET{'intrashell'} add && $SET{'intrashell'} play" );
 206 	&mpdbar_refresh; # Impatience
 207 	&set_active;
 208     } else {
 209 	print "%W/map (add play) (album|artist|filename|title) {search term} {search term}..%w";
 210 	print " - Search for {search term} and automagically add it to the end of the queue";
 211 	print " - This command does not support play number. (it doesn't make sense)";
 212 	print " - If not specified it will use filename by default";
 213     }
 214 }
 215 
 216 sub addShuffle { 
 217     if ($_[0]) {
 218 	&read_settings;
 219 	my $j;
 220 	&current_window;
 221 	if ($_[0] =~ /^album\s/ or $_[0]=~ /^filename\s/ or $_[0]=~ /^title\s/ or $_[0]=~ /^artist\s/ ) {
 222 	    my @i = split / /, $_[0];
 223 	    $j = $i[0];
 224 	    $_[0] =~ s/^(\w+)\s//;
 225 	} else { 
 226 	    $j = "filename";
 227 	}
 228 	Irssi::command( "$SET{'intrairssi'} search $j \Q$_[0]\E | $SET{'intrashell'} add && $SET{'intrashell'} shuffle" );
 229 	&set_active;
 230     } else {
 231 	print "%W/mas (add shuffle) (album|artist|filename|title) {search term} {search term}..%w";
 232 	print " - Search for {search term} and automagically add it to the end of the queue";
 233 	print " - This command does not support play number. (it doesn't make sense)";
 234 	print " - If not specified it will use filename by default";
 235     }
 236 }
 237 
 238 sub addShufflePlay { 
 239     if ($_[0]) {
 240 	&read_settings;
 241 	my $j;
 242 	&current_window;
 243 	if ($_[0] =~ /^album\s/ or $_[0]=~ /^filename\s/ or $_[0]=~ /^title\s/ or $_[0]=~ /^artist\s/ ) {
 244 	    my @i = split / /, $_[0];
 245 	    $j = $i[0];
 246 	    $_[0] =~ s/^(\w+)\s//;
 247 	} else { 
 248 	    $j = "filename";
 249 	}
 250 	Irssi::command( "$SET{'intrairssi'} search $j \Q$_[0]\E | $SET{'intrashell'} add && $SET{'intrashell'} shuffle && $SET{'intrashell'} play" );
 251 	&mpdbar_refresh; # Impatience
 252 	&set_active;
 253     } else {
 254 	print "%W/masp (add shuffle play) (album|artist|filename|title) {search term} {search term}..%w";
 255 	print " - Search for {search term} and automagically add it to the end of the queue";
 256 	print " - This command does not support play number. (it doesn't make sense)";
 257 	print " - If not specified it will use filename by default";
 258     }
 259 }
 260 
 261 
 262 sub cleanup {
 263     my ($file) = Irssi::get_irssi_dir."/iMPD.conf";
 264 
 265     open CONF, "> $file";
 266     for my $net (sort keys %SAVE_VARS) {
 267 	print CONF "$net\t$SAVE_VARS{$net}\n";
 268 	close CONF;
 269     }
 270     Irssi::command( "statusbar mpdbar disable" );
 271   }
 272  
 273 sub clear {
 274     &read_settings;
 275     &current_window;    
 276     Irssi::command( "$SET{'intrairssi'} clear" );
 277     &mpdbar_refresh; # Impatience
 278     &set_active;
 279 }
 280 
 281 sub clearAddAllPlay {
 282     &read_settings;
 283     &current_window;
 284     Irssi::command( "$SET{'intrairssi'} clear && $SET{'intrashell'} add \"\" && $SET{'intrashell'} play" );
 285     &mpdbar_refresh; # Impatience
 286     &set_active;
 287 }
 288 
 289 sub clearAddAllShufflePlay {
 290     &read_settings;
 291     &current_window;
 292     Irssi::command( "$SET{'intrairssi'} clear && $SET{'intrashell'} add \"\" && $SET{'intrashell'} shuffle && $SET{'intrashell'} play" );
 293     &mpdbar_refresh; # Impatience
 294     &set_active;
 295 }
 296 
 297 sub clearAddPlay { 
 298     if ($_[0]) {
 299 	&read_settings;
 300 	my $j;
 301 	&current_window;
 302 	if ($_[0] =~ /^album\s/ or $_[0]=~ /^filename\s/ or $_[0]=~ /^title\s/ or $_[0]=~ /^artist\s/ ) {
 303 	    my @i = split / /, $_[0];
 304 	    $j = $i[0];
 305 	    $_[0] =~ s/^(\w+)\s//;
 306 	} else { 
 307 	    $j = "filename";
 308 	}
 309 	Irssi::command( "$SET{'intrairssi'} clear && $SET{'intrashell'} search $j \Q$_[0]\E | $SET{'intrashell'} add && $SET{'intrashell'} play" );
 310 	&mpdbar_refresh; # Impatience
 311 	&set_active;
 312     } else {
 313 	print "%W/mcap (clear add play) (album|artist|filename|title) {search term} {search term}..%w";
 314 	print " - Search for {search term} and automagically add it to the end of the queue";
 315 	print " - This command does not support play number. (it doesn't make sense)";
 316 	print " - If not specified it will use filename by default";
 317     }
 318 }
 319 
 320 sub clearAddShufflePlay { 
 321     if ($_[0]) {
 322 	&read_settings;
 323 	my $j;
 324 	&current_window;
 325 	if ($_[0] =~ /^album\s/ or $_[0]=~ /^filename\s/ or $_[0]=~ /^title\s/ or $_[0]=~ /^artist\s/ ) {
 326 	    my @i = split / /, $_[0];
 327 	    $j = $i[0];
 328 	    $_[0] =~ s/^(\w+)\s//;
 329 	} else { 
 330 	    $j = "filename";
 331 	}
 332 	Irssi::command( "$SET{'intrairssi'} clear && $SET{'intrashell'} search $j \Q$_[0]\E | $SET{'intrashell'} add && $SET{'intrashell'} shuffle && $SET{'intrashell'} play" );
 333 	&mpdbar_refresh; # Impatience
 334 	&set_active;
 335     } else {
 336 	print "%W/mcasp (clear add shuffle play) (album|artist|filename|title) {search term} {search term}..%w";
 337 	print " - Search for {search term} and automagically add it to the end of the queue";
 338 	print " - This command does not support play number. (it doesn't make sense)";
 339 	print " - If not specified it will use filename by default";
 340     }
 341 }
 342 
 343 sub clearback {
 344     &read_settings;
 345     &song_count;
 346     &current_window;
 347     Irssi::command( "$SET{'intrairssi'} del $COUNT{'sr1'}" );
 348     &set_active;
 349 }
 350 
 351 sub crossfade {
 352     &read_settings;
 353     if ($_[0] =~ m/\d{1-4}/) {
 354 	&current_window;
 355 	Irssi::command( "$SET{'intrairssi'} crossfade $_[0]" );
 356 	&mpdbar_refresh; # Impatience
 357 	&set_active;
 358     } else {
 359 	print "%W/mcrossfade <num> %w- Number of seconds to crossfade between songs";
 360     }
 361 }
 362 
 363 sub current_status{
 364     &read_settings;
 365     &current_window;
 366     my $i = `$SET{'intrashell'}`;
 367     chomp($i);
 368     $SET{'active'}->print( $i );
 369     &set_active;
 370     return;
 371 }
 372 
 373 sub current_window {
 374     $SET{'active'} = Irssi::active_win();
 375     if (! $SET{'current'}) {
 376 	Irssi::window_find_refnum($SET{'output'})->set_active;
 377       }
 378 }
 379 
 380 sub delete {
 381     if($_[0]) {
 382 	my (@i,$j,$k);
 383 	@i = split / /, $_[0]; 
 384 	$j = shift(@i);
 385 
 386 	&read_settings;
 387 	&current_window;
 388 	# You may ask why? This is for the future when del (hopefully) has useful output
 389 	$k = "$SET{'intrairssi'} playlist | grep \"$j\" | $SET{'intrashell'} del";
 390 	$_[0] =~ s/^(\w+)\s//; 
 391 	$k = "$k && $SET{'intrashell'} playlist | grep \"$_[0]\" | $SET{'intrashell'} del";
 392 	Irssi::command( "$k" );
 393 	&set_active;
 394     } else {
 395 	print"%W/mdel {search term} {search term}..%w";
 396         print" - Search for {search term} and automagically";
 397 	print" - delete it from the queue";
 398     }
 399 }
 400 
 401 sub iMPD_help {
 402 my $mpd_help = <<MPD_HELP;
 403     %r---=[ %WMusic Control Commands %r]=---%w
 404     %W/mmute                      %w- Mutes/Unmutes the volume
 405     %W/mnext                      %w- Starts playing next song on playlist
 406     %W/mpause                     %w- Pauses playing
 407     %W/mplay <number>             %w- Starts MPD (with optional number of song 
 408                                               to start on)
 409     %W/mprev                      %w- Previous Song
 410     %W/mstop <minutes> <m|h|d>    %w- Stops the current playlist, 
 411                                   options are minutes, hours and days, seconds 
 412                                   are the default
 413     %W/mupdate                    %w- Update MPD Database
 414     %W/mvolume <value> (0-100)    %w- Sets the volume on the OSS mixer
 415                                   to <value> (0-100)
 416 
 417     %r---=[ %WSearch Commands %r]=---%w
 418     %W/madd (album|artist|filename|title) {search term} {search term} ..%w
 419                                 %w- Search for {search term} and automagically 
 420                                     add it to the end of the queue, upto 5 search terms
 421                                 - If not specified it will use filename by default
 422     %W/mdel {search term} {search term} ..%w
 423                                 %w- Search for {search term} and automagically 
 424                                     delete it from the queue
 425     %W/msearch (album|artist|filename|title) {search term} {search term}..%w
 426                                 %w- Search for {search term}
 427                                 - If not specified it will use filename by default
 428 
 429     %r---=[ %WNavigation/Playlist Commands %r]=---%w
 430     %W/maddall                    %w- Add all known music to the playlist
 431     %W/mclear                     %w- Clear the current playlist
 432     %W/mclearback                 %w- Clears all songs before the current playing song
 433     %W/mcrossfade <num>           %w- Number of seconds to crossfade between songs
 434     %W/mls [<directory>]          %w- Lists all files/folders in <directory>
 435     %W/mmove <num> <num>          %w- Move song on playlist
 436     %W/mplaylist <range>          %w- Print entire playlist if there's no range
 437                                 - Otherwise will print the range (i.e. 1-10)
 438     %W/mplaylistls                %w- List available playlists
 439     %W/mplaylistload <file>       %w- Load playlist <file>
 440     %W/mplaylistrm <file>         %w- Remove (delete) playlist <file>
 441     %W/mplaylistsave <file>       %w- Save playlist <file>
 442     %W/mpls {search term} {search term}...%w
 443                                 %w- Playlist search {search term}
 444     %W/mseek <num>                %w- Seeks to the spot specified for the current file, in terms of percent time (0-100)
 445     %W/mshuffle                   %w- Shuffle the MPD playlist
 446     %W/mrandom                    %w- Play the playlist randomly 
 447     %W/mwipe                      %w- Remove all songs but the one currently playing
 448 
 449     %r---=[ %WMiscellaneous Commands %r]=---%w
 450     %W/mhelp                      %w- This screen
 451     %W/mloud                      %w- Show everyone in the current window the MPD stats
 452     %W/mlouder                    %w- Show everyone in the current window the MPD stats
 453                                       *use with caution*
 454     %W/minfo                      %w- Show MPD Status in the status window
 455     %W/mrm <num> <num>..          %w- Remove song from the current playlist (by number 
 456                                 %w- or number range)
 457  See Also: /mhelpadv
 458            /mhelpmpdbar
 459            /set mpd_host mpd_port
 460            /set mpd_current_window mpd_output_window (EXPERIMENTAL)
 461 MPD_HELP
 462 print $mpd_help;
 463 }
 464 
 465 sub iMPD_helpAdv{
 466 my $mpd_help_advanced = <<MPD_HELP_ADVANCED;
 467     %r---=[ %WCombination Commands %r]=---%w
 468     These do not take play arguments.
 469     %W/map {search term} {search term} ..     %w- Add, Play
 470     %W/maap                                   %w- Addall, Play
 471     %W/maasp                                  %w- Addall, Shuffle, Play
 472     %W/mas {search term} {search term} ..     %w- Add, Shuffle
 473     %W/masp {search term} {search term} ..    %w- Add, Shuffle, Play
 474     %W/mcap {search term} {search term} ..    %w- Clear, Add, Play
 475     %W/mcaap                                  %w- Clear, Addall, Play
 476     %W/mcaasp                                 %w- Clear, Addall, Shuffle, Play
 477     %W/mcasp {search term} {search term} ..   %w- Clear, Add, Shuffle, Play 
 478     %W/mwa {search term} {search term} ..     %w- Wipe, Add, 
 479     %W/mwaa                                   %w- Wipe, Addall
 480     %W/mwaas                                  %w- Wipe, Addall, Shuffle
 481     %W/mwas {search term} {search term} ..    %w- Wipe, Add, Shuffle
 482 
 483  See Also: /set mpd_port mpd_host
 484            /set mpd_current_window mpd_output_window (EXPERIMENTAL)
 485 MPD_HELP_ADVANCED
 486 print $mpd_help_advanced;
 487 }
 488 
 489 sub load_settings {
 490     my ($file) = Irssi::get_irssi_dir."/iMPD.conf";
 491     
 492     open CONF, "< $file";
 493     while (<CONF>) {
 494 	my($net,$val) = split;
 495 	if ($net && $val) {
 496 	    $SAVE_VARS{$net} = $val;
 497 	}
 498 	close CONF;
 499     }
 500 }
 501 
 502 # For those who want to be loud/annoying :)
 503 sub loud {
 504     &read_settings;
 505     my ($i,$j);
 506     my @split = `$SET{'intrashell'}`;
 507 
 508     if (! $split[1]) {
 509 	Irssi::print( "iMPD is not currently playing" );
 510 	  return;
 511       }
 512     
 513     $i = basename $split[0]; 
 514     $i =~ s/[_]/ /g;
 515 # Feel free to put your personal PERL regexps here ;p
 516 # Experiment with these to do some wicked stuff to your loud output.
 517 #    $i =~ s/.mp3//ig;
 518 #    $i =~ s/.flac//ig;
 519 #    $i =~ s/.flc//ig;
 520 #    $i =~ s/.ogg//ig;
 521 #    $i =~ s/^\p{0,2}//;
 522 #    $i =~ s/[.]//g;
 523     $i = substr($i,0,-1);
 524     
 525     Irssi::active_win->command( "/me is listening to $i" );
 526     close Reader;
 527 }
 528 
 529 sub louder {
 530     &read_settings;
 531     my @split=`$SET{'intrashell'}`;
 532     chomp(@split);
 533     Irssi::active_win->command( "/say $split[0]" );
 534     Irssi::active_win->command( "/say $split[1]" );
 535     Irssi::active_win->command( "/say $split[2]" );
 536     close Reader;
 537 }
 538 
 539 sub ls {
 540     if ($_[0]) {
 541 	&read_settings;
 542 	&current_window;
 543 	$_[0] =~ "\Q$_[0]\E";
 544 	$_[0] =~ s/^\\//; # Rid of beginning / it doesn't delimit correctly.
 545 	$_[0] =~ s/\///; # Help out the degenerates.
 546 	Irssi::command( "$SET{'intrairssi'} ls " . "\Q$_[0]\E" );
 547 	&set_active;
 548     } else {
 549 	print "%W/mls [<directory>] %w- Lists all files/folders in <directory>.";
 550     }
 551 }
 552 
 553 sub lsplaylists {
 554     &read_settings;
 555     &current_window;
 556     Irssi::command( "$SET{'intrairssi'} lsplaylists" );
 557     &set_active;
 558 }
 559 
 560 sub move {
 561     &read_settings;
 562     if ($_[0] =~ m/\d{1,2}\s{1,2}/) {
 563 	&current_window;
 564 	Irssi::command( "$SET{'intrairssi'} move $_[0]" );
 565 	&mpdbar_refresh; # Impatience
 566 	&set_active;
 567     } else {
 568 	print "%W/mmove <num> <num>          %w- Move song on playlist";
 569     }
 570 }
 571 
 572 sub mpdbar_help {
 573 my $mpdbarhelp = <<MPDBAR_HELP;
 574  mpdbar was made to be a simple way to get your statusbar up and 
 575  to hide it when it's not playing. If you feel that I'm not being
 576  flexable enough in my choices you're free to setup a statusbar
 577  without these commands or present me with an idea for a new
 578  mpdbar command. But the current ones are:
 579 
 580  /set mpdbar_bottom on -
 581      This command will (obviously) display a mpdbar on the bottom.
 582 
 583  /set mpdbar_refresh <num> -
 584      This command will set the refresh in seconds, it defaults to 
 585      5 seconds, you might be able to set it higher although I don't
 586      recommend setting it higher if your mpd server is across a 
 587      network (of any kind ;p).
 588 
 589  /set mpdbar_top on
 590      This command will (obviously) display a mpdbar on the top.
 591 
 592  /set mpdbar_window on
 593      This command will (not-so-obviously) display a mpdbar next to your
 594      current window statusbar.
 595 MPDBAR_HELP
 596 print $mpdbarhelp;
 597 }
 598 
 599 sub mpdbar_get_stats {
 600 ### Variable map  ###
 601 # $SET{'stat_time'}-Time/Percent(change)
 602 # $SET{'stat_current'}-Status(change)
 603 # $SET{'songbase'}-basename filename
 604     if(Irssi::settings_get_bool('mpdbar_bottom') or 
 605        Irssi::settings_get_bool('mpdbar_top') or
 606        Irssi::settings_get_bool('mpdbar_window')) {
 607 	&read_settings;
 608 		
 609 	($SET{'stat1'},$SET{'stat2'},$SET{'stat3'}) = undef;
 610 	($SET{'stat1'},$SET{'stat2'},$SET{'stat3'}) = `$SET{'intrashell'}`;
 611 	chomp($SET{'stat1'},$SET{'stat2'},$SET{'stat3'});
 612 
 613 	if ($SET{'stat2'} =~ m/(\d{1,5}\:\d{1,2}\s\(\d{1,3}\%\))/) {
 614 	    $SET{'stat_time'} = $1;	
 615 	}
 616 	if ($SET{'stat2'} =~ m/\[(\w+)\]/) {
 617 	    $SET{'stat_current'} = $1;
 618 	}
 619 	if($SET{'stat2'} and $SET{'stat1'} =~ m/\//g) { # Not sure if this will have an effect :/
 620 	    $SET{'songbase'} = basename $SET{'stat1'};
 621 	} else {
 622 	    $SET{'songbase'} = $SET{'stat1'};
 623 	}
 624     }
 625 }
 626     
 627 sub mpdbar_refresh {    
 628     if(Irssi::settings_get_bool('mpdbar_bottom') or 
 629        Irssi::settings_get_bool('mpdbar_top') or
 630        Irssi::settings_get_bool('mpdbar_window')) {
 631 	&mpdbar_get_stats;
 632 	if (Irssi::settings_get_bool('mpdbar_bottom') and Irssi::settings_get_bool('mpdbar_top')) {
 633 	    Irssi::print( "Have not implemented ability to mpdbar top and bottom at the same time" );
 634 	      Irssi::print( "That's fine though, I'll just set it to the bottom for you for now" );
 635 	      Irssi::settings_set_bool('mpdbar_bottom',1);
 636 	      Irssi::settings_set_bool('mpdbar_top',0);
 637 	  }
 638 	if (Irssi::settings_get_bool('mpdbar_window') and $SET{'stat2'}) {
 639 	    $ENABLED{'window'} = "1";
 640 	    Irssi::command( "statusbar window add mpdbar" );
 641 	    Irssi::command( "statusbar window enable mpdbar" );
 642 	} else {
 643 	    if($ENABLED{'window'} == 1) {
 644 		Irssi::command( "statusbar window remove mpdbar" );
 645 		  $ENABLED{'window'} = 0;
 646 	      }
 647 	}
 648 	if (Irssi::settings_get_bool('mpdbar_bottom') and $SET{'stat2'} and ! $ENABLED{'top'}) {
 649 	    $ENABLED{'bottom'} = "1";
 650 	    Irssi::command( "statusbar mpdbar placement bottom" );
 651 	    Irssi::command( "statusbar mpdbar position 2" );
 652 	    Irssi::command( "statusbar mpdbar enable" );
 653 	    Irssi::command( "statusbar mpdbar add mpdbar" );
 654 	    Irssi::command( "statusbar mpdbar visible active" );
 655 	} else {
 656 	    if($ENABLED{'bottom'} == 1){
 657 		Irssi::command( "statusbar mpdbar remove mpdbar" );
 658 		  Irssi::command( "statusbar mpdbar disable" );
 659 		  $ENABLED{'bottom'} = 0;
 660 	      }
 661 	}
 662 	if (Irssi::settings_get_bool('mpdbar_top') and $SET{'stat2'} and ! $ENABLED{'bottom'}) {
 663 	    $ENABLED{'top'} = "1";
 664 	    Irssi::command( "statusbar mpdbar placement top" );
 665 	    Irssi::command( "statusbar mpdbar position 2" );
 666 	    Irssi::command( "statusbar mpdbar enable" );
 667 	    Irssi::command( "statusbar mpdbar add mpdbar" );
 668 	    Irssi::command( "statusbar mpdbar visible active" );
 669 	} else {
 670 	    if($ENABLED{'top'} == 1){
 671 		Irssi::command( "statusbar mpdbar remove mpdbar" );
 672 		  Irssi::command( "statusbar mpdbar disable" );
 673 		  $ENABLED{'top'} = 0;
 674 	      }     
 675 	}
 676     }
 677 }
 678 
 679 sub mpdbar_setup {	
 680     my ($item, $get_size_only) = @_;
 681     if (! $SET{'stat2'}) { # If it's not on
 682 	$item->default_handler($get_size_only, undef, "$SET{'stat2'}", 1);
 683     } else {
 684 	$SET{'stat_current'} =~ s/$SET{'stat_current'}/\u\L$SET{'stat_current'}/;
 685 	$item->default_handler($get_size_only, undef, "$SET{'stat_current'} $SET{'songbase'} $SET{'stat_time'}", 1);
 686     }
 687 }
 688 
 689 sub mute {
 690     &read_settings;
 691     &current_window;
 692 
 693     my @i = `$SET{'intrashell'}`;
 694     my $j;
 695     # This next conditional is for when the music is not playing
 696     if (exists $i[2]) {
 697 	$j = $i[2]; 
 698     } else {
 699 	$j = $i[0];
 700     }
 701     if ($j =~ m/volume\:\s{0,2}(\d{1,3})\%/) {
 702 	$j = $1;
 703     }
 704 
 705     if ($j != 0 and ! $SAVE_VARS{'muted'} == 0) {
 706 	print "Warning: Not currently muted, although it said it was";
 707 	delete $SAVE_VARS{'muted'}
 708     }
 709     if ($j == 0 and ! $SAVE_VARS{'muted'}) {
 710 	print "Error: Volume is currently muted, but I don't know how it got there. Manually set the volume please.";
 711 	delete $SAVE_VARS{'muted'};
 712     }
 713     if (!$SAVE_VARS{'muted'}) {
 714 	$SAVE_VARS{'muted'} = $j;
 715 	`$SET{'intrashell'} volume 0`;
 716 	print "Sound is muted, to unmute just hit /mmute again";
 717     } else {
 718 	`$SET{'intrashell'} volume $SAVE_VARS{'muted'}`;
 719 	print "Reset the volume back to it's originial position ($SAVE_VARS{'muted'}%)";
 720 	delete $SAVE_VARS{'muted'};
 721     }
 722 }
 723 
 724 sub next {
 725     &read_settings;
 726     &current_window;
 727     Irssi::command( "$SET{'intrairssi'} next" );
 728     &set_active;
 729     &mpdbar_refresh; # Impatience
 730 }
 731 
 732 sub pause {
 733     &read_settings;
 734     &current_window;
 735     Irssi::command( "$SET{'intrairssi'} pause" );
 736     &mpdbar_refresh; # Impatience
 737     &set_active;
 738 }
 739 
 740 sub play {
 741     &read_settings;
 742     my $i;
 743     &current_window;
 744     if ($_[0] =~ m/\d{1,6}/) {
 745 	$i = $_[0];
 746     }
 747     Irssi::command( "$SET{'intrairssi'} play $i" );
 748     &mpdbar_refresh; # Impatience
 749     &set_active;
 750 }
 751 
 752 sub playlist {
 753     &read_settings;
 754     my @playlist;
 755     if ($_[0] =~ m/\d{1,6}\-\d{1,6}/) {
 756 	my ($head,$tail);
 757 	my @playlist = `$SET{'intrashell'} playlist`;
 758 	($head, $tail) = split /-/, $_[0]; 
 759 
 760 	# OK, just understand I'm here for you if you're 
 761 	# tired enough to let this happen to you.
 762 	if($head > $tail) {
 763 	    my $i;
 764 	    $i = $head;
 765 	    $head = $tail;
 766 	    $tail = $i;
 767 	}
 768 
 769 	$head =~ $head--;
 770 	$tail = $tail - $head;
 771 	chomp $head;
 772 	chomp $tail;
 773 	
 774 	@playlist = splice(@playlist,$head,$tail);
 775 	my $i = pop(@playlist);
 776 	chomp $i;
 777 	push (@playlist,$i);
 778 	print @playlist;
 779     } else {
 780 	&current_window;
 781 	Irssi::command( "$SET{'intrairssi'} playlist" );
 782 	&set_active;
 783     }
 784 }
 785 
 786 sub playlist_load {
 787     if ($_[0]) {
 788 	&read_settings;
 789 	&current_window;
 790 	Irssi::command( "$SET{'intrairssi'} load \Q$_[0]\E" );
 791 	&set_active;
 792     } else {
 793 	print "%W/mplaylistload <file> %w- Load playlist <file>";
 794     }
 795 }
 796 
 797 sub playlist_remove {
 798     if ($_[0]) {
 799 	&read_settings;
 800 	&current_window;
 801 	Irssi::command( "$SET{'intrairssi'} rm \Q$_[0]\E" );
 802 	&set_active;
 803     }
 804 }
 805 
 806 sub playlist_save {
 807     if ($_[0]) {
 808 	&read_settings;
 809 	&current_window;
 810 	Irssi::command( "$SET{'intrairssi'} save \Q$_[0]\E" );
 811 	&set_active;
 812     } else {
 813 	print "%W/mplaylistsave <file> %w- Save playlist <file>";
 814     }
 815 }
 816 
 817 sub playlistsearch {
 818     if ($_[0]) {
 819 	&read_settings;
 820 	my @i = split / /, $_[0];
 821 	&current_window;
 822 	foreach(@i) {
 823 	    Irssi::command( "$SET{'intrairssi'} playlist | grep $_" );
 824 	  }
 825 	&set_active;
 826     } else {
 827 	print "%W/pls {search term} {search term}..%w";
 828 	print " - Search for {search term} and automagically and show the playlist entry";
 829     }    
 830 }
 831 
 832 sub previous {
 833     &read_settings;
 834     &current_window;
 835     Irssi::command( "$SET{'intrairssi'} prev" );
 836     &mpdbar_refresh; # Impatience
 837     &set_active;
 838 }
 839 
 840 sub random{
 841     &read_settings;
 842     &current_window;
 843     Irssi::command( "$SET{'intrairssi'} random" );
 844     &set_active;
 845 }
 846 
 847 sub read_settings {    
 848     ($SET{'mbar_time'}) && Irssi::timeout_remove($SET{'mbar_time'});
 849     $SET{'mbar_time'}=Irssi::timeout_add(Irssi::settings_get_int('mpdbar_refresh') * 1000, 'mpdbar_refresh', undef);
 850 
 851     $SET{'current'} = Irssi::settings_get_bool('current_window');
 852     $SET{'output'} = Irssi::settings_get_int('output_window');
 853     
 854     if (Irssi::settings_get_int( "mpd_port" )) {
 855 	$SET{'port'} = Irssi::settings_get_int( "mpd_port" );
 856 	$SET{'port'} = "MPD_PORT=$SET{'port'}"
 857 	}
 858     if (Irssi::settings_get_str( "mpd_host" )) {
 859 	$SET{'host'} = Irssi::settings_get_str( "mpd_host" );
 860 	$SET{'host'} = "MPD_HOST=$SET{'host'}"
 861     }
 862     my $MPC_BIN;
 863     if ( ! -x $SET{'mpc_override'} ) {
 864 	my @paths = split/:/,$ENV{'PATH'};
 865 	
 866 	foreach(@paths) {
 867 	    my $path = $_;
 868 	    if( -x "$path" . "/" . "mpc" ) {
 869 		$MPC_BIN = "$path/mpc";
 870 	    }
 871 	}
 872     } else {
 873 	$MPC_BIN = $SET{'mpc_override'};
 874     }
 875 
 876     if (! $MPC_BIN) {
 877 	print "mpc was not found in any of the known paths";
 878 	print "mpc is required to use this script, please download it from http://musicpd.org/files.php";
 879     }   
 880 
 881     $SET{'intrashell'} = "$SET{'port'} $SET{'host'} $MPC_BIN";
 882     $SET{'intrairssi'} = "exec - $SET{'intrashell'}";
 883 }
 884 
 885 sub repeat {
 886     &read_settings;
 887     &current_window;
 888     Irssi::command( "$SET{'intrairssi'} repeat" );
 889     &set_active;
 890 }
 891 
 892 sub remove_song {
 893     &read_settings;
 894     if ($_[0] =~ m/\d{1,6}/ or $_[0] =~ m/\d{1,6}\-\d{1,6}/) {
 895 	&current_window;
 896 	Irssi::command( "$SET{'intrairssi'} del $_[0]" );
 897 	&mpdbar_refresh; # Impatience
 898 	&set_active;
 899     } else {
 900 	print "%W/mrm <num> <num>.. %w- Remove song from the current playlist (by number)";
 901 	print "%w                   - Note that <num> can be a range also";
 902     }
 903 }
 904 
 905 sub search { 
 906     if ($_[0]) {
 907 	&read_settings;
 908 	my $j;
 909 	&current_window;
 910 	if ($_[0] =~ /^album\s/ or $_[0]=~ /^filename\s/ or $_[0]=~ /^title\s/ or $_[0]=~ /^artist\s/ ) {
 911 	    my @i = split / /, $_[0];
 912 	    $j = $i[0];
 913 	    $_[0] =~ s/^(\w+)\s//;
 914 	} else { 
 915 	    $j = "filename";
 916 	}
 917 	Irssi::command( "$SET{'intrairssi'} search $j \Q$_[0]\E" );
 918 	&set_active;
 919     } else {
 920 	print "%W/search (album|artist|filename|title) {search term} {search term}..%w";
 921 	print " - Search for {search term} and automagically add it to the end of the queue";
 922         print " - If not specified it will use filename by default";
 923     }
 924 }
 925 
 926 sub seek {
 927     &read_settings;
 928     if ($_[0] =~ m/\d{1-3}/) {
 929 	&current_window;
 930 	Irssi::command( "$SET{'intrairssi'} seek $_[0]" );
 931 	&mpdbar_refresh; # Impatience
 932 	&set_active;
 933     } else {
 934 	print "%W/mseek <num> %w- Seeks to the spot specified for the current file, in terms of percent time (0-100)";
 935     }
 936 }
 937 
 938 sub set_active { 
 939     if (! $SET{'current'}) { 
 940 	$SET{'active'}->set_active; 
 941     }
 942 }    
 943 
 944 sub shuffle{
 945     &read_settings;
 946     &current_window;
 947     Irssi::command( "$SET{'intrairssi'} shuffle" );
 948     &set_active;
 949 }
 950 
 951 sub song_count {
 952     %COUNT = undef;
 953     
 954     my @counts = `$SET{'intrashell'}`;
 955     chomp(@counts);
 956 
 957     if ($counts[1] =~ m/\#(\d{1,6})\//) {
 958 	$COUNT{'song'} = $1;
 959     }
 960     if ($counts[1] =~ m/\/(\d{1,6})\s/) { 
 961 	$COUNT{'playlist'} = $1;
 962     } 
 963     if ($COUNT{'song'} > 1) {
 964 	my $i = $COUNT{'song'} - 1;
 965 	$COUNT{'sr1'} = "1-$i";
 966     }
 967     if ($COUNT{'song'} < $COUNT{'playlist'}){# and $COUNT{'song'} != $COUNT{'playlist'}) {
 968 	my $i = $COUNT{'song'} + 1;
 969 	$COUNT{'sr2'} = "$i-$COUNT{'playlist'}";
 970     }
 971 }
 972 
 973 sub stop {
 974     &read_settings;
 975     my ($i,$time);
 976     if ($_[0]) {
 977 	my $unit;
 978 	($time, $unit) = split / /, $_[0]; 
 979 	if ($unit =~ /minute/i or $unit =~ /minutes/i) {
 980 	    $time = ($time * 60);
 981 	}
 982 	if ($unit =~ /hour/i or $unit =~ /hours/i) {
 983 	    $time = ($time * 86400);
 984 	}
 985 	#ok. it's ridiculous to use this script for days, but in any case here ya go.
 986 	if ($unit =~ /day/i or $unit =~ /days/i) {
 987 	    $time = ($time * 2073600);
 988 	}
 989 	$time = $time . "s";
 990 	$i = "exec - /bin/sleep $time && $SET{'intrashell'} stop";
 991     } else {
 992 	$i = "$SET{'intrairssi'} stop";
 993     }
 994     &current_window;
 995     Irssi::command( "$i" );
 996     &mpdbar_refresh; # Impatience
 997     &set_active;
 998 }
 999 
1000 sub update {
1001     &read_settings;
1002     &current_window;
1003     Irssi::command( "$SET{'intrairssi'} update" );
1004     Irssi::print( "Irssi will not be accepting commands while updating" );
1005     &set_active;
1006 }
1007 
1008 sub volume {
1009     &read_settings;
1010     &current_window;
1011     my (@i,$j);
1012     if ($_[0] =~ m/\d{1,3}/) {
1013 	@i = `$SET{'intrashell'} volume $_[0]`;
1014     } else {
1015 	@i = `$SET{'intrashell'}`;
1016     }
1017     # This next conditional is for when the music is not playing
1018     if (exists $i[2]) {
1019 	$j = $i[2]; 
1020     } else {
1021 	$j = $i[0];
1022     }
1023     if ($j =~ m/volume\:\s{0,2}(\d{1,3})\%/) {
1024 	$j = $1;
1025     }
1026     # OK, if anyone wants to tell me _why_ this seems to be the only way
1027     # to get a "%" on the end please feel free (suspected to be due to
1028     # color codes
1029     if ($_[0]) {
1030 	Irssi::print( "The volume is at $j%" . "%" );
1031     } else {
1032 	$SET{'active'}->print( "The volume is at $j%" . "%" );  
1033       }
1034     &set_active;
1035 }
1036 
1037 sub wipe {
1038     &read_settings;
1039     &current_window;
1040     &song_count;
1041     if($COUNT{'sr1'} or $COUNT{'sr2'}) {
1042 	Irssi::command( "$SET{'intrairssi'} del $COUNT{'sr1'} $COUNT{'sr2'}" );
1043       } else {
1044 	  Irssi::print( "Can't wipe when there's only one song in the playlist" );
1045 	}
1046     &set_active;
1047 }
1048 
1049 sub wipeAdd{
1050     if ($_[0]) {
1051 	&read_settings;
1052 	&song_count;
1053 	my $j;
1054 	if ($_[0] =~ /^album\s/ or $_[0]=~ /^filename\s/ or $_[0]=~ /^title\s/ or $_[0]=~ /^artist\s/ ) {
1055 	    my @i = split / /, $_[0];
1056 	    $j = $i[0];
1057 	    $_[0] =~ s/^(\w+)\s//;
1058 	} else { 
1059 	    $j = "filename";
1060 	}
1061 	&current_window;
1062 	if($COUNT{'sr1'} or $COUNT{'sr2'}) {
1063 	    Irssi::command( "$SET{'intrairssi'} del $COUNT{'sr1'} $COUNT{'sr2'} && $SET{'intrashell'} search $j \Q$_[0]\E | $SET{'intrashell'} add" );
1064 	  } else { # Do the thinking for the person
1065 	      Irssi::command( "$SET{'intrairssi'} search $j \Q$_[0]\E | $SET{'intrashell'} add" );    
1066 	    }
1067 	&set_active;
1068     } else {
1069 	print "%W/mwa (wipe add) (album|artist|filename|title) {search term} {search term}..%w";
1070 	print " - Search for {search term} and automagically add it to the end of the queue";
1071 	print " - This command does not support play number. (it doesn't make sense)";
1072 	print " - If not specified it will use filename by default"
1073 	}
1074 }
1075 
1076 sub wipeAddall{
1077     &read_settings;
1078     &song_count;
1079     &current_window;
1080     if($COUNT{'sr1'} or $COUNT{'sr2'}) {
1081 	Irssi::command( "$SET{'intrairssi'} del $COUNT{'sr1'} $COUNT{'sr2'} && $SET{'intrashell'} add \"\"" );
1082       } else {
1083 	  Irssi::command( "$SET{'intrairssi'} add \"\"" );
1084 	}	  
1085     &set_active;
1086 }
1087 
1088 sub wipeAddallShuffle{
1089     &read_settings;
1090     &song_count;
1091     &current_window;
1092     if($COUNT{'sr1'} or $COUNT{'sr2'}) {
1093 	Irssi::command( "$SET{'intrairssi'} del $COUNT{'sr1'} $COUNT{'sr2'} && $SET{'intrashell'} add \"\" && $SET{'intrashell'} shuffle" );
1094       } else {
1095 	Irssi::command( "$SET{'intrairssi'} add \"\" && $SET{'intrashell'} shuffle" );
1096       }
1097     &set_active;
1098 }
1099 
1100 sub wipeAddShuffle{
1101     if ($_[0]) {
1102 	&read_settings;
1103 	my $j;
1104 	if ($_[0] =~ /^album\s/ or $_[0]=~ /^filename\s/ or $_[0]=~ /^title\s/ or $_[0]=~ /^artist\s/ ) {
1105 	    my @i = split / /, $_[0];
1106 	    $j = $i[0];
1107 	    $_[0] =~ s/^(\w+)\s//;
1108 	} else { 
1109 	    $j = "filename";
1110 	}
1111 	&song_count;
1112 	&current_window;
1113 	if($COUNT{'sr1'} or $COUNT{'sr2'}) {
1114 	    Irssi::command( "$SET{'intrairssi'} del $COUNT{'sr1'} $COUNT{'sr2'} && $SET{'intrashell'} search $j \Q$_[0]\E | $SET{'intrashell'} add && $SET{'intrashell'} shuffle" );
1115 	  } else {
1116 	      Irssi::command( "$SET{'intrairssi'} search $j \Q$_[0]\E | $SET{'intrashell'} add && $SET{'intrashell'} shuffle" );
1117 	    }
1118 	&set_active;
1119     } else {
1120 	print "%W/mwas (wipe add shuffle) (album|artist|filename|title) {search term} {search term}..%w";
1121 	print " - Search for {search term} and automagically add it to the end of the queue";
1122 	print " - This command does not support play number. (it doesn't make sense)";
1123 	print " - If not specified it will use filename by default";
1124 	}
1125 }
1126 Irssi::settings_add_int('misc', 'mpdbar_refresh', '5');
1127 
1128 &load_settings;
1129 &mpdbar_refresh;
1130 
1131 Irssi::command_bind madd => \&add;
1132 Irssi::command_bind maddall => \&addall;
1133 # Irssi::command_bind maddnext => \&addNext;
1134 Irssi::command_bind maap => \&addallPlay;
1135 Irssi::command_bind maasp => \&addallShufflePlay;
1136 Irssi::command_bind mas => \&addShuffle;
1137 Irssi::command_bind masp => \&addShufflePlay;
1138 Irssi::command_bind map => \&addPlay;
1139 Irssi::command_bind mclear => \&clear;
1140 Irssi::command_bind mclearback => \&clearback;
1141 Irssi::command_bind mcaap => \&clearAddAllPlay;
1142 Irssi::command_bind mcaasp => \&clearAddAllShufflePlay;
1143 Irssi::command_bind mcap => \&clearAddPlay;
1144 Irssi::command_bind mcasp => \&clearAddShufflePlay;
1145 Irssi::command_bind mdel => \&delete;
1146 Irssi::command_bind mls => \&ls;
1147 Irssi::command_bind mhelp => \&iMPD_help;
1148 Irssi::command_bind mhelpadv => \&iMPD_helpAdv;
1149 Irssi::command_bind minfo => \&current_status;
1150 Irssi::command_bind mloud => \&loud;
1151 Irssi::command_bind mlouder => \&louder;
1152 Irssi::command_bind mmute => \&mute;
1153 Irssi::command_bind mnext => \&next;
1154 Irssi::command_bind mpause => \&pause;
1155 Irssi::command_bind mhelpmpdbar => \&mpdbar_help;
1156 Irssi::command_bind mmove => \&move;
1157 Irssi::command_bind mplay => \&play;
1158 Irssi::command_bind mplaylist => \&playlist;
1159 Irssi::command_bind mpls => \&playlistsearch;
1160 Irssi::command_bind mplaylistls => \&lsplaylists;
1161 Irssi::command_bind mplaylistload => \&playlist_load;
1162 Irssi::command_bind mplaylistrm => \&playlist_remove;
1163 Irssi::command_bind mplaylistsave => \&playlist_save;
1164 Irssi::command_bind mprev => \&previous;
1165 Irssi::command_bind mrandom => \&random;
1166 Irssi::command_bind mrepeat => \&repeat;
1167 Irssi::command_bind mrm => \&remove_song;
1168 Irssi::command_bind mseek => \&seek;
1169 Irssi::command_bind msearch => \&search;
1170 Irssi::command_bind mshuffle => \&shuffle;
1171 Irssi::command_bind mstop => \&stop;
1172 Irssi::command_bind mupdate => \&update;
1173 Irssi::command_bind mvolume => \&volume;
1174 Irssi::command_bind mwa => \&wipeAdd;
1175 Irssi::command_bind mwaa => \&wipeAddall;
1176 Irssi::command_bind mwaas => \&wipeAddallShuffle;
1177 Irssi::command_bind mwas => \&wipeAddShuffle;
1178 Irssi::command_bind mwipe => \&wipe;