[boinc_dev] Fish shell tab completion

Nicolas Alvarez nicolas.alvarez at gmail.com
Wed Jun 18 14:15:43 PDT 2008


Okay, I think the script is complete enough to be shown to the world.

To summarize what it *is*: A boinc_cmd tab completion script for the Fish 
shell (http://fishshell.org/). Similar to the one already written for Bash, 
but more powerful.

Pressing tab after --project shows the list of URLs from the attached projects 
(and project names as descriptions). Tab after the URL completes the possible 
operations on the project.

Pressing tab after --result shows the list of URLs from the attached projects 
(and project names as descriptions). Tab after the URL completes task names 
from that project. Tab after the task name completes the operation names.

Tab after --set_run_mode lists the possible modes: always, auto, never.

Tab after --lookup_account, --project_attach, and --create_account complete 
URLs for all projects (list from BOINC website). The completion script 
downloads (and caches) the list by itself. I can't take it from the BOINC 
data directory because there is no way to reliably find where the data dir 
is, and a just-installed BOINC (first project attach) wouldn't have 
downloaded the list yet.

There may be some parameters missing.
-------------- next part --------------
# This progra-- err, script, is free software. It comes without any warranty,
# to the extent permitted by applicable law. You can redistribute it and/or
# modify it under the terms of the Do What The Fuck You Want To Public License,
# Version 2, as published by Sam Hocevar. See http://sam.zoy.org/wtfpl/COPYING
# for more details.

# {{{ Helper functions
function __fish_boinccmd_no_subcommand -d 'Test if boinc_cmd has yet to be given a subcommand' # {{{
	for i in (commandline -opc)
		if contains -- $i --$__fish_boinccmd_switches
			return 1
		end
	end
	return 0
end # }}}
function __fish_boinccmd_subcommand -d 'Test if boinc_cmd was given this subcommand' # {{{
	# this function is not used anymore; all previous uses were replaced with __fish_boinccmd_arg
	for i in (commandline -opc)
		if contains -- $i --$argv[1]
			return 0;
		end
	end
	return 1
end # }}}
function __fish_boinccmd_arg -d "Test if boinc_cmd was given this subcommand and we\'re at the right argument" # {{{
	set -l cmd (commandline -opc);
	set -l idx (math (count $cmd) - $argv[2] + 1);
	if test $idx -le 0;
		return 1;
	end
	if test "$cmd[$idx]" = "--$argv[1]";
		return 0;
	end
	return 1;
end # }}}
function __fish_print_boinccmd_result_url -d "Print the current project URL from a --result subcommand" # {{{
	set -l found no
	for i in (commandline -opc)
		if test $found = yes;
			echo $i;
			return 0;
		end
		if test $i = --result;
			set found yes
		end
	end
	return 1;
end # }}}
function __fish_complete_boinccmd_project -d "Completes to a list of attached BOINC projects" # {{{
	set -l name x;
	boinc_cmd --get_project_status | grep '^ \+\(master URL\|name\)' | sed 's,^ \+\(master URL\|name\): \(.*\),\1\t\2,' | while read line;
		switch (echo $line | cut -f1);
			case 'name'
				set name (echo $line | cut -f2)
			case 'master URL'
				echo (echo $line | cut -f2)\t$name
		end
	end
end # }}}
function __fish_complete_boinccmd_result -d "Completes to a list of results from the specified project" # {{{
	boinc_cmd --get_results | grep '^ \+\(project URL\|name\)' | sed 's,^ \+\(project URL\|name\): \(.*\),\1\t\2,' | while read line;
		switch (echo $line | cut -f1);
			case 'name'
				set name (echo $line | cut -f2)
			case 'project URL'
				if test (echo $line | cut -f2) = $argv[1];
					echo $name
				end
		end
	end
end # }}}
function __fish_complete_boinccmd_all_projects -d "Returns the list of all projects; not only attached ones" # {{{
	set -l file_path /tmp/all_projects_list_$USER.xml;
	set -l list_url "http://boinc.berkeley.edu/project_list.php";
	if test ! -s $file_path;
		if not wget --quiet -O $file_path $list_url; return 1; end;
		chmod 644 $file_path;
	end
	grep '<\(name\|url\)>' $file_path | sed '/<name>/N; s/\n//; s,^ *<name>\([^<]*\)</name> *<url>\(https\?://[^<]*\)</url>,\2\t\1,'
end # }}}
# }}}
# {{{ Options: --host and --passwd
complete -x -n '__fish_boinccmd_no_subcommand' -c boinc_cmd -l passwd -d 'Password'
complete -x -n '__fish_boinccmd_no_subcommand' -c boinc_cmd -l host -a '(__fish_print_hostnames)' -d 'Remote host'
# }}}

# {{{ Project operations (--project)
complete -f -n '__fish_boinccmd_no_subcommand' -c boinc_cmd -l project -d 'Project operation'
complete -f -n '__fish_boinccmd_arg project 1' -c boinc_cmd -a "(__fish_complete_boinccmd_project)"
begin
	set -l cmds reset detach update suspend resume nomorework allowmorework;
	set -l desc_reset "Reset project";
	set -l desc_detach "Detach project";
	set -l desc_update "Update project, contacting the server";
	set -l desc_suspend "Suspend project";
	set -l desc_resume "Resume project";
	set -l desc_nomorework "Stop getting work from project";
	set -l desc_allowmorework "Allow project to download work";
	for i in $cmds;
		set -l descvar desc_$i;
		complete -f -n '__fish_boinccmd_arg project 2' -c boinc_cmd -a $i -d $$descvar
	end
end
set __fish_boinccmd_switches $__fish_boinccmd_switches project
# }}}

# {{{ Task operations (--result)
complete -f -n '__fish_boinccmd_no_subcommand' -c boinc_cmd -l result -d 'Task operation'
complete -f -n '__fish_boinccmd_arg result 1' -c boinc_cmd -a "(__fish_complete_boinccmd_project)"
complete -f -n '__fish_boinccmd_arg result 2' -c boinc_cmd -a "(__fish_complete_boinccmd_result (__fish_print_boinccmd_result_url))"
begin
	set -l cmds suspend resume abort graphics_window graphics_fullscreen;
	set -l desc_suspend "Suspend task";
	set -l desc_resume "Resume task";
	set -l desc_abort "Abort task";
	set -l desc_graphics_window "Show task graphics in a window";
	set -l desc_graphics_fullscreen "Show task graphics in a window";
	for i in $cmds;
		set -l descvar desc_$i;
		complete -f -n '__fish_boinccmd_arg result 3' -c boinc_cmd -a $i -d $$descvar
	end
end
set __fish_boinccmd_switches $__fish_boinccmd_switches result
# }}}

# {{{ Operations that don't need an extra argument, starting with --get
begin
	set -l cmds state results simple_gui_info file_transfers project_status disk_usage proxy_settings host_info messages;
	set -l desc_state "Show entire state";
	set -l desc_results "Show tasks";
	set -l desc_simple_gui_info "Show projects and active tasks";
	set -l desc_file_transfers "Show file transfers";
	set -l desc_project_status "Show all attached projects";
	set -l desc_disk_usage "Show disk usage";
	set -l desc_proxy_settings "Show proxy settings";
	set -l desc_host_info "Show computer information";
	set -l desc_messages "Show messages";

	for i in $cmds;
		set -l descvar desc_$i;
		complete -f -n '__fish_boinccmd_no_subcommand' -c boinc_cmd -l get_$i -d $$descvar
	end

	set __fish_boinccmd_switches $__fish_boinccmd_switches get_$cmds # this syntax is great - I love fish
end
# }}}

# {{{ Other argument-less operations (not starting with --get)
begin
	set -l cmds quit_acct_mgr run_benchmarks read_global_prefs_override quit read_cc_config network_available
	set -l desc_quit_acct_mgr "Quit account manager";
	set -l desc_run_benchmarks "Run client benchmarks";
	set -l desc_read_global_prefs_override "Re-read global_prefs_override.xml";
	set -l desc_quit "Make the core client quit";
	set -l desc_read_cc_config "Re-read cc_config.xml";
	set -l desc_network_available "Retry project communications";

	for i in $cmds;
		set -l descvar desc_$i;
		complete -f -n '__fish_boinccmd_no_subcommand' -c boinc_cmd -l $i -d $$descvar
	end
	set __fish_boinccmd_switches $__fish_boinccmd_switches $cmds
end
# }}}

# {{{ Run mode
complete -f -n '__fish_boinccmd_no_subcommand' -c boinc_cmd -l set_run_mode -d 'Set run mode'

# I can't just use -a "always auto never" in the -l set_run_mode completion, because then fish would allow the syntax: --set_run_mode=always.
# boinc_cmd doesn't support separating with the equals sign, and fish doesn't support disabling that completion.

complete -f -n '__fish_boinccmd_arg set_run_mode 1' -c boinc_cmd -a 'always\tRun\ always auto\tRun\ based\ on\ preferences never\tSuspend\ computation'

set __fish_boinccmd_switches $__fish_boinccmd_switches set_run_mode
# }}}

# {{{ Attach projects
complete -f -n '__fish_boinccmd_no_subcommand' -c boinc_cmd -l 'lookup_account' -d 'Get project account key'
complete -f -n '__fish_boinccmd_no_subcommand' -c boinc_cmd -l 'project_attach' -d 'Attach to project with account key'
complete -f -n '__fish_boinccmd_no_subcommand' -c boinc_cmd -l 'create_account' -d 'Create an account on a project'
for i in lookup_account project_attach create_account;
	complete -f -n "__fish_boinccmd_arg $i 1" -c boinc_cmd -a "(__fish_complete_boinccmd_all_projects)"
end;
set __fish_boinccmd_switches $__fish_boinccmd_switches lookup_account project_attach create_account
# }}}

# vim: set ft=fish ts=4 sw=4 noet fdm=marker:


More information about the boinc_dev mailing list