⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tabkey.jm

📁 EPIC IRC客户端。来源于IRCII客户端但做了很多性能和功能的优化。
💻 JM
字号:
# tabkey.jm: a full-featured tab key script for epic4## written by nsx## this script features:##  * target history cycling for /msg and /notice#  * match possibility cycling (zsh-style completion)#  * reverse cycling (ctrl + r)#  * shell-like completion for /exec#  * script name completion for /load#  * the ability to complete words anywhere in the input line#  * proper handling of file names that contain spaces#  * multi-server support#  * completion of aliases, command names, channel names, nicknames,#    /set variables, /help topics and file names###  /set variables this script uses:##    NICK_COMPLETION_CHAR -- the value of this set will be appended each time#                            nickname completion occurs as the first word of the#                            input line.  a typical value might be ':'.##   TAB_HISTORY_CYCLE_SIZE -- how many nicknames to keep in the /msg history##   ZSH_STYLE_COMPLETION -- turning this on allows you to cycle through completion#                           possibilities, when there is more than one completion#                           possibility, similar to how zsh behaves for tab#                           completion### note: this script uses the serial number 110 for its serial hooks## *** config variables ***@nick_completion_char = []@tab_history_cycle_size = 10@zsh_style_completion = [off]# *** global variables ***@last_input_line = []@match_index = -1@match_cycle_list = []@target_index = 0@target_cycle_list = []bind ^I parse_command do_tabkey 1bind ^R parse_command do_tabkey -1xdebug +extractwalias add_target (msg_cmd, target) {	if (numwords($myservers()) > 1 && count(: $target) == 0 && left(1 $target) != [=]) {		@:target = [${servernum()}:${target}]	}	@target_cycle_list = remw("$msg_cmd $target" $target_cycle_list)	if (#target_cycle_list > ((tab_history_cycle_size * 2) -1)) {		@target_cycle_list = restw(2 $target_cycle_list)	}	@target_index = 0	@push(target_cycle_list $msg_cmd)	@push(target_cycle_list $target)}alias current_fragment_start {	@:i = 0	@:j = curpos() - 1	@:last_space = 0	@:last_quote = 0	@:quotes = 0	while (i < j) {		@:char = mid($i 1 $L)		if (char == [ ]) {			@:last_space = i		} elsif (char == ["]) {			@:last_quote = i			@:quotes++		}		@:i++	}	if (quotes % 2) {		if (mid($curpos() 1 $L) == ["] || last_quote > last_space) {			return ${last_quote + 1}		} elsif (mid(${curpos() - 1} 1 $L) == ["]) {			parsekey backward_character			return ${last_quote + 1}		} else {			return ${last_space + 1}		}	} else {		if (mid(${curpos() - 1} 1 $L) == [ ]) {			return $curpos()		} elsif (last_space) {			return ${last_space + 1}		} else {			return 0		}	}}alias do_match_cycle (direction) {	@:frag_start = current_fragment_start()	if (frag_start == -1) {		return	}	@:fraglen = curpos() - frag_start	if (mid($curpos() 1 $L) == ["]) {		parsekey forward_character		repeat ${fraglen + 1} parsekey backspace	} elsif (mid(${curpos() - 1} 1 $L) == ["]) {		repeat ${fraglen + 1} parsekey backspace	} else {		repeat $fraglen parsekey backspace	}	if (mid(${curpos() - 1} 1 $L) == ["]) {		parsekey backspace	}	@match_index += direction	if (match_index == #match_cycle_list) {		@match_index = 0	} elsif (match_index < 0) {		@match_index = #match_cycle_list - 1	}	@:new_match = word($match_index $match_cycle_list)	if (index("$chr(32)" $new_match) == -1) {		xtype -l $new_match	} else {		xtype -l "$new_match"		parsekey backward_character	}	@last_input_line = L}alias do_msg_cycle (direction) {	if (#target_cycle_list < 2) {		return	}	@target_index -= (direction * 2)	if (target_index == #target_cycle_list) {		@target_index = 0	} elsif (target_index < 0) {		@target_index = #target_cycle_list - 2	}	@:msg_cmd = word($target_index $target_cycle_list)	@:msg_targ = word(${target_index + 1} $target_cycle_list)	parsekey erase_line	xtype -l /${msg_cmd} ${msg_targ}${chr(32)}	@last_input_line = []}alias do_set (variable, value) {	if (value == []) {		^eval @:setval = $variable		if (setval == []) {			xecho -b No value for $variable has been set		} else {			xecho -b Current value of $variable is $setval		}		return	}	switch ($variable) {		(NICK_COMPLETION_CHAR) {			if (value == [<unset>]) {				@nick_completion_char = []				xecho -b Value of NICK_COMPLETION_CHAR set to <EMPTY>			} else {				@nick_completion_char = value				xecho -b Value of NICK_COMPLETION_CHAR set to $value			}		}		(TAB_HISTORY_CYCLE_SIZE) {			if (!isnumber($value)) {				xecho -b Value of TAB_HISTORY_CYCLE_SIZE must be numeric!			} elsif (value < 1) {				xecho -b Value of TAB_HISTORY_CYCLE_SIZE cannot be less than 1			} else {				@tab_history_cycle_size = value				@target_cycle_list = rightw(${value * 2} $target_cycle_list)				xecho -b Value of TAB_HISTORY_CYCLE_SIZE set to $value			}		}		(ZSH_STYLE_COMPLETION) {			if (value == [on]) {				@zsh_style_completion = [ON]				xecho -b Value of ZSH_STYLE_COMPLETION set to ON                        } elsif (value == [off]) {				@zsh_style_completion = [OFF]				xecho -b Value of ZSH_STYLE_COMPLETION set to OFF			} else {				xecho -b Value of ZSH_STYLE_COMPLETION must be ON or OFF!			}		}		(*) {			xecho -b I don't know how to handle "$variable"		}	}}alias do_tabkey (cycle_direction) {	@:input_line = left($curpos() $L)	if (L == []) {		@target_index = #target_cycle_list		@do_msg_cycle($cycle_direction)		return	} elsif (encode($L) == encode($last_input_line)) {		if (zsh_style_completion == [ON] && #match_cycle_list > 1) {			@do_match_cycle($cycle_direction)			return		} else {			return		}	} elsif (leftw(1 $L) == [/msg] || leftw(1 $L) == [/notice]) {		if (#L == 2 && mid(${@L - 1} 1 $L) == [ ]) {			@do_msg_cycle($cycle_direction)			return		}	}	@:frag_start = current_fragment_start()	if (frag_start == -1 || cycle_direction == -1) {		return	}	@:fragment = mid($frag_start ${curpos() - frag_start} $L)	@:fraglen = strlen($fragment)	@:padding = []	switch ($input_line) {		(/dcc %) {			@:matches = match_dcc($fragment)			if (#matches == 1) {				@:padding = [ ]			}		}		(/dcc send % *)		(/exec % *) {			@:matches = match_file($fragment)			if (#matches == 1 && !isdirectory($matches)) {				@:padding = [ ]			}		}		(/exec %) {			@:matches = match_exec($fragment)			if (#matches == 1 && !isdirectory($matches)) {				@:padding = [ ]			}		}		(/help %) {			@:matches = match_help($fragment)			if (#matches == 1) {				if (!isdirectory(${getset(HELP_PATH)}/${matches})) {					@:padding = [ ]				}			}		}		(/load *)		(/unload *) {			@:matches = match_load($fragment)			if (#matches == 1 && !isdirectory($matches)) {				@:padding = [ ]			}		}		(/notify -%) {			@:fragment = rest($fragment)			@:fraglen--			@:matches = match_notify($fragment)			if (#matches == 1) {				@:padding = [ ]			}		}		(/set -%) {			@:fragment = rest($fragment)			@:fraglen--			@:matches = match_set($fragment)			if (#matches == 1) {				@:padding = [ ]			}		}		(/set %) {			@:matches = match_set($fragment)			if (#matches == 1) {				@:padding = [ ]			}		}		(/%) {			@:fragment = rest($fragment)			@:fraglen--			@:matches = match_command($fragment)			if (#matches == 1) {				@:padding = [ ]			}		}		(*) {			@:matches = []			@push(matches $match_chan($fragment))			@push(matches $match_nick($fragment))			if (#matches == 1) {				if (#L == 1 && !ischannel($matches)) {					if (nick_completion_char != []) {						@:padding = [$nick_completion_char ]					}				} else {					@:padding = [ ]				}			}		}	}	@last_input_line = L	@match_index = -1	@:match_prefix = prefix($matches)	if (@match_prefix <= fraglen && #matches > 1) {		xecho -c Possible matches:		xecho -c -- $matches		xecho -c		return	}	if (match_prefix != []) {		@:new_fragment = left($fraglen $match_prefix)		if (encode($fragment) != encode($new_fragment)) {			repeat $fraglen parsekey backspace			xtype -l $new_fragment		}	}	@:completion = rest($fraglen $match_prefix)	if (completion == [] && padding == []) {		return	}	if (index("$chr(32)" $fragment) == -1) {		if (index("$chr(32)" $match_prefix) > -1) {			repeat $fraglen parsekey backspace			if (mid($curpos() 1 $L) == ["] && mid(${curpos() - 1} 1 $L) == ["]) {				xtype -l $match_prefix				if (padding != []) {					parsekey forward_character				}			} else {				xtype -l "$match_prefix"				if (padding == []) {					parsekey backward_character				}			}		} else {			xtype -l $completion		}	} else {		xtype -l $completion		if (padding == []) {			if (mid($curpos() 1 $L) != ["]) {				xtype -l "				parsekey backward_character			}		} else {			if (mid($curpos() 1 $L) == ["]) {				parsekey forward_character			} else {				xtype -l "			}		}	}	if (mid(${curpos()} 1 $L) != padding) {		xtype -l $padding	}	@last_input_line = []}alias isdirectory (pathname) {	@:statret = stat("$pathname")	@:file_type = left(1 $word(2 $statret))	if (file_type & 4) {		return 1	} else {		return 0	}}alias isexe (pathname) {	@:statret = stat("$pathname")	@:file_mode = word(2 $statret)	@:file_type = left(1 $file_mode)	@:permissions = right(3 $file_mode)	@:user_perm = left(1 $permissions)	@:group_perm = mid(1 1 $permissions)	@:other_perm = right(1 $permissions)	if (file_type == 1) {		if ((user_perm & 1) || (group_perm & 1) || (other_perm & 1)) {			return 1		} else {			return 0		}	} else {		return 0	}}alias match_chan (fragment) {	@:matches = pattern("${fragment}*" $mychannels())	@match_cycle_list = matches	return $matches}alias match_command (fragment) {	@:matches = []	@:command_matches = []	@push(matches $getcommands(${fragment}*))	@push(matches $aliasctl(alias pmatch ${fragment}*))	fe ($matches) match {		@push(command_matches /${match})	}	@match_cycle_list = uniq($command_matches)	return $uniq($matches)}alias match_dcc (fragment) {	@:dcc_cmds = [chat close closeall get list raw rename resume send]	@:matches = pattern(${fragment}% $dcc_cmds)	@match_cycle_list = matches	return $matches}alias match_exec (fragment) {	@:matches = []	if (index(/ $fragment) == -1) {		@:path_list = PATH		while (path_list != []) {			@:pathname = before(: $path_list)			if (pathname == []) {				@:pathname = path_list				@:path_list = []			} else {				@:path_list = after(: $path_list)			}			fe ($glob("${pathname}/${fragment}*")) filename {				if (isexe($filename)) {					@push(matches $after(-1 / $filename))				}			}		}		fe ($glob("${fragment}*")) filename {			if (isdirectory($filename)) {				@push(matches $filename)			}		}	} else {		fe ($glob("${fragment}*")) filename {			if (isexe($filename) || isdirectory($filename)) {				@push(matches $filename)			}		}	}	@match_cycle_list = matches = uniq($matches)	return $matches}alias match_file (fragment) {	@:matches = glob("${fragment}*")	@match_cycle_list = matches	return $matches}alias match_help (fragment) {	@:matches = []	@:help_path = getset(HELP_PATH)	@:help_matches = globi("${help_path}/${fragment}*")	fe ($help_matches) match {		@push(matches $rest(${@help_path + 1} $match))	}	@match_cycle_list = matches	return $matches}alias match_load (fragment) {	@:matches = []	if (index(/ $fragment) == -1) {		@:path_list = LOAD_PATH		while (path_list != []) {			@:pathname = before(: $path_list)			if (pathname == []) {				@:pathname = path_list				@:path_list = []			} else {				@:path_list = after(: $path_list)			}			fe ($glob("${pathname}/${fragment}*")) filename {				@push(matches $after(-1 / $filename))			}		}	}	@push(matches $glob("${fragment}*"))	@match_cycle_list = matches = uniq($matches)	return $matches}		alias match_nick (fragment) {	@:nick_matches = pattern("${fragment}*" $onchannel())	if (nick_matches == []) {		@:nick_list = []		fe ($remw($C $mychannels())) chan {			@push(nick_list $onchannel($chan))		}		@push(nick_list $notify(on))		@:nick_matches = pattern(${fragment}* $nick_list)	}	if (nick_completion_char != [] && #matches > 1 && #L == 1) {		fe ($nick_matches) nickname {			@push(matches ${nickname}${nick_completion_char})		}	} else {		@:matches = nick_matches	}	@:matches = uniq($matches)	@match_cycle_list = matches	return $matches}alias match_notify (fragment) {	@:matches = pattern(${fragment}* $notify())	@match_cycle_list = matches	return $matches}alias match_set (fragment) {	@:matches = []	@:my_sets = [NICK_COMPLETION_CHAR TAB_HISTORY_CYCLE_SIZE ZSH_STYLE_COMPLETION]	@push(matches $getsets(${fragment}*))	@push(matches $pattern(${fragment}* $my_sets))	@match_cycle_list = matches	return $matches}alias match_theme (fragment) {	@:matches = []	@:theme_matches = globi("${theme_directory}/${fragment}*.theme")	fe ($theme_matches) match {		@push(matches $before(-1 . $rest(${@theme_directory + 1} $match)))	}	@match_cycle_list = matches	return $matches}alias tclear {	@target_cycle_list = []	@target_index = -2	xecho target history cleared }# *** hooks ***on #^action 110 "*" {	if (!rmatch($1 #* &* +*) ) {		@add_target(msg $0)	}}on #^dcc_chat 110 "*" {	@add_target(msg =$0)}on #^dcc_connect 110 "% CHAT *" {	@add_target(msg =$0)}on #^general_notice 110 "% *" {	@add_target(notice $1)}on #^msg 110 "*" {	@add_target(msg $0)}on #^send_action 110 "*" {	if (!rmatch($0 #* &* +*) ) {		@add_target(msg $0)	}}on #^send_dcc_chat 110 "*" {	@add_target(msg =$0)}on #^send_msg 110 "*" {	@add_target(msg $0)}on #^send_notice 110 "*" {	@add_target(notice $0)}on ?send_to_server "% % NOTICE %:% *" {	if (ischannel($3)) {		return 0	}	@:refnum = before(: $3)	@:target = after(: $3)	xquote -server $refnum NOTICE $target $4-	return 1}on ?send_to_server "% % PRIVMSG %:% *" {	if (ischannel($3)) {		return 0	}	@:refnum = before(: $3)	@:target = after(: $3)	xquote -server $refnum PRIVMSG $target $4-	return 1}on ^set "NICK_COMPLETION_CHAR *" {	@do_set(NICK_COMPLETION_CHAR $1)}on ^set "TAB_HISTORY_CYCLE_SIZE *" {	@do_set(TAB_HISTORY_CYCLE_SIZE $1)}on ^set "ZSH_STYLE_COMPLETION *" {	@do_set(ZSH_STYLE_COMPLETION $1)}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -