141 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			141 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| Shell completion for CLI
 | ||
| ========================
 | ||
| 
 | ||
| This code generates shell completion scripts for hledger's command line
 | ||
| interface.
 | ||
| Shell completion is usually triggered by pressing the tab key once or twice
 | ||
| after typing the command `hledger `.
 | ||
| (The exact behavior may differ in shells other than Bash.)
 | ||
| 
 | ||
| Currently, only Bash is supported but Zsh or Fish can be added.
 | ||
| 
 | ||
| [](https://asciinema.org/a/227935)
 | ||
| 
 | ||
| The completions can handle hledger's CLI:
 | ||
| 
 | ||
| - commands and generic options
 | ||
| - command-specific options
 | ||
| - most option arguments
 | ||
| - account names, tags, payees, etc. from journal files
 | ||
| - query filter keywords like `status:`, `tag:`, or `amt:`
 | ||
| 
 | ||
| Installation for end users
 | ||
| --------------------------
 | ||
| 
 | ||
| Completions are currently only implemented for the Bash shell.
 | ||
| 
 | ||
| Please check first if the completions for hledger are already installed on your
 | ||
| distribution. Refer to the last paragraph of this section for how to test that.
 | ||
| 
 | ||
| To install from the repository, do:
 | ||
| 
 | ||
| ```sh
 | ||
| cd /path-to-repo/shell-completion
 | ||
| make install
 | ||
| ```
 | ||
| 
 | ||
| Completions installed this way will be loaded dynamically after you use the hledger
 | ||
| command. Upon the first invocation of a command that has no predefined completion
 | ||
| bash looks for a file with the same name in a set of predefined locations in this order:
 | ||
| 
 | ||
| - `$BASH_COMPLETION_USER_DIR/completions`
 | ||
| - `$XDG_DATA_HOME/bash-completion/completions`
 | ||
| - `$HOME/.local/share/bash-completion/completions`
 | ||
| - etc.
 | ||
| 
 | ||
| You can manually achieve the effects of `make install` by copying
 | ||
| `shell-completion/hledger-completion.bash` to one of the above, and renaming it
 | ||
| to `hledger`, `_hledger` or `hledger.bash`. For the gory details, type this in a
 | ||
| bash shell:
 | ||
| 
 | ||
| ```sh
 | ||
| type __load_completion
 | ||
| ```
 | ||
| 
 | ||
| To install the completions manually, you can also just download and copy
 | ||
| `shell-completion/hledger-completion.bash` to a directory of your choosing, and
 | ||
| source it from your shell start up files. This way completions are loaded
 | ||
| eagerly and that adds a delay to shell start up time.
 | ||
| 
 | ||
| Example:
 | ||
| 
 | ||
| ```sh
 | ||
| cp hledger-completion.bash ~/.bash_completion.d/hledger
 | ||
| echo 'source ~/.bash_completion.d/hledger' >> ~/.bashrc
 | ||
| # Restart shell
 | ||
| exec bash
 | ||
| # Confirm that completion is loaded
 | ||
| complete -p hledger
 | ||
| ```
 | ||
| 
 | ||
| Now, try it by typing `hledger` (with a space after the command) and press the
 | ||
| tab key twice. You should see a list of appropriate completions for hledger.
 | ||
| Then you can type a part of one of the suggestions and press tab again to
 | ||
| complete it.
 | ||
| 
 | ||
| Background
 | ||
| ----------
 | ||
| 
 | ||
| The Bash completion script is generated (GNU make) by parsing output of `hledger`,
 | ||
| `hledger -h`, and `hledger <cmd> -h`. The script also uses `hledger accounts` for
 | ||
| account name completion. I propose that the Makefile is not run at every built
 | ||
| but rather manually when the CLI changes.
 | ||
| 
 | ||
| Information for developers
 | ||
| --------------------------
 | ||
| 
 | ||
| Generate the completion script for Bash:
 | ||
| 
 | ||
| ```sh
 | ||
| # change into this folder:
 | ||
| cd shell-completion/
 | ||
| make
 | ||
| ```
 | ||
| 
 | ||
| Hint: GNU make and  GNU m4 must be installed to call `make`.
 | ||
| These are present on most systems anyway.
 | ||
| Additionally the build will run a lot faster with parallell jobs.
 | ||
| Use `make -j$(nproc)` for best effect.
 | ||
| 
 | ||
| The generated completion script must be installed. The package maintainer for
 | ||
| your distribution should be responsible for this.
 | ||
| 
 | ||
| For now, or to live-test the script, you can use these two commands:
 | ||
| 
 | ||
| ```sh
 | ||
| ln -s hledger-completion.bash ~/.hledger-completion.bash
 | ||
| echo 'source ~/.hledger-completion.bash' >> ~/.bashrc
 | ||
| ```
 | ||
| 
 | ||
| After that, you have to start a new Bash, e.g. by typing `bash` on the current
 | ||
| shell.
 | ||
| 
 | ||
| Now, try it by typing `hledger` (with a space after the command) and press the
 | ||
| tab key twice. You know how completions work – if not, see above in the
 | ||
| Installation section.
 | ||
| 
 | ||
| Completion scripts for other shells (e.g. Fish or Zsh)
 | ||
| ------------------------------------------------------
 | ||
| 
 | ||
| You're welcome to add completion scripts for other shells. It should not be too
 | ||
| hard! All available hledger options and commands are already there (generated by
 | ||
| the Makefile).
 | ||
| 
 | ||
| The generated text files with options and commands are: `commands.txt`,
 | ||
| `generic-options.txt`, and `options-*.txt` where `*` is the subcommand.
 | ||
| 
 | ||
| Instructions to add support for another shell:
 | ||
| 
 | ||
| 1. Create e.g. `hledger-completion.fish.m4` as a template file.
 | ||
| 
 | ||
| 2. Add a Make rule to transform it to `hledger-completion.fish`.
 | ||
| 
 | ||
| 3. Use m4 commands to include hledger options and commands into your script
 | ||
|    template. See `hledger-completion.bash.m4` as a reference.
 | ||
| 
 | ||
| 4. Use `make` and then `make hledger-completion.fish` to create and test the
 | ||
|    completion script.
 | ||
| 
 | ||
| 5. Finally, if everything is working, also add the generated artifact
 | ||
|    `hledger-completion.fish` to the repo so that people can use it directly.
 |