Project Level Shortcuts (pls) is a command-line tool designed to streamline your workflow by allowing you to create, manage, and execute custom aliases for frequently used commands. Say goodbye to messy bash profiles, and say hello to pls! 🐦
Run your most frequently used commands with ease, e.g. pls test to run tests, pls godot to open your Godot project and editor, pls open-here to open the current directory in your file manager, and whatever else you can think of!
-
Install
For advanced users, here's a quick guide to get pls working on your system.
# cd to directory that should house the pls script cd /path/to/pls/dir # download and make executable curl -sS https://raw.githubusercontent.com/codevogel/pls/main/release/pls > pls && chmod +x pls # add pls to your PATH echo 'export PATH="$PATH:/path/to/pls/dir"' >> ~/.bashrc -
Try in Docker
If you want to try pls without installing it on your own system first, you can use the following commands:
# cd to directory that should house the Dockerfile cd ./pls-test # download the Dockerfile curl -sS https://raw.githubusercontent.com/codevogel/pls/main/docker/Dockerfile > Dockerfile # build and run the Docker container docker build -t plsbuntu . --no-cache docker run -it plsbuntu
- Quick Start
- What is pls and why do I want pls?
- Getting started
- Command overview
- Execute commands in the main shell
- File format
- Command cache
- Configuration
- Roadmap
- Contributing
pls allows you to store your aliases in pls files. You can either define system-wide aliases in a global file, or place project-specific aliases in a local file, e.g., in the root of your project directory. The pls file (by default named .pls.yml) contains a list of aliases and their corresponding commands. When you run pls <alias>, the command associated with that alias is executed. Aliases from a local, project-specific context take precedence over aliases from the global, system-wide context, allowing you to reuse the same alias in different contexts. For example, if you have two projects that use different testing frameworks, pls allows you to just run pls test in either directory, reducing the need to remember framework-specific commands.
pls supports single-line and multi-line commands, as well as parameterized commands. Additionally, it caches the commands you run, and warns you when an alias points to an uncached command. This lets you be sure that you are only running the commands that you expect.
❓Why would I use pls?- Organized alias management: Instead of cluttering your shell profile with numerous aliases, pls lets you keep them organized in separate files, making it easier to manage and maintain your shortcuts.
- Context-aware aliases: pls allows you to have project-specific aliases that override global ones, enabling you to reuse common alias names (like "test") across different projects with varying implementations.
- Command cache verification: The command caching feature warns you when you're about to run a new or modified command, helping prevent accidental execution of potentially harmful commands.
- Portability and synchronization: Easily sync your aliases between different machines (e.g., work and home computers) by managing your .pls.yml files.
- Fuzzy command picker: The built-in alias picker (with optional fzf integration) makes it easy to find and execute aliases without remembering exact names.
- Parameterized commands: pls supports parameterized commands, allowing you to pass arguments to your aliases.
- Works with bash: pls is a lightweight shell script that works with any shell that supports bash syntax.
This is a quick guide to get pls working on your system. 🔧🐦
First, make sure you have the dependencies installed, then proceed to the instructions below.
- yq (tested with v4.44.2) - A lightweight and portable command-line YAML processor. (Installation instructions)
- Optional: fzf - A command-line fuzzy finder. (Installation instructions)
ℹ️ Note: fzf is completely optional. It is used only for the pick_alias command, which uses a fallback picker if you don't have fzf installed.
-
Download the pls script and extract it to a directory on your PATH (or add it to your PATH in step 2).
- using curl: curl -O https://raw.githubusercontent.com/codevogel/pls/main/release/pls
- using wget: wget https://raw.githubusercontent.com/codevogel/pls/main/release/pls
- Clone this repository and copy the release/pls script.
- Download the pls script from here manually.
-
Add the pls script to your PATH.
- If your shell is bash: echo 'export PATH="$PATH:/path/to/dir"' >> ~/.bashrc
- If your shell is zsh: echo 'export PATH="$PATH:/path/to/dir"' >> ~/.zshrc
- If your shell is something else, do the equivalent of the above.
-
Optionally, add support for running the commands in your main shell process. See the Use in main shell section for more information.
-
Test the installation by running pls --help.
-
To get started with pls, add your first alias. There are two approaches:
- Create a .pls.yml file and manually add the following contents (see 'File format' if you want to expand on it further):
commands: - alias: "hello" command: "echo 'Hello, World!'"
- Add an alias using the pls add command:
pls hello --add --command "echo 'Hello, World!'" --scope local
ℹ️ Note: As pls supports combining flags, this is a shorter equivalent of the above command:
pls hello -ac "echo 'Hello, World!'" -s local
- Create a .pls.yml file and manually add the following contents (see 'File format' if you want to expand on it further):
-
To execute the alias, run pls hello. You should first be prompted to confirm that you indeed want to run this command. Enter y or Y and press Return.
ℹ️ Note: When you execute the alias another time, pls will have cached usage of the command, and you will not be prompted until the command (or location of the file) changes.
❯ ./pls hello Alias 'hello' was found in '/home/codevogel/work/pls/.pls.yml', but this command seems new. echo 'Hello, World!' Are you sure you want to invoke the above command? [y/n] y Hello, World! ❯ ./pls hello Hello, World!ℹ️ Note: When you add the -p flag, the command will be printed instead of executed. This is useful if you want to run the command in your main shell process, or want to pipe the command to run in a different shell.
-
You can also leave out the alias, and pls will launch an interactive picker that lets you choose from a list of available aliases. Try it now, just run pls !
To keep the syntax for using pls as short as possible, and because we want to keep the namespace for aliases clean of commands, pls uses just a single root command: pls. This command can be followed by an alias, command arguments, or flags.
This is an overview of the flags that trigger pls to perform alternative operations (instead of the default operation: executing an alias). Each of these operation flags conflict with one another: you can only use one at a time.
--add | -a | --command --scope |
--force | Adds a new alias for a --command <command> to the pls file at a given --scope <[g]lobal, [l]ocal, [h]ere>. Use with --force to overwrite the alias if it exists. |
--delete | -d | --scope | Delete the alias from the pls file at given --scope <[g]lobal, [l]ocal, [h]ere>. |
|
--list | -l | --scope --print | List all aliases available in the current directory. Or, list aliases only from --scope <[g]lobal, [l]ocal, [a]ll>. Use with --print to print the command associated with each alias. |
These are the flags that do not represent operations. Some of them are used to provide additional information to operations, or to modify the behavior of the root command.
--command | yes | --add | Supplies a command to associate with the alias in the --add operation. Pass the command as a string, newline characters ('\n') are allowed. |
--scope | yes | --add --delete --list |
The selected scope for --add, --delete, and --list operations. Allowed scopes are [g]lobal, [l]ocal, [a]ll, [h]ere. The 'all' scope is exclusive to --list. The 'here' scope is excluded from --list. |
root command --list |
Prints the command instead of executing it when used with root command. Useful for piping to other commands or shells. Or, if used in conjunction with --list, it additionally prints the command for each alias. | ||
--force | --add | Overwrite the alias if it already exists when using the --add operation. | |
--clear-cache | Before doing anything, clears the cache of all commands that have been run with pls. | ||
--help | Show the help. | ||
--version | Show the version number. |
View EXAMPLES.md (here) to see some examples of how to use commands that pls provides.
Given the following .pls.yml:
We can now run the following commands:
If you want pls to execute the command in your main shell process, and your shell is bash, then you can simply add . or source in front of your pls command:
You could setup an alias for this in your .bashrc:
If your main shell is not bash, you can still use pls in your main shell process. Just know that the command will be executed in a bash subshell. If you want to execute the command in your main shell process, you can make use of the -p flag and eval. Here is an example for zsh, in which we set up a function plz that executes the command in the main shell process:
We create a zsh function at ~/.zshfuncs/plz
Then we load it in our .zshrc:
Now say we have the following in our .pls.yml file:
We can use plz in our zsh shell:
Here is a real-world example of how I load my development environment for a Godot project. In my global .pls.yml I have setup the following alias:
Now, whenever I sit down to work on my game, I just run plz godot and my project loads up, along with launching a new terminal with nvim open in the project directory.
pls uses YAML files to store aliases. YAML is a human-readable data serialization format that is easy to read and write, which should make adding commands a pretty straight-forward experience. An example of a properly formatted .pls.yml file is shown here:
A few points of interest here:
- The commands key should be the only root key of the YAML file, and must always be present. (This means that at minimum, a pls file should contain commands:)
- The commands key contains an array of objects (which may be empty), and can hold:
- An alias key that contains a single-line string representing the alias you want to use. (Spaces and symbols are allowed, but discouraged.)
- The command key that contains either a single-line or multi-line string containing the command you want to execute. Multi-line commands must be preceded by a | or |- character and indented.
- The command key can also contain a parameterized command, where $1, $2, etc. are replaced with the arguments passed to the alias.
ℹ️ Don't worry too much about remembering all this - if you break any of these rules, you should get an error when running pls, pointing you in the right direction to correct the formatting.
Each time you execute an alias, pls stores:
- The alias that was executed
- The exact command that was executed
- The path to the file where the alias was found
This allows pls to warn you when you try to execute an alias that points to a different command than the one you have previously executed. This is especially useful when you are working on a project with multiple collaborators (maybe someone has changed one of the aliases), or when you have multiple aliases with the same name in different directories.
ℹ️ If you want to be informed about the contents of the command, regardless of it being cached already, or if you want to turn off the warning altogether, see the PLS_ALWAYS_VERIFY and PLS_ENABLE_CACHE_CHECK environment variables in the Configuration section.
To clear the cache, you can run pls clear_cache.
pls can be configured using a .plsrc file, which is stored at the environment variable $PLS_RC. If you have not set $PLS_RC, then it will be created at $HOME/.config/pls/.plsrc by default, including the default values listed in the table below:
PLS_FILENAME | The name of the data file that pls looks for. | .pls.yml |
PLS_GLOBAL | The path to the global pls file (system-wide) | $HOME/$PLS_FILENAME |
PLS_ENABLE_CACHE_CHECK | If set to true, pls will check the cache for the command before executing it. | true |
PLS_ALWAYS_VERIFY | If set to true, pls will always prompt you to confirm the execution of the command, even if PLS_ENABLE_CACHE_CHECK is false | false |
PLS_ENABLE_FZF | If set to true, pls will use fzf as the picker (given that you have it installed). | N/A |
PLS_DIR | The directory where internal pls files are stored. Not recommended to place this in /tmp/ as that would delete the cache on reboot. | $HOME/local/.share/pls |
Make sure each of these variables is on a new line in the .plsrc file, and that you are not missing any. If in doubt, you can always delete the .plsrc file and pls will recreate it with the default values.
- Add support for single-line commands
- Add support for multi-line commands
- Add support for parameterized commands
- Add context-aware aliases
- Add command cache verification
- List available aliases
- Add alias picker
- Add .rc file
- Use pls with flags, preventing commands from taking up alias namespace.
- What else would you like to see? Let us know by opening an issue!
Please refer to the CONTRIBUTING.md file for more information on how to contribute to this project.