auto completion in zsh on 3rd parameter - autocomplete

I have a shell script it's usage is:
foo.sh <name> <type> <*.tar.gz>
I want to setup a complete on 3rd parameter only.
If I press on 1st parameter, just show the usage.
Could I use zsh's zshcomp to do this job?
for example:
foo.sh <tab> # display usage
foo.sh a b <tab> # show files match with *.tar.gz
Is there similar script which I could follow?

Things to read.
Here is a blog post discussing the Z-Shell Completion System.
For a slightly more in-depth discussion, read this unix.stackexchange answer.
And, as always, read the man pages!.
Edit: Forgot to add: echo $fpath will show you the function path that zsh uses. On OSX, I have: /usr/local/share/zsh/4.3.17/functions, (location may vary for you), which contains all the ZSH completion functions. Have a look at _ssh, _ls, _tar etc - they're all there, and they all have lots of nifty features you can learn from.
Addressing the question: the direction you should go.
What you're asking is achievable, though. There are several steps.
You need to write a z-shell completion function. It needs to be located on the fpath; the function-path that zsh uses for it's completion system functions. (If it's a small function, putting it into ~/.zshrc will also work, but isn't recommended).
You want completion on the 3rd parameter. To do that, your function would look something like the following:
_arguments "3:<MENU>:<COMPLETION>"
<MENU> is the menu description, which you'll see if you've enabled the menu descriptions. (That's done using zstyle; read the man pages, or the linked pages, for more information).
<COMPLETION> is the things that you can complete with. For example, if you used:
_arguments "3::(Foo Bar)"
when you ran your script and pressed <TAB>, you'd have the option of either Foo or Bar.
[NOTE: There is no <MENU> in that example. If you don't want a menu descriptor, you can omit it as shown].
You want completion on *.tar files. You can call _files to do that:
_files -g \*.tar
Show usage on first parameter: that'd be a completion with no arguments (ie, argument 1). I'm not sure why you'd want completion on only the third option but not the first two (typical usage descriptions), so I don't know how to answer this. If your script is supposed to be used like this: script foo bar FILE.tar, wouldn't you want to complete the foo and bar arguments as well?
Perhaps a better solution would be displaying the usage when the script is run without parameters.
Full script would look something like the following:
#compdef myscript
_arguments "3:tar files:_files -g \*.tar"

Related

What fish function controls completion of filenames, and how can I change it?

I am trying to alter the standard logic used by fish to find filename completions. In particular, I want fish not to consider any filename that ends in a tilde (~) character, as these are emacs backup files and are not interesting.
I had assumed that the list of possible completions would be provided by a fish function, which I could then edit to remove the ones ending in tildes. But I cannot find the function. I have looked in the documentation at fishshell.com, and I have also tried functions | grep complete. What function should I be editing?
Unlike most completions file name completions is not implemented as a function; it's baked into the C++ code. See the completer_t::complete_param_expand() method in src/complete.cpp. If you can make a cogent argument for how this type of customization would be implemented I'd encourage you to open an issue.
P.S., Note that functions will not show private functions unless you invoke it as functions -a. I mention this because many completion functions are marked private by beginning their name with an underscore.

How do I find out which function is used for zsh tab completion

I want to know which function zsh is using for tab completion of a command.
For many commands (make, ls, cd …) I can apparently guess _<COMMANDNAME>, but I might actually have overriden this setting with compdef _mycd cd.
The reasons why I want to know this are two:
I might want to read some function definitions to use parts of them in functions I'm writing
I want to wrote a completion function which itself calls the completion for other commands (like one does in _nice, with the exception that I might not rely on shift; CURRENT--; _normal)
The current completion rules are stored in $_comps.
So one can display the completion rule for cd with echo $_comps[cd] and display the actual function definition with functions $_comps[cd].

How to cleanly pass command-line parameters when test-running my Python script?

So I'm writing Python with IDLE and my usual workflow is to have two windows (an editor and a console), and run my script with F5 to quickly test it.
My script has some non-optional command line parameters, and I have two conflicting desires:
If someone launches my script without passing any parameters, I'd like him to get an error telling him to do so (argparse does this well)
When I hit F5 in IDLE, I'd like to have my script run with dummy parameters (and I don't want to have more keystrokes than F5 to have this work, and I don't want to have a piece of code I have to remember to remove when I'm not debugging any more)
So far my solution has been that if I get no parameters, I look for a params.debug file (that's not under source control), and if so, take that as default params, but it's a bit ugly... so would there be a cleaner, more "standard" solution to this? Do other IDEs offer easier ways of doing this?
Other solutions I can think of: environment variables, having a separate "launcher" script that's the one taking the "official" parameters.
(I'm likely to try out another IDE anyway)
With some editors you can define the 'execute' command,
For example with Geany, for Python files, F5 is python2.7 %f. That could be modified to something like python2.7 %f dummy parameters. But I use an attached terminal window and its line history more than F5 like commands.
I'm an Ipython user, so don't remember much about the IDLE configuration. In Ipython I usually use the %run magic, which is more like invoking the script from a shell than from an IDE. Ipython also has a better previous line history than the shell.
For larger scripts I like to put the guts of the code (classes, functions) in one file, and test code in the if __name__ block. The user interface is in another file that imports this core module.
Thanks for your question. I also searched for a way to do this. I found that Spyder which is the IDE I use has an option under Run/Configure to enter the command line parameters for running the program. You can even configure different ones for the different editors you have open.
Python tracker issue 5680 is a proposal to add to Idle a way to set command lines args for F5 Run module. You are free to test any of the proposed patches if you are able to apply them.
In the meanwhile conditionally extending sys.argv as done below should fulfill your requirements.
import sys
in __name__ == '__main__':
if 'idlelib.PyShell' in sys.modules:
sys.argv.extend(('a', '-2')) # add your argments here.
print(sys.argv) # in use, parse sys.argv after extending it
# ['C:\\Programs\\python34\\tem.py', 'a', '-2']

How can I use a simpler link syntax in org-mode?

I'd like to have links with the syntax [[foo bar]] go to files with the name foo bar.org. This would make using org-mode much more like using a personal local wiki.
Is this possible without breaking existing link functionality? I'd also ideally still be able to export to html, etc. with standard org-mode tools.
The best I've been able to do is something like: (setq org-link-abbrev-alist '(("o" . "file:%s.org")))
This lets me use the syntax [[o:foo bar]], but that is more verbose, and looks distractingly ugly inline. For example: The quick brown o:fox jumps over the o:lazy_dog. And [[o:foo bar][foo bar]] is even more verbose to type and edit (though it reads fine in org mode).
I don't have a ready made solution and am not a programmer, but this part is self-documenting in org.el, you can write a dedicated link search function. I cite:
"List of functions to execute a file search triggered by a link.
Functions added to this hook must accept a single argument, the search
string that was part of the file link, the part after the double
colon. The function must first check if it would like to handle this
search, for example by checking the `major-mode' or the file
extension. If it decides not to handle this search, it should just
return nil to give other functions a chance. If it does handle the
search, it must return a non-nil value to keep other functions from
trying.
Each function can access the current prefix argument through the
variable `current-prefix-arg'. Note that a single prefix is used to
force opening a link in Emacs, so it may be good to only use a numeric
or double prefix to guide the search function.
In case this is needed, a function in this hook can also restore the
window configuration before `org-open-at-point' was called using:
(set-window-configuration org-window-config-before-follow-link)")
See also Hyperlinks :: Custom Searches # gnu.org

how to "copy" existing completions to other commands in zsh

I have a custom script that takes hostnames as parameters. I know that I can easily copy the existing completion of ssh like this:
compdef myscript=ssh
But that only enables completion of the 1st parameter. Is there an easy way to enable the same completion for all parameters?
I'm not aware of an easy method to enable completion for a custom command. Assuming you've got a command foo with a bunch of allowable arguments bar, bas or baz, then the completion is easy: you can either have foo bar, foo bas, or foo baz. If they're not or'd, though, you could have any combination of the three.
It gets somewhat worse when you've got a 'depth' of more than 1 (bar can take arguments car, cas and caz, for example).
In zsh, my general understanding is that completion for commands is detailed in completion functions. These functions are application specific, because the arguments for each application are specific to those applications. As an example, the tmux (a terminal multiplexer, similar to screen, in case you're not familiar) has a completion function that's fairly complex: here's a link.
If you want to write your own completion functions, the documentation is available and accessible. Here are a bunch of links that I'm (slowly) working my way through - they'll definitely tell you how to get completion working, but there's a lot of reading. The Z-Shell is a complex beast.
Z-Shell completion introduction
Z-Shell functions: Writing and loading your own
ZSH Users Guide, Ch. 6: "Completion, old and new"
You're specifically interested in enabling completion for hostname-like arguments, and you've singled out ssh as the idea. The zsh completion function for ssh is defined in Completion/Unix/Command/_ssh, if you've got the ZSH source. If not, here's a link.
Of course, this SO question is rather similar. compdef alone may do what you want, if myscript and ssh parameters are identical enough.