Home | Download/Install | Documentation | Contact
tako is a command language and shell, based on Python 3, with additional syntax to make starting processes, manipulating the environment, and dealing with the filesystem easy. In fact, it is a strict superset of Python (3.4+), so any command that is valid Python is also a valid tako command; as a result, you can use tako purely as an interactive Python interpreter if you don't need any of the additional syntax (though in a few situations, the semantics are slightly different). This page will not focus on Python, but rather on using tako as an interactive command prompt and customizing it to fit your needs.
This page is based on the xonsh "tutorial," and pieces have been copied verbatim.
~ $ 1+1
2
One place where tako differs from Python is in its handling of numbers. When dividing integers, tako keeps an exact representation of a number rather than converting to a float (it will only convert to a float if necessary). For example:
~ $ 3.1 3.1 ~ $ 2 / 3 2/3 ~ $ 2.0/3 0.6666666666666666(You can turn this behavior off and revert to Python's regular handling of numbers by setting $TAKO_SETTINGS.number_mode = 'python'. You can cause tako to convert decimals to rationals as well by setting $TAKO_SETTINGS.number_mode = 'exact').
Since tako is a superset of Python, you are able import modules, print values, and use other built-in Python functionality directly from the command prompt:
~ $ import sys ~ $ print(sys.version) 3.5.2 (default, Aug 26 2016, 06:23:54) [GCC 4.9.2]If you have third-party Python modules installed, you can use those as well:
~ $ import numpy ~ $ print(numpy.mean(range(4))) 1.5You can also create and use literal data types, such as ints, floats, lists, sets, and dictionaries. Everything that you are used to if you already know Python is there:
>>> d = {'tako': True} >>> d.get('bash', False) FalseLike many interactive Python prompts, tako also supports multi-line input for more advanced flow control. The multi-line mode is automatically entered whenever the first line of input is not syntactically valid on its own. Multi-line mode is then exited when enter (or return) is pressed when the cursor is in the first column.
~ $ if True: ... print(1) ... else: ... print(2) ... 1Flow control, of course, includes for and while loops:
~ $ for i, x in enumerate('tako'): ... print(i, x) ... 0 t 1 a 2 k 3 oFunctions and classes can also be defined directly from the command prompt:
~ $ def f(): ... return "tako" ... ~ $ f() 'tako'
~ $ $HOME '/home/takofan123' ~ $ print($PATH) ['/usr/local/bin', '/usr/bin', '/bin', '/usr/games']Note that environment variables are typed, unlike in some other shells. $PATH, for example, is an object much like a Python list, and you can interact with it in the same way you would a list. For example:
~ $ $PATH.append('~/bin') ~ $ print($PATH) ['/usr/local/bin', '/usr/bin', '/bin', '/usr/games', '/home/takofan123/bin'] ~ $ $PATH = $PATH[:-1] ~ $ print($PATH) ['/usr/local/bin', '/usr/bin', '/bin', '/usr/games']One other thing to note is that environment variables in tako are automatically exported. If you want a local variable (that is not shared with subprocesses), you can just use a normal Python variable (with no $). tako will automatically convert back and forth to untyped (string-only) representations of the environment as needed (mostly by subprocess commands). From the command prompt, you'll always have the typed version.
~ $ x = 'TH' ~ $ ${'PA' + x} ['/usr/local/bin', '/usr/bin', '/bin', '/usr/games'] ~ $ ${...}['PATH'].append('~/bin') ['/usr/local/bin', '/usr/bin', '/bin', '/usr/games'] ~ $ 'PATH' in ${...} True ~ $ myenv = ${...} ~ $ myenv['PATH'] ['/usr/local/bin', '/usr/bin', '/bin', '/usr/games', '/home/takofan123/bin'](Note that this is three "dots" in a row, rather than an actual ellipsis character)
tako builds on Python's syntax to make running other programs easy. In general, running other programs works very much like it would in any other shell.
~/tako $ echo "howdy there" howdy there ~/tako $ cd tako ~/t/tako $ git status On branch master Your branch is up-to-date with 'origin/master'. nothing to commit, working directory clean ~/t/tako $ exit
When working with tako, it is important to make the distinction between lines that operate in pure Python mode and those that use shell-specific syntax to run commands.
Unfortunately, it is not always clear from the syntax alone what mode is desired. This ambiguity stems from most command line utilities looking a lot like Python operators.
Take the case of ls -l. This is valid Python code, though it could have also been written as ls - l or ls-l. So we need a way to determine whether this was intended as a command or as a Python expression.
For any given line that only contains an expression statement, tako will treat it as a Python expression if all of the included variables are defined in the current scope. If not, tako will try to parse the line as a subprocess-mode command instead. In the example above, the expression ls -l will be treated as a Python-mode expression if and only if ls and l are both variables defined in the current scope. Otherwise, it will be run as a command (executing the ls program with the -l flag).
~ $ # this will be in subprocess-mode, because ls is not defined ~ $ ls -l total 0 -rw-rw-r-- 1 takofan123 takofan123 0 Mar 8 15:46 tako ~ $ # set ls and l variables to force python-mode ~ $ ls = 44 ~ $ l = 2 ~ $ ls -l 42 ~ $ # deleting ls will return us to supbroc-mode ~ $ del ls ~ $ ls -l total 0 -rw-rw-r-- 1 takofan123 takofan123 0 Mar 8 15:46 tako
If you absolutely want to run a command in subprocess mode, you can always force tako to do so with the $(), $[], !(), and ![] operators discussed in later sections.
~ $ env | uniq | sort | grep PATH
DATAPATH=/usr/share/MCNPX/v260/Data/
DEFAULTS_PATH=/usr/share/gconf/awesome-gnome.default.path
LD_LIBRARY_PATH=/home/snail/.local/lib:
MANDATORY_PATH=/usr/share/gconf/awesome-gnome.mandatory.path
PATH=/home/snail/.local/bin:/home/snail/sandbox/bin:/usr/local/bin
XDG_SEAT_PATH=/org/freedesktop/DisplayManager/Seat0
XDG_SESSION_PATH=/org/freedesktop/DisplayManager/Session0
This is only available in subprocess-mode because | is otherwise a Python operator.
tako also allows you to redirect stdin, stdout, and/or stderr, allowing you to control where the output of a command is sent, and where it receives its input from.
The basic operations for I/O redirection are "write to" (>), "append to" (>>), and "read from" (<). The details of these are perhaps best explained through examples.~ $ COMMAND > output.txt ~ $ COMMAND out> output.txt ~ $ COMMAND o> output.txt
These can be made to append to output.txt instead of overwriting its contents by replacing > with > (note that > will still create the file if it does not exist).
~ $ COMMAND err> errors.txt ~ $ COMMAND e> errors.txtAs above, replacing > with >> will cause the error output to be appended to errors.txt rather than replacing its contents.
~ $ COMMAND all> combined.txt ~ $ COMMAND a> combined.txtIt is also possible to explicitly merge stderr into stdout so that error messages are reported to the same location as regular output. You can do this with the following syntax:
~ $ COMMAND err>out ~ $ COMMAND err>o ~ $ COMMAND e>out ~ $ COMMAND e>oThis merge can be combined with other redirections, including pipes (see the section on Pipes above):
~ $ COMMAND err>out | COMMAND2 ~ $ COMMAND e>o > combined.txtIt is worth noting that this last example is equivalent to: COMMAND a> combined.txt
~ $ COMMAND < input.txt ~ $ < input.txt COMMAND
~ $ COMMAND1 e>o < input.txt | COMMAND2 > output.txt e>> errors.txt
This line will run COMMAND1 with the contents of input.txt fed in as input, and it will pipe all output (stdout and stderr) to COMMAND2; the regular output of COMMAND2 will be redirected to output.txt, and the error output will be appended to errors.txt.
~ $ gvim really_interesting_file.txt & ~ $Note that the prompt is returned to you after gvim is started.
If you start a program in the foreground (with no ampersand), you can suspend that program's execution and return to the command prompt by pressing Control-Z. This will give control of the terminal back to tako, and will keep the program paused in the background.
To unpause the program and bring it back to the foreground, you can use the fg command. To unpause the program have it continue in the background (giving you continued access to the tako prompt), you can use the bg command.
You can get a listing of all currently running jobs with the jobs command.
Each job has a unique identifier (starting with 1 and counting upward). By default, the fg and bg commands operate on the job that was started most recently. You can bring older jobs to the foreground or background by specifying the appropriate ID; for example, fg 1 brings the job with ID 1 to the foreground.
~ $ touch exists ~ $ ls exists and ls doesnt exists /bin/ls: cannot access doesnt: No such file or directoryHowever, if you list the file that doesn't exist first, you would have only seen the error (because ls exists would not run):
~ $ ls doesnt and ls exists
/bin/ls: cannot access doesnt: No such file or directory
Much like with and, you can use the or operator to chain together subprocess commands. The difference is that subsequent commands will be executed if the return code is non-zero (i.e. a failure). Using the file example from above:
~ $ ls exists or ls doesnt
exists
This doesn't even try to list the non-existent file, because ls exists suceeded). However, if you list the file that doesn't exist first, you will see the error and then the file that does exist:
~ $ ls doesnt or ls exists
/bin/ls: cannot access doesnt: No such file or directory
exists
You can also use the more conventional && in place of and, and || in place of or, if you prefer.
~ $ x = 'tako' ~ $ y = 'tuesday' ~ $ echo @(x + ' ' + y) tako tuesday ~ $ echo @(2+2) 4 ~ $ echo @([42, 'hello']) 42 helloThus, @() allows us to create complex commands in Python-mode and then feed them to a subprocess as needed. For example:
for i in range(20): touch @('file%02d' % i)
Strings can be used to escape special characters in subprocess-mode. The contents of the string are passed directly to the subprocess command as a single argument. So whenever you are in doubt, or if there is a syntax error because of a filename, just wrap the offending portion in a string.
A common use case for this is files with spaces in their names.~ $/tako $ touch "sp ace" ~ $/tako $ ls -l total 0 -rw-rw-r-- 1 takofan123 takofan123 0 Mar 8 17:50 sp ace -rw-rw-r-- 1 takofan123 takofan123 0 Mar 8 15:46 takoBy default, the name of an environment variable inside a string will be replaced by the contents of that variable (in subprocess mode only). For example:
~/tako $ $ print("my home is $HOME") my home is $HOME ~tako $ echo "my home is $HOME" my home is /home/takofan123You can avoid this expansion within a particular command by forcing the strings to be evaluated in Python mode using the @() syntax:
~/tako $ echo "my home is $HOME" my home is /home/takofan123 ~/tako $ echo @("my home is $HOME") my home is $HOME
The $(<expr>) operator in tako executes a subprocess command and captures some information about that command.
The $() syntax captures and returns the standard output stream as a string (with trailing newlines removed), which should be equivalent to how $() performs in Bash. For example:
~/tako $ $(ls -l)
'total 0\n-rw-rw-r-- 1 takofan123 takofan123 0 Mar 8 15:46 tako'
The !(<expr>) syntax captures more information about the command, as an instance of a class called CompletedCommand, which contains information about the result of the given command, including the return code, the process id, the standard output and standard error streams, and information about how input and output were redirected. For example:
~ $ !(ls nonexistent_directory)
CompletedCommand(stdin=None, stdout='', stderr='/bin/ls: cannot access nonexistent_directory: No such file or directory\n', pid=1862, returncode=2, args=['ls', 'nonexistent_directory'], alias=['ls', '--color=auto'], stdin_redirect=None, stdout_redirect=None, stderr_redirect=None)
This object will be "truthy" if its return code was 0, and it is equal (via ==) to its return code. It also hashes to its return code. This allows for some interesting kinds of interactions with subprocess commands, for example:
def check_file(file): if !(test -e @(file)): if !(test -f @(file)) or !(test -d @(file)): print("File is a regular file or directory") else: print("File is not a regular file or directory") else: print("File does not exist") def wait_until_google_responds(): while not !(ping -c 1 google.com): sleep 1Iterating over the object will yield a string for each line in stdout.
The $() and !() operators are expressions themselves. This means that you can assign the results to a variable, or manipulate them in other ways as you would any other Python expression.
~/tako $ x = $(ls -l) ~/tako $ print(x.upper()) TOTAL 0 -RW-RW-R-- 1 TAKOFAN123 TAKOFAN123 0 MAR 8 15:46 TAKO ~/tako $ y = !(ls -l) ~/tako $ print(y.returncode) 0 ~/tako $ print(y.rtn) # alias to returncode 0Note that job control is not implemented for captured subprocesses. While in subprocess-mode or inside of a captured subprocess, you can still query the environment with $NAME variables or the ${} syntax:
~/tako $ $(echo $HOME)[0]
'/home/takofan123'
Uncaptured subprocesses are denoted with the $[<expr>] and ![<expr>] operators. They are the same as $() captured subprocesses in almost every way. The only difference is that the subprocess's stdout passes directly to the screen rather than being captured.
In the following, we can see that the results of $[] are automatically printed, and the return value is not a string:
~/tako $ x = $[ls -l] total 0 -rw-rw-r-- 1 takofan123 takofan123 0 Mar 8 15:46 tako ~/tako $ x is None True
The ![] operator is similar to !() in that it returns an object containing information about the result of executing the given command. However, its standard output and standard error streams are directed to the terminal, and the resulting object is not displayed. For example:
~/tako $ x = ![ls -l] and ![echo "hi"]
total 0
-rw-rw-r-- 1 takofan123 takofan123 0 Mar 8 15:46 tako
hi
Previously when we automatically entered subprocess-mode, uncaptured subprocesses were used automatically. Thus ls -l and ![ls -l] are usually equivalent (and, in fact, the former is transformed to the latter internally when ls -l is determined to be a subprocess-mode command).
A common use of the @() and $() operators is allowing the output of a command to replace the command itself (command substitution): @([i.strip() for i in $(cmd).split()]). tako also offers a short-hand syntax for this operation: @$(cmd).
Consider the following example:
~ $ # this returns a string representing stdout ~ $ $(which ls) 'ls --color=auto\n'
~ $ # this attempts to run the command, but as one argument ~ $ # (looks in $PATH for 'ls --color=auto\n' with spaces and newline) ~ $ @($(which ls).strip()) tako: subprocess mode: command not found: ls --color=auto
~ $ # this actually executes the intended command ~ $ @([i.strip() for i in $(which ls).split()]) some_file some_other_file
~ $ # this does the same thing, but is much more concise ~ $ @$(which ls) some_file some_other_file
It is possible to nest the subprocess operators that we have seen so far ($(), $[], ${}, !(), ![], @(), @$()). Nesting these subprocess operators inside of $(), !(), $[], and/or ![] works because the contents of those operators are executed in subprocess mode. Since @() and ${} run their contents in Python mode, it is not possible to nest other subprocess operators inside of them (they can only contain Python expressions).
The up and down keys search history matching from the start of the line, much like they do in the IPython shell. tako also supports reverse incremental search with Ctrl-r.
Tab completion is present as well. By default, in Python-mode you are able to complete based on the variable names in the current builtins; globals; and locals; as well as tako language keywords and operators; files and directories; and environment variable names. In subprocess-mode, you additionally complete on the names of executable files on your $PATH, and aliases.
It is also possible to make tako to use Bash to provide auxiliary tab completion for a number of commands, provided you have Bash installed. In order to use this functionality, run the following command:
~ $ completer bash enable
The first time this command runs, it will be a bit slow, as it builds up a cache of the Bash completion functions available on your system, but it should be much faster on subsequent runs. If you want these completions to be available every time, add the above line to your ~/.config/tako/config.tako file.
The tab completion itself is fully customizable, so you can remove completers that are included by default, or implement your own. See the section below on programmable tab completion for more information.
tako offers additional ways to find path names beyond regular globbing, both in Python mode and in subprocess mode, via special string that use backticks (`) instead of quotes.
Note that backticks have a very different meaning in tako, versus Bash.
~ $ touch a aa aaa aba abba aab aabb abcba ~ $ ls `a(a+|b+)a` aaa aba abba ~ $ print(`a(a+|b+)a`) ['aaa', 'aba', 'abba'] ~ $ len(`a(a+|b+)a`) 3This same kind of search is performed if the backticks are prefaced with r. So the following expresions are equivalent: `test` and r`test`.
In subprocess mode, normal globbing happens without any special syntax. However, the backtick syntax has a few additional features:
Similarly to regex globbing, normal globbing can be performed (either in Python mode or subprocess mode) by using the g`` syntax:
~ $ touch a aa aaa aba abba aab aabb abcba ~ $ ls a*b* aab aabb aba abba abcba ~ $ ls g`a*b*` aab aabb aba abba abcba ~ $ print(g`a*b*`) ['aab', 'aabb', 'abba', 'abcba', 'aba'] ~ $ len(g`a*b*`) 5 ~ $ len(g`a{b,bb}a`) 2
~ $ def foo(s): ... return [i for i in os.listdir('.') if i.startswith(s)] ~ $ @foo`aa` ['aa', 'aaa', 'aab', 'aabb']
bash $ tako -s -c "echo @(7+3)"
10
Longer scripts can be run either by specifying a filename containing the script, or by feeding them to tako via stdin. For example, consider the following script, stored in test.tako:
#!/usr/bin/env tako ls print('removing files') rm `file\d+.txt` ls print('adding files') # This is a comment for i, x in enumerate("tako"): echo @(x) > @("file{0}.txt".format(i)) print(' '.join(!(ls)))
This script could be run by piping its contents to tako:
bash $ cat test.tako | tako -s
file0.txt file1.txt file2.txt file3.txt test.tako
removing files
test.tako
adding files
file0.txt file1.txt file2.txt file3.txt test.tako
or by invoking tako with its filename as an argument:
bash $ tako -s test.tako
file0.txt file1.txt file2.txt file3.txt test.tako
removing files
test.tako
adding files
file0.txt file1.txt file2.txt file3.txt test.tako
tako scripts can also accept arguments. These arguments are made available to the script in two different ways:
For example, consider a slight variation of the example script from above that operates on a given argument, rather than on the string 'tako' (notice how $ARGS and $1 are used):
#!/usr/bin/env tako print($ARGS) ls print('removing files') rm `file\d+.txt` ls print('adding files') # This is a comment for i, x in enumerate($1): echo @(x) > @("file{0}.txt".format(i)) print(' '.join(!(ls))) print()
bash $ tako test2.tako hello ['test2.tako', 'hello'] file0.txt file1.txt file2.txt file3.txt file4.txt test2.tako removing files test2.tako adding files file0.txt file1.txt file2.txt file3.txt file4.txt test2.tako ~ $ echo @(' '.join($(cat @('file%d.txt' % i)) for i in range(5))) h e l l o
You can import tako source files with the *.tako file extension using the normal Python syntax. Say you had a file called mine.tako, you could, therefore, perform a Bash-like source into your current shell with the following:
from mine import *You can also use source to run a .tako file in the current environment.
Customizing the prompt by modifying $TAKO_SETTINGS.prompt is probably the most common reason for changing the settings.
$TAKO_SETTINGS.prompt can be a string, or it can be a function (of no arguments) that returns a string. The result can contain keyword arguments, which will be replaced automatically:
~ $ $TAKO_SETTINGS.prompt = '{user}@{hostname}:{cwd} > '
takofan123@home:~ > # it works!
takofan123@home:~ > $TAKO_SETTINGS.prompt = lambda: '{user}@{hostname}:{cwd} >> '
takofan123@home:~ >> # so does that!
By default, the following variables are available for use:
You can also color your prompt easily by inserting keywords such as {GREEN} or {BOLD_BLUE}. Colors have the form shown below:
You can make use of additional variables beyond these by adding them to the $TAKO_SETTINGS.prompt_fields variable. The values in this dictionary should be strings (which will be inserted into the prompt verbatim), or functions of no arguments (which will be called each time the prompt is generated, and the results of those calls will be inserted into the prompt). For example:
~ $ $TAKO_SETTINGS.prompt_fields['test'] = "hey" ~ $ $TAKO_SETTINGS.prompt = "{test} {cwd} $ " hey ~ $ hey ~ $ import random hey ~ $ $TAKO_SETTINGS.prompt_fields['test'] = lambda: random.randint(1,9) 3 ~ $ 5 ~ $ 2 ~ $ 8 ~ $
If a function in $TAKO_SETTINGS.prompt_fields returns None, the None will be interpreted as an empty string.
Environment variables and functions are also available with the $ prefix. For example:
~ $ $TAKO_SETTINGS.prompt = "{$LANG} >"
en_US.utf8 >
Another important tako built-in is the $TAKO_SETTINGS.aliases mapping. This is like a dictionary that affects how subprocess commands are run. If you are familiar with the Bash alias built-in, this is similar.
The keys of $TAKO_SETTINGS.aliases are strings that act as commands in subprocess-mode. The values are lists of strings, where the first element is the command, and the rest are the arguments. You can also set the value to a string, in which case it will be converted to a list automatically.
For example, the following creates several aliases for the git version control system. Both styles (list of strings and single string) are shown:
~ $ $TAKO_SETTINGS.aliases['g'] = 'git status -sb' ~ $ $TAKO_SETTINGS.aliases['gco'] = 'git checkout' ~ $ $TAKO_SETTINGS.aliases['gp'] = ['git', 'pull']
If you were to run gco mybranch with the above aliases in effect, the command would reduce to ['git', 'checkout', 'mybranch'] before being executed.
Lastly, if an alias value is a function (or other callable), then this function is called with particular arguments instead of going to a subprocess command. Such functions can take one of two forms, detailed below.
def _mycmd(args, stdin=None): print('I go to stdout and will be printed or piped') return (None, "I failed", 2)
Note that the form above does not allow for streaming of its input or output; rather, it assumes that its entire input comes in as one chunk, and that its entire output should be produced as a single chunk as well.
However, there is an alternate form that allows for this kind of streaming. This kind of Python function alias takes 4 arguments:
The function should return a single integer representing its return code.
Here is a simple example:
def _echo(args, stdin, stdout, stderr): x = stdin.read(1024) stdout.write(x) stderr.write(x) return 0
~ $ def _foo(args, stdin=None): ... return 'The arguments were: %s' % ' '.join(args) ~ $ $TAKO_SETTINGS.aliases['foo'] = _foo ~ $ foo bar baz The arguments were: bar baz ~ # foo bar baz | grep baz # pipes, I/O redirection, etc, still work! The arguments were: bar baz
Alias functions should generally be defined with a leading underscore. Otherwise, they may shadow the alias itself, as Python variables take precedence over aliases when tako executes commands.
~ $ $TAKO_SETTINGS.hooks['on_chdir'].append(lambda new, old: print('we moved to %s!' % new)) ~ $ cd tako we moved to /home/takofan123/tako! ~/tako $ cd we moved to /home/takofan123! ~ $
~ $ $TAKO_SETTINGS.hooks['post_command'].append(lambda result: print(':)' if result else ':(')) ~ $ cd we moved to /home/takofan123! :) ~ $ ls nonexistent /bin/ls: cannot access 'nonexistent': No such file or directory :(
As of version 0.2.0, tako also provides an interface for plug-ins, which can be used to extend or modify the base features of tako. Each plugin takes the form of a single .tako file. To install a plugin, simply place that .tako file in ~/.config/tako/plugins.
A small number of "official" plugins are available
from the Git repository at git://hz.mit.edu/tako-plugins.git
. Some
may be available from third parties, as well (but please only install plugins
from trusted sources and perform an audit of the code yourself where possible,
since plugins can execute arbitrary code on your machine).
Plugins' configurations options are available from the $TAKO_SETTINGS.plugins object. For example, to configure the frecency plugin, one can modify $TAKO_SETTINGS.plugins.frecency.frecency_max_items.
In addition to installing plugins from other sources, it is of course also possible to create plugins of your own. Note, though, that, due to tako's license, plugins are almost certainly required to be licensed under the same terms as tako itself (the GPLv3+).
Plugins take the form of a single .tako file, which is executed just before the user's main run control file. A plugin can contain arbitrary code (and so can be used to modify features of tako itself), but it is executed in a separate environment (so, for example, variables set in the plugin's file are not directly accessible from the global tako environment).
Plugins are provided with a special PLUGIN_SETTINGS variable, which can be used for storage of relevant state and/or configuration options specific to the plugin. In addition, plugins can register their own aliases and hooks by adding functions to the PLUGIN_SETTINGS.aliases and PLUGIN_SETTINGS.hooks mappings (whose interfaces are the same as their counterparts in $TAKO_SETTINGS. The PLUGIN_SETTINGS object is accessible from the global tako environment as $TAKO_SETTINGS.plugins.your_plugin_name.
For reference, a few example plugins are available in the Git repository at git://hz.mit.edu/tako-plugins.git
tako also provides a mechanism by which the results of a tab completion can be customized (i.e., new completions can be generated, or a subset of the built-in completions can be ignored).
This section details the internal structure of tako's completion system and includes instructions for implementing new tab completion functions.
tako's built-in completers live in the tako.completers package, and they are managed through an instance of OrderedDict (__tako_completers__) that maps unique identifiers to completion functions.
When the "tab" key is pressed, tako loops over the completion functions in order, calling each one in turn until it reaches one that returns a non-empty set of completion for the current line. This set is then displayed to the user.
This function should return a Python set of possible completions for prefix in the current context. If the completer should not be used in this case, it should return None or an empty set, which will cause tako to move on and try to use the next completer. If a completer raises StopIteration, then following completers will not be tested, and an empty set of results will be returned.
The docstring of a completer should contain a brief description of its functionality, which will be displayed by completer list.
Three examples follow. For more examples, see the source code of the completers tako actually uses, in the tako.completers module.
def dummy_completer(prefix, line, begidx, endidx, ctx): ''' Completes everything with options "hardshell" and "softshell", regardless of the value of prefix. ''' return {"hardshell", "softshell"}
def python_context_completer(prefix, line, begidx, endidx, ctx): ''' Completes based on the names in the current Python environment ''' return {i for i in ctx if i.startswith(prefix)}
Usage: completer add NAME FUNC [POS]
where NAME is a unique name to use in the listing, FUNC is the name of a completer function to use, and POS (optional) is a position into the list of completers at which the new completer should be added. POS can be one of the following values:
Note: It is also possible to manipulate __tako_completers__ directly if that is easier.
____ ( oo ) _||||_
The contents of this page are licensed under a
Creative Commons Attribution-ShareAlike 4.0 International License.
The web site is available online at https://takoshell.org, or as a Tor "onion service" at http://takoezpr7wxrc7d6.onion or http://tehbemfqolualhxwkyimu3bdob5s4hkrfuwbwxzbblncjy2j2owgolqd.onion.
The source code for the web site is available in a git repository: git clone git://hz.mit.edu/takoshell.org.git
.