tab键输入中文目录源代码解读

851阅读 0评论2010-08-16 bailiangcn
分类:Python/Ruby

这段代码是发现的,很有趣

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# shaozx@gmail.com 2009-08-31
#
# 用拼音补全命令行中的中文名称和路径
#
# 实验目录如下:
# biff@lenovo:/domain/WorkSpace$ ls
# SVN培训 全球眼 浙江建行 浙江农信
#
# 使用: (输完后按 TAB 键自动补全)
# cd S <tab> 进入[SVN培训]
# cd q <tab> 进入[全球眼]
# cd z <tab> 自动补全[浙江]
# cd zj <tab><tab> 提示[浙江建行 浙江农信]备选
# cd 浙江j <tab> 进入[浙江建行]
# cd zjj <tab> 进入[浙江建行]
# cd zj1 <tab> 进入[浙江建行]
# cd zj2 <tab> 进入[浙江农信]
#
# 2009-05-08修订 取不到拼音的汉字匹配任何字符
# 2009-05-07新增 名称中有中文全角,可以用英文符号补全
# 2009-05-06修订 解决数字序号定位时借位的问题
# 2009-08-30新增 增加多音字支持,比如“音乐”
# ((遇到有未被收入的多音字,请邮件联系我))
# 2009-08-31新增 增加模糊拼音支持,比如'n'->'l'
# ((需手工增加环境变量,配置方法见后面说明))
#
# 安装:
# 直接执行 sh install.sh 进行安装;
#
# 如需模糊拼音支持,在系统环境变量中增加匹配的列表,对 n/l 进行模糊匹配
# export CHSDIR="{ 'n':'l' }"
# 多个匹配对之间用逗号隔开:
# export CHSDIR="{ 'n':'l','f':'p' }"
#
#
# 问题:
# 1、多音字未解决,比如[浙江建行]要输入[zjjx]; ((已解决))
# 2、大字符集输入使用变通的方法(取不到拼音的汉字匹配任何字符)
#
# 蔡国权/ 蔡依林/ 陈百强/ 陈楚生/ 陈慧琳/ 陈坤/ 陈淑桦/ 成龙/
# 蔡琴/ 草蜢/ 陈柏宇/ 陈海铃/ 陈慧娴/ 陈倩倩/ 陈小春/
# 如上,因为"蜢""倩"都是"?",[草蜢]无法用[cm]进入,只能用[c4]进入
# 如果输入[cm<tab>],会提示[草蜢][陈倩倩],这时用[cm1]进入
# 如果输入[cq<tab>],会提示[蔡琴][草蜢][陈倩倩],同样用数字选择
#
#
#
#
#

import os,sys
import locale

LIST_POLYPHONE={ u"龟":u"jgq", u"咯":u"gkl", u"轧":u"gyz", u"单":u"dcs",
        u"腌":u"ay", u"阿":u"ae", u"艾":u"ay", u"扒":u"bp", u"膀":u"bp",
        u"磅":u"bp", u"堡":u"bp", u"刨":u"bp", u"暴":u"bp", u"泌":u"bm",
        u"辟":u"bp", u"扁":u"bp", u"便":u"bp", u"便":u"pb", u"骠":u"bp",
        u"泊":u"bp", u"藏":u"cz", u"曾":u"cz", u"禅":u"cs", u"裳":u"cs",
        u"剿":u"cj", u"嘲":u"cz", u"车":u"cj", u"铛":u"cd", u"乘":u"cs",
        u"澄":u"cd", u"匙":u"cs", u"臭":u"cx", u"畜":u"cx", u"幢":u"cz",
        u"椎":u"cz", u"兹":u"cz", u"伺":u"cs", u"枞":u"cz", u"攒":u"cz",
        u"撮":u"cz", u"沓":u"dt", u"沓":u"dt", u"叨":u"dt", u"钿":u"dt",
        u"调":u"dt", u"囤":u"dt", u"否":u"fp", u"脯":u"fp", u"芥":u"gj",
        u"扛":u"gk", u"革":u"gj", u"给":u"gj", u"颈":u"gj", u"枸":u"gj",
        u"谷":u"gy", u"鹄":u"gh", u"纶":u"gl", u"莞":u"gw", u"桧":u"gh",
        u"咳":u"hk", u"吭":u"hk", u"行":u"hx", u"巷":u"hx", u"合":u"hg",
        u"红":u"hg", u"虹":u"hj", u"会":u"hk", u"稽":u"jq", u"矜":u"jq",
        u"稽":u"jq", u"缉":u"jq", u"亟":u"jq", u"茄":u"jq", u"侥":u"jy",
        u"缴":u"jz", u"解":u"jx", u"趄":u"qj", u"咀":u"jz", u"卡":u"kq",
        u"壳":u"kq", u"溃":u"kh", u"括":u"kg", u"蔓":u"mw", u"秘":u"mb",
        u"粘":u"nz", u"拗":u"na", u"弄":u"nl", u"炮":u"pb", u"屏":u"pb",
        u"曝":u"pb", u"瀑":u"pb", u"栖":u"qx", u"蹊":u"qx", u"奇":u"qj",
        u"荨":u"qx", u"纤":u"qx", u"强":u"qj", u"圈":u"qj", u"葚":u"sr",
        u"厦":u"sx", u"省":u"sx", u"识":u"sz", u"属":u"sz", u"忪":u"sz",
        u"宿":u"sx", u"汤":u"st", u"提":u"td", u"圩":u"wx", u"尾":u"wy",
        u"尉":u"wy", u"系":u"xj", u"虾":u"xh", u"吓":u"xh", u"校":u"xj",
        u"吁":u"xy", u"叶":u"yx", u"遗":u"yw", u"乐":u"yl", u"颤":u"zc",
        u"殖":u"zs" }

