根据使用频率输出dmenu的结果

清华大佬耗费三个月吐血整理的几百G的资源,免费分享!....>>>

#!/usr/bin/perl

# sydi_dmenu --- 
# 
# Filename: sydi_dmenu
# Description: This script make dmenu more 'smart' choosing program
#              run by making a counter to each command. Simplely use
#              this script as how u r using dmenu.
# Author: Sylvester Y. Shi
# Maintainer: Sylvester Y. Shi
# Created: 一 11月 28 21:15:47 2011 (+0800)
# Version: 0.1
# Last-Updated: 一 11月 28 21:27:52 2011 (+0800)
#           By: Sylvester Y. Shi
#     Update #: 16
# URL: http://blog.sydi.org/
# Keywords: dmenu, smart, perl
# Compatibility: dmenu 4.4.1+, or less than it, but without test.
# 
# 

# Commentary: 
# varible $data_file is the data file using this script, change it 
# as u like to satified ur need.
# 
# The script is writtern by `sylvester' for fun, u can contact to me
# as follow.
# mail:   cedsyd@gmail.com
# weibo:  sylvester324


# Change Log:
# 28-Nov-2011    Sylvester Y. Shi  
#    Last-Updated: 一 11月 28 21:23:47 2011 (+0800) #2 (Sylvester Y. Shi)
# Create File.    
# 
# 

# 
# *This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; see the file COPYING.  If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street, Fifth
# Floor, Boston, MA 02110-1301, USA.
# 
# 

# Code:

use autodie;

my $data_file = "/home/sylvester/bin/data.dmenu.sydi";
my @bin_dirs = split /:/, $ENV{PATH};
my %all_bins;

sub check_data_file
{
    system("touch $data_file") if not -e $data_file;
}

sub load_data
{
    open my $fh, "lsx @bin_dirs 2>/dev/null |";
    my %now_bins = map { chomp; $_ => 0 } <$fh>;
    close $fh;

    open my $fh_old, "<$data_file";
    my %old_bins = map { chomp; split / /,$_ } <$fh_old>;
    close $fh_old;

    %all_bins = (%now_bins, %old_bins);
}

sub sort_bins
{
    my @bins = keys %all_bins;
    my @sorted_bins = sort { $all_bins{$b} cmp $all_bins{$a} } @bins;
}

sub get_bins_str
{
    my $sorted_bins = shift;
    my $bins_str;
    foreach (@$sorted_bins)
    {
	$bins_str .= "$_\n";
    }
    return $bins_str;
}

sub call_dmenu
{
    my $bins_str = shift;
    my @args = map { "'$_'" } @ARGV;

    open my $fh, "echo '$bins_str' | dmenu @args |";

    my $cmd = <$fh>;
    chomp $cmd;
    $all_bins{$cmd}++ if $cmd ne '' and exists $all_bins{$cmd};
    
    print $cmd;
}

sub keep_in_data_file
{
    open my $fh_old, ">$data_file";
    while (my ($key, $value) = each %all_bins)
    {
	print $fh_old "$key $value\n";
    }
    close $fh_old;
}


check_data_file;
load_data;
my @sorted_bins = sort_bins;
my $bins_str = get_bins_str \@sorted_bins;
call_dmenu $bins_str;
keep_in_data_file;


# 
# sydi_dmenu ends here