LIST_CHARS={ u"~":u"~", u"!":u"!", u"@":u"@", u"#":u"#", u"$":u"$",
        u"%":u"%", u"&":u"&", u"*":u"*", u"(":u"(", u")":u")", u"_":u"_",
        u"-":u"-", u"+":u"+", u"[":u"[", u"]":u"]", u"<":u"<", u">":u">",
        u"?":u"?", u",":u",", u"。":u".", u"/":u"/", u"、":u"," }

LIST_TEST={}
try:
    LIST_TEST=eval( os.getenv("CHSDIR") )
    LIST_TEST.keys()
except:
    LIST_TEST={}

def getPYSTR(s):
    try: s=unicode(s,"UTF8")
    except: return s

    ret = ""
    for i in range(len(s)):
        uchr = LIST_CHARS.get(s[i],s[i])
        if uchr == s[i] :
            uchr = LIST_POLYPHONE.get(uchr,uchr)
            if len(uchr) > 1 :
                uchr = u"`%s`"%uchr
            else:
                uchr = getPY(uchr)
                if uchr != s[i]:
                    uchr = LIST_TEST.get(uchr,uchr)
        ret += uchr
    return ret.encode("UTF8")


def getPY(s):
    try: chr=s.encode("GB18030")
    except: return s
    if chr<"\xb0\xa1": return s
    if chr>"\xd7\xf9": return u"?"
    if chr<"\xb0\xc5": return u"a"
    if chr<"\xb2\xc1": return u"b"
    if chr<"\xb4\xee": return u"c"
    if chr<"\xb6\xea": return u"d"
    if chr<"\xb7\xa2": return u"e"
    if chr<"\xb8\xc1": return u"f"
    if chr<"\xb9\xfe": return u"g"
    if chr<"\xbb\xf7": return u"h"
    if chr<"\xbf\xa6": return u"j"
    if chr<"\xc0\xac": return u"k"
    if chr<"\xc2\xe8": return u"l"
    if chr<"\xc4\xc3": return u"m"
    if chr<"\xc5\xb6": return u"n"
    if chr<"\xc5\xbe": return u"o"
    if chr<"\xc6\xda": return u"p"
    if chr<"\xc8\xbb": return u"q"
    if chr<"\xc8\xf6": return u"r"
    if chr<"\xcb\xfa": return u"s"
    if chr<"\xcd\xda": return u"t"
    if chr<"\xce\xf4": return u"w"
    if chr<"\xd1\xb9": return u"x"
    if chr<"\xd4\xd1": return u"y"
    if chr<"\xd7\xfa": return u"z"
    return s


if __name__== '__main__':
    if len(sys.argv) != 3 :
        sys.exit(1)

    dironly = sys.argv[1]

    cur = sys.argv[2].replace("\\","")
    for k in LIST_TEST.keys():
        cur = cur.replace( k, LIST_TEST.get(k) )

    idx=None; _cur=cur
    if len(cur)>1 and cur[-1:] >='0' and cur[-1:]<='9':
        idx = int(cur[-1])
        _cur = cur[:-1]

    _name=os.path.basename(_cur)
    name=os.path.basename(cur)
    dir=os.path.dirname(cur)
    if len(dir)==0 : dir="./"

    if not os.path.exists(dir):
        sys.exit(0)

    try:
        list = os.listdir(dir)
    except:
        sys.exit(0)

    if name in list or _name in list :
        sys.exit(0)

    ret = []

    _name_py= getPYSTR(_name).replace("\\","");
    for l in list:
        _file_py = getPYSTR(l).replace("\\","")
        if l == _file_py : continue

        i=0;j=0;
        while len(_name_py) > i and len(_file_py) > j :
            if _file_py[j] == "`":
                end = _file_py.index("`",j+1)
                if _file_py.find( _name_py[i], j, end ) > 0 :
                    i+=1; j=end+1
                    continue
            else:
                if _name_py[i] == _file_py[j] or _file_py[i] == "?":
                    i+=1; j+=1
                    continue;
            if _name_py[i]!=l[i] : break
        if len(_name_py) == i :
            tmp = (dir+"/"+l).replace(".//","")
            if dironly == "x-d" and not os.path.isdir(tmp): continue
            ret.append( tmp )

    try:
        locale.setlocale(locale.LC_ALL,"")
    except:
        pass

    ret.sort(key=locale.strxfrm)
    if idx and len(ret) > idx-1:
        print ret[idx-1]
    else:
        print "\n".join(ret)


上一篇:sftp应用技巧
下一篇:linux下比较2个文件