mirror of
https://github.com/ohmyzsh/ohmyzsh.git
synced 2024-11-19 21:41:07 +01:00
Merge branch 'ohmyzsh:master' into master
This commit is contained in:
commit
a4c3c67308
418 changed files with 12295 additions and 5099 deletions
|
@ -6,3 +6,6 @@ insert_final_newline = true
|
||||||
charset = utf-8
|
charset = utf-8
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
indent_style = space
|
indent_style = space
|
||||||
|
|
||||||
|
[*.py]
|
||||||
|
indent_size = 4
|
||||||
|
|
5
.github/CODEOWNERS
vendored
5
.github/CODEOWNERS
vendored
|
@ -1,11 +1,14 @@
|
||||||
# Plugin owners
|
# Plugin owners
|
||||||
plugins/archlinux/ @ratijas
|
plugins/archlinux/ @ratijas
|
||||||
plugins/aws/ @maksyms
|
plugins/dbt/ @msempere
|
||||||
|
plugins/eza/ @pepoluan
|
||||||
plugins/genpass/ @atoponce
|
plugins/genpass/ @atoponce
|
||||||
plugins/git-lfs/ @hellovietduc
|
plugins/git-lfs/ @hellovietduc
|
||||||
plugins/gitfast/ @felipec
|
plugins/gitfast/ @felipec
|
||||||
|
plugins/react-native @esthor
|
||||||
plugins/sdk/ @rgoldberg
|
plugins/sdk/ @rgoldberg
|
||||||
plugins/shell-proxy/ @septs
|
plugins/shell-proxy/ @septs
|
||||||
|
plugins/starship/ @axieax
|
||||||
plugins/universalarchive/ @Konfekt
|
plugins/universalarchive/ @Konfekt
|
||||||
plugins/wp-cli/ @joshmedeski
|
plugins/wp-cli/ @joshmedeski
|
||||||
plugins/zoxide/ @ajeetdsouza
|
plugins/zoxide/ @ajeetdsouza
|
||||||
|
|
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
|
@ -9,6 +9,7 @@
|
||||||
- [ ] The code is mine or it's from somewhere with an MIT-compatible license.
|
- [ ] The code is mine or it's from somewhere with an MIT-compatible license.
|
||||||
- [ ] The code is efficient, to the best of my ability, and does not waste computer resources.
|
- [ ] The code is efficient, to the best of my ability, and does not waste computer resources.
|
||||||
- [ ] The code is stable and I have tested it myself, to the best of my abilities.
|
- [ ] The code is stable and I have tested it myself, to the best of my abilities.
|
||||||
|
- [ ] If the code introduces new aliases, I provide a valid use case for all plugin users down below.
|
||||||
|
|
||||||
## Changes:
|
## Changes:
|
||||||
|
|
||||||
|
|
12
.github/dependabot.yml
vendored
Normal file
12
.github/dependabot.yml
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: github-actions
|
||||||
|
directory: /
|
||||||
|
schedule:
|
||||||
|
interval: "weekly"
|
||||||
|
day: "sunday"
|
||||||
|
- package-ecosystem: "pip"
|
||||||
|
directory: "/.github/workflows/dependencies"
|
||||||
|
schedule:
|
||||||
|
interval: "weekly"
|
||||||
|
day: "sunday"
|
46
.github/dependencies.yml
vendored
Normal file
46
.github/dependencies.yml
vendored
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
dependencies:
|
||||||
|
plugins/gitfast:
|
||||||
|
repo: felipec/git-completion
|
||||||
|
branch: master
|
||||||
|
version: tag:v2.1
|
||||||
|
postcopy: |
|
||||||
|
set -e
|
||||||
|
rm -rf git-completion.plugin.zsh Makefile README.adoc t tools
|
||||||
|
test -e git-completion.zsh && mv -f git-completion.zsh _git
|
||||||
|
plugins/z:
|
||||||
|
branch: master
|
||||||
|
repo: agkozak/zsh-z
|
||||||
|
version: afaf2965b41fdc6ca66066e09382726aa0b6aa04
|
||||||
|
precopy: |
|
||||||
|
set -e
|
||||||
|
test -e README.md && mv -f README.md MANUAL.md
|
||||||
|
postcopy: |
|
||||||
|
set -e
|
||||||
|
test -e _zshz && mv -f _zshz _z
|
||||||
|
test -e zsh-z.plugin.zsh && mv -f zsh-z.plugin.zsh z.plugin.zsh
|
||||||
|
plugins/history-substring-search:
|
||||||
|
repo: zsh-users/zsh-history-substring-search
|
||||||
|
branch: master
|
||||||
|
version: 87ce96b1862928d84b1afe7c173316614b30e301
|
||||||
|
precopy: |
|
||||||
|
set -e
|
||||||
|
rm -f zsh-history-substring-search.plugin.zsh
|
||||||
|
test -e zsh-history-substring-search.zsh && mv zsh-history-substring-search.zsh history-substring-search.zsh
|
||||||
|
postcopy: |
|
||||||
|
set -e
|
||||||
|
test -e dependencies/OMZ-README.md && cat dependencies/OMZ-README.md >> README.md
|
||||||
|
plugins/gradle:
|
||||||
|
repo: gradle/gradle-completion
|
||||||
|
branch: master
|
||||||
|
version: 25da917cf5a88f3e58f05be3868a7b2748c8afe6
|
||||||
|
precopy: |
|
||||||
|
set -e
|
||||||
|
find . ! -name _gradle ! -name LICENSE -delete
|
||||||
|
plugins/wd:
|
||||||
|
repo: mfaerevaag/wd
|
||||||
|
branch: master
|
||||||
|
version: tag:v0.7.1
|
||||||
|
precopy: |
|
||||||
|
set -e
|
||||||
|
rm -r test
|
||||||
|
rm install.sh tty.gif wd.1
|
36
.github/workflows/dependencies.yml
vendored
Normal file
36
.github/workflows/dependencies.yml
vendored
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
name: Update dependencies
|
||||||
|
on:
|
||||||
|
workflow_dispatch: {}
|
||||||
|
schedule:
|
||||||
|
- cron: "0 6 * * 0"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
check:
|
||||||
|
name: Check for updates
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: github.repository == 'ohmyzsh/ohmyzsh'
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- name: Authenticate as @ohmyzsh
|
||||||
|
id: generate_token
|
||||||
|
uses: ohmyzsh/github-app-token@v2
|
||||||
|
with:
|
||||||
|
app_id: ${{ secrets.OHMYZSH_APP_ID }}
|
||||||
|
private_key: ${{ secrets.OHMYZSH_APP_PRIVATE_KEY }}
|
||||||
|
- name: Setup Python
|
||||||
|
uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: "3.12"
|
||||||
|
cache: "pip"
|
||||||
|
- name: Process dependencies
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ steps.generate_token.outputs.token }}
|
||||||
|
GIT_APP_NAME: ohmyzsh[bot]
|
||||||
|
GIT_APP_EMAIL: 54982679+ohmyzsh[bot]@users.noreply.github.com
|
||||||
|
TMP_DIR: ${{ runner.temp }}
|
||||||
|
run: |
|
||||||
|
pip install -r .github/workflows/dependencies/requirements.txt
|
||||||
|
python3 .github/workflows/dependencies/updater.py
|
7
.github/workflows/dependencies/requirements.txt
vendored
Normal file
7
.github/workflows/dependencies/requirements.txt
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
certifi==2024.6.2
|
||||||
|
charset-normalizer==3.3.2
|
||||||
|
idna==3.7
|
||||||
|
PyYAML==6.0.1
|
||||||
|
requests==2.32.3
|
||||||
|
semver==3.0.2
|
||||||
|
urllib3==2.2.2
|
598
.github/workflows/dependencies/updater.py
vendored
Normal file
598
.github/workflows/dependencies/updater.py
vendored
Normal file
|
@ -0,0 +1,598 @@
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import timeit
|
||||||
|
from copy import deepcopy
|
||||||
|
from typing import Literal, NotRequired, Optional, TypedDict
|
||||||
|
|
||||||
|
import requests
|
||||||
|
import yaml
|
||||||
|
from semver import Version
|
||||||
|
|
||||||
|
# Get TMP_DIR variable from environment
|
||||||
|
TMP_DIR = os.path.join(os.environ.get("TMP_DIR", "/tmp"), "ohmyzsh")
|
||||||
|
# Relative path to dependencies.yml file
|
||||||
|
DEPS_YAML_FILE = ".github/dependencies.yml"
|
||||||
|
# Dry run flag
|
||||||
|
DRY_RUN = os.environ.get("DRY_RUN", "0") == "1"
|
||||||
|
|
||||||
|
# utils for tag comparison
|
||||||
|
BASEVERSION = re.compile(
|
||||||
|
r"""[vV]?
|
||||||
|
(?P<major>(0|[1-9])\d*)
|
||||||
|
(\.
|
||||||
|
(?P<minor>(0|[1-9])\d*)
|
||||||
|
(\.
|
||||||
|
(?P<patch>(0|[1-9])\d*)
|
||||||
|
)?
|
||||||
|
)?
|
||||||
|
""",
|
||||||
|
re.VERBOSE,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def coerce(version: str) -> Optional[Version]:
|
||||||
|
match = BASEVERSION.search(version)
|
||||||
|
if not match:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# BASEVERSION looks for `MAJOR.minor.patch` in the string given
|
||||||
|
# it fills with None if any of them is missing (for example `2.1`)
|
||||||
|
ver = {
|
||||||
|
key: 0 if value is None else value for key, value in match.groupdict().items()
|
||||||
|
}
|
||||||
|
# Version takes `major`, `minor`, `patch` arguments
|
||||||
|
ver = Version(**ver) # pyright: ignore[reportArgumentType]
|
||||||
|
return ver
|
||||||
|
|
||||||
|
|
||||||
|
class CodeTimer:
|
||||||
|
def __init__(self, name=None):
|
||||||
|
self.name = " '" + name + "'" if name else ""
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
self.start = timeit.default_timer()
|
||||||
|
|
||||||
|
def __exit__(self, exc_type, exc_value, traceback):
|
||||||
|
self.took = (timeit.default_timer() - self.start) * 1000.0
|
||||||
|
print("Code block" + self.name + " took: " + str(self.took) + " ms")
|
||||||
|
|
||||||
|
|
||||||
|
### YAML representation
|
||||||
|
def str_presenter(dumper, data):
|
||||||
|
"""
|
||||||
|
Configures yaml for dumping multiline strings
|
||||||
|
Ref: https://stackoverflow.com/a/33300001
|
||||||
|
"""
|
||||||
|
if len(data.splitlines()) > 1: # check for multiline string
|
||||||
|
return dumper.represent_scalar("tag:yaml.org,2002:str", data, style="|")
|
||||||
|
return dumper.represent_scalar("tag:yaml.org,2002:str", data)
|
||||||
|
|
||||||
|
|
||||||
|
yaml.add_representer(str, str_presenter)
|
||||||
|
yaml.representer.SafeRepresenter.add_representer(str, str_presenter)
|
||||||
|
|
||||||
|
|
||||||
|
# Types
|
||||||
|
class DependencyDict(TypedDict):
|
||||||
|
repo: str
|
||||||
|
branch: str
|
||||||
|
version: str
|
||||||
|
precopy: NotRequired[str]
|
||||||
|
postcopy: NotRequired[str]
|
||||||
|
|
||||||
|
|
||||||
|
class DependencyYAML(TypedDict):
|
||||||
|
dependencies: dict[str, DependencyDict]
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateStatusFalse(TypedDict):
|
||||||
|
has_updates: Literal[False]
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateStatusTrue(TypedDict):
|
||||||
|
has_updates: Literal[True]
|
||||||
|
version: str
|
||||||
|
compare_url: str
|
||||||
|
head_ref: str
|
||||||
|
head_url: str
|
||||||
|
|
||||||
|
|
||||||
|
class CommandRunner:
|
||||||
|
class Exception(Exception):
|
||||||
|
def __init__(self, message, returncode, stage, stdout, stderr):
|
||||||
|
super().__init__(message)
|
||||||
|
self.returncode = returncode
|
||||||
|
self.stage = stage
|
||||||
|
self.stdout = stdout
|
||||||
|
self.stderr = stderr
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def run_or_fail(command: list[str], stage: str, *args, **kwargs):
|
||||||
|
if DRY_RUN and command[0] == "gh":
|
||||||
|
command.insert(0, "echo")
|
||||||
|
|
||||||
|
result = subprocess.run(command, *args, capture_output=True, **kwargs)
|
||||||
|
|
||||||
|
if result.returncode != 0:
|
||||||
|
raise CommandRunner.Exception(
|
||||||
|
f"{stage} command failed with exit code {result.returncode}",
|
||||||
|
returncode=result.returncode,
|
||||||
|
stage=stage,
|
||||||
|
stdout=result.stdout.decode("utf-8"),
|
||||||
|
stderr=result.stderr.decode("utf-8"),
|
||||||
|
)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
class DependencyStore:
|
||||||
|
store: DependencyYAML = {"dependencies": {}}
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def set(data: DependencyYAML):
|
||||||
|
DependencyStore.store = data
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def update_dependency_version(path: str, version: str) -> DependencyYAML:
|
||||||
|
with CodeTimer(f"store deepcopy: {path}"):
|
||||||
|
store_copy = deepcopy(DependencyStore.store)
|
||||||
|
|
||||||
|
dependency = store_copy["dependencies"].get(path)
|
||||||
|
if dependency is None:
|
||||||
|
raise ValueError(f"Dependency {path} {version} not found")
|
||||||
|
dependency["version"] = version
|
||||||
|
store_copy["dependencies"][path] = dependency
|
||||||
|
|
||||||
|
return store_copy
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def write_store(file: str, data: DependencyYAML):
|
||||||
|
with open(file, "w") as yaml_file:
|
||||||
|
yaml.safe_dump(data, yaml_file, sort_keys=False)
|
||||||
|
|
||||||
|
|
||||||
|
class Dependency:
|
||||||
|
def __init__(self, path: str, values: DependencyDict):
|
||||||
|
self.path = path
|
||||||
|
self.values = values
|
||||||
|
|
||||||
|
self.name: str = ""
|
||||||
|
self.desc: str = ""
|
||||||
|
self.kind: str = ""
|
||||||
|
|
||||||
|
match path.split("/"):
|
||||||
|
case ["plugins", name]:
|
||||||
|
self.name = name
|
||||||
|
self.kind = "plugin"
|
||||||
|
self.desc = f"{name} plugin"
|
||||||
|
case ["themes", name]:
|
||||||
|
self.name = name.replace(".zsh-theme", "")
|
||||||
|
self.kind = "theme"
|
||||||
|
self.desc = f"{self.name} theme"
|
||||||
|
case _:
|
||||||
|
self.name = self.desc = path
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
output: str = ""
|
||||||
|
for key in DependencyDict.__dict__["__annotations__"].keys():
|
||||||
|
if key not in self.values:
|
||||||
|
output += f"{key}: None\n"
|
||||||
|
continue
|
||||||
|
|
||||||
|
value = self.values[key]
|
||||||
|
if "\n" not in value:
|
||||||
|
output += f"{key}: {value}\n"
|
||||||
|
else:
|
||||||
|
output += f"{key}:\n "
|
||||||
|
output += value.replace("\n", "\n ", value.count("\n") - 1)
|
||||||
|
return output
|
||||||
|
|
||||||
|
def update_or_notify(self):
|
||||||
|
# Print dependency settings
|
||||||
|
print(f"Processing {self.desc}...", file=sys.stderr)
|
||||||
|
print(self, file=sys.stderr)
|
||||||
|
|
||||||
|
# Check for updates
|
||||||
|
repo = self.values["repo"]
|
||||||
|
remote_branch = self.values["branch"]
|
||||||
|
version = self.values["version"]
|
||||||
|
is_tag = version.startswith("tag:")
|
||||||
|
|
||||||
|
try:
|
||||||
|
with CodeTimer(f"update check: {repo}"):
|
||||||
|
if is_tag:
|
||||||
|
status = GitHub.check_newer_tag(repo, version.replace("tag:", ""))
|
||||||
|
else:
|
||||||
|
status = GitHub.check_updates(repo, remote_branch, version)
|
||||||
|
|
||||||
|
if status["has_updates"] is True:
|
||||||
|
short_sha = status["head_ref"][:8]
|
||||||
|
new_version = status["version"] if is_tag else short_sha
|
||||||
|
|
||||||
|
try:
|
||||||
|
branch_name = f"update/{self.path}/{new_version}"
|
||||||
|
|
||||||
|
# Create new branch
|
||||||
|
branch = Git.checkout_or_create_branch(branch_name)
|
||||||
|
|
||||||
|
# Update dependencies.yml file
|
||||||
|
self.__update_yaml(
|
||||||
|
f"tag:{new_version}" if is_tag else status["version"]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Update dependency files
|
||||||
|
self.__apply_upstream_changes()
|
||||||
|
|
||||||
|
# Add all changes and commit
|
||||||
|
has_new_commit = Git.add_and_commit(self.name, short_sha)
|
||||||
|
|
||||||
|
if has_new_commit:
|
||||||
|
# Push changes to remote
|
||||||
|
Git.push(branch)
|
||||||
|
|
||||||
|
# Create GitHub PR
|
||||||
|
GitHub.create_pr(
|
||||||
|
branch,
|
||||||
|
f"feat({self.name}): update to version {new_version}",
|
||||||
|
f"""## Description
|
||||||
|
|
||||||
|
Update for **{self.desc}**: update to version [{new_version}]({status['head_url']}).
|
||||||
|
Check out the [list of changes]({status['compare_url']}).
|
||||||
|
""",
|
||||||
|
)
|
||||||
|
|
||||||
|
# Clean up repository
|
||||||
|
Git.clean_repo()
|
||||||
|
except (CommandRunner.Exception, shutil.Error) as e:
|
||||||
|
# Handle exception on automatic update
|
||||||
|
match type(e):
|
||||||
|
case CommandRunner.Exception:
|
||||||
|
# Print error message
|
||||||
|
print(
|
||||||
|
f"Error running {e.stage} command: {e.returncode}", # pyright: ignore[reportAttributeAccessIssue]
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
|
print(e.stderr, file=sys.stderr) # pyright: ignore[reportAttributeAccessIssue]
|
||||||
|
case shutil.Error:
|
||||||
|
print(f"Error copying files: {e}", file=sys.stderr)
|
||||||
|
|
||||||
|
try:
|
||||||
|
Git.clean_repo()
|
||||||
|
except CommandRunner.Exception as e:
|
||||||
|
print(
|
||||||
|
f"Error reverting repository to clean state: {e}",
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Create a GitHub issue to notify maintainer
|
||||||
|
title = f"{self.path}: update to {new_version}"
|
||||||
|
body = f"""## Description
|
||||||
|
|
||||||
|
There is a new version of `{self.name}` {self.kind} available.
|
||||||
|
|
||||||
|
New version: [{new_version}]({status['head_url']})
|
||||||
|
Check out the [list of changes]({status['compare_url']}).
|
||||||
|
"""
|
||||||
|
|
||||||
|
print("Creating GitHub issue", file=sys.stderr)
|
||||||
|
print(f"{title}\n\n{body}", file=sys.stderr)
|
||||||
|
GitHub.create_issue(title, body)
|
||||||
|
except Exception as e:
|
||||||
|
print(e, file=sys.stderr)
|
||||||
|
|
||||||
|
def __update_yaml(self, new_version: str) -> None:
|
||||||
|
dep_yaml = DependencyStore.update_dependency_version(self.path, new_version)
|
||||||
|
DependencyStore.write_store(DEPS_YAML_FILE, dep_yaml)
|
||||||
|
|
||||||
|
def __apply_upstream_changes(self) -> None:
|
||||||
|
# Patterns to ignore in copying files from upstream repo
|
||||||
|
GLOBAL_IGNORE = [".git", ".github", ".gitignore"]
|
||||||
|
|
||||||
|
path = os.path.abspath(self.path)
|
||||||
|
precopy = self.values.get("precopy")
|
||||||
|
postcopy = self.values.get("postcopy")
|
||||||
|
|
||||||
|
repo = self.values["repo"]
|
||||||
|
branch = self.values["branch"]
|
||||||
|
remote_url = f"https://github.com/{repo}.git"
|
||||||
|
repo_dir = os.path.join(TMP_DIR, repo)
|
||||||
|
|
||||||
|
# Clone repository
|
||||||
|
Git.clone(remote_url, branch, repo_dir, reclone=True)
|
||||||
|
|
||||||
|
# Run precopy on tmp repo
|
||||||
|
if precopy is not None:
|
||||||
|
print("Running precopy script:", end="\n ", file=sys.stderr)
|
||||||
|
print(
|
||||||
|
precopy.replace("\n", "\n ", precopy.count("\n") - 1), file=sys.stderr
|
||||||
|
)
|
||||||
|
CommandRunner.run_or_fail(
|
||||||
|
["bash", "-c", precopy], cwd=repo_dir, stage="Precopy"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Copy files from upstream repo
|
||||||
|
print(f"Copying files from {repo_dir} to {path}", file=sys.stderr)
|
||||||
|
shutil.copytree(
|
||||||
|
repo_dir,
|
||||||
|
path,
|
||||||
|
dirs_exist_ok=True,
|
||||||
|
ignore=shutil.ignore_patterns(*GLOBAL_IGNORE),
|
||||||
|
)
|
||||||
|
|
||||||
|
# Run postcopy on our repository
|
||||||
|
if postcopy is not None:
|
||||||
|
print("Running postcopy script:", end="\n ", file=sys.stderr)
|
||||||
|
print(
|
||||||
|
postcopy.replace("\n", "\n ", postcopy.count("\n") - 1),
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
|
CommandRunner.run_or_fail(
|
||||||
|
["bash", "-c", postcopy], cwd=path, stage="Postcopy"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class Git:
|
||||||
|
default_branch = "master"
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def clone(remote_url: str, branch: str, repo_dir: str, reclone=False):
|
||||||
|
# If repo needs to be fresh
|
||||||
|
if reclone and os.path.exists(repo_dir):
|
||||||
|
shutil.rmtree(repo_dir)
|
||||||
|
|
||||||
|
# Clone repo in tmp directory and checkout branch
|
||||||
|
if not os.path.exists(repo_dir):
|
||||||
|
print(
|
||||||
|
f"Cloning {remote_url} to {repo_dir} and checking out {branch}",
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
|
CommandRunner.run_or_fail(
|
||||||
|
["git", "clone", "--depth=1", "-b", branch, remote_url, repo_dir],
|
||||||
|
stage="Clone",
|
||||||
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def checkout_or_create_branch(branch_name: str):
|
||||||
|
# Get current branch name
|
||||||
|
result = CommandRunner.run_or_fail(
|
||||||
|
["git", "rev-parse", "--abbrev-ref", "HEAD"], stage="GetDefaultBranch"
|
||||||
|
)
|
||||||
|
Git.default_branch = result.stdout.decode("utf-8").strip()
|
||||||
|
|
||||||
|
# Create new branch and return created branch name
|
||||||
|
try:
|
||||||
|
# try to checkout already existing branch
|
||||||
|
CommandRunner.run_or_fail(
|
||||||
|
["git", "checkout", branch_name], stage="CreateBranch"
|
||||||
|
)
|
||||||
|
except CommandRunner.Exception:
|
||||||
|
# otherwise create new branch
|
||||||
|
CommandRunner.run_or_fail(
|
||||||
|
["git", "checkout", "-b", branch_name], stage="CreateBranch"
|
||||||
|
)
|
||||||
|
return branch_name
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def add_and_commit(scope: str, version: str) -> bool:
|
||||||
|
"""
|
||||||
|
Returns `True` if there were changes and were indeed commited.
|
||||||
|
Returns `False` if the repo was clean and no changes were commited.
|
||||||
|
"""
|
||||||
|
# check if repo is clean (clean => no error, no commit)
|
||||||
|
try:
|
||||||
|
CommandRunner.run_or_fail(
|
||||||
|
["git", "diff", "--exit-code"], stage="CheckRepoClean"
|
||||||
|
)
|
||||||
|
return False
|
||||||
|
except CommandRunner.Exception:
|
||||||
|
# if it's other kind of error just throw!
|
||||||
|
pass
|
||||||
|
|
||||||
|
user_name = os.environ.get("GIT_APP_NAME")
|
||||||
|
user_email = os.environ.get("GIT_APP_EMAIL")
|
||||||
|
|
||||||
|
# Add all files to git staging
|
||||||
|
CommandRunner.run_or_fail(["git", "add", "-A", "-v"], stage="AddFiles")
|
||||||
|
|
||||||
|
# Reset environment and git config
|
||||||
|
clean_env = os.environ.copy()
|
||||||
|
clean_env["LANG"] = "C.UTF-8"
|
||||||
|
clean_env["GIT_CONFIG_GLOBAL"] = "/dev/null"
|
||||||
|
clean_env["GIT_CONFIG_NOSYSTEM"] = "1"
|
||||||
|
|
||||||
|
# Commit with settings above
|
||||||
|
CommandRunner.run_or_fail(
|
||||||
|
[
|
||||||
|
"git",
|
||||||
|
"-c",
|
||||||
|
f"user.name={user_name}",
|
||||||
|
"-c",
|
||||||
|
f"user.email={user_email}",
|
||||||
|
"commit",
|
||||||
|
"-m",
|
||||||
|
f"feat({scope}): update to {version}",
|
||||||
|
],
|
||||||
|
stage="CreateCommit",
|
||||||
|
env=clean_env,
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def push(branch: str):
|
||||||
|
CommandRunner.run_or_fail(
|
||||||
|
["git", "push", "-u", "origin", branch], stage="PushBranch"
|
||||||
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def clean_repo():
|
||||||
|
CommandRunner.run_or_fail(
|
||||||
|
["git", "reset", "--hard", "HEAD"], stage="ResetRepository"
|
||||||
|
)
|
||||||
|
CommandRunner.run_or_fail(
|
||||||
|
["git", "checkout", Git.default_branch], stage="CheckoutDefaultBranch"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class GitHub:
|
||||||
|
@staticmethod
|
||||||
|
def check_newer_tag(repo, current_tag) -> UpdateStatusFalse | UpdateStatusTrue:
|
||||||
|
# GET /repos/:owner/:repo/git/refs/tags
|
||||||
|
url = f"https://api.github.com/repos/{repo}/git/refs/tags"
|
||||||
|
|
||||||
|
# Send a GET request to the GitHub API
|
||||||
|
response = requests.get(url)
|
||||||
|
current_version = coerce(current_tag)
|
||||||
|
if current_version is None:
|
||||||
|
raise ValueError(
|
||||||
|
f"Stored {current_version} from {repo} does not follow semver"
|
||||||
|
)
|
||||||
|
|
||||||
|
# If the request was successful
|
||||||
|
if response.status_code == 200:
|
||||||
|
# Parse the JSON response
|
||||||
|
data = response.json()
|
||||||
|
|
||||||
|
if len(data) == 0:
|
||||||
|
return {
|
||||||
|
"has_updates": False,
|
||||||
|
}
|
||||||
|
|
||||||
|
latest_ref = None
|
||||||
|
latest_version: Optional[Version] = None
|
||||||
|
for ref in data:
|
||||||
|
# we find the tag since GitHub returns it as plain git ref
|
||||||
|
tag_version = coerce(ref["ref"].replace("refs/tags/", ""))
|
||||||
|
if tag_version is None:
|
||||||
|
# we skip every tag that is not semver-complaint
|
||||||
|
continue
|
||||||
|
if latest_version is None or tag_version.compare(latest_version) > 0:
|
||||||
|
# if we have a "greater" semver version, set it as latest
|
||||||
|
latest_version = tag_version
|
||||||
|
latest_ref = ref
|
||||||
|
|
||||||
|
# raise if no valid semver tag is found
|
||||||
|
if latest_ref is None or latest_version is None:
|
||||||
|
raise ValueError(f"No tags following semver found in {repo}")
|
||||||
|
|
||||||
|
# we get the tag since GitHub returns it as plain git ref
|
||||||
|
latest_tag = latest_ref["ref"].replace("refs/tags/", "")
|
||||||
|
|
||||||
|
if latest_version.compare(current_version) <= 0:
|
||||||
|
return {
|
||||||
|
"has_updates": False,
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
"has_updates": True,
|
||||||
|
"version": latest_tag,
|
||||||
|
"compare_url": f"https://github.com/{repo}/compare/{current_tag}...{latest_tag}",
|
||||||
|
"head_ref": latest_ref["object"]["sha"],
|
||||||
|
"head_url": f"https://github.com/{repo}/releases/tag/{latest_tag}",
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
# If the request was not successful, raise an exception
|
||||||
|
raise Exception(
|
||||||
|
f"GitHub API request failed with status code {response.status_code}: {response.json()}"
|
||||||
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def check_updates(repo, branch, version) -> UpdateStatusFalse | UpdateStatusTrue:
|
||||||
|
url = f"https://api.github.com/repos/{repo}/compare/{version}...{branch}"
|
||||||
|
|
||||||
|
# Send a GET request to the GitHub API
|
||||||
|
response = requests.get(url)
|
||||||
|
|
||||||
|
# If the request was successful
|
||||||
|
if response.status_code == 200:
|
||||||
|
# Parse the JSON response
|
||||||
|
data = response.json()
|
||||||
|
|
||||||
|
# If the base is behind the head, there is a newer version
|
||||||
|
has_updates = data["status"] != "identical"
|
||||||
|
|
||||||
|
if not has_updates:
|
||||||
|
return {
|
||||||
|
"has_updates": False,
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
"has_updates": data["status"] != "identical",
|
||||||
|
"version": data["commits"][-1]["sha"],
|
||||||
|
"compare_url": data["permalink_url"],
|
||||||
|
"head_ref": data["commits"][-1]["sha"],
|
||||||
|
"head_url": data["commits"][-1]["html_url"],
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
# If the request was not successful, raise an exception
|
||||||
|
raise Exception(
|
||||||
|
f"GitHub API request failed with status code {response.status_code}: {response.json()}"
|
||||||
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def create_issue(title: str, body: str) -> None:
|
||||||
|
cmd = ["gh", "issue", "create", "-t", title, "-b", body]
|
||||||
|
CommandRunner.run_or_fail(cmd, stage="CreateIssue")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def create_pr(branch: str, title: str, body: str) -> None:
|
||||||
|
# first of all let's check if PR is already open
|
||||||
|
check_cmd = [
|
||||||
|
"gh",
|
||||||
|
"pr",
|
||||||
|
"list",
|
||||||
|
"--state",
|
||||||
|
"open",
|
||||||
|
"--head",
|
||||||
|
branch,
|
||||||
|
"--json",
|
||||||
|
"title",
|
||||||
|
]
|
||||||
|
# returncode is 0 also if no PRs are found
|
||||||
|
output = json.loads(
|
||||||
|
CommandRunner.run_or_fail(check_cmd, stage="CheckPullRequestOpen")
|
||||||
|
.stdout.decode("utf-8")
|
||||||
|
.strip()
|
||||||
|
)
|
||||||
|
# we have PR in this case!
|
||||||
|
if len(output) > 0:
|
||||||
|
return
|
||||||
|
cmd = [
|
||||||
|
"gh",
|
||||||
|
"pr",
|
||||||
|
"create",
|
||||||
|
"-B",
|
||||||
|
Git.default_branch,
|
||||||
|
"-H",
|
||||||
|
branch,
|
||||||
|
"-t",
|
||||||
|
title,
|
||||||
|
"-b",
|
||||||
|
body,
|
||||||
|
]
|
||||||
|
CommandRunner.run_or_fail(cmd, stage="CreatePullRequest")
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
# Load the YAML file
|
||||||
|
with open(DEPS_YAML_FILE, "r") as yaml_file:
|
||||||
|
data: DependencyYAML = yaml.safe_load(yaml_file)
|
||||||
|
|
||||||
|
if "dependencies" not in data:
|
||||||
|
raise Exception("dependencies.yml not properly formatted")
|
||||||
|
|
||||||
|
# Cache YAML version
|
||||||
|
DependencyStore.set(data)
|
||||||
|
|
||||||
|
dependencies = data["dependencies"]
|
||||||
|
for path in dependencies:
|
||||||
|
dependency = Dependency(path, dependencies[path])
|
||||||
|
dependency.update_or_notify()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
56
.github/workflows/installer.yml
vendored
Normal file
56
.github/workflows/installer.yml
vendored
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
name: Test and Deploy installer
|
||||||
|
on:
|
||||||
|
workflow_dispatch: {}
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- 'tools/install.sh'
|
||||||
|
- '.github/workflows/installer/**'
|
||||||
|
- '.github/workflows/installer.yml'
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||||
|
cancel-in-progress: false
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read # to checkout
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
name: Test installer
|
||||||
|
if: github.repository == 'ohmyzsh/ohmyzsh'
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os:
|
||||||
|
- ubuntu-latest
|
||||||
|
- macos-latest
|
||||||
|
steps:
|
||||||
|
- name: Set up git repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: Install zsh
|
||||||
|
if: runner.os == 'Linux'
|
||||||
|
run: sudo apt-get update; sudo apt-get install zsh
|
||||||
|
- name: Test installer
|
||||||
|
run: sh ./tools/install.sh
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
name: Deploy installer in install.ohmyz.sh
|
||||||
|
if: github.ref == 'refs/heads/master'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
environment: vercel
|
||||||
|
needs:
|
||||||
|
- test
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: Install Vercel CLI
|
||||||
|
run: npm install -g vercel
|
||||||
|
- name: Setup project and deploy
|
||||||
|
env:
|
||||||
|
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
|
||||||
|
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
|
||||||
|
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
|
||||||
|
run: |
|
||||||
|
cp tools/install.sh .github/workflows/installer/install.sh
|
||||||
|
cd .github/workflows/installer
|
||||||
|
vc deploy --prod -t "$VERCEL_TOKEN"
|
1
.github/workflows/installer/.gitignore
vendored
Normal file
1
.github/workflows/installer/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
install.sh
|
2
.github/workflows/installer/.vercelignore
vendored
Normal file
2
.github/workflows/installer/.vercelignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/*
|
||||||
|
!/install.sh
|
23
.github/workflows/installer/vercel.json
vendored
Normal file
23
.github/workflows/installer/vercel.json
vendored
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"headers": [
|
||||||
|
{
|
||||||
|
"source": "/((?!favicon.ico).*)",
|
||||||
|
"headers": [
|
||||||
|
{
|
||||||
|
"key": "Content-Type",
|
||||||
|
"value": "text/plain"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Content-Disposition",
|
||||||
|
"value": "inline; filename=\"install.sh\""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"rewrites": [
|
||||||
|
{
|
||||||
|
"source": "/((?!favicon.ico|install.sh).*)",
|
||||||
|
"destination": "/install.sh"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
13
.github/workflows/main.yml
vendored
13
.github/workflows/main.yml
vendored
|
@ -14,22 +14,19 @@ concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read # to fetch code (actions/checkout)
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
tests:
|
tests:
|
||||||
name: Run tests
|
name: Run tests
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ubuntu-latest
|
||||||
if: github.repository == 'ohmyzsh/ohmyzsh'
|
if: github.repository == 'ohmyzsh/ohmyzsh'
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
os: [ubuntu-latest, macos-latest]
|
|
||||||
steps:
|
steps:
|
||||||
- name: Set up git repository
|
- name: Set up git repository
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v4
|
||||||
- name: Install zsh
|
- name: Install zsh
|
||||||
if: runner.os == 'Linux'
|
|
||||||
run: sudo apt-get update; sudo apt-get install zsh
|
run: sudo apt-get update; sudo apt-get install zsh
|
||||||
- name: Test installer
|
|
||||||
run: sh ./tools/install.sh
|
|
||||||
- name: Check syntax
|
- name: Check syntax
|
||||||
run: |
|
run: |
|
||||||
for file in ./oh-my-zsh.sh \
|
for file in ./oh-my-zsh.sh \
|
||||||
|
|
51
.github/workflows/project.yml
vendored
51
.github/workflows/project.yml
vendored
|
@ -9,14 +9,21 @@ concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
permissions: {}
|
||||||
jobs:
|
jobs:
|
||||||
add-to-project:
|
add-to-project:
|
||||||
name: Add to project
|
name: Add to project
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: github.repository == 'ohmyzsh/ohmyzsh'
|
if: github.repository == 'ohmyzsh/ohmyzsh'
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.PROJECT_TOKEN }}
|
|
||||||
steps:
|
steps:
|
||||||
|
- name: Authenticate as @ohmyzsh
|
||||||
|
id: generate_token
|
||||||
|
uses: ohmyzsh/github-app-token@v2
|
||||||
|
with:
|
||||||
|
app_id: ${{ secrets.OHMYZSH_APP_ID }}
|
||||||
|
private_key: ${{ secrets.OHMYZSH_APP_PRIVATE_KEY }}
|
||||||
|
- name: Store app token
|
||||||
|
run: echo "GH_TOKEN=${{ steps.generate_token.outputs.token }}" >> "$GITHUB_ENV"
|
||||||
- name: Read project data
|
- name: Read project data
|
||||||
env:
|
env:
|
||||||
ORGANIZATION: ohmyzsh
|
ORGANIZATION: ohmyzsh
|
||||||
|
@ -26,24 +33,25 @@ jobs:
|
||||||
gh api graphql -f query='
|
gh api graphql -f query='
|
||||||
query($org: String!, $number: Int!) {
|
query($org: String!, $number: Int!) {
|
||||||
organization(login: $org){
|
organization(login: $org){
|
||||||
projectNext(number: $number) {
|
projectV2(number: $number) {
|
||||||
id
|
id
|
||||||
fields(first:20) {
|
fields(first:20) {
|
||||||
nodes {
|
nodes {
|
||||||
id
|
... on ProjectV2Field {
|
||||||
name
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}' -f org=$ORGANIZATION -F number=$PROJECT_NUMBER > project_data.json
|
||||||
' -f org=$ORGANIZATION -F number=$PROJECT_NUMBER > project_data.json
|
|
||||||
|
|
||||||
# Parse project data
|
# Parse project data
|
||||||
cat >> $GITHUB_ENV <<EOF
|
cat >> $GITHUB_ENV <<EOF
|
||||||
PROJECT_ID=$(jq '.data.organization.projectNext.id' project_data.json)
|
PROJECT_ID=$(jq '.data.organization.projectV2.id' project_data.json)
|
||||||
PLUGIN_FIELD_ID=$(jq '.data.organization.projectNext.fields.nodes[] | select(.name == "Plugin") | .id' project_data.json)
|
PLUGIN_FIELD_ID=$(jq '.data.organization.projectV2.fields.nodes[] | select(.name == "Plugin") | .id' project_data.json)
|
||||||
THEME_FIELD_ID=$(jq '.data.organization.projectNext.fields.nodes[] | select(.name == "Theme") | .id' project_data.json)
|
THEME_FIELD_ID=$(jq '.data.organization.projectV2.fields.nodes[] | select(.name == "Theme") | .id' project_data.json)
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
- name: Add to project
|
- name: Add to project
|
||||||
|
@ -52,13 +60,13 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
item_id="$(gh api graphql -f query='
|
item_id="$(gh api graphql -f query='
|
||||||
mutation($project: ID!, $content: ID!) {
|
mutation($project: ID!, $content: ID!) {
|
||||||
addProjectNextItem(input: {projectId: $project, contentId: $content}) {
|
addProjectV2ItemById(input: {projectId: $project, contentId: $content}) {
|
||||||
projectNextItem {
|
item {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
' -f project=$PROJECT_ID -f content=$ISSUE_OR_PR_ID --jq '.data.addProjectNextItem.projectNextItem.id')"
|
' -f project=$PROJECT_ID -f content=$ISSUE_OR_PR_ID --jq '.data.addProjectV2ItemById.item.id')"
|
||||||
|
|
||||||
echo "ITEM_ID=$item_id" >> $GITHUB_ENV
|
echo "ITEM_ID=$item_id" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
@ -107,23 +115,27 @@ jobs:
|
||||||
$theme_field: ID!
|
$theme_field: ID!
|
||||||
$theme_value: String!
|
$theme_value: String!
|
||||||
) {
|
) {
|
||||||
set_plugin: updateProjectNextItemField(input: {
|
set_plugin: updateProjectV2ItemFieldValue(input: {
|
||||||
projectId: $project
|
projectId: $project
|
||||||
itemId: $item
|
itemId: $item
|
||||||
fieldId: $plugin_field
|
fieldId: $plugin_field
|
||||||
value: $plugin_value
|
value: {
|
||||||
|
text: $plugin_value
|
||||||
|
}
|
||||||
}) {
|
}) {
|
||||||
projectNextItem {
|
projectV2Item {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
set_theme: updateProjectNextItemField(input: {
|
set_theme: updateProjectV2ItemFieldValue(input: {
|
||||||
projectId: $project
|
projectId: $project
|
||||||
itemId: $item
|
itemId: $item
|
||||||
fieldId: $theme_field
|
fieldId: $theme_field
|
||||||
value: $theme_value
|
value: {
|
||||||
|
text: $theme_value
|
||||||
|
}
|
||||||
}) {
|
}) {
|
||||||
projectNextItem {
|
projectV2Item {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,4 +144,3 @@ jobs:
|
||||||
-f plugin_field=$PLUGIN_FIELD_ID -f plugin_value=$PLUGIN \
|
-f plugin_field=$PLUGIN_FIELD_ID -f plugin_value=$PLUGIN \
|
||||||
-f theme_field=$THEME_FIELD_ID -f theme_value=$THEME \
|
-f theme_field=$THEME_FIELD_ID -f theme_value=$THEME \
|
||||||
--silent
|
--silent
|
||||||
|
|
||||||
|
|
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -6,3 +6,7 @@ cache/
|
||||||
log/
|
log/
|
||||||
*.swp
|
*.swp
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
|
# editor configs
|
||||||
|
.vscode
|
||||||
|
.idea
|
||||||
|
|
4
.prettierrc
Normal file
4
.prettierrc
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"printWidth": 110,
|
||||||
|
"proseWrap": "always"
|
||||||
|
}
|
|
@ -35,13 +35,13 @@ you would make is not already covered.
|
||||||
Please be so kind as to [search](#use-the-search-luke) for any open issue already covering
|
Please be so kind as to [search](#use-the-search-luke) for any open issue already covering
|
||||||
your problem.
|
your problem.
|
||||||
|
|
||||||
If you find one, comment on it so we can know there are more people experiencing it.
|
If you find one, comment on it, so we know more people are experiencing it.
|
||||||
|
|
||||||
If not, look at the [Troubleshooting](https://github.com/ohmyzsh/ohmyzsh/wiki/Troubleshooting)
|
If not, look at the [Troubleshooting](https://github.com/ohmyzsh/ohmyzsh/wiki/Troubleshooting)
|
||||||
page for instructions on how to gather data to better debug your problem.
|
page for instructions on how to gather data to better debug your problem.
|
||||||
|
|
||||||
Then, you can go ahead and create an issue with as much detail as you can provide.
|
Then, you can go ahead and create an issue with as much detail as you can provide.
|
||||||
It should include the data gathered as indicated above, along with:
|
It should include the data gathered as indicated above, along with the following:
|
||||||
|
|
||||||
1. How to reproduce the problem
|
1. How to reproduce the problem
|
||||||
2. What the correct behavior should be
|
2. What the correct behavior should be
|
||||||
|
@ -57,7 +57,7 @@ We will do our very best to help you.
|
||||||
Please be so kind as to [search](#use-the-search-luke) for any open issue already covering
|
Please be so kind as to [search](#use-the-search-luke) for any open issue already covering
|
||||||
your suggestion.
|
your suggestion.
|
||||||
|
|
||||||
If you find one, comment on it so we can know there are more people supporting it.
|
If you find one, comment on it, so we know more people are supporting it.
|
||||||
|
|
||||||
If not, you can go ahead and create an issue. Please copy to anyone relevant (e.g. plugin
|
If not, you can go ahead and create an issue. Please copy to anyone relevant (e.g. plugin
|
||||||
maintainers) by mentioning their GitHub handle (starting with `@`) in your message.
|
maintainers) by mentioning their GitHub handle (starting with `@`) in your message.
|
||||||
|
@ -84,7 +84,7 @@ your [problem](#you-have-a-problem), and any pending/merged/rejected PR covering
|
||||||
|
|
||||||
If the solution is already reported, try it out and +1 the pull request if the
|
If the solution is already reported, try it out and +1 the pull request if the
|
||||||
solution works ok. On the other hand, if you think your solution is better, post
|
solution works ok. On the other hand, if you think your solution is better, post
|
||||||
it with a reference to the other one so we can have both solutions to compare.
|
it with reference to the other one so we can have both solutions to compare.
|
||||||
|
|
||||||
If not, then go ahead and submit a PR. Please copy to anyone relevant (e.g. plugin
|
If not, then go ahead and submit a PR. Please copy to anyone relevant (e.g. plugin
|
||||||
maintainers) by mentioning their GitHub handle (starting with `@`) in your message.
|
maintainers) by mentioning their GitHub handle (starting with `@`) in your message.
|
||||||
|
@ -104,6 +104,27 @@ maintainers) by mentioning their GitHub handle (starting with `@`) in your messa
|
||||||
|
|
||||||
For any extensive change, such as a new plugin, you will have to find testers to +1 your PR.
|
For any extensive change, such as a new plugin, you will have to find testers to +1 your PR.
|
||||||
|
|
||||||
|
### New plugin aliases
|
||||||
|
|
||||||
|
We acknowledge that aliases are a core part of Oh My Zsh. There are plugins that have +100 aliases!
|
||||||
|
|
||||||
|
This has become an issue for two opposing reasons:
|
||||||
|
|
||||||
|
- Some users want to have their personal aliases in Oh My Zsh.
|
||||||
|
- Some users don't want any aliases at all and feel that there are too many.
|
||||||
|
|
||||||
|
Because of this, from now on, we require that new aliases follow these conditions:
|
||||||
|
|
||||||
|
1. They will be used by many people, not just a few.
|
||||||
|
2. The aliases will be used many times and for common tasks.
|
||||||
|
3. Prefer one generic alias over many specific ones.
|
||||||
|
4. When justifying the need for an alias, talk about workflows where you'll use it,
|
||||||
|
preferably in combination with other aliases.
|
||||||
|
5. If a command with the same name exists, look for a different alias name.
|
||||||
|
|
||||||
|
This list is not exhaustive! Please remember that your alias will be in the machines of many people,
|
||||||
|
so it should be justified why they should have it.
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
## Use the Search, Luke
|
## Use the Search, Luke
|
||||||
|
@ -193,7 +214,7 @@ type(scope)!: subject
|
||||||
```
|
```
|
||||||
|
|
||||||
- `subject`: a brief description of the changes. This will be displayed in the changelog. If you need
|
- `subject`: a brief description of the changes. This will be displayed in the changelog. If you need
|
||||||
to specify other details you can use the commit body but it won't be visible.
|
to specify other details, you can use the commit body, but it won't be visible.
|
||||||
|
|
||||||
Formatting tricks: the commit subject may contain:
|
Formatting tricks: the commit subject may contain:
|
||||||
|
|
||||||
|
@ -210,9 +231,9 @@ type(scope)!: subject
|
||||||
|
|
||||||
### Style
|
### Style
|
||||||
|
|
||||||
Try to keep the first commit line short. This is harder to do using this commit style but try to be
|
Try to keep the first commit line short. It's harder to do using this commit style but try to be
|
||||||
concise and if you need more space, you can use the commit body. Try to make sure that the commit
|
concise, and if you need more space, you can use the commit body. Try to make sure that the commit
|
||||||
subject is clear and precise enough that users will know what change by just looking at the changelog.
|
subject is clear and precise enough that users will know what changed by just looking at the changelog.
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
|
|
174
README.md
174
README.md
|
@ -10,41 +10,46 @@ Once installed, your terminal shell will become the talk of the town _or your mo
|
||||||
|
|
||||||
Finally, you'll begin to get the sort of attention that you have always felt you deserved. ...or maybe you'll use the time that you're saving to start flossing more often. 😬
|
Finally, you'll begin to get the sort of attention that you have always felt you deserved. ...or maybe you'll use the time that you're saving to start flossing more often. 😬
|
||||||
|
|
||||||
To learn more, visit [ohmyz.sh](https://ohmyz.sh), follow [@ohmyzsh](https://twitter.com/ohmyzsh) on Twitter, and join us on [Discord](https://discord.gg/ohmyzsh).
|
To learn more, visit [ohmyz.sh](https://ohmyz.sh), follow [@ohmyzsh](https://x.com/ohmyzsh) on X (formerly Twitter), and join us on [Discord](https://discord.gg/ohmyzsh).
|
||||||
|
|
||||||
[![CI](https://github.com/ohmyzsh/ohmyzsh/workflows/CI/badge.svg)](https://github.com/ohmyzsh/ohmyzsh/actions?query=workflow%3ACI)
|
[![CI](https://github.com/ohmyzsh/ohmyzsh/workflows/CI/badge.svg)](https://github.com/ohmyzsh/ohmyzsh/actions?query=workflow%3ACI)
|
||||||
[![Follow @ohmyzsh](https://img.shields.io/twitter/follow/ohmyzsh?label=Follow+@ohmyzsh&style=flat)](https://twitter.com/intent/follow?screen_name=ohmyzsh)
|
[![X (formerly Twitter) Follow](https://img.shields.io/twitter/follow/ohmyzsh?label=%40ohmyzsh&logo=x&style=flat)](https://twitter.com/intent/follow?screen_name=ohmyzsh)
|
||||||
|
[![Mastodon Follow](https://img.shields.io/mastodon/follow/111169632522566717?label=%40ohmyzsh&domain=https%3A%2F%2Fmstdn.social&logo=mastodon&style=flat)](https://mstdn.social/@ohmyzsh)
|
||||||
[![Discord server](https://img.shields.io/discord/642496866407284746)](https://discord.gg/ohmyzsh)
|
[![Discord server](https://img.shields.io/discord/642496866407284746)](https://discord.gg/ohmyzsh)
|
||||||
[![Gitpod ready](https://img.shields.io/badge/Gitpod-ready-blue?logo=gitpod)](https://gitpod.io/#https://github.com/ohmyzsh/ohmyzsh)
|
[![Gitpod ready](https://img.shields.io/badge/Gitpod-ready-blue?logo=gitpod)](https://gitpod.io/#https://github.com/ohmyzsh/ohmyzsh)
|
||||||
[![huntr.dev](https://cdn.huntr.dev/huntr_security_badge_mono.svg)](https://huntr.dev/bounties/disclose/?utm_campaign=ohmyzsh%2Fohmyzsh&utm_medium=social&utm_source=github&target=https%3A%2F%2Fgithub.com%2Fohmyzsh%2Fohmyzsh)
|
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>Table of Contents</summary>
|
<summary>Table of Contents</summary>
|
||||||
|
|
||||||
- [Getting Started](#getting-started)
|
- [Getting Started](#getting-started)
|
||||||
|
- [Operating System Compatibility](#operating-system-compatibility)
|
||||||
- [Prerequisites](#prerequisites)
|
- [Prerequisites](#prerequisites)
|
||||||
- [Basic Installation](#basic-installation)
|
- [Basic Installation](#basic-installation)
|
||||||
- [Manual inspection](#manual-inspection)
|
- [Manual Inspection](#manual-inspection)
|
||||||
- [Using Oh My Zsh](#using-oh-my-zsh)
|
- [Using Oh My Zsh](#using-oh-my-zsh)
|
||||||
- [Plugins](#plugins)
|
- [Plugins](#plugins)
|
||||||
- [Enabling Plugins](#enabling-plugins)
|
- [Enabling Plugins](#enabling-plugins)
|
||||||
- [Using Plugins](#using-plugins)
|
- [Using Plugins](#using-plugins)
|
||||||
- [Themes](#themes)
|
- [Themes](#themes)
|
||||||
- [Selecting a Theme](#selecting-a-theme)
|
- [Selecting A Theme](#selecting-a-theme)
|
||||||
- [FAQ](#faq)
|
- [FAQ](#faq)
|
||||||
- [Advanced Topics](#advanced-topics)
|
- [Advanced Topics](#advanced-topics)
|
||||||
- [Advanced Installation](#advanced-installation)
|
- [Advanced Installation](#advanced-installation)
|
||||||
- [Custom Directory](#custom-directory)
|
- [Custom Directory](#custom-directory)
|
||||||
- [Unattended install](#unattended-install)
|
- [Unattended Install](#unattended-install)
|
||||||
- [Installing from a forked repository](#installing-from-a-forked-repository)
|
- [Installing From A Forked Repository](#installing-from-a-forked-repository)
|
||||||
- [Manual Installation](#manual-installation)
|
- [Manual Installation](#manual-installation)
|
||||||
- [Installation Problems](#installation-problems)
|
- [Installation Problems](#installation-problems)
|
||||||
- [Custom Plugins and Themes](#custom-plugins-and-themes)
|
- [Custom Plugins And Themes](#custom-plugins-and-themes)
|
||||||
|
- [Enable GNU ls In macOS And freeBSD Systems](#enable-gnu-ls-in-macos-and-freebsd-systems)
|
||||||
|
- [Skip Aliases](#skip-aliases)
|
||||||
|
- [Disable async git prompt](#disable-async-git-prompt)
|
||||||
- [Getting Updates](#getting-updates)
|
- [Getting Updates](#getting-updates)
|
||||||
|
- [Updates Verbosity](#updates-verbosity)
|
||||||
- [Manual Updates](#manual-updates)
|
- [Manual Updates](#manual-updates)
|
||||||
- [Uninstalling Oh My Zsh](#uninstalling-oh-my-zsh)
|
- [Uninstalling Oh My Zsh](#uninstalling-oh-my-zsh)
|
||||||
- [How do I contribute to Oh My Zsh?](#how-do-i-contribute-to-oh-my-zsh)
|
- [How Do I Contribute To Oh My Zsh?](#how-do-i-contribute-to-oh-my-zsh)
|
||||||
- [Do NOT send us themes](#do-not-send-us-themes)
|
- [Do Not Send Us Themes](#do-not-send-us-themes)
|
||||||
- [Contributors](#contributors)
|
- [Contributors](#contributors)
|
||||||
- [Follow Us](#follow-us)
|
- [Follow Us](#follow-us)
|
||||||
- [Merchandise](#merchandise)
|
- [Merchandise](#merchandise)
|
||||||
|
@ -55,9 +60,21 @@ To learn more, visit [ohmyz.sh](https://ohmyz.sh), follow [@ohmyzsh](https://twi
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
|
### Operating System Compatibility
|
||||||
|
|
||||||
|
| O/S | Status |
|
||||||
|
| :------------- | :-----: |
|
||||||
|
| Android | ✅ |
|
||||||
|
| freeBSD | ✅ |
|
||||||
|
| LCARS | 🛸 |
|
||||||
|
| Linux | ✅ |
|
||||||
|
| macOS | ✅ |
|
||||||
|
| OS/2 Warp | ❌ |
|
||||||
|
| Windows (WSL2) | ✅ |
|
||||||
|
|
||||||
|
|
||||||
### Prerequisites
|
### Prerequisites
|
||||||
|
|
||||||
- A Unix-like operating system: macOS, Linux, BSD. On Windows: WSL2 is preferred, but cygwin or msys also mostly work.
|
|
||||||
- [Zsh](https://www.zsh.org) should be installed (v4.3.9 or more recent is fine but we prefer 5.0.8 and newer). If not pre-installed (run `zsh --version` to confirm), check the following wiki instructions here: [Installing ZSH](https://github.com/ohmyzsh/ohmyzsh/wiki/Installing-ZSH)
|
- [Zsh](https://www.zsh.org) should be installed (v4.3.9 or more recent is fine but we prefer 5.0.8 and newer). If not pre-installed (run `zsh --version` to confirm), check the following wiki instructions here: [Installing ZSH](https://github.com/ohmyzsh/ohmyzsh/wiki/Installing-ZSH)
|
||||||
- `curl` or `wget` should be installed
|
- `curl` or `wget` should be installed
|
||||||
- `git` should be installed (recommended v2.4.11 or higher)
|
- `git` should be installed (recommended v2.4.11 or higher)
|
||||||
|
@ -72,9 +89,17 @@ Oh My Zsh is installed by running one of the following commands in your terminal
|
||||||
| **wget** | `sh -c "$(wget -O- https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"` |
|
| **wget** | `sh -c "$(wget -O- https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"` |
|
||||||
| **fetch** | `sh -c "$(fetch -o - https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"` |
|
| **fetch** | `sh -c "$(fetch -o - https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"` |
|
||||||
|
|
||||||
|
Alternatively, the installer is also mirrored outside GitHub. Using this URL instead may be required if you're in a country like China or India (for certain ISPs), that blocks `raw.githubusercontent.com`:
|
||||||
|
|
||||||
|
| Method | Command |
|
||||||
|
| :-------- | :------------------------------------------------------------------------------------------------ |
|
||||||
|
| **curl** | `sh -c "$(curl -fsSL https://install.ohmyz.sh/)"` |
|
||||||
|
| **wget** | `sh -c "$(wget -O- https://install.ohmyz.sh/)"` |
|
||||||
|
| **fetch** | `sh -c "$(fetch -o - https://install.ohmyz.sh/)"` |
|
||||||
|
|
||||||
_Note that any previous `.zshrc` will be renamed to `.zshrc.pre-oh-my-zsh`. After installation, you can move the configuration you want to preserve into the new `.zshrc`._
|
_Note that any previous `.zshrc` will be renamed to `.zshrc.pre-oh-my-zsh`. After installation, you can move the configuration you want to preserve into the new `.zshrc`._
|
||||||
|
|
||||||
#### Manual inspection
|
#### Manual Inspection
|
||||||
|
|
||||||
It's a good idea to inspect the install script from projects you don't yet know. You can do
|
It's a good idea to inspect the install script from projects you don't yet know. You can do
|
||||||
that by downloading the install script first, looking through it so everything looks normal,
|
that by downloading the install script first, looking through it so everything looks normal,
|
||||||
|
@ -85,6 +110,8 @@ wget https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh
|
||||||
sh install.sh
|
sh install.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
|
If the above URL times out or otherwise fails, you may have to substitute the URL for `https://install.ohmyz.sh` to be able to get the script.
|
||||||
|
|
||||||
## Using Oh My Zsh
|
## Using Oh My Zsh
|
||||||
|
|
||||||
### Plugins
|
### Plugins
|
||||||
|
@ -123,7 +150,7 @@ Each built-in plugin includes a **README**, documenting it. This README should s
|
||||||
|
|
||||||
We'll admit it. Early in the Oh My Zsh world, we may have gotten a bit too theme happy. We have over one hundred and fifty themes now bundled. Most of them have [screenshots](https://github.com/ohmyzsh/ohmyzsh/wiki/Themes) on the wiki (We are working on updating this!). Check them out!
|
We'll admit it. Early in the Oh My Zsh world, we may have gotten a bit too theme happy. We have over one hundred and fifty themes now bundled. Most of them have [screenshots](https://github.com/ohmyzsh/ohmyzsh/wiki/Themes) on the wiki (We are working on updating this!). Check them out!
|
||||||
|
|
||||||
#### Selecting a Theme
|
#### Selecting A Theme
|
||||||
|
|
||||||
_Robby's theme is the default one. It's not the fanciest one. It's not the simplest one. It's just the right one (for him)._
|
_Robby's theme is the default one. It's not the fanciest one. It's not the simplest one. It's just the right one (for him)._
|
||||||
|
|
||||||
|
@ -194,7 +221,7 @@ like this:
|
||||||
ZSH="$HOME/.dotfiles/oh-my-zsh" sh install.sh
|
ZSH="$HOME/.dotfiles/oh-my-zsh" sh install.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Unattended install
|
#### Unattended Install
|
||||||
|
|
||||||
If you're running the Oh My Zsh install script as part of an automated install, you can pass the `--unattended`
|
If you're running the Oh My Zsh install script as part of an automated install, you can pass the `--unattended`
|
||||||
flag to the `install.sh` script. This will have the effect of not trying to change
|
flag to the `install.sh` script. This will have the effect of not trying to change
|
||||||
|
@ -204,9 +231,11 @@ the default shell, and it also won't run `zsh` when the installation has finishe
|
||||||
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended
|
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Installing from a forked repository
|
If you're in China, India, or another country that blocks `raw.githubusercontent.com`, you may have to substitute the URL for `https://install.ohmyz.sh` for it to install.
|
||||||
|
|
||||||
The install script also accepts these variables to allow installation of a different repository:
|
#### Installing From A Forked Repository
|
||||||
|
|
||||||
|
The install script also accepts these variables to allow the installation of a different repository:
|
||||||
|
|
||||||
- `REPO` (default: `ohmyzsh/ohmyzsh`): this takes the form of `owner/repository`. If you set
|
- `REPO` (default: `ohmyzsh/ohmyzsh`): this takes the form of `owner/repository`. If you set
|
||||||
this variable, the installer will look for a repository at `https://github.com/{owner}/{repository}`.
|
this variable, the installer will look for a repository at `https://github.com/{owner}/{repository}`.
|
||||||
|
@ -229,19 +258,19 @@ REPO=apjanke/oh-my-zsh BRANCH=edge sh install.sh
|
||||||
|
|
||||||
#### Manual Installation
|
#### Manual Installation
|
||||||
|
|
||||||
##### 1. Clone the repository <!-- omit in toc -->
|
##### 1. Clone The Repository <!-- omit in toc -->
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
git clone https://github.com/ohmyzsh/ohmyzsh.git ~/.oh-my-zsh
|
git clone https://github.com/ohmyzsh/ohmyzsh.git ~/.oh-my-zsh
|
||||||
```
|
```
|
||||||
|
|
||||||
##### 2. _Optionally_, backup your existing `~/.zshrc` file <!-- omit in toc -->
|
##### 2. _Optionally_, Backup Your Existing `~/.zshrc` File <!-- omit in toc -->
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
cp ~/.zshrc ~/.zshrc.orig
|
cp ~/.zshrc ~/.zshrc.orig
|
||||||
```
|
```
|
||||||
|
|
||||||
##### 3. Create a new zsh configuration file <!-- omit in toc -->
|
##### 3. Create A New Zsh Configuration File <!-- omit in toc -->
|
||||||
|
|
||||||
You can create a new zsh config file by copying the template that we have included for you.
|
You can create a new zsh config file by copying the template that we have included for you.
|
||||||
|
|
||||||
|
@ -249,7 +278,7 @@ You can create a new zsh config file by copying the template that we have includ
|
||||||
cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc
|
cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc
|
||||||
```
|
```
|
||||||
|
|
||||||
##### 4. Change your default shell <!-- omit in toc -->
|
##### 4. Change Your Default Shell <!-- omit in toc -->
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
chsh -s $(which zsh)
|
chsh -s $(which zsh)
|
||||||
|
@ -257,7 +286,7 @@ chsh -s $(which zsh)
|
||||||
|
|
||||||
You must log out from your user session and log back in to see this change.
|
You must log out from your user session and log back in to see this change.
|
||||||
|
|
||||||
##### 5. Initialize your new zsh configuration <!-- omit in toc -->
|
##### 5. Initialize Your New Zsh Configuration <!-- omit in toc -->
|
||||||
|
|
||||||
Once you open up a new terminal window, it should load zsh with Oh My Zsh's configuration.
|
Once you open up a new terminal window, it should load zsh with Oh My Zsh's configuration.
|
||||||
|
|
||||||
|
@ -268,7 +297,7 @@ If you have any hiccups installing, here are a few common fixes.
|
||||||
- You _might_ need to modify your `PATH` in `~/.zshrc` if you're not able to find some commands after switching to `oh-my-zsh`.
|
- You _might_ need to modify your `PATH` in `~/.zshrc` if you're not able to find some commands after switching to `oh-my-zsh`.
|
||||||
- If you installed manually or changed the install location, check the `ZSH` environment variable in `~/.zshrc`.
|
- If you installed manually or changed the install location, check the `ZSH` environment variable in `~/.zshrc`.
|
||||||
|
|
||||||
### Custom Plugins and Themes
|
### Custom Plugins And Themes
|
||||||
|
|
||||||
If you want to override any of the default behaviors, just add a new file (ending in `.zsh`) in the `custom/` directory.
|
If you want to override any of the default behaviors, just add a new file (ending in `.zsh`) in the `custom/` directory.
|
||||||
|
|
||||||
|
@ -276,6 +305,83 @@ If you have many functions that go well together, you can put them as a `XYZ.plu
|
||||||
|
|
||||||
If you would like to override the functionality of a plugin distributed with Oh My Zsh, create a plugin of the same name in the `custom/plugins/` directory and it will be loaded instead of the one in `plugins/`.
|
If you would like to override the functionality of a plugin distributed with Oh My Zsh, create a plugin of the same name in the `custom/plugins/` directory and it will be loaded instead of the one in `plugins/`.
|
||||||
|
|
||||||
|
### Enable GNU ls In macOS And freeBSD Systems
|
||||||
|
|
||||||
|
<a name="enable-gnu-ls"></a>
|
||||||
|
|
||||||
|
The default behaviour in Oh My Zsh is to use BSD `ls` in macOS and FreeBSD systems. If GNU `ls` is installed
|
||||||
|
(as `gls` command), you can choose to use it instead. To do it, you can use zstyle-based config before
|
||||||
|
sourcing `oh-my-zsh.sh`:
|
||||||
|
|
||||||
|
```zsh
|
||||||
|
zstyle ':omz:lib:theme-and-appearance' gnu-ls yes
|
||||||
|
```
|
||||||
|
|
||||||
|
_Note: this is not compatible with `DISABLE_LS_COLORS=true`_
|
||||||
|
|
||||||
|
### Skip Aliases
|
||||||
|
|
||||||
|
<a name="remove-directories-aliases"></a>
|
||||||
|
|
||||||
|
If you want to skip default Oh My Zsh aliases (those defined in `lib/*` files) or plugin aliases,
|
||||||
|
you can use the settings below in your `~/.zshrc` file, **before Oh My Zsh is loaded**. Note that
|
||||||
|
there are many different ways to skip aliases, depending on your needs.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# Skip all aliases, in lib files and enabled plugins
|
||||||
|
zstyle ':omz:*' aliases no
|
||||||
|
|
||||||
|
# Skip all aliases in lib files
|
||||||
|
zstyle ':omz:lib:*' aliases no
|
||||||
|
# Skip only aliases defined in the directories.zsh lib file
|
||||||
|
zstyle ':omz:lib:directories' aliases no
|
||||||
|
|
||||||
|
# Skip all plugin aliases
|
||||||
|
zstyle ':omz:plugins:*' aliases no
|
||||||
|
# Skip only the aliases from the git plugin
|
||||||
|
zstyle ':omz:plugins:git' aliases no
|
||||||
|
```
|
||||||
|
|
||||||
|
You can combine these in other ways taking into account that more specific scopes take precedence:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# Skip all plugin aliases, except for the git plugin
|
||||||
|
zstyle ':omz:plugins:*' aliases no
|
||||||
|
zstyle ':omz:plugins:git' aliases yes
|
||||||
|
```
|
||||||
|
|
||||||
|
A previous version of this feature was using the setting below, which has been removed:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
zstyle ':omz:directories' aliases no
|
||||||
|
```
|
||||||
|
|
||||||
|
Instead, you can now use the following:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
zstyle ':omz:lib:directories' aliases no
|
||||||
|
```
|
||||||
|
|
||||||
|
### Disable async git prompt
|
||||||
|
|
||||||
|
Async prompt functions are an experimental feature (included on April 3, 2024) that allows Oh My Zsh to render prompt information
|
||||||
|
asynchronously. This can improve prompt rendering performance, but it might not work well with some setups. We hope that's not an
|
||||||
|
issue, but if you're seeing problems with this new feature, you can turn it off by setting the following in your .zshrc file,
|
||||||
|
before Oh My Zsh is sourced:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
zstyle ':omz:alpha:lib:git' async-prompt no
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Notice <!-- omit in toc -->
|
||||||
|
|
||||||
|
> This feature is currently in a testing phase and it may be subject to change in the future.
|
||||||
|
> It is also not currently compatible with plugin managers such as zpm or zinit, which don't
|
||||||
|
> source the init script (`oh-my-zsh.sh`) where this feature is implemented in.
|
||||||
|
|
||||||
|
> It is also not currently aware of "aliases" that are defined as functions. Example of such
|
||||||
|
> are `gccd`, `ggf`, or `ggl` functions from the git plugin.
|
||||||
|
|
||||||
## Getting Updates
|
## Getting Updates
|
||||||
|
|
||||||
By default, you will be prompted to check for updates every 2 weeks. You can choose other update modes by adding a line to your `~/.zshrc` file, **before Oh My Zsh is loaded**:
|
By default, you will be prompted to check for updates every 2 weeks. You can choose other update modes by adding a line to your `~/.zshrc` file, **before Oh My Zsh is loaded**:
|
||||||
|
@ -307,6 +413,18 @@ zstyle ':omz:update' frequency 7
|
||||||
zstyle ':omz:update' frequency 0
|
zstyle ':omz:update' frequency 0
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Updates Verbosity
|
||||||
|
|
||||||
|
You can also limit the update verbosity with the following settings:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
zstyle ':omz:update' verbose default # default update prompt
|
||||||
|
|
||||||
|
zstyle ':omz:update' verbose minimal # only few lines
|
||||||
|
|
||||||
|
zstyle ':omz:update' verbose silent # only errors
|
||||||
|
```
|
||||||
|
|
||||||
### Manual Updates
|
### Manual Updates
|
||||||
|
|
||||||
If you'd like to update at any point in time (maybe someone just released a new plugin and you don't want to wait a week?) you just need to run:
|
If you'd like to update at any point in time (maybe someone just released a new plugin and you don't want to wait a week?) you just need to run:
|
||||||
|
@ -323,7 +441,7 @@ Oh My Zsh isn't for everyone. We'll miss you, but we want to make this an easy b
|
||||||
|
|
||||||
If you want to uninstall `oh-my-zsh`, just run `uninstall_oh_my_zsh` from the command-line. It will remove itself and revert your previous `bash` or `zsh` configuration.
|
If you want to uninstall `oh-my-zsh`, just run `uninstall_oh_my_zsh` from the command-line. It will remove itself and revert your previous `bash` or `zsh` configuration.
|
||||||
|
|
||||||
## How do I contribute to Oh My Zsh?
|
## How Do I Contribute To Oh My Zsh?
|
||||||
|
|
||||||
Before you participate in our delightful community, please read the [code of conduct](CODE_OF_CONDUCT.md).
|
Before you participate in our delightful community, please read the [code of conduct](CODE_OF_CONDUCT.md).
|
||||||
|
|
||||||
|
@ -333,7 +451,7 @@ We also need people to test out pull requests. So take a look through [the open
|
||||||
|
|
||||||
See [Contributing](CONTRIBUTING.md) for more details.
|
See [Contributing](CONTRIBUTING.md) for more details.
|
||||||
|
|
||||||
### Do NOT send us themes
|
### Do Not Send Us Themes
|
||||||
|
|
||||||
We have (more than) enough themes for the time being. Please add your theme to the [external themes](https://github.com/ohmyzsh/ohmyzsh/wiki/External-themes) wiki page.
|
We have (more than) enough themes for the time being. Please add your theme to the [external themes](https://github.com/ohmyzsh/ohmyzsh/wiki/External-themes) wiki page.
|
||||||
|
|
||||||
|
@ -343,11 +461,15 @@ Oh My Zsh has a vibrant community of happy users and delightful contributors. Wi
|
||||||
|
|
||||||
Thank you so much!
|
Thank you so much!
|
||||||
|
|
||||||
|
<a href="https://github.com/ohmyzsh/ohmyzsh/graphs/contributors">
|
||||||
|
<img src="https://contrib.rocks/image?repo=ohmyzsh/ohmyzsh" width="100%"/>
|
||||||
|
</a>
|
||||||
|
|
||||||
## Follow Us
|
## Follow Us
|
||||||
|
|
||||||
We're on social media:
|
We're on social media:
|
||||||
|
|
||||||
- [@ohmyzsh](https://twitter.com/ohmyzsh) on Twitter. You should follow it.
|
- [@ohmyzsh](https://x.com/ohmyzsh) on X (formerly Twitter). You should follow it.
|
||||||
- [Facebook](https://www.facebook.com/Oh-My-Zsh-296616263819290/) poke us.
|
- [Facebook](https://www.facebook.com/Oh-My-Zsh-296616263819290/) poke us.
|
||||||
- [Instagram](https://www.instagram.com/_ohmyzsh/) tag us in your post showing Oh My Zsh!
|
- [Instagram](https://www.instagram.com/_ohmyzsh/) tag us in your post showing Oh My Zsh!
|
||||||
- [Discord](https://discord.gg/ohmyzsh) to chat with us!
|
- [Discord](https://discord.gg/ohmyzsh) to chat with us!
|
||||||
|
@ -364,4 +486,4 @@ Oh My Zsh is released under the [MIT license](LICENSE.txt).
|
||||||
|
|
||||||
![Planet Argon](https://pa-github-assets.s3.amazonaws.com/PARGON_logo_digital_COL-small.jpg)
|
![Planet Argon](https://pa-github-assets.s3.amazonaws.com/PARGON_logo_digital_COL-small.jpg)
|
||||||
|
|
||||||
Oh My Zsh was started by the team at [Planet Argon](https://www.planetargon.com/?utm_source=github), a [Ruby on Rails development agency](https://www.planetargon.com/skills/ruby-on-rails-development?utm_source=github). Check out our [other open source projects](https://www.planetargon.com/open-source?utm_source=github).
|
Oh My Zsh was started by the team at [Planet Argon](https://www.planetargon.com/?utm_source=github), a [Ruby on Rails development agency](https://www.planetargon.com/services/ruby-on-rails-development?utm_source=github). Check out our [other open source projects](https://www.planetargon.com/open-source?utm_source=github).
|
||||||
|
|
|
@ -17,8 +17,7 @@ In the near future we will introduce versioning, so expect this section to chang
|
||||||
|
|
||||||
**Do not submit an issue or pull request**: this might reveal the vulnerability.
|
**Do not submit an issue or pull request**: this might reveal the vulnerability.
|
||||||
|
|
||||||
Instead, you should email the maintainers directly at: [**security@ohmyz.sh**](mailto:security@ohmyz.sh).
|
Instead, you should email the maintainers directly at: [**security@ohmyz.sh**](mailto:security@ohmyz.sh),
|
||||||
|
or using the link to [privately report a vulnerability with GitHub](https://github.com/ohmyzsh/ohmyzsh/security/advisories/new).
|
||||||
|
|
||||||
We will deal with the vulnerability privately and submit a patch as soon as possible.
|
We will deal with the vulnerability privately and submit a patch as soon as possible.
|
||||||
|
|
||||||
You can also submit your vulnerability report to [huntr.dev](https://huntr.dev/bounties/disclose/?utm_campaign=ohmyzsh%2Fohmyzsh&utm_medium=social&utm_source=github&target=https%3A%2F%2Fgithub.com%2Fohmyzsh%2Fohmyzsh) and see if you can get a bounty reward.
|
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
# You can put files here to add functionality separated per file, which
|
# Put files in this folder to add your own custom functionality.
|
||||||
# will be ignored by git.
|
# See: https://github.com/ohmyzsh/ohmyzsh/wiki/Customization
|
||||||
# Files on the custom/ directory will be automatically loaded by the init
|
#
|
||||||
# script, in alphabetical order.
|
# Files in the custom/ directory will be:
|
||||||
|
# - loaded automatically by the init script, in alphabetical order
|
||||||
# For example: add yourself some shortcuts to projects you often work on.
|
# - loaded last, after all built-ins in the lib/ directory, to override them
|
||||||
|
# - ignored by git by default
|
||||||
|
#
|
||||||
|
# Example: add custom/shortcuts.zsh for shortcuts to your local projects
|
||||||
#
|
#
|
||||||
# brainstormr=~/Projects/development/planetargon/brainstormr
|
# brainstormr=~/Projects/development/planetargon/brainstormr
|
||||||
# cd $brainstormr
|
# cd $brainstormr
|
||||||
#
|
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
# Add your own custom plugins in the custom/plugins directory. Plugins placed
|
# Add your own custom plugins in the custom/plugins directory. Plugins placed
|
||||||
# here will override ones with the same name in the main plugins directory.
|
# here will override ones with the same name in the main plugins directory.
|
||||||
|
# See: https://github.com/ohmyzsh/ohmyzsh/wiki/Customization#overriding-and-adding-plugins
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
# Put your custom themes in this folder.
|
# Put your custom themes in this folder.
|
||||||
|
# See: https://github.com/ohmyzsh/ohmyzsh/wiki/Customization#overriding-and-adding-themes
|
||||||
|
#
|
||||||
# Example:
|
# Example:
|
||||||
|
|
||||||
PROMPT="%{$fg[red]%}%n%{$reset_color%}@%{$fg[blue]%}%m %{$fg[yellow]%}%~ %{$reset_color%}%% "
|
PROMPT="%{$fg[red]%}%n%{$reset_color%}@%{$fg[blue]%}%m %{$fg[yellow]%}%~ %{$reset_color%}%% "
|
||||||
|
|
144
lib/async_prompt.zsh
Normal file
144
lib/async_prompt.zsh
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
# The async code is taken from
|
||||||
|
# https://github.com/zsh-users/zsh-autosuggestions/blob/master/src/async.zsh
|
||||||
|
# https://github.com/woefe/git-prompt.zsh/blob/master/git-prompt.zsh
|
||||||
|
|
||||||
|
zmodload zsh/system
|
||||||
|
autoload -Uz is-at-least
|
||||||
|
|
||||||
|
# For now, async prompt function handlers are set up like so:
|
||||||
|
# First, define the async function handler and register the handler
|
||||||
|
# with _omz_register_handler:
|
||||||
|
#
|
||||||
|
# function _git_prompt_status_async {
|
||||||
|
# # Do some expensive operation that outputs to stdout
|
||||||
|
# }
|
||||||
|
# _omz_register_handler _git_prompt_status_async
|
||||||
|
#
|
||||||
|
# Then add a stub prompt function in `$PROMPT` or similar prompt variables,
|
||||||
|
# which will show the output of "$_OMZ_ASYNC_OUTPUT[handler_name]":
|
||||||
|
#
|
||||||
|
# function git_prompt_status {
|
||||||
|
# echo -n $_OMZ_ASYNC_OUTPUT[_git_prompt_status_async]
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# RPROMPT='$(git_prompt_status)'
|
||||||
|
#
|
||||||
|
# This API is subject to change and optimization. Rely on it at your own risk.
|
||||||
|
|
||||||
|
function _omz_register_handler {
|
||||||
|
setopt localoptions noksharrays
|
||||||
|
typeset -ga _omz_async_functions
|
||||||
|
# we want to do nothing if there's no $1 function or we already set it up
|
||||||
|
if [[ -z "$1" ]] || (( ! ${+functions[$1]} )) \
|
||||||
|
|| (( ${_omz_async_functions[(Ie)$1]} )); then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
_omz_async_functions+=("$1")
|
||||||
|
# let's add the hook to async_request if it's not there yet
|
||||||
|
if (( ! ${precmd_functions[(Ie)_omz_async_request]} )) \
|
||||||
|
&& (( ${+functions[_omz_async_request]})); then
|
||||||
|
autoload -Uz add-zsh-hook
|
||||||
|
add-zsh-hook precmd _omz_async_request
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Set up async handlers and callbacks
|
||||||
|
function _omz_async_request {
|
||||||
|
local -i ret=$?
|
||||||
|
typeset -gA _OMZ_ASYNC_FDS _OMZ_ASYNC_PIDS _OMZ_ASYNC_OUTPUT
|
||||||
|
|
||||||
|
# executor runs a subshell for all async requests based on key
|
||||||
|
local handler
|
||||||
|
for handler in ${_omz_async_functions}; do
|
||||||
|
(( ${+functions[$handler]} )) || continue
|
||||||
|
|
||||||
|
local fd=${_OMZ_ASYNC_FDS[$handler]:--1}
|
||||||
|
local pid=${_OMZ_ASYNC_PIDS[$handler]:--1}
|
||||||
|
|
||||||
|
# If we've got a pending request, cancel it
|
||||||
|
if (( fd != -1 && pid != -1 )) && { true <&$fd } 2>/dev/null; then
|
||||||
|
# Close the file descriptor and remove the handler
|
||||||
|
exec {fd}<&-
|
||||||
|
zle -F $fd
|
||||||
|
|
||||||
|
# Zsh will make a new process group for the child process only if job
|
||||||
|
# control is enabled (MONITOR option)
|
||||||
|
if [[ -o MONITOR ]]; then
|
||||||
|
# Send the signal to the process group to kill any processes that may
|
||||||
|
# have been forked by the async function handler
|
||||||
|
kill -TERM -$pid 2>/dev/null
|
||||||
|
else
|
||||||
|
# Kill just the child process since it wasn't placed in a new process
|
||||||
|
# group. If the async function handler forked any child processes they may
|
||||||
|
# be orphaned and left behind.
|
||||||
|
kill -TERM $pid 2>/dev/null
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Define global variables to store the file descriptor, PID and output
|
||||||
|
_OMZ_ASYNC_FDS[$handler]=-1
|
||||||
|
_OMZ_ASYNC_PIDS[$handler]=-1
|
||||||
|
|
||||||
|
# Fork a process to fetch the git status and open a pipe to read from it
|
||||||
|
exec {fd}< <(
|
||||||
|
# Tell parent process our PID
|
||||||
|
builtin echo ${sysparams[pid]}
|
||||||
|
# Set exit code for the handler if used
|
||||||
|
() { return $ret }
|
||||||
|
# Run the async function handler
|
||||||
|
$handler
|
||||||
|
)
|
||||||
|
|
||||||
|
# Save FD for handler
|
||||||
|
_OMZ_ASYNC_FDS[$handler]=$fd
|
||||||
|
|
||||||
|
# There's a weird bug here where ^C stops working unless we force a fork
|
||||||
|
# See https://github.com/zsh-users/zsh-autosuggestions/issues/364
|
||||||
|
# and https://github.com/zsh-users/zsh-autosuggestions/pull/612
|
||||||
|
is-at-least 5.8 || command true
|
||||||
|
|
||||||
|
# Save the PID from the handler child process
|
||||||
|
read -u $fd "_OMZ_ASYNC_PIDS[$handler]"
|
||||||
|
|
||||||
|
# When the fd is readable, call the response handler
|
||||||
|
zle -F "$fd" _omz_async_callback
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Called when new data is ready to be read from the pipe
|
||||||
|
function _omz_async_callback() {
|
||||||
|
emulate -L zsh
|
||||||
|
|
||||||
|
local fd=$1 # First arg will be fd ready for reading
|
||||||
|
local err=$2 # Second arg will be passed in case of error
|
||||||
|
|
||||||
|
if [[ -z "$err" || "$err" == "hup" ]]; then
|
||||||
|
# Get handler name from fd
|
||||||
|
local handler="${(k)_OMZ_ASYNC_FDS[(r)$fd]}"
|
||||||
|
|
||||||
|
# Store old output which is supposed to be already printed
|
||||||
|
local old_output="${_OMZ_ASYNC_OUTPUT[$handler]}"
|
||||||
|
|
||||||
|
# Read output from fd
|
||||||
|
IFS= read -r -u $fd -d '' "_OMZ_ASYNC_OUTPUT[$handler]"
|
||||||
|
|
||||||
|
# Repaint prompt if output has changed
|
||||||
|
if [[ "$old_output" != "${_OMZ_ASYNC_OUTPUT[$handler]}" ]]; then
|
||||||
|
zle .reset-prompt
|
||||||
|
zle -R
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Close the fd
|
||||||
|
exec {fd}<&-
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Always remove the handler
|
||||||
|
zle -F "$fd"
|
||||||
|
|
||||||
|
# Unset global FD variable to prevent closing user created FDs in the precmd hook
|
||||||
|
_OMZ_ASYNC_FDS[$handler]=-1
|
||||||
|
_OMZ_ASYNC_PIDS[$handler]=-1
|
||||||
|
}
|
||||||
|
|
||||||
|
autoload -Uz add-zsh-hook
|
||||||
|
add-zsh-hook precmd _omz_async_request
|
85
lib/cli.zsh
85
lib/cli.zsh
|
@ -11,7 +11,7 @@ function omz {
|
||||||
|
|
||||||
# Subcommand functions start with _ so that they don't
|
# Subcommand functions start with _ so that they don't
|
||||||
# appear as completion entries when looking for `omz`
|
# appear as completion entries when looking for `omz`
|
||||||
(( $+functions[_omz::$command] )) || {
|
(( ${+functions[_omz::$command]} )) || {
|
||||||
_omz::help
|
_omz::help
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
@ -241,21 +241,29 @@ function _omz::plugin::disable {
|
||||||
|
|
||||||
# Remove plugins substitution awk script
|
# Remove plugins substitution awk script
|
||||||
local awk_subst_plugins="\
|
local awk_subst_plugins="\
|
||||||
gsub(/\s+(${(j:|:)dis_plugins})/, \"\") # with spaces before
|
gsub(/[ \t]+(${(j:|:)dis_plugins})[ \t]+/, \" \") # with spaces before or after
|
||||||
gsub(/(${(j:|:)dis_plugins})\s+/, \"\") # with spaces after
|
gsub(/[ \t]+(${(j:|:)dis_plugins})$/, \"\") # with spaces before and EOL
|
||||||
gsub(/\((${(j:|:)dis_plugins})\)/, \"\") # without spaces (only plugin)
|
gsub(/^(${(j:|:)dis_plugins})[ \t]+/, \"\") # with BOL and spaces after
|
||||||
|
|
||||||
|
gsub(/\((${(j:|:)dis_plugins})[ \t]+/, \"(\") # with parenthesis before and spaces after
|
||||||
|
gsub(/[ \t]+(${(j:|:)dis_plugins})\)/, \")\") # with spaces before or parenthesis after
|
||||||
|
gsub(/\((${(j:|:)dis_plugins})\)/, \"()\") # with only parentheses
|
||||||
|
|
||||||
|
gsub(/^(${(j:|:)dis_plugins})\)/, \")\") # with BOL and closing parenthesis
|
||||||
|
gsub(/\((${(j:|:)dis_plugins})$/, \"(\") # with opening parenthesis and EOL
|
||||||
"
|
"
|
||||||
|
|
||||||
# Disable plugins awk script
|
# Disable plugins awk script
|
||||||
local awk_script="
|
local awk_script="
|
||||||
# if plugins=() is in oneline form, substitute disabled plugins and go to next line
|
# if plugins=() is in oneline form, substitute disabled plugins and go to next line
|
||||||
/^\s*plugins=\([^#]+\).*\$/ {
|
/^[ \t]*plugins=\([^#]+\).*\$/ {
|
||||||
$awk_subst_plugins
|
$awk_subst_plugins
|
||||||
print \$0
|
print \$0
|
||||||
next
|
next
|
||||||
}
|
}
|
||||||
|
|
||||||
# if plugins=() is in multiline form, enable multi flag and disable plugins if they're there
|
# if plugins=() is in multiline form, enable multi flag and disable plugins if they're there
|
||||||
/^\s*plugins=\(/ {
|
/^[ \t]*plugins=\(/ {
|
||||||
multi=1
|
multi=1
|
||||||
$awk_subst_plugins
|
$awk_subst_plugins
|
||||||
print \$0
|
print \$0
|
||||||
|
@ -280,9 +288,10 @@ multi == 1 && length(\$0) > 0 {
|
||||||
"
|
"
|
||||||
|
|
||||||
local zdot="${ZDOTDIR:-$HOME}"
|
local zdot="${ZDOTDIR:-$HOME}"
|
||||||
awk "$awk_script" "$zdot/.zshrc" > "$zdot/.zshrc.new" \
|
local zshrc="${${:-"${zdot}/.zshrc"}:A}"
|
||||||
&& command mv -f "$zdot/.zshrc" "$zdot/.zshrc.bck" \
|
awk "$awk_script" "$zshrc" > "$zdot/.zshrc.new" \
|
||||||
&& command mv -f "$zdot/.zshrc.new" "$zdot/.zshrc"
|
&& command cp -f "$zshrc" "$zdot/.zshrc.bck" \
|
||||||
|
&& command mv -f "$zdot/.zshrc.new" "$zshrc"
|
||||||
|
|
||||||
# Exit if the new .zshrc file wasn't created correctly
|
# Exit if the new .zshrc file wasn't created correctly
|
||||||
[[ $? -eq 0 ]] || {
|
[[ $? -eq 0 ]] || {
|
||||||
|
@ -294,8 +303,7 @@ multi == 1 && length(\$0) > 0 {
|
||||||
# Exit if the new .zshrc file has syntax errors
|
# Exit if the new .zshrc file has syntax errors
|
||||||
if ! command zsh -n "$zdot/.zshrc"; then
|
if ! command zsh -n "$zdot/.zshrc"; then
|
||||||
_omz::log error "broken syntax in '"${zdot/#$HOME/\~}/.zshrc"'. Rolling back changes..."
|
_omz::log error "broken syntax in '"${zdot/#$HOME/\~}/.zshrc"'. Rolling back changes..."
|
||||||
command mv -f "$zdot/.zshrc" "$zdot/.zshrc.new"
|
command mv -f "$zdot/.zshrc.bck" "$zshrc"
|
||||||
command mv -f "$zdot/.zshrc.bck" "$zdot/.zshrc"
|
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -330,14 +338,14 @@ function _omz::plugin::enable {
|
||||||
# Enable plugins awk script
|
# Enable plugins awk script
|
||||||
local awk_script="
|
local awk_script="
|
||||||
# if plugins=() is in oneline form, substitute ) with new plugins and go to the next line
|
# if plugins=() is in oneline form, substitute ) with new plugins and go to the next line
|
||||||
/^\s*plugins=\([^#]+\).*\$/ {
|
/^[ \t]*plugins=\([^#]+\).*\$/ {
|
||||||
sub(/\)/, \" $add_plugins&\")
|
sub(/\)/, \" $add_plugins&\")
|
||||||
print \$0
|
print \$0
|
||||||
next
|
next
|
||||||
}
|
}
|
||||||
|
|
||||||
# if plugins=() is in multiline form, enable multi flag
|
# if plugins=() is in multiline form, enable multi flag
|
||||||
/^\s*plugins=\(/ {
|
/^[ \t]*plugins=\(/ {
|
||||||
multi=1
|
multi=1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -354,9 +362,10 @@ multi == 1 && /^[^#]*\)/ {
|
||||||
"
|
"
|
||||||
|
|
||||||
local zdot="${ZDOTDIR:-$HOME}"
|
local zdot="${ZDOTDIR:-$HOME}"
|
||||||
awk "$awk_script" "$zdot/.zshrc" > "$zdot/.zshrc.new" \
|
local zshrc="${${:-"${zdot}/.zshrc"}:A}"
|
||||||
&& command mv -f "$zdot/.zshrc" "$zdot/.zshrc.bck" \
|
awk "$awk_script" "$zshrc" > "$zdot/.zshrc.new" \
|
||||||
&& command mv -f "$zdot/.zshrc.new" "$zdot/.zshrc"
|
&& command cp -f "$zshrc" "$zdot/.zshrc.bck" \
|
||||||
|
&& command mv -f "$zdot/.zshrc.new" "$zshrc"
|
||||||
|
|
||||||
# Exit if the new .zshrc file wasn't created correctly
|
# Exit if the new .zshrc file wasn't created correctly
|
||||||
[[ $? -eq 0 ]] || {
|
[[ $? -eq 0 ]] || {
|
||||||
|
@ -368,8 +377,7 @@ multi == 1 && /^[^#]*\)/ {
|
||||||
# Exit if the new .zshrc file has syntax errors
|
# Exit if the new .zshrc file has syntax errors
|
||||||
if ! command zsh -n "$zdot/.zshrc"; then
|
if ! command zsh -n "$zdot/.zshrc"; then
|
||||||
_omz::log error "broken syntax in '"${zdot/#$HOME/\~}/.zshrc"'. Rolling back changes..."
|
_omz::log error "broken syntax in '"${zdot/#$HOME/\~}/.zshrc"'. Rolling back changes..."
|
||||||
command mv -f "$zdot/.zshrc" "$zdot/.zshrc.new"
|
command mv -f "$zdot/.zshrc.bck" "$zshrc"
|
||||||
command mv -f "$zdot/.zshrc.bck" "$zdot/.zshrc"
|
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -416,14 +424,14 @@ function _omz::plugin::list {
|
||||||
|
|
||||||
if (( ${#custom_plugins} )); then
|
if (( ${#custom_plugins} )); then
|
||||||
print -P "%U%BCustom plugins%b%u:"
|
print -P "%U%BCustom plugins%b%u:"
|
||||||
print -l ${(q-)custom_plugins} | column -x
|
print -lac ${(q-)custom_plugins}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if (( ${#builtin_plugins} )); then
|
if (( ${#builtin_plugins} )); then
|
||||||
(( ${#custom_plugins} )) && echo # add a line of separation
|
(( ${#custom_plugins} )) && echo # add a line of separation
|
||||||
|
|
||||||
print -P "%U%BBuilt-in plugins%b%u:"
|
print -P "%U%BBuilt-in plugins%b%u:"
|
||||||
print -l ${(q-)builtin_plugins} | column -x
|
print -lac ${(q-)builtin_plugins}
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -448,7 +456,7 @@ function _omz::plugin::load {
|
||||||
if [[ ! -f "$base/_$plugin" && ! -f "$base/$plugin.plugin.zsh" ]]; then
|
if [[ ! -f "$base/_$plugin" && ! -f "$base/$plugin.plugin.zsh" ]]; then
|
||||||
_omz::log warn "'$plugin' is not a valid plugin"
|
_omz::log warn "'$plugin' is not a valid plugin"
|
||||||
continue
|
continue
|
||||||
# It it is a valid plugin, add its directory to $fpath unless it is already there
|
# It is a valid plugin, add its directory to $fpath unless it is already there
|
||||||
elif (( ! ${fpath[(Ie)$base]} )); then
|
elif (( ! ${fpath[(Ie)$base]} )); then
|
||||||
fpath=("$base" $fpath)
|
fpath=("$base" $fpath)
|
||||||
fi
|
fi
|
||||||
|
@ -674,13 +682,13 @@ function _omz::theme::list {
|
||||||
# Print custom themes if there are any
|
# Print custom themes if there are any
|
||||||
if (( ${#custom_themes} )); then
|
if (( ${#custom_themes} )); then
|
||||||
print -P "%U%BCustom themes%b%u:"
|
print -P "%U%BCustom themes%b%u:"
|
||||||
print -l ${(q-)custom_themes} | column -x
|
print -lac ${(q-)custom_themes}
|
||||||
echo
|
echo
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Print built-in themes
|
# Print built-in themes
|
||||||
print -P "%U%BBuilt-in themes%b%u:"
|
print -P "%U%BBuilt-in themes%b%u:"
|
||||||
print -l ${(q-)builtin_themes} | column -x
|
print -lac ${(q-)builtin_themes}
|
||||||
}
|
}
|
||||||
|
|
||||||
function _omz::theme::set {
|
function _omz::theme::set {
|
||||||
|
@ -699,9 +707,9 @@ function _omz::theme::set {
|
||||||
|
|
||||||
# Enable theme in .zshrc
|
# Enable theme in .zshrc
|
||||||
local awk_script='
|
local awk_script='
|
||||||
!set && /^\s*ZSH_THEME=[^#]+.*$/ {
|
!set && /^[ \t]*ZSH_THEME=[^#]+.*$/ {
|
||||||
set=1
|
set=1
|
||||||
sub(/^\s*ZSH_THEME=[^#]+.*$/, "ZSH_THEME=\"'$1'\" # set by `omz`")
|
sub(/^[ \t]*ZSH_THEME=[^#]+.*$/, "ZSH_THEME=\"'$1'\" # set by `omz`")
|
||||||
print $0
|
print $0
|
||||||
next
|
next
|
||||||
}
|
}
|
||||||
|
@ -715,7 +723,8 @@ END {
|
||||||
'
|
'
|
||||||
|
|
||||||
local zdot="${ZDOTDIR:-$HOME}"
|
local zdot="${ZDOTDIR:-$HOME}"
|
||||||
awk "$awk_script" "$zdot/.zshrc" > "$zdot/.zshrc.new" \
|
local zshrc="${${:-"${zdot}/.zshrc"}:A}"
|
||||||
|
awk "$awk_script" "$zshrc" > "$zdot/.zshrc.new" \
|
||||||
|| {
|
|| {
|
||||||
# Prepend ZSH_THEME= line to .zshrc if it doesn't exist
|
# Prepend ZSH_THEME= line to .zshrc if it doesn't exist
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
|
@ -724,8 +733,8 @@ ZSH_THEME="$1" # set by \`omz\`
|
||||||
EOF
|
EOF
|
||||||
cat "$zdot/.zshrc"
|
cat "$zdot/.zshrc"
|
||||||
} > "$zdot/.zshrc.new" \
|
} > "$zdot/.zshrc.new" \
|
||||||
&& command mv -f "$zdot/.zshrc" "$zdot/.zshrc.bck" \
|
&& command cp -f "$zshrc" "$zdot/.zshrc.bck" \
|
||||||
&& command mv -f "$zdot/.zshrc.new" "$zdot/.zshrc"
|
&& command mv -f "$zdot/.zshrc.new" "$zshrc"
|
||||||
|
|
||||||
# Exit if the new .zshrc file wasn't created correctly
|
# Exit if the new .zshrc file wasn't created correctly
|
||||||
[[ $? -eq 0 ]] || {
|
[[ $? -eq 0 ]] || {
|
||||||
|
@ -737,8 +746,7 @@ EOF
|
||||||
# Exit if the new .zshrc file has syntax errors
|
# Exit if the new .zshrc file has syntax errors
|
||||||
if ! command zsh -n "$zdot/.zshrc"; then
|
if ! command zsh -n "$zdot/.zshrc"; then
|
||||||
_omz::log error "broken syntax in '"${zdot/#$HOME/\~}/.zshrc"'. Rolling back changes..."
|
_omz::log error "broken syntax in '"${zdot/#$HOME/\~}/.zshrc"'. Rolling back changes..."
|
||||||
command mv -f "$zdot/.zshrc" "$zdot/.zshrc.new"
|
command mv -f "$zdot/.zshrc.bck" "$zshrc"
|
||||||
command mv -f "$zdot/.zshrc.bck" "$zdot/.zshrc"
|
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -773,13 +781,24 @@ function _omz::theme::use {
|
||||||
}
|
}
|
||||||
|
|
||||||
function _omz::update {
|
function _omz::update {
|
||||||
local last_commit=$(builtin cd -q "$ZSH"; git rev-parse HEAD)
|
# Check if git command is available
|
||||||
|
(( $+commands[git] )) || {
|
||||||
|
_omz::log error "git is not installed. Aborting..."
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
local last_commit=$(builtin cd -q "$ZSH"; git rev-parse HEAD 2>/dev/null)
|
||||||
|
[[ $? -eq 0 ]] || {
|
||||||
|
_omz::log error "\`$ZSH\` is not a git directory. Aborting..."
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
# Run update script
|
# Run update script
|
||||||
|
zstyle -s ':omz:update' verbose verbose_mode || verbose_mode=default
|
||||||
if [[ "$1" != --unattended ]]; then
|
if [[ "$1" != --unattended ]]; then
|
||||||
ZSH="$ZSH" command zsh -f "$ZSH/tools/upgrade.sh" --interactive || return $?
|
ZSH="$ZSH" command zsh -f "$ZSH/tools/upgrade.sh" -i -v $verbose_mode || return $?
|
||||||
else
|
else
|
||||||
ZSH="$ZSH" command zsh -f "$ZSH/tools/upgrade.sh" || return $?
|
ZSH="$ZSH" command zsh -f "$ZSH/tools/upgrade.sh" -v $verbose_mode || return $?
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Update last updated file
|
# Update last updated file
|
||||||
|
|
|
@ -10,8 +10,8 @@
|
||||||
# - pbcopy, pbpaste (macOS)
|
# - pbcopy, pbpaste (macOS)
|
||||||
# - cygwin (Windows running Cygwin)
|
# - cygwin (Windows running Cygwin)
|
||||||
# - wl-copy, wl-paste (if $WAYLAND_DISPLAY is set)
|
# - wl-copy, wl-paste (if $WAYLAND_DISPLAY is set)
|
||||||
# - xclip (if $DISPLAY is set)
|
|
||||||
# - xsel (if $DISPLAY is set)
|
# - xsel (if $DISPLAY is set)
|
||||||
|
# - xclip (if $DISPLAY is set)
|
||||||
# - lemonade (for SSH) https://github.com/pocke/lemonade
|
# - lemonade (for SSH) https://github.com/pocke/lemonade
|
||||||
# - doitclient (for SSH) http://www.chiark.greenend.org.uk/~sgtatham/doit/
|
# - doitclient (for SSH) http://www.chiark.greenend.org.uk/~sgtatham/doit/
|
||||||
# - win32yank (Windows)
|
# - win32yank (Windows)
|
||||||
|
@ -52,38 +52,38 @@ function detect-clipboard() {
|
||||||
emulate -L zsh
|
emulate -L zsh
|
||||||
|
|
||||||
if [[ "${OSTYPE}" == darwin* ]] && (( ${+commands[pbcopy]} )) && (( ${+commands[pbpaste]} )); then
|
if [[ "${OSTYPE}" == darwin* ]] && (( ${+commands[pbcopy]} )) && (( ${+commands[pbpaste]} )); then
|
||||||
function clipcopy() { pbcopy < "${1:-/dev/stdin}"; }
|
function clipcopy() { cat "${1:-/dev/stdin}" | pbcopy; }
|
||||||
function clippaste() { pbpaste; }
|
function clippaste() { pbpaste; }
|
||||||
elif [[ "${OSTYPE}" == (cygwin|msys)* ]]; then
|
elif [[ "${OSTYPE}" == (cygwin|msys)* ]]; then
|
||||||
function clipcopy() { cat "${1:-/dev/stdin}" > /dev/clipboard; }
|
function clipcopy() { cat "${1:-/dev/stdin}" > /dev/clipboard; }
|
||||||
function clippaste() { cat /dev/clipboard; }
|
function clippaste() { cat /dev/clipboard; }
|
||||||
|
elif (( $+commands[clip.exe] )) && (( $+commands[powershell.exe] )); then
|
||||||
|
function clipcopy() { cat "${1:-/dev/stdin}" | clip.exe; }
|
||||||
|
function clippaste() { powershell.exe -noprofile -command Get-Clipboard; }
|
||||||
elif [ -n "${WAYLAND_DISPLAY:-}" ] && (( ${+commands[wl-copy]} )) && (( ${+commands[wl-paste]} )); then
|
elif [ -n "${WAYLAND_DISPLAY:-}" ] && (( ${+commands[wl-copy]} )) && (( ${+commands[wl-paste]} )); then
|
||||||
function clipcopy() { wl-copy < "${1:-/dev/stdin}"; }
|
function clipcopy() { cat "${1:-/dev/stdin}" | wl-copy &>/dev/null &|; }
|
||||||
function clippaste() { wl-paste; }
|
function clippaste() { wl-paste --no-newline; }
|
||||||
elif [ -n "${DISPLAY:-}" ] && (( ${+commands[xclip]} )); then
|
|
||||||
function clipcopy() { xclip -in -selection clipboard < "${1:-/dev/stdin}"; }
|
|
||||||
function clippaste() { xclip -out -selection clipboard; }
|
|
||||||
elif [ -n "${DISPLAY:-}" ] && (( ${+commands[xsel]} )); then
|
elif [ -n "${DISPLAY:-}" ] && (( ${+commands[xsel]} )); then
|
||||||
function clipcopy() { xsel --clipboard --input < "${1:-/dev/stdin}"; }
|
function clipcopy() { cat "${1:-/dev/stdin}" | xsel --clipboard --input; }
|
||||||
function clippaste() { xsel --clipboard --output; }
|
function clippaste() { xsel --clipboard --output; }
|
||||||
|
elif [ -n "${DISPLAY:-}" ] && (( ${+commands[xclip]} )); then
|
||||||
|
function clipcopy() { cat "${1:-/dev/stdin}" | xclip -selection clipboard -in &>/dev/null &|; }
|
||||||
|
function clippaste() { xclip -out -selection clipboard; }
|
||||||
elif (( ${+commands[lemonade]} )); then
|
elif (( ${+commands[lemonade]} )); then
|
||||||
function clipcopy() { lemonade copy < "${1:-/dev/stdin}"; }
|
function clipcopy() { cat "${1:-/dev/stdin}" | lemonade copy; }
|
||||||
function clippaste() { lemonade paste; }
|
function clippaste() { lemonade paste; }
|
||||||
elif (( ${+commands[doitclient]} )); then
|
elif (( ${+commands[doitclient]} )); then
|
||||||
function clipcopy() { doitclient wclip < "${1:-/dev/stdin}"; }
|
function clipcopy() { cat "${1:-/dev/stdin}" | doitclient wclip; }
|
||||||
function clippaste() { doitclient wclip -r; }
|
function clippaste() { doitclient wclip -r; }
|
||||||
elif (( ${+commands[win32yank]} )); then
|
elif (( ${+commands[win32yank]} )); then
|
||||||
function clipcopy() { win32yank -i < "${1:-/dev/stdin}"; }
|
function clipcopy() { cat "${1:-/dev/stdin}" | win32yank -i; }
|
||||||
function clippaste() { win32yank -o; }
|
function clippaste() { win32yank -o; }
|
||||||
elif [[ $OSTYPE == linux-android* ]] && (( $+commands[termux-clipboard-set] )); then
|
elif [[ $OSTYPE == linux-android* ]] && (( $+commands[termux-clipboard-set] )); then
|
||||||
function clipcopy() { termux-clipboard-set < "${1:-/dev/stdin}"; }
|
function clipcopy() { cat "${1:-/dev/stdin}" | termux-clipboard-set; }
|
||||||
function clippaste() { termux-clipboard-get; }
|
function clippaste() { termux-clipboard-get; }
|
||||||
elif [ -n "${TMUX:-}" ] && (( ${+commands[tmux]} )); then
|
elif [ -n "${TMUX:-}" ] && (( ${+commands[tmux]} )); then
|
||||||
function clipcopy() { tmux load-buffer "${1:--}"; }
|
function clipcopy() { tmux load-buffer "${1:--}"; }
|
||||||
function clippaste() { tmux save-buffer -; }
|
function clippaste() { tmux save-buffer -; }
|
||||||
elif [[ $(uname -r) = *icrosoft* ]]; then
|
|
||||||
function clipcopy() { clip.exe < "${1:-/dev/stdin}"; }
|
|
||||||
function clippaste() { powershell.exe -noprofile -command Get-Clipboard; }
|
|
||||||
else
|
else
|
||||||
function _retry_clipboard_detection_or_fail() {
|
function _retry_clipboard_detection_or_fail() {
|
||||||
local clipcmd="${1}"; shift
|
local clipcmd="${1}"; shift
|
||||||
|
@ -100,8 +100,8 @@ function detect-clipboard() {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Detect at startup. A non-zero exit here indicates that the dummy clipboards were set,
|
function clipcopy clippaste {
|
||||||
# which is not really an error. If the user calls them, they will attempt to redetect
|
unfunction clipcopy clippaste
|
||||||
# (for example, perhaps the user has now installed xclip) and then either print an error
|
detect-clipboard || true # let one retry
|
||||||
# or proceed successfully.
|
"$0" "$@"
|
||||||
detect-clipboard || true
|
}
|
||||||
|
|
|
@ -18,9 +18,9 @@ if [[ "$CASE_SENSITIVE" = true ]]; then
|
||||||
zstyle ':completion:*' matcher-list 'r:|=*' 'l:|=* r:|=*'
|
zstyle ':completion:*' matcher-list 'r:|=*' 'l:|=* r:|=*'
|
||||||
else
|
else
|
||||||
if [[ "$HYPHEN_INSENSITIVE" = true ]]; then
|
if [[ "$HYPHEN_INSENSITIVE" = true ]]; then
|
||||||
zstyle ':completion:*' matcher-list 'm:{a-zA-Z-_}={A-Za-z_-}' 'r:|=*' 'l:|=* r:|=*'
|
zstyle ':completion:*' matcher-list 'm:{[:lower:][:upper:]-_}={[:upper:][:lower:]_-}' 'r:|=*' 'l:|=* r:|=*'
|
||||||
else
|
else
|
||||||
zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' 'r:|=*' 'l:|=* r:|=*'
|
zstyle ':completion:*' matcher-list 'm:{[:lower:][:upper:]}={[:upper:][:lower:]}' 'r:|=*' 'l:|=* r:|=*'
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
unset CASE_SENSITIVE HYPHEN_INSENSITIVE
|
unset CASE_SENSITIVE HYPHEN_INSENSITIVE
|
||||||
|
@ -49,7 +49,7 @@ zstyle ':completion:*:*:*:users' ignored-patterns \
|
||||||
adm amanda apache at avahi avahi-autoipd beaglidx bin cacti canna \
|
adm amanda apache at avahi avahi-autoipd beaglidx bin cacti canna \
|
||||||
clamav daemon dbus distcache dnsmasq dovecot fax ftp games gdm \
|
clamav daemon dbus distcache dnsmasq dovecot fax ftp games gdm \
|
||||||
gkrellmd gopher hacluster haldaemon halt hsqldb ident junkbust kdm \
|
gkrellmd gopher hacluster haldaemon halt hsqldb ident junkbust kdm \
|
||||||
ldap lp mail mailman mailnull man messagebus mldonkey mysql nagios \
|
ldap lp mail mailman mailnull man messagebus mldonkey mysql nagios \
|
||||||
named netdump news nfsnobody nobody nscd ntp nut nx obsrun openvpn \
|
named netdump news nfsnobody nobody nscd ntp nut nx obsrun openvpn \
|
||||||
operator pcap polkitd postfix postgres privoxy pulse pvm quagga radvd \
|
operator pcap polkitd postfix postgres privoxy pulse pvm quagga radvd \
|
||||||
rpc rpcuser rpm rtkit scard shutdown squid sshd statd svn sync tftp \
|
rpc rpcuser rpm rtkit scard shutdown squid sshd statd svn sync tftp \
|
||||||
|
|
|
@ -1,13 +1,8 @@
|
||||||
if [[ "$ENABLE_CORRECTION" == "true" ]]; then
|
if [[ "$ENABLE_CORRECTION" == "true" ]]; then
|
||||||
alias cp='nocorrect cp'
|
alias cp='nocorrect cp'
|
||||||
alias ebuild='nocorrect ebuild'
|
|
||||||
alias gist='nocorrect gist'
|
|
||||||
alias heroku='nocorrect heroku'
|
|
||||||
alias hpodder='nocorrect hpodder'
|
|
||||||
alias man='nocorrect man'
|
alias man='nocorrect man'
|
||||||
alias mkdir='nocorrect mkdir'
|
alias mkdir='nocorrect mkdir'
|
||||||
alias mv='nocorrect mv'
|
alias mv='nocorrect mv'
|
||||||
alias mysql='nocorrect mysql'
|
|
||||||
alias sudo='nocorrect sudo'
|
alias sudo='nocorrect sudo'
|
||||||
alias su='nocorrect su'
|
alias su='nocorrect su'
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
# Changing/making/removing directory
|
# Changing/making/removing directory
|
||||||
|
setopt auto_cd
|
||||||
setopt auto_pushd
|
setopt auto_pushd
|
||||||
setopt pushd_ignore_dups
|
setopt pushd_ignore_dups
|
||||||
setopt pushdminus
|
setopt pushdminus
|
||||||
|
|
||||||
|
|
||||||
alias -g ...='../..'
|
alias -g ...='../..'
|
||||||
alias -g ....='../../..'
|
alias -g ....='../../..'
|
||||||
alias -g .....='../../../..'
|
alias -g .....='../../../..'
|
||||||
|
|
|
@ -5,7 +5,7 @@ function zsh_stats() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function uninstall_oh_my_zsh() {
|
function uninstall_oh_my_zsh() {
|
||||||
env ZSH="$ZSH" sh "$ZSH/tools/uninstall.sh"
|
command env ZSH="$ZSH" sh "$ZSH/tools/uninstall.sh"
|
||||||
}
|
}
|
||||||
|
|
||||||
function upgrade_oh_my_zsh() {
|
function upgrade_oh_my_zsh() {
|
||||||
|
@ -30,6 +30,13 @@ function open_command() {
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
# If a URL is passed, $BROWSER might be set to a local browser within SSH.
|
||||||
|
# See https://github.com/ohmyzsh/ohmyzsh/issues/11098
|
||||||
|
if [[ -n "$BROWSER" && "$1" = (http|https)://* ]]; then
|
||||||
|
"$BROWSER" "$@"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
${=open_cmd} "$@" &>/dev/null
|
${=open_cmd} "$@" &>/dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +63,7 @@ function takegit() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function take() {
|
function take() {
|
||||||
if [[ $1 =~ ^(https?|ftp).*\.tar\.(gz|bz2|xz)$ ]]; then
|
if [[ $1 =~ ^(https?|ftp).*\.(tar\.(gz|bz2|xz)|tgz)$ ]]; then
|
||||||
takeurl "$1"
|
takeurl "$1"
|
||||||
elif [[ $1 =~ ^([A-Za-z0-9]\+@|https?|git|ssh|ftps?|rsync).*\.git/?$ ]]; then
|
elif [[ $1 =~ ^([A-Za-z0-9]\+@|https?|git|ssh|ftps?|rsync).*\.git/?$ ]]; then
|
||||||
takegit "$1"
|
takegit "$1"
|
||||||
|
@ -175,6 +182,8 @@ function omz_urlencode() {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Use LC_CTYPE=C to process text byte-by-byte
|
# Use LC_CTYPE=C to process text byte-by-byte
|
||||||
|
# Note that this doesn't work in Termux, as it only has UTF-8 locale.
|
||||||
|
# Characters will be processed as UTF-8, which is fine for URLs.
|
||||||
local i byte ord LC_ALL=C
|
local i byte ord LC_ALL=C
|
||||||
export LC_ALL
|
export LC_ALL
|
||||||
local reserved=';/?:@&=+$,'
|
local reserved=';/?:@&=+$,'
|
||||||
|
@ -199,6 +208,9 @@ function omz_urlencode() {
|
||||||
else
|
else
|
||||||
if [[ "$byte" == " " && -n $spaces_as_plus ]]; then
|
if [[ "$byte" == " " && -n $spaces_as_plus ]]; then
|
||||||
url_str+="+"
|
url_str+="+"
|
||||||
|
elif [[ "$PREFIX" = *com.termux* ]]; then
|
||||||
|
# Termux does not have non-UTF8 locales, so just send the UTF-8 character directly
|
||||||
|
url_str+="$byte"
|
||||||
else
|
else
|
||||||
ord=$(( [##16] #byte ))
|
ord=$(( [##16] #byte ))
|
||||||
url_str+="%$ord"
|
url_str+="%$ord"
|
||||||
|
|
64
lib/git.zsh
64
lib/git.zsh
|
@ -1,3 +1,5 @@
|
||||||
|
autoload -Uz is-at-least
|
||||||
|
|
||||||
# The git prompt's git commands are read-only and should not interfere with
|
# The git prompt's git commands are read-only and should not interfere with
|
||||||
# other processes. This environment variable is equivalent to running with `git
|
# other processes. This environment variable is equivalent to running with `git
|
||||||
# --no-optional-locks`, but falls back gracefully for older versions of git.
|
# --no-optional-locks`, but falls back gracefully for older versions of git.
|
||||||
|
@ -9,16 +11,21 @@ function __git_prompt_git() {
|
||||||
GIT_OPTIONAL_LOCKS=0 command git "$@"
|
GIT_OPTIONAL_LOCKS=0 command git "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
function git_prompt_info() {
|
function _omz_git_prompt_info() {
|
||||||
# If we are on a folder not tracked by git, get out.
|
# If we are on a folder not tracked by git, get out.
|
||||||
# Otherwise, check for hide-info at global and local repository level
|
# Otherwise, check for hide-info at global and local repository level
|
||||||
if ! __git_prompt_git rev-parse --git-dir &> /dev/null \
|
if ! __git_prompt_git rev-parse --git-dir &> /dev/null \
|
||||||
|| [[ "$(__git_prompt_git config --get oh-my-zsh.hide-info 2>/dev/null)" == 1 ]]; then
|
|| [[ "$(__git_prompt_git config --get oh-my-zsh.hide-info 2>/dev/null)" == 1 ]]; then
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Get either:
|
||||||
|
# - the current branch name
|
||||||
|
# - the tag name if we are on a tag
|
||||||
|
# - the short SHA of the current commit
|
||||||
local ref
|
local ref
|
||||||
ref=$(__git_prompt_git symbolic-ref --short HEAD 2> /dev/null) \
|
ref=$(__git_prompt_git symbolic-ref --short HEAD 2> /dev/null) \
|
||||||
|
|| ref=$(__git_prompt_git describe --tags --exact-match HEAD 2> /dev/null) \
|
||||||
|| ref=$(__git_prompt_git rev-parse --short HEAD 2> /dev/null) \
|
|| ref=$(__git_prompt_git rev-parse --short HEAD 2> /dev/null) \
|
||||||
|| return 0
|
|| return 0
|
||||||
|
|
||||||
|
@ -32,6 +39,57 @@ function git_prompt_info() {
|
||||||
echo "${ZSH_THEME_GIT_PROMPT_PREFIX}${ref:gs/%/%%}${upstream:gs/%/%%}$(parse_git_dirty)${ZSH_THEME_GIT_PROMPT_SUFFIX}"
|
echo "${ZSH_THEME_GIT_PROMPT_PREFIX}${ref:gs/%/%%}${upstream:gs/%/%%}$(parse_git_dirty)${ZSH_THEME_GIT_PROMPT_SUFFIX}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Use async version if setting is enabled, or unset but zsh version is at least 5.0.6.
|
||||||
|
# This avoids async prompt issues caused by previous zsh versions:
|
||||||
|
# - https://github.com/ohmyzsh/ohmyzsh/issues/12331
|
||||||
|
# - https://github.com/ohmyzsh/ohmyzsh/issues/12360
|
||||||
|
# TODO(2024-06-12): @mcornella remove workaround when CentOS 7 reaches EOL
|
||||||
|
if zstyle -t ':omz:alpha:lib:git' async-prompt \
|
||||||
|
|| { is-at-least 5.0.6 && zstyle -T ':omz:alpha:lib:git' async-prompt }; then
|
||||||
|
function git_prompt_info() {
|
||||||
|
if [[ -n "${_OMZ_ASYNC_OUTPUT[_omz_git_prompt_info]}" ]]; then
|
||||||
|
echo -n "${_OMZ_ASYNC_OUTPUT[_omz_git_prompt_info]}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function git_prompt_status() {
|
||||||
|
if [[ -n "${_OMZ_ASYNC_OUTPUT[_omz_git_prompt_status]}" ]]; then
|
||||||
|
echo -n "${_OMZ_ASYNC_OUTPUT[_omz_git_prompt_status]}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Conditionally register the async handler, only if it's needed in $PROMPT
|
||||||
|
# or any of the other prompt variables
|
||||||
|
function _defer_async_git_register() {
|
||||||
|
# Check if git_prompt_info is used in a prompt variable
|
||||||
|
case "${PS1}:${PS2}:${PS3}:${PS4}:${RPROMPT}:${RPS1}:${RPS2}:${RPS3}:${RPS4}" in
|
||||||
|
*(\$\(git_prompt_info\)|\`git_prompt_info\`)*)
|
||||||
|
_omz_register_handler _omz_git_prompt_info
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
case "${PS1}:${PS2}:${PS3}:${PS4}:${RPROMPT}:${RPS1}:${RPS2}:${RPS3}:${RPS4}" in
|
||||||
|
*(\$\(git_prompt_status\)|\`git_prompt_status\`)*)
|
||||||
|
_omz_register_handler _omz_git_prompt_status
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
add-zsh-hook -d precmd _defer_async_git_register
|
||||||
|
unset -f _defer_async_git_register
|
||||||
|
}
|
||||||
|
|
||||||
|
# Register the async handler first. This needs to be done before
|
||||||
|
# the async request prompt is run
|
||||||
|
precmd_functions=(_defer_async_git_register $precmd_functions)
|
||||||
|
else
|
||||||
|
function git_prompt_info() {
|
||||||
|
_omz_git_prompt_info
|
||||||
|
}
|
||||||
|
function git_prompt_status() {
|
||||||
|
_omz_git_prompt_status
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
|
||||||
# Checks if working tree is dirty
|
# Checks if working tree is dirty
|
||||||
function parse_git_dirty() {
|
function parse_git_dirty() {
|
||||||
local STATUS
|
local STATUS
|
||||||
|
@ -160,7 +218,7 @@ function git_prompt_long_sha() {
|
||||||
SHA=$(__git_prompt_git rev-parse HEAD 2> /dev/null) && echo "$ZSH_THEME_GIT_PROMPT_SHA_BEFORE$SHA$ZSH_THEME_GIT_PROMPT_SHA_AFTER"
|
SHA=$(__git_prompt_git rev-parse HEAD 2> /dev/null) && echo "$ZSH_THEME_GIT_PROMPT_SHA_BEFORE$SHA$ZSH_THEME_GIT_PROMPT_SHA_AFTER"
|
||||||
}
|
}
|
||||||
|
|
||||||
function git_prompt_status() {
|
function _omz_git_prompt_status() {
|
||||||
[[ "$(__git_prompt_git config --get oh-my-zsh.hide-status 2>/dev/null)" = 1 ]] && return
|
[[ "$(__git_prompt_git config --get oh-my-zsh.hide-status 2>/dev/null)" = 1 ]] && return
|
||||||
|
|
||||||
# Maps a git status prefix to an internal constant
|
# Maps a git status prefix to an internal constant
|
||||||
|
|
|
@ -24,8 +24,8 @@ else
|
||||||
if [[ -n "$GREP_OPTIONS" ]]; then
|
if [[ -n "$GREP_OPTIONS" ]]; then
|
||||||
# export grep, egrep and fgrep settings
|
# export grep, egrep and fgrep settings
|
||||||
alias grep="grep $GREP_OPTIONS"
|
alias grep="grep $GREP_OPTIONS"
|
||||||
alias egrep="egrep $GREP_OPTIONS"
|
alias egrep="grep -E $GREP_OPTIONS"
|
||||||
alias fgrep="fgrep $GREP_OPTIONS"
|
alias fgrep="grep -F $GREP_OPTIONS"
|
||||||
|
|
||||||
# write to cache file if cache directory is writable
|
# write to cache file if cache directory is writable
|
||||||
if [[ -w "$ZSH_CACHE_DIR" ]]; then
|
if [[ -w "$ZSH_CACHE_DIR" ]]; then
|
||||||
|
|
|
@ -1,19 +1,27 @@
|
||||||
## History wrapper
|
## History wrapper
|
||||||
function omz_history {
|
function omz_history {
|
||||||
local clear list
|
# parse arguments and remove from $@
|
||||||
zparseopts -E c=clear l=list
|
local clear list stamp REPLY
|
||||||
|
zparseopts -E -D c=clear l=list f=stamp E=stamp i=stamp t:=stamp
|
||||||
|
|
||||||
if [[ -n "$clear" ]]; then
|
if [[ -n "$clear" ]]; then
|
||||||
# if -c provided, clobber the history file
|
# if -c provided, clobber the history file
|
||||||
echo -n >| "$HISTFILE"
|
|
||||||
|
# confirm action before deleting history
|
||||||
|
print -nu2 "This action will irreversibly delete your command history. Are you sure? [y/N] "
|
||||||
|
builtin read -E
|
||||||
|
[[ "$REPLY" = [yY] ]] || return 0
|
||||||
|
|
||||||
|
print -nu2 >| "$HISTFILE"
|
||||||
fc -p "$HISTFILE"
|
fc -p "$HISTFILE"
|
||||||
echo >&2 History file deleted.
|
|
||||||
elif [[ -n "$list" ]]; then
|
print -u2 History file deleted.
|
||||||
# if -l provided, run as if calling `fc' directly
|
elif [[ $# -eq 0 ]]; then
|
||||||
builtin fc "$@"
|
# if no arguments provided, show full history starting from 1
|
||||||
|
builtin fc $stamp -l 1
|
||||||
else
|
else
|
||||||
# unless a number is provided, show all history events (starting from 1)
|
# otherwise, run `fc -l` with a custom format
|
||||||
[[ ${@[-1]-} = *[0-9]* ]] && builtin fc -l "$@" || builtin fc -l "$@" 1
|
builtin fc $stamp -l "$@"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,19 +32,26 @@ if [[ -n "${terminfo[knp]}" ]]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Start typing + [Up-Arrow] - fuzzy find history forward
|
# Start typing + [Up-Arrow] - fuzzy find history forward
|
||||||
if [[ -n "${terminfo[kcuu1]}" ]]; then
|
autoload -U up-line-or-beginning-search
|
||||||
autoload -U up-line-or-beginning-search
|
zle -N up-line-or-beginning-search
|
||||||
zle -N up-line-or-beginning-search
|
|
||||||
|
|
||||||
|
bindkey -M emacs "^[[A" up-line-or-beginning-search
|
||||||
|
bindkey -M viins "^[[A" up-line-or-beginning-search
|
||||||
|
bindkey -M vicmd "^[[A" up-line-or-beginning-search
|
||||||
|
if [[ -n "${terminfo[kcuu1]}" ]]; then
|
||||||
bindkey -M emacs "${terminfo[kcuu1]}" up-line-or-beginning-search
|
bindkey -M emacs "${terminfo[kcuu1]}" up-line-or-beginning-search
|
||||||
bindkey -M viins "${terminfo[kcuu1]}" up-line-or-beginning-search
|
bindkey -M viins "${terminfo[kcuu1]}" up-line-or-beginning-search
|
||||||
bindkey -M vicmd "${terminfo[kcuu1]}" up-line-or-beginning-search
|
bindkey -M vicmd "${terminfo[kcuu1]}" up-line-or-beginning-search
|
||||||
fi
|
fi
|
||||||
# Start typing + [Down-Arrow] - fuzzy find history backward
|
|
||||||
if [[ -n "${terminfo[kcud1]}" ]]; then
|
|
||||||
autoload -U down-line-or-beginning-search
|
|
||||||
zle -N down-line-or-beginning-search
|
|
||||||
|
|
||||||
|
# Start typing + [Down-Arrow] - fuzzy find history backward
|
||||||
|
autoload -U down-line-or-beginning-search
|
||||||
|
zle -N down-line-or-beginning-search
|
||||||
|
|
||||||
|
bindkey -M emacs "^[[B" down-line-or-beginning-search
|
||||||
|
bindkey -M viins "^[[B" down-line-or-beginning-search
|
||||||
|
bindkey -M vicmd "^[[B" down-line-or-beginning-search
|
||||||
|
if [[ -n "${terminfo[kcud1]}" ]]; then
|
||||||
bindkey -M emacs "${terminfo[kcud1]}" down-line-or-beginning-search
|
bindkey -M emacs "${terminfo[kcud1]}" down-line-or-beginning-search
|
||||||
bindkey -M viins "${terminfo[kcud1]}" down-line-or-beginning-search
|
bindkey -M viins "${terminfo[kcud1]}" down-line-or-beginning-search
|
||||||
bindkey -M vicmd "${terminfo[kcud1]}" down-line-or-beginning-search
|
bindkey -M vicmd "${terminfo[kcud1]}" down-line-or-beginning-search
|
||||||
|
|
21
lib/misc.zsh
21
lib/misc.zsh
|
@ -15,21 +15,24 @@ if [[ $DISABLE_MAGIC_FUNCTIONS != true ]]; then
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
## jobs
|
setopt multios # enable redirect to multiple streams: echo >file1 >file2
|
||||||
setopt long_list_jobs
|
setopt long_list_jobs # show long list format job notifications
|
||||||
|
setopt interactivecomments # recognize comments
|
||||||
|
|
||||||
env_default 'PAGER' 'less'
|
# define pager dependant on what is available (less or more)
|
||||||
env_default 'LESS' '-R'
|
if (( ${+commands[less]} )); then
|
||||||
|
env_default 'PAGER' 'less'
|
||||||
|
env_default 'LESS' '-R'
|
||||||
|
elif (( ${+commands[more]} )); then
|
||||||
|
env_default 'PAGER' 'more'
|
||||||
|
fi
|
||||||
|
|
||||||
## super user alias
|
## super user alias
|
||||||
alias _='sudo '
|
alias _='sudo '
|
||||||
|
|
||||||
## more intelligent acking for ubuntu users
|
## more intelligent acking for ubuntu users and no alias for users without ack
|
||||||
if (( $+commands[ack-grep] )); then
|
if (( $+commands[ack-grep] )); then
|
||||||
alias afind='ack-grep -il'
|
alias afind='ack-grep -il'
|
||||||
else
|
elif (( $+commands[ack] )); then
|
||||||
alias afind='ack -il'
|
alias afind='ack -il'
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# recognize comments
|
|
||||||
setopt interactivecomments
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ function chruby_prompt_info \
|
||||||
vi_mode_prompt_info \
|
vi_mode_prompt_info \
|
||||||
virtualenv_prompt_info \
|
virtualenv_prompt_info \
|
||||||
jenv_prompt_info \
|
jenv_prompt_info \
|
||||||
|
azure_prompt_info \
|
||||||
tf_prompt_info \
|
tf_prompt_info \
|
||||||
{
|
{
|
||||||
return 1
|
return 1
|
||||||
|
@ -39,5 +40,5 @@ ZSH_THEME_RVM_PROMPT_OPTIONS="i v g"
|
||||||
# use this to enable users to see their ruby version, no matter which
|
# use this to enable users to see their ruby version, no matter which
|
||||||
# version management system they use
|
# version management system they use
|
||||||
function ruby_prompt_info() {
|
function ruby_prompt_info() {
|
||||||
echo $(rvm_prompt_info || rbenv_prompt_info || chruby_prompt_info)
|
echo "$(rvm_prompt_info || rbenv_prompt_info || chruby_prompt_info)"
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ typeset -AHg FX FG BG
|
||||||
FX=(
|
FX=(
|
||||||
reset "%{[00m%}"
|
reset "%{[00m%}"
|
||||||
bold "%{[01m%}" no-bold "%{[22m%}"
|
bold "%{[01m%}" no-bold "%{[22m%}"
|
||||||
|
dim "%{[02m%}" no-dim "%{[22m%}"
|
||||||
italic "%{[03m%}" no-italic "%{[23m%}"
|
italic "%{[03m%}" no-italic "%{[23m%}"
|
||||||
underline "%{[04m%}" no-underline "%{[24m%}"
|
underline "%{[04m%}" no-underline "%{[24m%}"
|
||||||
blink "%{[05m%}" no-blink "%{[25m%}"
|
blink "%{[05m%}" no-blink "%{[25m%}"
|
||||||
|
|
|
@ -17,7 +17,7 @@ function title {
|
||||||
: ${2=$1}
|
: ${2=$1}
|
||||||
|
|
||||||
case "$TERM" in
|
case "$TERM" in
|
||||||
cygwin|xterm*|putty*|rxvt*|konsole*|ansi|mlterm*|alacritty|st*|foot)
|
cygwin|xterm*|putty*|rxvt*|konsole*|ansi|mlterm*|alacritty*|st*|foot*|contour*)
|
||||||
print -Pn "\e]2;${2:q}\a" # set window name
|
print -Pn "\e]2;${2:q}\a" # set window name
|
||||||
print -Pn "\e]1;${1:q}\a" # set tab name
|
print -Pn "\e]1;${1:q}\a" # set tab name
|
||||||
;;
|
;;
|
||||||
|
@ -109,28 +109,55 @@ if [[ -z "$INSIDE_EMACS" || "$INSIDE_EMACS" = vterm ]]; then
|
||||||
add-zsh-hook preexec omz_termsupport_preexec
|
add-zsh-hook preexec omz_termsupport_preexec
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Keep Apple Terminal.app's current working directory updated
|
# Keep terminal emulator's current working directory correct,
|
||||||
# Based on this answer: https://superuser.com/a/315029
|
# even if the current working directory path contains symbolic links
|
||||||
# With extra fixes to handle multibyte chars and non-UTF-8 locales
|
#
|
||||||
|
# References:
|
||||||
|
# - Apple's Terminal.app: https://superuser.com/a/315029
|
||||||
|
# - iTerm2: https://iterm2.com/documentation-escape-codes.html (iTerm2 Extension / CurrentDir+RemoteHost)
|
||||||
|
# - Konsole: https://bugs.kde.org/show_bug.cgi?id=327720#c1
|
||||||
|
# - libvte (gnome-terminal, mate-terminal, …): https://bugzilla.gnome.org/show_bug.cgi?id=675987#c14
|
||||||
|
# Apparently it had a bug before ~2012 were it would display the unknown OSC 7 code
|
||||||
|
#
|
||||||
|
# As of May 2021 mlterm, PuTTY, rxvt, screen, termux & xterm simply ignore the unknown OSC.
|
||||||
|
|
||||||
if [[ "$TERM_PROGRAM" == "Apple_Terminal" ]] && [[ -z "$INSIDE_EMACS" ]]; then
|
# Don't define the function if we're inside Emacs or in an SSH session (#11696)
|
||||||
# Emits the control sequence to notify Terminal.app of the cwd
|
if [[ -n "$INSIDE_EMACS" || -n "$SSH_CLIENT" || -n "$SSH_TTY" ]]; then
|
||||||
# Identifies the directory using a file: URI scheme, including
|
return
|
||||||
# the host name to disambiguate local vs. remote paths.
|
|
||||||
function update_terminalapp_cwd() {
|
|
||||||
emulate -L zsh
|
|
||||||
|
|
||||||
# Percent-encode the host and path names.
|
|
||||||
local URL_HOST URL_PATH
|
|
||||||
URL_HOST="$(omz_urlencode -P $HOST)" || return 1
|
|
||||||
URL_PATH="$(omz_urlencode -P $PWD)" || return 1
|
|
||||||
|
|
||||||
# Undocumented Terminal.app-specific control sequence
|
|
||||||
printf '\e]7;%s\a' "file://$URL_HOST$URL_PATH"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Use a precmd hook instead of a chpwd hook to avoid contaminating output
|
|
||||||
add-zsh-hook precmd update_terminalapp_cwd
|
|
||||||
# Run once to get initial cwd set
|
|
||||||
update_terminalapp_cwd
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Don't define the function if we're in an unsupported terminal
|
||||||
|
case "$TERM" in
|
||||||
|
# all of these either process OSC 7 correctly or ignore entirely
|
||||||
|
xterm*|putty*|rxvt*|konsole*|mlterm*|alacritty*|screen*|tmux*) ;;
|
||||||
|
contour*|foot*) ;;
|
||||||
|
*)
|
||||||
|
# Terminal.app and iTerm2 process OSC 7 correctly
|
||||||
|
case "$TERM_PROGRAM" in
|
||||||
|
Apple_Terminal|iTerm.app) ;;
|
||||||
|
*) return ;;
|
||||||
|
esac ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Emits the control sequence to notify many terminal emulators
|
||||||
|
# of the cwd
|
||||||
|
#
|
||||||
|
# Identifies the directory using a file: URI scheme, including
|
||||||
|
# the host name to disambiguate local vs. remote paths.
|
||||||
|
function omz_termsupport_cwd {
|
||||||
|
# Percent-encode the host and path names.
|
||||||
|
local URL_HOST URL_PATH
|
||||||
|
URL_HOST="$(omz_urlencode -P $HOST)" || return 1
|
||||||
|
URL_PATH="$(omz_urlencode -P $PWD)" || return 1
|
||||||
|
|
||||||
|
# Konsole errors if the HOST is provided
|
||||||
|
[[ -z "$KONSOLE_PROFILE_NAME" && -z "$KONSOLE_DBUS_SESSION" ]] || URL_HOST=""
|
||||||
|
|
||||||
|
# common control sequence (OSC 7) to set current host and path
|
||||||
|
printf "\e]7;file://%s%s\e\\" "${URL_HOST}" "${URL_PATH}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Use a precmd hook instead of a chpwd hook to avoid contaminating output
|
||||||
|
# i.e. when a script or function changes directory without `cd -q`, chpwd
|
||||||
|
# will be called the output may be swallowed by the script or function.
|
||||||
|
add-zsh-hook precmd omz_termsupport_cwd
|
||||||
|
|
169
lib/tests/cli.test.zsh
Normal file
169
lib/tests/cli.test.zsh
Normal file
|
@ -0,0 +1,169 @@
|
||||||
|
#!/usr/bin/zsh -df
|
||||||
|
|
||||||
|
run_awk() {
|
||||||
|
local -a dis_plugins=(${=1})
|
||||||
|
local input_text="$2"
|
||||||
|
|
||||||
|
(( ! DEBUG )) || set -xv
|
||||||
|
|
||||||
|
local awk_subst_plugins="\
|
||||||
|
gsub(/[ \t]+(${(j:|:)dis_plugins})[ \t]+/, \" \") # with spaces before or after
|
||||||
|
gsub(/[ \t]+(${(j:|:)dis_plugins})$/, \"\") # with spaces before and EOL
|
||||||
|
gsub(/^(${(j:|:)dis_plugins})[ \t]+/, \"\") # with BOL and spaces after
|
||||||
|
|
||||||
|
gsub(/\((${(j:|:)dis_plugins})[ \t]+/, \"(\") # with parenthesis before and spaces after
|
||||||
|
gsub(/[ \t]+(${(j:|:)dis_plugins})\)/, \")\") # with spaces before or parenthesis after
|
||||||
|
gsub(/\((${(j:|:)dis_plugins})\)/, \"()\") # with only parentheses
|
||||||
|
|
||||||
|
gsub(/^(${(j:|:)dis_plugins})\)/, \")\") # with BOL and closing parenthesis
|
||||||
|
gsub(/\((${(j:|:)dis_plugins})$/, \"(\") # with opening parenthesis and EOL
|
||||||
|
"
|
||||||
|
# Disable plugins awk script
|
||||||
|
local awk_script="
|
||||||
|
# if plugins=() is in oneline form, substitute disabled plugins and go to next line
|
||||||
|
/^[ \t]*plugins=\([^#]+\).*\$/ {
|
||||||
|
$awk_subst_plugins
|
||||||
|
print \$0
|
||||||
|
next
|
||||||
|
}
|
||||||
|
|
||||||
|
# if plugins=() is in multiline form, enable multi flag and disable plugins if they're there
|
||||||
|
/^[ \t]*plugins=\(/ {
|
||||||
|
multi=1
|
||||||
|
$awk_subst_plugins
|
||||||
|
print \$0
|
||||||
|
next
|
||||||
|
}
|
||||||
|
|
||||||
|
# if multi flag is enabled and we find a valid closing parenthesis, remove plugins and disable multi flag
|
||||||
|
multi == 1 && /^[^#]*\)/ {
|
||||||
|
multi=0
|
||||||
|
$awk_subst_plugins
|
||||||
|
print \$0
|
||||||
|
next
|
||||||
|
}
|
||||||
|
|
||||||
|
multi == 1 && length(\$0) > 0 {
|
||||||
|
$awk_subst_plugins
|
||||||
|
if (length(\$0) > 0) print \$0
|
||||||
|
next
|
||||||
|
}
|
||||||
|
|
||||||
|
{ print \$0 }
|
||||||
|
"
|
||||||
|
|
||||||
|
command awk "$awk_script" <<< "$input_text"
|
||||||
|
|
||||||
|
(( ! DEBUG )) || set +xv
|
||||||
|
}
|
||||||
|
|
||||||
|
# runs awk against stdin, checks if the resulting file is not empty and then checks if the file has valid zsh syntax
|
||||||
|
run_awk_and_test() {
|
||||||
|
local description="$1"
|
||||||
|
local plugins_to_disable="$2"
|
||||||
|
local input_text="$3"
|
||||||
|
local expected_output="$4"
|
||||||
|
|
||||||
|
local tmpfile==(:)
|
||||||
|
|
||||||
|
{
|
||||||
|
print -u2 "Test: $description"
|
||||||
|
DEBUG=0 run_awk "$plugins_to_disable" "$input_text" >| $tmpfile
|
||||||
|
|
||||||
|
if [[ ! -s "$tmpfile" ]]; then
|
||||||
|
print -u2 "\e[31mError\e[0m: output file empty"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! zsh -n $tmpfile; then
|
||||||
|
print -u2 "\e[31mError\e[0m: zsh syntax error"
|
||||||
|
diff -u $tmpfile <(echo "$expected_output")
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! diff -u --color=always $tmpfile <(echo "$expected_output"); then
|
||||||
|
if (( DEBUG )); then
|
||||||
|
print -u2 ""
|
||||||
|
DEBUG=1 run_awk "$plugins_to_disable" "$input_text"
|
||||||
|
print -u2 ""
|
||||||
|
fi
|
||||||
|
print -u2 "\e[31mError\e[0m: output file does not match expected output"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
print -u2 "\e[32mSuccess\e[0m"
|
||||||
|
} always {
|
||||||
|
print -u2 ""
|
||||||
|
command rm -f "$tmpfile"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# These tests are for the `omz plugin disable` command
|
||||||
|
run_awk_and_test \
|
||||||
|
"it should delete a single plugin in oneline format" \
|
||||||
|
"git" \
|
||||||
|
"plugins=(git)" \
|
||||||
|
"plugins=()"
|
||||||
|
|
||||||
|
run_awk_and_test \
|
||||||
|
"it should delete a single plugin in multiline format" \
|
||||||
|
"github" \
|
||||||
|
"plugins=(
|
||||||
|
github
|
||||||
|
)" \
|
||||||
|
"plugins=(
|
||||||
|
)"
|
||||||
|
|
||||||
|
run_awk_and_test \
|
||||||
|
"it should delete multiple plugins in oneline format" \
|
||||||
|
"github git z" \
|
||||||
|
"plugins=(github git z)" \
|
||||||
|
"plugins=()"
|
||||||
|
|
||||||
|
run_awk_and_test \
|
||||||
|
"it should delete multiple plugins in multiline format" \
|
||||||
|
"github git z" \
|
||||||
|
"plugins=(
|
||||||
|
github
|
||||||
|
git
|
||||||
|
z
|
||||||
|
)" \
|
||||||
|
"plugins=(
|
||||||
|
)"
|
||||||
|
|
||||||
|
run_awk_and_test \
|
||||||
|
"it should delete a single plugin among multiple in oneline format" \
|
||||||
|
"git" \
|
||||||
|
"plugins=(github git z)" \
|
||||||
|
"plugins=(github z)"
|
||||||
|
|
||||||
|
run_awk_and_test \
|
||||||
|
"it should delete a single plugin among multiple in multiline format" \
|
||||||
|
"git" \
|
||||||
|
"plugins=(
|
||||||
|
github
|
||||||
|
git
|
||||||
|
z
|
||||||
|
)" \
|
||||||
|
"plugins=(
|
||||||
|
github
|
||||||
|
z
|
||||||
|
)"
|
||||||
|
|
||||||
|
run_awk_and_test \
|
||||||
|
"it should delete multiple plugins in mixed format" \
|
||||||
|
"git z" \
|
||||||
|
"plugins=(github
|
||||||
|
git z)" \
|
||||||
|
"plugins=(github
|
||||||
|
)"
|
||||||
|
|
||||||
|
run_awk_and_test \
|
||||||
|
"it should delete multiple plugins in mixed format 2" \
|
||||||
|
"github z" \
|
||||||
|
"plugins=(github
|
||||||
|
git
|
||||||
|
z)" \
|
||||||
|
"plugins=(
|
||||||
|
git
|
||||||
|
)"
|
|
@ -1,59 +1,81 @@
|
||||||
# ls colors
|
# Sets color variable such as $fg, $bg, $color and $reset_color
|
||||||
autoload -U colors && colors
|
autoload -U colors && colors
|
||||||
|
|
||||||
# Enable ls colors
|
# Expand variables and commands in PROMPT variables
|
||||||
|
setopt prompt_subst
|
||||||
|
|
||||||
|
# Prompt function theming defaults
|
||||||
|
ZSH_THEME_GIT_PROMPT_PREFIX="git:(" # Beginning of the git prompt, before the branch name
|
||||||
|
ZSH_THEME_GIT_PROMPT_SUFFIX=")" # End of the git prompt
|
||||||
|
ZSH_THEME_GIT_PROMPT_DIRTY="*" # Text to display if the branch is dirty
|
||||||
|
ZSH_THEME_GIT_PROMPT_CLEAN="" # Text to display if the branch is clean
|
||||||
|
ZSH_THEME_RUBY_PROMPT_PREFIX="("
|
||||||
|
ZSH_THEME_RUBY_PROMPT_SUFFIX=")"
|
||||||
|
|
||||||
|
|
||||||
|
# Use diff --color if available
|
||||||
|
if command diff --color /dev/null{,} &>/dev/null; then
|
||||||
|
function diff {
|
||||||
|
command diff --color "$@"
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Don't set ls coloring if disabled
|
||||||
|
[[ "$DISABLE_LS_COLORS" != true ]] || return 0
|
||||||
|
|
||||||
|
# Default coloring for BSD-based ls
|
||||||
export LSCOLORS="Gxfxcxdxbxegedabagacad"
|
export LSCOLORS="Gxfxcxdxbxegedabagacad"
|
||||||
|
|
||||||
# TODO organise this chaotic logic
|
# Default coloring for GNU-based ls
|
||||||
|
if [[ -z "$LS_COLORS" ]]; then
|
||||||
if [[ "$DISABLE_LS_COLORS" != "true" ]]; then
|
# Define LS_COLORS via dircolors if available. Otherwise, set a default
|
||||||
# Find the option for using colors in ls, depending on the version
|
# equivalent to LSCOLORS (generated via https://geoff.greer.fm/lscolors)
|
||||||
if [[ "$OSTYPE" == netbsd* ]]; then
|
if (( $+commands[dircolors] )); then
|
||||||
# On NetBSD, test if "gls" (GNU ls) is installed (this one supports colors);
|
[[ -f "$HOME/.dircolors" ]] \
|
||||||
# otherwise, leave ls as is, because NetBSD's ls doesn't support -G
|
&& source <(dircolors -b "$HOME/.dircolors") \
|
||||||
gls --color -d . &>/dev/null && alias ls='gls --color=tty'
|
|| source <(dircolors -b)
|
||||||
elif [[ "$OSTYPE" == openbsd* ]]; then
|
|
||||||
# On OpenBSD, "gls" (ls from GNU coreutils) and "colorls" (ls from base,
|
|
||||||
# with color and multibyte support) are available from ports. "colorls"
|
|
||||||
# will be installed on purpose and can't be pulled in by installing
|
|
||||||
# coreutils, so prefer it to "gls".
|
|
||||||
gls --color -d . &>/dev/null && alias ls='gls --color=tty'
|
|
||||||
colorls -G -d . &>/dev/null && alias ls='colorls -G'
|
|
||||||
elif [[ "$OSTYPE" == (darwin|freebsd)* ]]; then
|
|
||||||
# this is a good alias, it works by default just using $LSCOLORS
|
|
||||||
ls -G . &>/dev/null && alias ls='ls -G'
|
|
||||||
|
|
||||||
# only use coreutils ls if there is a dircolors customization present ($LS_COLORS or .dircolors file)
|
|
||||||
# otherwise, gls will use the default color scheme which is ugly af
|
|
||||||
[[ -n "$LS_COLORS" || -f "$HOME/.dircolors" ]] && gls --color -d . &>/dev/null && alias ls='gls --color=tty'
|
|
||||||
else
|
else
|
||||||
# For GNU ls, we use the default ls color theme. They can later be overwritten by themes.
|
export LS_COLORS="di=1;36:ln=35:so=32:pi=33:ex=31:bd=34;46:cd=34;43:su=30;41:sg=30;46:tw=30;42:ow=30;43"
|
||||||
if [[ -z "$LS_COLORS" ]]; then
|
|
||||||
(( $+commands[dircolors] )) && eval "$(dircolors -b)"
|
|
||||||
fi
|
|
||||||
|
|
||||||
ls --color -d . &>/dev/null && alias ls='ls --color=tty' || { ls -G . &>/dev/null && alias ls='ls -G' }
|
|
||||||
|
|
||||||
# Take advantage of $LS_COLORS for completion as well.
|
|
||||||
zstyle ':completion:*' list-colors "${(s.:.)LS_COLORS}"
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# enable diff color if possible.
|
function test-ls-args {
|
||||||
if command diff --color /dev/null /dev/null &>/dev/null; then
|
local cmd="$1" # ls, gls, colorls, ...
|
||||||
alias diff='diff --color'
|
local args="${@[2,-1]}" # arguments except the first one
|
||||||
fi
|
command "$cmd" "$args" /dev/null &>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
setopt auto_cd
|
# Find the option for using colors in ls, depending on the version
|
||||||
setopt multios
|
case "$OSTYPE" in
|
||||||
setopt prompt_subst
|
netbsd*)
|
||||||
|
# On NetBSD, test if `gls` (GNU ls) is installed (this one supports colors);
|
||||||
|
# otherwise, leave ls as is, because NetBSD's ls doesn't support -G
|
||||||
|
test-ls-args gls --color && alias ls='gls --color=tty'
|
||||||
|
;;
|
||||||
|
openbsd*)
|
||||||
|
# On OpenBSD, `gls` (ls from GNU coreutils) and `colorls` (ls from base,
|
||||||
|
# with color and multibyte support) are available from ports.
|
||||||
|
# `colorls` will be installed on purpose and can't be pulled in by installing
|
||||||
|
# coreutils (which might be installed for ), so prefer it to `gls`.
|
||||||
|
test-ls-args gls --color && alias ls='gls --color=tty'
|
||||||
|
test-ls-args colorls -G && alias ls='colorls -G'
|
||||||
|
;;
|
||||||
|
(darwin|freebsd)*)
|
||||||
|
# This alias works by default just using $LSCOLORS
|
||||||
|
test-ls-args ls -G && alias ls='ls -G'
|
||||||
|
# Only use GNU ls if installed and there are user defaults for $LS_COLORS,
|
||||||
|
# as the default coloring scheme is not very pretty
|
||||||
|
zstyle -t ':omz:lib:theme-and-appearance' gnu-ls \
|
||||||
|
&& test-ls-args gls --color \
|
||||||
|
&& alias ls='gls --color=tty'
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
if test-ls-args ls --color; then
|
||||||
|
alias ls='ls --color=tty'
|
||||||
|
elif test-ls-args ls -G; then
|
||||||
|
alias ls='ls -G'
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
[[ -n "$WINDOW" ]] && SCREEN_NO="%B$WINDOW%b " || SCREEN_NO=""
|
unfunction test-ls-args
|
||||||
|
|
||||||
# git theming default: Variables for theming the git info prompt
|
|
||||||
ZSH_THEME_GIT_PROMPT_PREFIX="git:(" # Prefix at the very beginning of the prompt, before the branch name
|
|
||||||
ZSH_THEME_GIT_PROMPT_SUFFIX=")" # At the very end of the prompt
|
|
||||||
ZSH_THEME_GIT_PROMPT_DIRTY="*" # Text to display if the branch is dirty
|
|
||||||
ZSH_THEME_GIT_PROMPT_CLEAN="" # Text to display if the branch is clean
|
|
||||||
ZSH_THEME_RUBY_PROMPT_PREFIX="("
|
|
||||||
ZSH_THEME_RUBY_PROMPT_SUFFIX=")"
|
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
# due to malicious input as a consequence of CVE-2021-45444, which affects
|
# due to malicious input as a consequence of CVE-2021-45444, which affects
|
||||||
# zsh versions from 5.0.3 to 5.8.
|
# zsh versions from 5.0.3 to 5.8.
|
||||||
#
|
#
|
||||||
autoload -Uz +X regexp-replace VCS_INFO_formats 2>/dev/null || return
|
autoload -Uz +X regexp-replace VCS_INFO_formats 2>/dev/null || return 0
|
||||||
|
|
||||||
# We use $tmp here because it's already a local variable in VCS_INFO_formats
|
# We use $tmp here because it's already a local variable in VCS_INFO_formats
|
||||||
typeset PATCH='for tmp (base base-name branch misc revision subdir) hook_com[$tmp]="${hook_com[$tmp]//\%/%%}"'
|
typeset PATCH='for tmp (base base-name branch misc revision subdir) hook_com[$tmp]="${hook_com[$tmp]//\%/%%}"'
|
||||||
|
|
117
oh-my-zsh.sh
117
oh-my-zsh.sh
|
@ -1,14 +1,14 @@
|
||||||
|
# ANSI formatting function (\033[<code>m)
|
||||||
|
# 0: reset, 1: bold, 4: underline, 22: no bold, 24: no underline, 31: red, 33: yellow
|
||||||
|
omz_f() {
|
||||||
|
[ $# -gt 0 ] || return
|
||||||
|
IFS=";" printf "\033[%sm" $*
|
||||||
|
}
|
||||||
|
# If stdout is not a terminal ignore all formatting
|
||||||
|
[ -t 1 ] || omz_f() { :; }
|
||||||
|
|
||||||
# Protect against non-zsh execution of Oh My Zsh (use POSIX syntax here)
|
# Protect against non-zsh execution of Oh My Zsh (use POSIX syntax here)
|
||||||
[ -n "$ZSH_VERSION" ] || {
|
[ -n "$ZSH_VERSION" ] || {
|
||||||
# ANSI formatting function (\033[<code>m)
|
|
||||||
# 0: reset, 1: bold, 4: underline, 22: no bold, 24: no underline, 31: red, 33: yellow
|
|
||||||
omz_f() {
|
|
||||||
[ $# -gt 0 ] || return
|
|
||||||
IFS=";" printf "\033[%sm" $*
|
|
||||||
}
|
|
||||||
# If stdout is not a terminal ignore all formatting
|
|
||||||
[ -t 1 ] || omz_f() { :; }
|
|
||||||
|
|
||||||
omz_ptree() {
|
omz_ptree() {
|
||||||
# Get process tree of the current process
|
# Get process tree of the current process
|
||||||
pid=$$; pids="$pid"
|
pid=$$; pids="$pid"
|
||||||
|
@ -38,14 +38,25 @@
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Check if in emulation mode, if so early return
|
||||||
|
# https://github.com/ohmyzsh/ohmyzsh/issues/11686
|
||||||
|
[[ "$(emulate)" = zsh ]] || {
|
||||||
|
printf "$(omz_f 1 31)Error:$(omz_f 22) Oh My Zsh can't be loaded in \`$(emulate)\` emulation mode.$(omz_f 0)\n" >&2
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
unset -f omz_f
|
||||||
|
|
||||||
# If ZSH is not defined, use the current script's directory.
|
# If ZSH is not defined, use the current script's directory.
|
||||||
[[ -z "$ZSH" ]] && export ZSH="${${(%):-%x}:a:h}"
|
[[ -n "$ZSH" ]] || export ZSH="${${(%):-%x}:a:h}"
|
||||||
|
|
||||||
|
# Set ZSH_CUSTOM to the path where your custom config files
|
||||||
|
# and plugins exists, or else we will use the default custom/
|
||||||
|
[[ -n "$ZSH_CUSTOM" ]] || ZSH_CUSTOM="$ZSH/custom"
|
||||||
|
|
||||||
# Set ZSH_CACHE_DIR to the path where cache files should be created
|
# Set ZSH_CACHE_DIR to the path where cache files should be created
|
||||||
# or else we will use the default cache/
|
# or else we will use the default cache/
|
||||||
if [[ -z "$ZSH_CACHE_DIR" ]]; then
|
[[ -n "$ZSH_CACHE_DIR" ]] || ZSH_CACHE_DIR="$ZSH/cache"
|
||||||
ZSH_CACHE_DIR="$ZSH/cache"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Make sure $ZSH_CACHE_DIR is writable, otherwise use a directory in $HOME
|
# Make sure $ZSH_CACHE_DIR is writable, otherwise use a directory in $HOME
|
||||||
if [[ ! -w "$ZSH_CACHE_DIR" ]]; then
|
if [[ ! -w "$ZSH_CACHE_DIR" ]]; then
|
||||||
|
@ -57,23 +68,15 @@ mkdir -p "$ZSH_CACHE_DIR/completions"
|
||||||
(( ${fpath[(Ie)"$ZSH_CACHE_DIR/completions"]} )) || fpath=("$ZSH_CACHE_DIR/completions" $fpath)
|
(( ${fpath[(Ie)"$ZSH_CACHE_DIR/completions"]} )) || fpath=("$ZSH_CACHE_DIR/completions" $fpath)
|
||||||
|
|
||||||
# Check for updates on initial load...
|
# Check for updates on initial load...
|
||||||
if [[ "$DISABLE_AUTO_UPDATE" != true ]]; then
|
source "$ZSH/tools/check_for_upgrade.sh"
|
||||||
source "$ZSH/tools/check_for_upgrade.sh"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Initializes Oh My Zsh
|
# Initializes Oh My Zsh
|
||||||
|
|
||||||
# add a function path
|
# add a function path
|
||||||
fpath=("$ZSH/functions" "$ZSH/completions" $fpath)
|
fpath=($ZSH/{functions,completions} $ZSH_CUSTOM/{functions,completions} $fpath)
|
||||||
|
|
||||||
# Load all stock functions (from $fpath files) called below.
|
# Load all stock functions (from $fpath files) called below.
|
||||||
autoload -U compaudit compinit
|
autoload -U compaudit compinit zrecompile
|
||||||
|
|
||||||
# Set ZSH_CUSTOM to the path where your custom config files
|
|
||||||
# and plugins exists, or else we will use the default custom/
|
|
||||||
if [[ -z "$ZSH_CUSTOM" ]]; then
|
|
||||||
ZSH_CUSTOM="$ZSH/custom"
|
|
||||||
fi
|
|
||||||
|
|
||||||
is_plugin() {
|
is_plugin() {
|
||||||
local base_dir=$1
|
local base_dir=$1
|
||||||
|
@ -142,22 +145,63 @@ EOF
|
||||||
fi
|
fi
|
||||||
unset zcompdump_revision zcompdump_fpath zcompdump_refresh
|
unset zcompdump_revision zcompdump_fpath zcompdump_refresh
|
||||||
|
|
||||||
# Load all of the config files in ~/oh-my-zsh that end in .zsh
|
# zcompile the completion dump file if the .zwc is older or missing.
|
||||||
|
if command mkdir "${ZSH_COMPDUMP}.lock" 2>/dev/null; then
|
||||||
|
zrecompile -q -p "$ZSH_COMPDUMP"
|
||||||
|
command rm -rf "$ZSH_COMPDUMP.zwc.old" "${ZSH_COMPDUMP}.lock"
|
||||||
|
fi
|
||||||
|
|
||||||
|
_omz_source() {
|
||||||
|
local context filepath="$1"
|
||||||
|
|
||||||
|
# Construct zstyle context based on path
|
||||||
|
case "$filepath" in
|
||||||
|
lib/*) context="lib:${filepath:t:r}" ;; # :t = lib_name.zsh, :r = lib_name
|
||||||
|
plugins/*) context="plugins:${filepath:h:t}" ;; # :h = plugins/plugin_name, :t = plugin_name
|
||||||
|
esac
|
||||||
|
|
||||||
|
local disable_aliases=0
|
||||||
|
zstyle -T ":omz:${context}" aliases || disable_aliases=1
|
||||||
|
|
||||||
|
# Back up alias names prior to sourcing
|
||||||
|
local -A aliases_pre galiases_pre
|
||||||
|
if (( disable_aliases )); then
|
||||||
|
aliases_pre=("${(@kv)aliases}")
|
||||||
|
galiases_pre=("${(@kv)galiases}")
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Source file from $ZSH_CUSTOM if it exists, otherwise from $ZSH
|
||||||
|
if [[ -f "$ZSH_CUSTOM/$filepath" ]]; then
|
||||||
|
source "$ZSH_CUSTOM/$filepath"
|
||||||
|
elif [[ -f "$ZSH/$filepath" ]]; then
|
||||||
|
source "$ZSH/$filepath"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Unset all aliases that don't appear in the backed up list of aliases
|
||||||
|
if (( disable_aliases )); then
|
||||||
|
if (( #aliases_pre )); then
|
||||||
|
aliases=("${(@kv)aliases_pre}")
|
||||||
|
else
|
||||||
|
(( #aliases )) && unalias "${(@k)aliases}"
|
||||||
|
fi
|
||||||
|
if (( #galiases_pre )); then
|
||||||
|
galiases=("${(@kv)galiases_pre}")
|
||||||
|
else
|
||||||
|
(( #galiases )) && unalias "${(@k)galiases}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Load all of the lib files in ~/oh-my-zsh/lib that end in .zsh
|
||||||
# TIP: Add files you don't want in git to .gitignore
|
# TIP: Add files you don't want in git to .gitignore
|
||||||
for config_file ("$ZSH"/lib/*.zsh); do
|
for lib_file ("$ZSH"/lib/*.zsh); do
|
||||||
custom_config_file="$ZSH_CUSTOM/lib/${config_file:t}"
|
_omz_source "lib/${lib_file:t}"
|
||||||
[[ -f "$custom_config_file" ]] && config_file="$custom_config_file"
|
|
||||||
source "$config_file"
|
|
||||||
done
|
done
|
||||||
unset custom_config_file
|
unset lib_file
|
||||||
|
|
||||||
# Load all of the plugins that were defined in ~/.zshrc
|
# Load all of the plugins that were defined in ~/.zshrc
|
||||||
for plugin ($plugins); do
|
for plugin ($plugins); do
|
||||||
if [[ -f "$ZSH_CUSTOM/plugins/$plugin/$plugin.plugin.zsh" ]]; then
|
_omz_source "plugins/$plugin/$plugin.plugin.zsh"
|
||||||
source "$ZSH_CUSTOM/plugins/$plugin/$plugin.plugin.zsh"
|
|
||||||
elif [[ -f "$ZSH/plugins/$plugin/$plugin.plugin.zsh" ]]; then
|
|
||||||
source "$ZSH/plugins/$plugin/$plugin.plugin.zsh"
|
|
||||||
fi
|
|
||||||
done
|
done
|
||||||
unset plugin
|
unset plugin
|
||||||
|
|
||||||
|
@ -185,3 +229,6 @@ if [[ -n "$ZSH_THEME" ]]; then
|
||||||
echo "[oh-my-zsh] theme '$ZSH_THEME' not found"
|
echo "[oh-my-zsh] theme '$ZSH_THEME' not found"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# set completion colors to be the same as `ls`, after theme has been loaded
|
||||||
|
[[ -z "$LS_COLORS" ]] || zstyle ':completion:*' list-colors "${(s.:.)LS_COLORS}"
|
||||||
|
|
|
@ -14,16 +14,18 @@ clipboard.
|
||||||
## `opswd`
|
## `opswd`
|
||||||
|
|
||||||
The `opswd` command is a wrapper around the `op` command. It takes a service
|
The `opswd` command is a wrapper around the `op` command. It takes a service
|
||||||
name as an argument and copies the password for that service to the clipboard.
|
name as an argument and copies the username, then the password for that service
|
||||||
|
to the clipboard, after confirmation on the user part.
|
||||||
|
|
||||||
If the service also contains a TOTP, it is copied to the clipboard after 10 seconds.
|
If the service also contains a TOTP, it is copied to the clipboard after confirmation
|
||||||
Finally, after 20 seconds, the clipboard is cleared.
|
on the user part. Finally, after 20 seconds, the clipboard is cleared.
|
||||||
|
|
||||||
The function has completion support, so you can use tab completion to select
|
For example, `opswd github.com` will put your GitHub username into your clipboard. Then,
|
||||||
which service you want to get.
|
it will ask for confirmation to continue, and copy the password to your clipboard. Finally,
|
||||||
|
if a TOTP is available, it will be copied to the clipboard after your confirmation.
|
||||||
|
|
||||||
For example, `opswd github.com` will put your GitHub password into your clipboard, and if
|
This function has completion support, so you can use tab completion to select which
|
||||||
a TOTP is available, it will be copied to the clipboard after 10 seconds.
|
service you want to get.
|
||||||
|
|
||||||
> NOTE: you need to be signed in for `opswd` to work. If you are using biometric unlock,
|
> NOTE: you need to be signed in for `opswd` to work. If you are using biometric unlock,
|
||||||
> 1Password CLI will automatically prompt you to sign in. See:
|
> 1Password CLI will automatically prompt you to sign in. See:
|
||||||
|
|
|
@ -14,6 +14,17 @@ function opswd() {
|
||||||
# If not logged in, print error and return
|
# If not logged in, print error and return
|
||||||
op user list > /dev/null || return
|
op user list > /dev/null || return
|
||||||
|
|
||||||
|
local username
|
||||||
|
# Copy the username to the clipboard
|
||||||
|
if ! username=$(op item get "$service" --fields username 2>/dev/null); then
|
||||||
|
echo "error: could not obtain username for $service"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -n "$username" | clipcopy
|
||||||
|
echo "✔ username for service $service copied to the clipboard. Press Enter to continue"
|
||||||
|
read
|
||||||
|
|
||||||
local password
|
local password
|
||||||
# Copy the password to the clipboard
|
# Copy the password to the clipboard
|
||||||
if ! password=$(op item get "$service" --fields password 2>/dev/null); then
|
if ! password=$(op item get "$service" --fields password 2>/dev/null); then
|
||||||
|
@ -22,12 +33,13 @@ function opswd() {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo -n "$password" | clipcopy
|
echo -n "$password" | clipcopy
|
||||||
echo "✔ password for $service copied to clipboard"
|
echo "✔ password for $service copied to clipboard. Press Enter to continue"
|
||||||
|
read
|
||||||
|
|
||||||
# If there's a one time password, copy it to the clipboard after 10 seconds
|
# If there's a one time password, copy it to the clipboard
|
||||||
local totp
|
local totp
|
||||||
if totp=$(op item get --otp "$service" 2>/dev/null) && [[ -n "$totp" ]]; then
|
if totp=$(op item get --otp "$service" 2>/dev/null) && [[ -n "$totp" ]]; then
|
||||||
sleep 10 && echo -n "$totp" | clipcopy
|
echo -n "$totp" | clipcopy
|
||||||
echo "✔ TOTP for $service copied to clipboard"
|
echo "✔ TOTP for $service copied to clipboard"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
9
plugins/alias-finder/.zunit.yml
Normal file
9
plugins/alias-finder/.zunit.yml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
tap: false
|
||||||
|
directories:
|
||||||
|
tests: tests
|
||||||
|
output: tests/_output
|
||||||
|
support: tests/_support
|
||||||
|
time_limit: 0
|
||||||
|
fail_fast: false
|
||||||
|
allow_risky: false
|
||||||
|
verbose: true
|
|
@ -2,45 +2,67 @@
|
||||||
|
|
||||||
This plugin searches the defined aliases and outputs any that match the command inputted. This makes learning new aliases easier.
|
This plugin searches the defined aliases and outputs any that match the command inputted. This makes learning new aliases easier.
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
To use it, add `alias-finder` to the `plugins` array of your zshrc file:
|
To use it, add `alias-finder` to the `plugins` array of your zshrc file:
|
||||||
```
|
```
|
||||||
plugins=(... alias-finder)
|
plugins=(... alias-finder)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
To enable it for every single command, set zstyle in your `~/.zshrc`.
|
||||||
|
|
||||||
|
```zsh
|
||||||
|
# ~/.zshrc
|
||||||
|
|
||||||
|
zstyle ':omz:plugins:alias-finder' autoload yes # disabled by default
|
||||||
|
zstyle ':omz:plugins:alias-finder' longer yes # disabled by default
|
||||||
|
zstyle ':omz:plugins:alias-finder' exact yes # disabled by default
|
||||||
|
zstyle ':omz:plugins:alias-finder' cheaper yes # disabled by default
|
||||||
|
```
|
||||||
|
|
||||||
|
As you can see, options are also available with zstyle.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
To see if there is an alias defined for the command, pass it as an argument to `alias-finder`. This can also run automatically before each command you input - add `ZSH_ALIAS_FINDER_AUTOMATIC=true` to your zshrc if you want this.
|
|
||||||
|
|
||||||
## Options
|
When you execute a command alias finder will look at your defined aliases and suggest shorter aliases you could have used, for example:
|
||||||
|
|
||||||
- Use `--longer` or `-l` to allow the aliases to be longer than the input (match aliases if they contain the input).
|
Running the un-aliased `git status` command:
|
||||||
- Use `--exact` or `-e` to avoid matching aliases that are shorter than the input.
|
```sh
|
||||||
|
╭─tim@fox ~/repo/gitopolis ‹main›
|
||||||
|
╰─$ git status
|
||||||
|
|
||||||
## Examples
|
gst='git status' # <=== shorter suggestion from alias-finder
|
||||||
|
|
||||||
|
On branch main
|
||||||
|
Your branch is up-to-date with 'origin/main'.
|
||||||
|
nothing to commit, working tree clean
|
||||||
```
|
```
|
||||||
$ alias-finder "git pull"
|
|
||||||
gl='git pull'
|
Running a shorter `git st` alias from `.gitconfig` that it suggested :
|
||||||
g=git
|
```sh
|
||||||
|
╭─tim@fox ~/repo/gitopolis ‹main›
|
||||||
|
╰─$ git st
|
||||||
|
gs='git st' # <=== shorter suggestion from alias-finder
|
||||||
|
## main...origin/main
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Running the shortest `gs` shell alias that it found:
|
||||||
|
```sh
|
||||||
|
╭─tim@fox ~/repo/gitopolis ‹main›
|
||||||
|
╰─$ gs
|
||||||
|
# <=== no suggestions alias-finder because this is the shortest
|
||||||
|
## main...origin/main
|
||||||
```
|
```
|
||||||
$ alias-finder "web_search google oh my zsh"
|
|
||||||
google='web_search google'
|
![image](https://github.com/ohmyzsh/ohmyzsh/assets/19378/39642750-fb10-4f1a-b7f9-f36789eeb01b)
|
||||||
```
|
|
||||||
```
|
|
||||||
$ alias-finder "git commit -v"
|
### Options
|
||||||
gc="git commit -v"
|
|
||||||
g=git
|
> In order to clarify, let's say `alias a=abc` has source 'abc' and destination 'a'.
|
||||||
```
|
|
||||||
```
|
- Use `--longer` or `-l` to include aliases where the source is longer than the input (in other words, the source could contain the whole input).
|
||||||
$ alias-finder -e "git commit -v"
|
- Use `--exact` or `-e` to avoid aliases where the source is shorter than the input (in other words, the source must be the same with the input).
|
||||||
gc='git commit -v'
|
- Use `--cheaper` or `-c` to avoid aliases where the destination is longer than the input (in other words, the destination must be the shorter than the input).
|
||||||
```
|
|
||||||
```
|
|
||||||
$ alias-finder -l "git commit -v"
|
|
||||||
gc='git commit -v'
|
|
||||||
'gc!'='git commit -v --amend'
|
|
||||||
gca='git commit -v -a'
|
|
||||||
'gca!'='git commit -v -a --amend'
|
|
||||||
'gcan!'='git commit -v -a --no-edit --amend'
|
|
||||||
'gcans!'='git commit -v -a -s --no-edit --amend'
|
|
||||||
'gcn!'='git commit -v --no-edit --amend'
|
|
||||||
```
|
|
||||||
|
|
|
@ -1,44 +1,59 @@
|
||||||
alias-finder() {
|
alias-finder() {
|
||||||
local cmd="" exact="" longer="" wordStart="" wordEnd="" multiWordEnd=""
|
local cmd=" " exact="" longer="" cheaper="" wordEnd="'{0,1}$" finder="" filter=""
|
||||||
for i in $@; do
|
|
||||||
case $i in
|
# build command and options
|
||||||
|
for c in "$@"; do
|
||||||
|
case $c in
|
||||||
|
# TODO: Remove backward compatibility (other than zstyle form)
|
||||||
|
# set options if exist
|
||||||
-e|--exact) exact=true;;
|
-e|--exact) exact=true;;
|
||||||
-l|--longer) longer=true;;
|
-l|--longer) longer=true;;
|
||||||
*)
|
-c|--cheaper) cheaper=true;;
|
||||||
if [[ -z $cmd ]]; then
|
# concatenate cmd
|
||||||
cmd=$i
|
*) cmd="$cmd$c " ;;
|
||||||
else
|
|
||||||
cmd="$cmd $i"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
cmd=$(sed 's/[].\|$(){}?+*^[]/\\&/g' <<< $cmd) # adds escaping for grep
|
|
||||||
if (( $(wc -l <<< $cmd) == 1 )); then
|
zstyle -t ':omz:plugins:alias-finder' longer && longer=true
|
||||||
while [[ $cmd != "" ]]; do
|
zstyle -t ':omz:plugins:alias-finder' exact && exact=true
|
||||||
if [[ $longer = true ]]; then
|
zstyle -t ':omz:plugins:alias-finder' cheaper && cheaper=true
|
||||||
wordStart="'{0,1}"
|
|
||||||
else
|
# format cmd for grep
|
||||||
wordEnd="$"
|
## - replace newlines with spaces
|
||||||
multiWordEnd="'$"
|
## - trim both ends
|
||||||
fi
|
## - replace multiple spaces with one space
|
||||||
if [[ $cmd == *" "* ]]; then
|
## - add escaping character to special characters
|
||||||
local finder="'$cmd$multiWordEnd"
|
cmd=$(echo -n "$cmd" | tr '\n' ' ' | xargs | tr -s '[:space:]' | sed 's/[].\|$(){}?+*^[]/\\&/g')
|
||||||
else
|
|
||||||
local finder=$wordStart$cmd$wordEnd
|
if [[ $longer == true ]]; then
|
||||||
fi
|
wordEnd="" # remove wordEnd to find longer aliases
|
||||||
alias | grep -E "=$finder"
|
|
||||||
if [[ $exact = true || $longer = true ]]; then
|
|
||||||
break
|
|
||||||
else
|
|
||||||
cmd=$(sed -E 's/ {0,1}[^ ]*$//' <<< $cmd) # removes last word
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# find with alias and grep, removing last word each time until no more words
|
||||||
|
while [[ $cmd != "" ]]; do
|
||||||
|
finder="'{0,1}$cmd$wordEnd"
|
||||||
|
|
||||||
|
# make filter to find only shorter results than current cmd
|
||||||
|
if [[ $cheaper == true ]]; then
|
||||||
|
cmdLen=$(echo -n "$cmd" | wc -c)
|
||||||
|
filter="^'{0,1}.{0,$((cmdLen - 1))}="
|
||||||
|
fi
|
||||||
|
|
||||||
|
alias | grep -E "$filter" | grep -E "=$finder"
|
||||||
|
|
||||||
|
if [[ $exact == true ]]; then
|
||||||
|
break # because exact case is only one
|
||||||
|
elif [[ $longer = true ]]; then
|
||||||
|
break # because above grep command already found every longer aliases during first cycle
|
||||||
|
fi
|
||||||
|
|
||||||
|
cmd=$(sed -E 's/ {0,}[^ ]*$//' <<< "$cmd") # remove last word
|
||||||
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
preexec_alias-finder() {
|
preexec_alias-finder() {
|
||||||
if [[ $ZSH_ALIAS_FINDER_AUTOMATIC = true ]]; then
|
# TODO: Remove backward compatibility (other than zstyle form)
|
||||||
|
zstyle -t ':omz:plugins:alias-finder' autoload && alias-finder $1 || if [[ $ZSH_ALIAS_FINDER_AUTOMATIC = true ]]; then
|
||||||
alias-finder $1
|
alias-finder $1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
0
plugins/alias-finder/tests/_output/.gitkeep
Normal file
0
plugins/alias-finder/tests/_output/.gitkeep
Normal file
0
plugins/alias-finder/tests/_support/.gitkeep
Normal file
0
plugins/alias-finder/tests/_support/.gitkeep
Normal file
2
plugins/alias-finder/tests/_support/bootstrap
Normal file
2
plugins/alias-finder/tests/_support/bootstrap
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
#!/usr/bin/env zsh
|
||||||
|
# Write your bootstrap code here
|
107
plugins/alias-finder/tests/test_run.sh
Normal file
107
plugins/alias-finder/tests/test_run.sh
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
#!/usr/bin/env zunit
|
||||||
|
|
||||||
|
@setup {
|
||||||
|
load ../alias-finder.plugin.zsh
|
||||||
|
|
||||||
|
set_git_aliases() {
|
||||||
|
unalias -a # all
|
||||||
|
alias g="git"
|
||||||
|
alias gc="git commit"
|
||||||
|
alias gcv="git commit -v"
|
||||||
|
alias gcvs="git commit -v -S"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'find aliases that contain input' {
|
||||||
|
set_git_aliases
|
||||||
|
|
||||||
|
run alias-finder "git"
|
||||||
|
|
||||||
|
assert "${#lines[@]}" equals 1
|
||||||
|
assert "${lines[1]}" same_as "g=git"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'find aliases that contain input with whitespaces at ends' {
|
||||||
|
set_git_aliases
|
||||||
|
|
||||||
|
run alias-finder " git "
|
||||||
|
|
||||||
|
assert "${#lines[@]}" equals 1
|
||||||
|
assert "${lines[1]}" same_as "g=git"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'find aliases that contain multiple words' {
|
||||||
|
set_git_aliases
|
||||||
|
|
||||||
|
run alias-finder "git commit -v"
|
||||||
|
|
||||||
|
assert "${#lines[@]}" equals 3
|
||||||
|
assert "${lines[1]}" same_as "gcv='git commit -v'"
|
||||||
|
assert "${lines[2]}" same_as "gc='git commit'"
|
||||||
|
assert "${lines[3]}" same_as "g=git"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'find alias that is the same with input when --exact option is set' {
|
||||||
|
set_git_aliases
|
||||||
|
|
||||||
|
run alias-finder -e "git"
|
||||||
|
|
||||||
|
assert "${#lines[@]}" equals 1
|
||||||
|
assert "${lines[1]}" same_as "g=git"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'find alias that is the same with multiple words input when --exact option is set' {
|
||||||
|
set_git_aliases
|
||||||
|
|
||||||
|
run alias-finder -e "git commit -v"
|
||||||
|
|
||||||
|
assert "${#lines[@]}" equals 1
|
||||||
|
assert "${lines[1]}" same_as "gcv='git commit -v'"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'find alias that is the same with or longer than input when --longer option is set' {
|
||||||
|
set_git_aliases
|
||||||
|
|
||||||
|
run alias-finder -l "git"
|
||||||
|
|
||||||
|
assert "${#lines[@]}" equals 4
|
||||||
|
assert "${lines[1]}" same_as "g=git"
|
||||||
|
assert "${lines[2]}" same_as "gc='git commit'"
|
||||||
|
assert "${lines[3]}" same_as "gcv='git commit -v'"
|
||||||
|
assert "${lines[4]}" same_as "gcvs='git commit -v -S'"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'find alias that is the same with or longer than multiple words input when --longer option is set' {
|
||||||
|
set_git_aliases
|
||||||
|
|
||||||
|
run alias-finder -l "git commit -v"
|
||||||
|
|
||||||
|
assert "${#lines[@]}" equals 2
|
||||||
|
assert "${lines[1]}" same_as "gcv='git commit -v'"
|
||||||
|
assert "${lines[2]}" same_as "gcvs='git commit -v -S'"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'find aliases including expensive (longer) than input' {
|
||||||
|
set_git_aliases
|
||||||
|
alias expensiveCommands="git commit"
|
||||||
|
|
||||||
|
run alias-finder "git commit -v"
|
||||||
|
|
||||||
|
assert "${#lines[@]}" equals 4
|
||||||
|
assert "${lines[1]}" same_as "gcv='git commit -v'"
|
||||||
|
assert "${lines[2]}" same_as "expensiveCommands='git commit'"
|
||||||
|
assert "${lines[3]}" same_as "gc='git commit'"
|
||||||
|
assert "${lines[4]}" same_as "g=git"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'find aliases excluding expensive (longer) than input when --cheap option is set' {
|
||||||
|
set_git_aliases
|
||||||
|
alias expensiveCommands="git commit"
|
||||||
|
|
||||||
|
run alias-finder -c "git commit -v"
|
||||||
|
|
||||||
|
assert "${#lines[@]}" equals 3
|
||||||
|
assert "${lines[1]}" same_as "gcv='git commit -v'"
|
||||||
|
assert "${lines[2]}" same_as "gc='git commit'"
|
||||||
|
assert "${lines[3]}" same_as "g=git"
|
||||||
|
}
|
|
@ -15,8 +15,14 @@ Requirements: Python needs to be installed.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
- `acs`: show all aliases by group.
|
- `als`: show all aliases by group
|
||||||
|
|
||||||
- `acs <keyword>`: filter aliases by `<keyword>` and highlight.
|
- `als -h/--help`: print help message
|
||||||
|
|
||||||
![screenshot](https://cloud.githubusercontent.com/assets/3602957/11581913/cb54fb8a-9a82-11e5-846b-5a67f67ad9ad.png)
|
- `als <keyword(s)>`: filter and highlight aliases by `<keyword>`
|
||||||
|
|
||||||
|
- `als -g <group>/--group <group>`: show only aliases for group `<group>`. Multiple uses of the flag show all groups
|
||||||
|
|
||||||
|
- `als --groups`: show only group names
|
||||||
|
|
||||||
|
![screenshot](https://github.com/ohmyzsh/ohmyzsh/assets/66907184/5bfa00ea-5fc3-4e97-8b22-2f74f6b948c7)
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
# with lots of 3rd-party amazing aliases installed, just need something to explore it quickly.
|
# Handle $0 according to the standard:
|
||||||
#
|
# https://zdharma-continuum.github.io/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html
|
||||||
# - acs: alias cheatsheet
|
0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}"
|
||||||
# group alias by command, pass addition argv to grep.
|
0="${${(M)0:#/*}:-$PWD/$0}"
|
||||||
function acs(){
|
|
||||||
(( $+commands[python3] )) || {
|
eval '
|
||||||
echo "[error] No python executable detected"
|
function als(){
|
||||||
return
|
(( $+commands[python3] )) || {
|
||||||
|
echo "[error] No python executable detected"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
alias | python3 "'"${0:h}"'/cheatsheet.py" "$@"
|
||||||
}
|
}
|
||||||
alias | python3 ${functions_source[$0]:h}/cheatsheet.py $@
|
'
|
||||||
}
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import sys
|
import sys
|
||||||
import itertools
|
import itertools
|
||||||
import termcolor
|
import termcolor
|
||||||
|
import argparse
|
||||||
|
|
||||||
def parse(line):
|
def parse(line):
|
||||||
left = line[0:line.find('=')].strip()
|
left = line[0:line.find('=')].strip()
|
||||||
|
@ -14,6 +15,7 @@ def parse(line):
|
||||||
|
|
||||||
def cheatsheet(lines):
|
def cheatsheet(lines):
|
||||||
exps = [ parse(line) for line in lines ]
|
exps = [ parse(line) for line in lines ]
|
||||||
|
exps.sort(key=lambda exp:exp[2])
|
||||||
cheatsheet = {'_default': []}
|
cheatsheet = {'_default': []}
|
||||||
for key, group in itertools.groupby(exps, lambda exp:exp[2]):
|
for key, group in itertools.groupby(exps, lambda exp:exp[2]):
|
||||||
group_list = [ item for item in group ]
|
group_list = [ item for item in group ]
|
||||||
|
@ -26,7 +28,7 @@ def cheatsheet(lines):
|
||||||
target_aliases.extend(group_list)
|
target_aliases.extend(group_list)
|
||||||
return cheatsheet
|
return cheatsheet
|
||||||
|
|
||||||
def pretty_print_group(key, aliases, highlight=None):
|
def pretty_print_group(key, aliases, highlight=None, only_groupname=False):
|
||||||
if len(aliases) == 0:
|
if len(aliases) == 0:
|
||||||
return
|
return
|
||||||
group_hl_formatter = lambda g, hl: termcolor.colored(hl, 'yellow').join([termcolor.colored(part, 'red') for part in ('[%s]' % g).split(hl)])
|
group_hl_formatter = lambda g, hl: termcolor.colored(hl, 'yellow').join([termcolor.colored(part, 'red') for part in ('[%s]' % g).split(hl)])
|
||||||
|
@ -35,21 +37,33 @@ def pretty_print_group(key, aliases, highlight=None):
|
||||||
alias_formatter = lambda alias: termcolor.colored('\t%s = %s' % alias[0:2], 'green')
|
alias_formatter = lambda alias: termcolor.colored('\t%s = %s' % alias[0:2], 'green')
|
||||||
if highlight and len(highlight)>0:
|
if highlight and len(highlight)>0:
|
||||||
print (group_hl_formatter(key, highlight))
|
print (group_hl_formatter(key, highlight))
|
||||||
print ('\n'.join([alias_hl_formatter(alias, highlight) for alias in aliases]))
|
if not only_groupname:
|
||||||
|
print ('\n'.join([alias_hl_formatter(alias, highlight) for alias in aliases]))
|
||||||
else:
|
else:
|
||||||
print (group_formatter(key))
|
print (group_formatter(key))
|
||||||
print ('\n'.join([alias_formatter(alias) for alias in aliases]))
|
if not only_groupname:
|
||||||
|
print ('\n'.join([alias_formatter(alias) for alias in aliases]))
|
||||||
print ('')
|
print ('')
|
||||||
|
|
||||||
def pretty_print(cheatsheet, wfilter):
|
def pretty_print(cheatsheet, wfilter, group_list=None, groups_only=False):
|
||||||
sorted_key = sorted(cheatsheet.keys())
|
sorted_key = sorted(cheatsheet.keys())
|
||||||
for key in sorted_key:
|
for key in sorted_key:
|
||||||
|
if group_list and key not in group_list:
|
||||||
|
continue
|
||||||
aliases = cheatsheet.get(key)
|
aliases = cheatsheet.get(key)
|
||||||
if not wfilter:
|
if not wfilter:
|
||||||
pretty_print_group(key, aliases, wfilter)
|
pretty_print_group(key, aliases, wfilter, groups_only)
|
||||||
else:
|
else:
|
||||||
pretty_print_group(key, [ alias for alias in aliases if alias[0].find(wfilter)>-1 or alias[1].find(wfilter)>-1], wfilter)
|
pretty_print_group(key, [ alias for alias in aliases if alias[0].find(wfilter)>-1 or alias[1].find(wfilter)>-1], wfilter)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
parser = argparse.ArgumentParser(description="Pretty print aliases.", prog="als")
|
||||||
|
parser.add_argument('filter', nargs="*", metavar="<keyword>", help="search aliases matching keywords")
|
||||||
|
parser.add_argument('-g', '--group', dest="group_list", action='append', help="only print aliases in given groups")
|
||||||
|
parser.add_argument('--groups', dest='groups_only', action='store_true', help="only print alias groups")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
lines = sys.stdin.readlines()
|
lines = sys.stdin.readlines()
|
||||||
pretty_print(cheatsheet(lines), sys.argv[1] if len(sys.argv)>1 else None)
|
group_list = args.group_list or None
|
||||||
|
wfilter = " ".join(args.filter) or None
|
||||||
|
pretty_print(cheatsheet(lines), wfilter, group_list, args.groups_only)
|
||||||
|
|
|
@ -21,7 +21,6 @@ plugins=(... ansible)
|
||||||
| `acon` | command `ansible-console` |
|
| `acon` | command `ansible-console` |
|
||||||
| `ainv` | command `ansible-inventory` |
|
| `ainv` | command `ansible-inventory` |
|
||||||
| `aplaybook` | command `ansible-playbook` |
|
| `aplaybook` | command `ansible-playbook` |
|
||||||
| `ainv` | command `ansible-inventory` |
|
|
||||||
| `adoc` | command `ansible-doc` |
|
| `adoc` | command `ansible-doc` |
|
||||||
| `agal` | command `ansible-galaxy` |
|
| `agal` | command `ansible-galaxy` |
|
||||||
| `apull` | command `ansible-pull` |
|
| `apull` | command `ansible-pull` |
|
||||||
|
|
|
@ -181,3 +181,4 @@ whether the package manager is installed, checked in the following order:
|
||||||
- Ybalrid (Arthur Brainville) - ybalrid@ybalrid.info
|
- Ybalrid (Arthur Brainville) - ybalrid@ybalrid.info
|
||||||
- Jeff M. Hubbard - jeffmhubbard@gmail.com
|
- Jeff M. Hubbard - jeffmhubbard@gmail.com
|
||||||
- K. Harishankar(harishnkr) - hari2menon1234@gmail.com
|
- K. Harishankar(harishnkr) - hari2menon1234@gmail.com
|
||||||
|
- WH-2099 - wh2099@outlook.com
|
|
@ -23,30 +23,27 @@ alias pacfiles='pacman -F'
|
||||||
alias pacls='pacman -Ql'
|
alias pacls='pacman -Ql'
|
||||||
alias pacown='pacman -Qo'
|
alias pacown='pacman -Qo'
|
||||||
alias pacupd="sudo pacman -Sy"
|
alias pacupd="sudo pacman -Sy"
|
||||||
alias upgrade='sudo pacman -Syu'
|
|
||||||
|
|
||||||
function paclist() {
|
function paclist() {
|
||||||
# Based on https://bbs.archlinux.org/viewtopic.php?id=93683
|
pacman -Qqe | xargs -I{} -P0 --no-run-if-empty pacman -Qs --color=auto "^{}\$"
|
||||||
pacman -Qqe | \
|
|
||||||
xargs -I '{}' \
|
|
||||||
expac "${bold_color}% 20n ${fg_no_bold[white]}%d${reset_color}" '{}'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function pacdisowned() {
|
function pacdisowned() {
|
||||||
local tmp db fs
|
local tmp_dir db fs
|
||||||
tmp=${TMPDIR-/tmp}/pacman-disowned-$UID-$$
|
tmp_dir=$(mktemp --directory)
|
||||||
db=$tmp/db
|
db=$tmp_dir/db
|
||||||
fs=$tmp/fs
|
fs=$tmp_dir/fs
|
||||||
|
|
||||||
mkdir "$tmp"
|
trap "rm -rf $tmp_dir" EXIT
|
||||||
trap 'rm -rf "$tmp"' EXIT
|
|
||||||
|
|
||||||
pacman -Qlq | sort -u > "$db"
|
pacman -Qlq | sort -u > "$db"
|
||||||
|
|
||||||
find /bin /etc /lib /sbin /usr ! -name lost+found \
|
find /etc /usr ! -name lost+found \
|
||||||
\( -type d -printf '%p/\n' -o -print \) | sort > "$fs"
|
\( -type d -printf '%p/\n' -o -print \) | sort > "$fs"
|
||||||
|
|
||||||
comm -23 "$fs" "$db"
|
comm -23 "$fs" "$db"
|
||||||
|
|
||||||
|
rm -rf $tmp_dir
|
||||||
}
|
}
|
||||||
|
|
||||||
alias pacmanallkeys='sudo pacman-key --refresh-keys'
|
alias pacmanallkeys='sudo pacman-key --refresh-keys'
|
||||||
|
@ -109,7 +106,6 @@ if (( $+commands[aura] )); then
|
||||||
alias auupd="sudo aura -Sy"
|
alias auupd="sudo aura -Sy"
|
||||||
alias auupg='sudo sh -c "aura -Syu && aura -Au"'
|
alias auupg='sudo sh -c "aura -Syu && aura -Au"'
|
||||||
alias ausu='sudo sh -c "aura -Syu --no-confirm && aura -Au --no-confirm"'
|
alias ausu='sudo sh -c "aura -Syu --no-confirm && aura -Au --no-confirm"'
|
||||||
alias upgrade='sudo aura -Syu'
|
|
||||||
|
|
||||||
# extra bonus specially for aura
|
# extra bonus specially for aura
|
||||||
alias auown="aura -Qqo"
|
alias auown="aura -Qqo"
|
||||||
|
@ -136,7 +132,6 @@ if (( $+commands[pacaur] )); then
|
||||||
alias painsd='pacaur -S --asdeps'
|
alias painsd='pacaur -S --asdeps'
|
||||||
alias pamir='pacaur -Syy'
|
alias pamir='pacaur -Syy'
|
||||||
alias paupd="pacaur -Sy"
|
alias paupd="pacaur -Sy"
|
||||||
alias upgrade='pacaur -Syu'
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if (( $+commands[trizen] )); then
|
if (( $+commands[trizen] )); then
|
||||||
|
@ -158,7 +153,6 @@ if (( $+commands[trizen] )); then
|
||||||
alias trinsd='trizen -S --asdeps'
|
alias trinsd='trizen -S --asdeps'
|
||||||
alias trmir='trizen -Syy'
|
alias trmir='trizen -Syy'
|
||||||
alias trupd="trizen -Sy"
|
alias trupd="trizen -Sy"
|
||||||
alias upgrade='trizen -Syu'
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if (( $+commands[yay] )); then
|
if (( $+commands[yay] )); then
|
||||||
|
@ -180,5 +174,30 @@ if (( $+commands[yay] )); then
|
||||||
alias yainsd='yay -S --asdeps'
|
alias yainsd='yay -S --asdeps'
|
||||||
alias yamir='yay -Syy'
|
alias yamir='yay -Syy'
|
||||||
alias yaupd="yay -Sy"
|
alias yaupd="yay -Sy"
|
||||||
alias upgrade='yay -Syu'
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Check Arch Linux PGP Keyring before System Upgrade to prevent failure.
|
||||||
|
function upgrade() {
|
||||||
|
echo ":: Checking Arch Linux PGP Keyring..."
|
||||||
|
local installedver="$(LANG= sudo pacman -Qi archlinux-keyring | grep -Po '(?<=Version : ).*')"
|
||||||
|
local currentver="$(LANG= sudo pacman -Si archlinux-keyring | grep -Po '(?<=Version : ).*')"
|
||||||
|
if [ $installedver != $currentver ]; then
|
||||||
|
echo " Arch Linux PGP Keyring is out of date."
|
||||||
|
echo " Updating before full system upgrade."
|
||||||
|
sudo pacman -Sy --needed --noconfirm archlinux-keyring
|
||||||
|
else
|
||||||
|
echo " Arch Linux PGP Keyring is up to date."
|
||||||
|
echo " Proceeding with full system upgrade."
|
||||||
|
fi
|
||||||
|
if (( $+commands[yay] )); then
|
||||||
|
yay -Syu
|
||||||
|
elif (( $+commands[trizen] )); then
|
||||||
|
trizen -Syu
|
||||||
|
elif (( $+commands[pacaur] )); then
|
||||||
|
pacaur -Syu
|
||||||
|
elif (( $+commands[aura] )); then
|
||||||
|
sudo aura -Syu
|
||||||
|
else
|
||||||
|
sudo pacman -Syu
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
20
plugins/argocd/README.md
Normal file
20
plugins/argocd/README.md
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# Argo CD plugin
|
||||||
|
|
||||||
|
This plugin adds completion for the [Argo CD](https://argoproj.github.io/cd/) CLI.
|
||||||
|
|
||||||
|
To use it, add `argocd` to the plugins array in your zshrc file:
|
||||||
|
|
||||||
|
```zsh
|
||||||
|
plugins=(... argocd)
|
||||||
|
```
|
||||||
|
|
||||||
|
This plugin does not add any aliases.
|
||||||
|
|
||||||
|
## Cache
|
||||||
|
|
||||||
|
This plugin caches the completion script and is automatically updated asynchronously when the plugin is
|
||||||
|
loaded, which is usually when you start up a new terminal emulator.
|
||||||
|
|
||||||
|
The cache is stored at:
|
||||||
|
|
||||||
|
- `$ZSH_CACHE/completions/_argocd` completions script
|
14
plugins/argocd/argocd.plugin.zsh
Normal file
14
plugins/argocd/argocd.plugin.zsh
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
# Autocompletion for argocd.
|
||||||
|
if (( ! $+commands[argocd] )); then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If the completion file doesn't exist yet, we need to autoload it and
|
||||||
|
# bind it to `argocd`. Otherwise, compinit will have already done that.
|
||||||
|
if [[ ! -f "$ZSH_CACHE_DIR/completions/_argocd" ]]; then
|
||||||
|
typeset -g -A _comps
|
||||||
|
autoload -Uz _argocd
|
||||||
|
_comps[argocd]=_argocd
|
||||||
|
fi
|
||||||
|
|
||||||
|
argocd completion zsh >| "$ZSH_CACHE_DIR/completions/_argocd" &|
|
|
@ -6,22 +6,25 @@ Adds integration with [asdf](https://github.com/asdf-vm/asdf), the extendable ve
|
||||||
|
|
||||||
### Installation
|
### Installation
|
||||||
|
|
||||||
1. Enable the plugin by adding it to your `plugins` definition in `~/.zshrc`.
|
1. [Download asdf](https://asdf-vm.com/guide/getting-started.html#_2-download-asdf) by running the following:
|
||||||
|
|
||||||
|
```
|
||||||
|
git clone https://github.com/asdf-vm/asdf.git ~/.asdf
|
||||||
|
```
|
||||||
|
|
||||||
|
2. [Enable asdf](https://asdf-vm.com/guide/getting-started.html#_3-install-asdf) by adding it to your `plugins` definition in `~/.zshrc`.
|
||||||
|
|
||||||
```
|
```
|
||||||
plugins=(asdf)
|
plugins=(asdf)
|
||||||
```
|
```
|
||||||
|
|
||||||
2. [Install asdf](https://github.com/asdf-vm/asdf#setup) by running the following:
|
|
||||||
```
|
|
||||||
git clone https://github.com/asdf-vm/asdf.git ~/.asdf
|
|
||||||
```
|
|
||||||
|
|
||||||
### Usage
|
### Usage
|
||||||
|
|
||||||
See the [asdf usage documentation](https://github.com/asdf-vm/asdf#usage) for information on how to use asdf:
|
See the [asdf documentation](https://asdf-vm.com/guide/getting-started.html#_4-install-a-plugin) for information on how to use asdf:
|
||||||
|
|
||||||
```
|
```
|
||||||
asdf plugin-add nodejs git@github.com:asdf-vm/asdf-nodejs.git
|
asdf plugin add nodejs https://github.com/asdf-vm/asdf-nodejs.git
|
||||||
asdf install nodejs 5.9.1
|
asdf install nodejs latest
|
||||||
|
asdf global nodejs latest
|
||||||
|
asdf local nodejs latest
|
||||||
```
|
```
|
||||||
|
|
|
@ -2,26 +2,29 @@
|
||||||
ASDF_DIR="${ASDF_DIR:-$HOME/.asdf}"
|
ASDF_DIR="${ASDF_DIR:-$HOME/.asdf}"
|
||||||
ASDF_COMPLETIONS="$ASDF_DIR/completions"
|
ASDF_COMPLETIONS="$ASDF_DIR/completions"
|
||||||
|
|
||||||
# If not found, check for archlinux/AUR package (/opt/asdf-vm/)
|
if [[ ! -f "$ASDF_DIR/asdf.sh" || ! -f "$ASDF_COMPLETIONS/_asdf" ]]; then
|
||||||
if [[ ! -f "$ASDF_DIR/asdf.sh" || ! -f "$ASDF_COMPLETIONS/asdf.bash" ]] && [[ -f "/opt/asdf-vm/asdf.sh" ]]; then
|
# If not found, check for archlinux/AUR package (/opt/asdf-vm/)
|
||||||
ASDF_DIR="/opt/asdf-vm"
|
if [[ -f "/opt/asdf-vm/asdf.sh" ]]; then
|
||||||
ASDF_COMPLETIONS="$ASDF_DIR"
|
ASDF_DIR="/opt/asdf-vm"
|
||||||
fi
|
ASDF_COMPLETIONS="$ASDF_DIR"
|
||||||
|
# If not found, check for Homebrew package
|
||||||
# If not found, check for Homebrew package
|
elif (( $+commands[brew] )); then
|
||||||
if [[ ! -f "$ASDF_DIR/asdf.sh" || ! -f "$ASDF_COMPLETIONS/asdf.bash" ]] && (( $+commands[brew] )); then
|
_ASDF_PREFIX="$(brew --prefix asdf)"
|
||||||
brew_prefix="$(brew --prefix asdf)"
|
ASDF_DIR="${_ASDF_PREFIX}/libexec"
|
||||||
ASDF_DIR="${brew_prefix}/libexec"
|
ASDF_COMPLETIONS="${_ASDF_PREFIX}/share/zsh/site-functions"
|
||||||
ASDF_COMPLETIONS="${brew_prefix}/etc/bash_completion.d"
|
unset _ASDF_PREFIX
|
||||||
unset brew_prefix
|
else
|
||||||
|
return
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Load command
|
# Load command
|
||||||
if [[ -f "$ASDF_DIR/asdf.sh" ]]; then
|
if [[ -f "$ASDF_DIR/asdf.sh" ]]; then
|
||||||
. "$ASDF_DIR/asdf.sh"
|
source "$ASDF_DIR/asdf.sh"
|
||||||
|
|
||||||
# Load completions
|
# Load completions
|
||||||
if [[ -f "$ASDF_COMPLETIONS/asdf.bash" ]]; then
|
if [[ -f "$ASDF_COMPLETIONS/_asdf" ]]; then
|
||||||
. "$ASDF_COMPLETIONS/asdf.bash"
|
fpath+=("$ASDF_COMPLETIONS")
|
||||||
|
autoload -Uz _asdf
|
||||||
|
compdef _asdf asdf # compdef is already loaded before loading plugins
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -17,9 +17,13 @@ if ! type autoenv_init >/dev/null; then
|
||||||
/usr/local/bin
|
/usr/local/bin
|
||||||
/usr/share/autoenv-git
|
/usr/share/autoenv-git
|
||||||
~/Library/Python/bin
|
~/Library/Python/bin
|
||||||
|
.venv/bin
|
||||||
|
venv/bin
|
||||||
|
env/bin
|
||||||
|
.env/bin
|
||||||
)
|
)
|
||||||
for d ( $install_locations ); do
|
for d ( $install_locations ); do
|
||||||
if [[ -e $d/activate.sh ]]; then
|
if [[ -e $d/activate || -e $d/activate.sh ]]; then
|
||||||
autoenv_dir=$d
|
autoenv_dir=$d
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
|
@ -29,7 +33,7 @@ if ! type autoenv_init >/dev/null; then
|
||||||
# Look for Homebrew path as a last resort
|
# Look for Homebrew path as a last resort
|
||||||
if [[ -z "$autoenv_dir" ]] && (( $+commands[brew] )); then
|
if [[ -z "$autoenv_dir" ]] && (( $+commands[brew] )); then
|
||||||
d=$(brew --prefix)/opt/autoenv
|
d=$(brew --prefix)/opt/autoenv
|
||||||
if [[ -e $d/activate.sh ]]; then
|
if [[ -e $d/activate || -e $d/activate.sh ]]; then
|
||||||
autoenv_dir=$d
|
autoenv_dir=$d
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
@ -46,7 +50,11 @@ END
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
# Load autoenv
|
# Load autoenv
|
||||||
source $autoenv_dir/activate.sh
|
if [[ -e $autoenv_dir/activate ]]; then
|
||||||
|
source $autoenv_dir/activate
|
||||||
|
else
|
||||||
|
source $autoenv_dir/activate.sh
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
[[ $? != 0 ]] && return $?
|
[[ $? != 0 ]] && return $?
|
||||||
|
|
|
@ -1,17 +1,21 @@
|
||||||
declare -a autojump_paths
|
declare -a autojump_paths
|
||||||
autojump_paths=(
|
autojump_paths=(
|
||||||
$HOME/.autojump/etc/profile.d/autojump.zsh # manual installation
|
$HOME/.autojump/etc/profile.d/autojump.zsh # manual installation
|
||||||
$HOME/.autojump/share/autojump/autojump.zsh # manual installation
|
$HOME/.autojump/share/autojump/autojump.zsh # manual installation
|
||||||
$HOME/.nix-profile/etc/profile.d/autojump.sh # NixOS installation
|
$HOME/.nix-profile/etc/profile.d/autojump.sh # NixOS installation
|
||||||
/run/current-system/sw/share/autojump/autojump.zsh # NixOS installation
|
/run/current-system/sw/share/autojump/autojump.zsh # NixOS installation
|
||||||
/usr/share/autojump/autojump.zsh # Debian and Ubuntu package
|
/etc/profiles/per-user/$USER/share/autojump/autojump.zsh # Home Manager, NixOS with user-scoped packages
|
||||||
/etc/profile.d/autojump.zsh # manual installation
|
/usr/share/autojump/autojump.zsh # Debian and Ubuntu package
|
||||||
/etc/profile.d/autojump.sh # Gentoo installation
|
/etc/profile.d/autojump.zsh # manual installation
|
||||||
/usr/local/share/autojump/autojump.zsh # FreeBSD installation
|
/etc/profile.d/autojump.sh # Gentoo installation
|
||||||
/usr/pkg/share/autojump/autojump.zsh # NetBSD installation
|
/usr/local/share/autojump/autojump.zsh # FreeBSD installation
|
||||||
/opt/local/etc/profile.d/autojump.sh # macOS with MacPorts
|
/usr/pkg/share/autojump/autojump.zsh # NetBSD installation
|
||||||
/usr/local/etc/profile.d/autojump.sh # macOS with Homebrew (default)
|
/opt/local/etc/profile.d/autojump.sh # macOS with MacPorts
|
||||||
/opt/homebrew/etc/profile.d/autojump.sh # macOS with Homebrew (default on M1 macs)
|
/usr/local/etc/profile.d/autojump.sh # macOS with Homebrew (default)
|
||||||
|
/opt/homebrew/etc/profile.d/autojump.sh # macOS with Homebrew (default on M1 macs)
|
||||||
|
/opt/pkg/share/autojump/autojump.zsh # macOS with pkgsrc
|
||||||
|
/etc/profiles/per-user/$USER/etc/profile.d/autojump.sh # macOS Nix, Home Manager and flakes
|
||||||
|
/nix/var/nix/gcroots/current-system/sw/share/zsh/site-functions/autojump.zsh # macOS Nix, nix-darwin
|
||||||
)
|
)
|
||||||
|
|
||||||
for file in $autojump_paths; do
|
for file in $autojump_paths; do
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
# aws
|
# aws
|
||||||
|
|
||||||
This plugin provides completion support for [awscli](https://docs.aws.amazon.com/cli/latest/reference/index.html)
|
This plugin provides completion support for [awscli v2](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/index.html)
|
||||||
and a few utilities to manage AWS profiles and display them in the prompt.
|
and a few utilities to manage AWS profiles/regions and display them in the prompt.
|
||||||
|
[awscli v1](https://docs.aws.amazon.com/cli/latest/userguide/cliv2-migration.html) is no longer supported.
|
||||||
|
|
||||||
To use it, add `aws` to the plugins array in your zshrc file.
|
To use it, add `aws` to the plugins array in your zshrc file.
|
||||||
|
|
||||||
|
@ -12,9 +13,14 @@ plugins=(... aws)
|
||||||
## Plugin commands
|
## Plugin commands
|
||||||
|
|
||||||
* `asp [<profile>]`: sets `$AWS_PROFILE` and `$AWS_DEFAULT_PROFILE` (legacy) to `<profile>`.
|
* `asp [<profile>]`: sets `$AWS_PROFILE` and `$AWS_DEFAULT_PROFILE` (legacy) to `<profile>`.
|
||||||
It also sets `$AWS_EB_PROFILE` to `<profile>` for the Elastic Beanstalk CLI.
|
It also sets `$AWS_EB_PROFILE` to `<profile>` for the Elastic Beanstalk CLI. It sets `$AWS_PROFILE_REGION` for display in `aws_prompt_info`.
|
||||||
Run `asp` without arguments to clear the profile.
|
Run `asp` without arguments to clear the profile.
|
||||||
* `asp [<profile>] login`: If AWS SSO has been configured in your aws profile, it will run the `aws sso login` command following profile selection.
|
* `asp [<profile>] login`: If AWS SSO has been configured in your aws profile, it will run the `aws sso login` command following profile selection.
|
||||||
|
* `asp [<profile>] login [<sso_session>]`: In addition to `asp [<profile>] login`, if SSO session has been configured in your aws profile, it will run the `aws sso login --sso-session <sso_session>` command following profile selection.
|
||||||
|
* `asp [<profile>] logout`: If AWS SSO has been configured in your aws profile, it will run the `aws sso logout` command following profile selection.
|
||||||
|
|
||||||
|
* `asr [<region>]`: sets `$AWS_REGION` and `$AWS_DEFAULT_REGION` (legacy) to `<region>`.
|
||||||
|
Run `asr` without arguments to clear the profile.
|
||||||
|
|
||||||
* `acp [<profile>] [<mfa_token>]`: in addition to `asp` functionality, it actually changes
|
* `acp [<profile>] [<mfa_token>]`: in addition to `asp` functionality, it actually changes
|
||||||
the profile by assuming the role specified in the `<profile>` configuration. It supports
|
the profile by assuming the role specified in the `<profile>` configuration. It supports
|
||||||
|
@ -25,25 +31,41 @@ plugins=(... aws)
|
||||||
|
|
||||||
* `agp`: gets the current value of `$AWS_PROFILE`.
|
* `agp`: gets the current value of `$AWS_PROFILE`.
|
||||||
|
|
||||||
|
* `agr`: gets the current value of `$AWS_REGION`.
|
||||||
|
|
||||||
* `aws_change_access_key`: changes the AWS access key of a profile.
|
* `aws_change_access_key`: changes the AWS access key of a profile.
|
||||||
|
|
||||||
* `aws_profiles`: lists the available profiles in the `$AWS_CONFIG_FILE` (default: `~/.aws/config`).
|
* `aws_profiles`: lists the available profiles in the `$AWS_CONFIG_FILE` (default: `~/.aws/config`).
|
||||||
Used to provide completion for the `asp` function.
|
Used to provide completion for the `asp` function.
|
||||||
|
|
||||||
|
* `aws_regions`: lists the available regions.
|
||||||
|
Used to provide completion for the `asr` function.
|
||||||
|
|
||||||
## Plugin options
|
## Plugin options
|
||||||
|
|
||||||
* Set `SHOW_AWS_PROMPT=false` in your zshrc file if you want to prevent the plugin from modifying your RPROMPT.
|
* Set `SHOW_AWS_PROMPT=false` in your zshrc file if you want to prevent the plugin from modifying your RPROMPT.
|
||||||
Some themes might overwrite the value of RPROMPT instead of appending to it, so they'll need to be fixed to
|
Some themes might overwrite the value of RPROMPT instead of appending to it, so they'll need to be fixed to
|
||||||
see the AWS profile prompt.
|
see the AWS profile/region prompt.
|
||||||
|
|
||||||
|
* Set `AWS_PROFILE_STATE_ENABLED=true` in your zshrc file if you want the aws profile to persist between shell sessions.
|
||||||
|
This option might slow down your shell startup time.
|
||||||
|
By default the state file path is `/tmp/.aws_current_profile`. This means that the state won't survive a reboot or otherwise GC.
|
||||||
|
You can control the state file path using the `AWS_STATE_FILE` environment variable.
|
||||||
|
|
||||||
## Theme
|
## Theme
|
||||||
|
|
||||||
The plugin creates an `aws_prompt_info` function that you can use in your theme, which displays
|
The plugin creates an `aws_prompt_info` function that you can use in your theme, which displays
|
||||||
the current `$AWS_PROFILE`. It uses two variables to control how that is shown:
|
the current `$AWS_PROFILE` and `$AWS_REGION`. It uses four variables to control how that is shown:
|
||||||
|
|
||||||
* ZSH_THEME_AWS_PREFIX: sets the prefix of the AWS_PROFILE. Defaults to `<aws:`.
|
* ZSH_THEME_AWS_PROFILE_PREFIX: sets the prefix of the AWS_PROFILE. Defaults to `<aws:`.
|
||||||
|
|
||||||
* ZSH_THEME_AWS_SUFFIX: sets the suffix of the AWS_PROFILE. Defaults to `>`.
|
* ZSH_THEME_AWS_PROFILE_SUFFIX: sets the suffix of the AWS_PROFILE. Defaults to `>`.
|
||||||
|
|
||||||
|
* ZSH_THEME_AWS_REGION_PREFIX: sets the prefix of the AWS_REGION. Defaults to `<region:`.
|
||||||
|
|
||||||
|
* ZSH_THEME_AWS_REGION_SUFFIX: sets the suffix of the AWS_REGION. Defaults to `>`.
|
||||||
|
|
||||||
|
* ZSH_THEME_AWS_DIVIDER: sets the divider between ZSH_THEME_AWS_PROFILE_SUFFIX and ZSH_THEME_AWS_REGION_PREFIX. Defaults to ` ` (single space).
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
|
@ -53,7 +75,7 @@ the current `$AWS_PROFILE`. It uses two variables to control how that is shown:
|
||||||
|
|
||||||
Source profile credentials in `~/.aws/credentials`:
|
Source profile credentials in `~/.aws/credentials`:
|
||||||
|
|
||||||
```
|
```ini
|
||||||
[source-profile-name]
|
[source-profile-name]
|
||||||
aws_access_key_id = ...
|
aws_access_key_id = ...
|
||||||
aws_secret_access_key = ...
|
aws_secret_access_key = ...
|
||||||
|
@ -61,7 +83,7 @@ aws_secret_access_key = ...
|
||||||
|
|
||||||
Role configuration in `~/.aws/config`:
|
Role configuration in `~/.aws/config`:
|
||||||
|
|
||||||
```
|
```ini
|
||||||
[profile source-profile-name]
|
[profile source-profile-name]
|
||||||
mfa_serial = arn:aws:iam::111111111111:mfa/myuser
|
mfa_serial = arn:aws:iam::111111111111:mfa/myuser
|
||||||
region = us-east-1
|
region = us-east-1
|
||||||
|
|
|
@ -2,10 +2,30 @@ function agp() {
|
||||||
echo $AWS_PROFILE
|
echo $AWS_PROFILE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function agr() {
|
||||||
|
echo $AWS_REGION
|
||||||
|
}
|
||||||
|
|
||||||
|
# Update state file if enabled
|
||||||
|
function _aws_update_state() {
|
||||||
|
if [[ "$AWS_PROFILE_STATE_ENABLED" == true ]]; then
|
||||||
|
test -d $(dirname ${AWS_STATE_FILE}) || exit 1
|
||||||
|
echo "${AWS_PROFILE} ${AWS_REGION}" > "${AWS_STATE_FILE}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function _aws_clear_state() {
|
||||||
|
if [[ "$AWS_PROFILE_STATE_ENABLED" == true ]]; then
|
||||||
|
test -d $(dirname ${AWS_STATE_FILE}) || exit 1
|
||||||
|
echo -n > "${AWS_STATE_FILE}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# AWS profile selection
|
# AWS profile selection
|
||||||
function asp() {
|
function asp() {
|
||||||
if [[ -z "$1" ]]; then
|
if [[ -z "$1" ]]; then
|
||||||
unset AWS_DEFAULT_PROFILE AWS_PROFILE AWS_EB_PROFILE
|
unset AWS_DEFAULT_PROFILE AWS_PROFILE AWS_EB_PROFILE AWS_PROFILE_REGION
|
||||||
|
_aws_clear_state
|
||||||
echo AWS profile cleared.
|
echo AWS profile cleared.
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
@ -22,11 +42,42 @@ function asp() {
|
||||||
export AWS_PROFILE=$1
|
export AWS_PROFILE=$1
|
||||||
export AWS_EB_PROFILE=$1
|
export AWS_EB_PROFILE=$1
|
||||||
|
|
||||||
|
export AWS_PROFILE_REGION=$(aws configure get region)
|
||||||
|
|
||||||
|
_aws_update_state
|
||||||
|
|
||||||
if [[ "$2" == "login" ]]; then
|
if [[ "$2" == "login" ]]; then
|
||||||
aws sso login
|
if [[ -n "$3" ]]; then
|
||||||
|
aws sso login --sso-session $3
|
||||||
|
else
|
||||||
|
aws sso login
|
||||||
|
fi
|
||||||
|
elif [[ "$2" == "logout" ]]; then
|
||||||
|
aws sso logout
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# AWS region selection
|
||||||
|
function asr() {
|
||||||
|
if [[ -z "$1" ]]; then
|
||||||
|
unset AWS_DEFAULT_REGION AWS_REGION
|
||||||
|
_aws_update_state
|
||||||
|
echo AWS region cleared.
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
local -a available_regions
|
||||||
|
available_regions=($(aws_regions))
|
||||||
|
if [[ -z "${available_regions[(r)$1]}" ]]; then
|
||||||
|
echo "${fg[red]}Available regions: \n$(aws_regions)"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
export AWS_REGION=$1
|
||||||
|
export AWS_DEFAULT_REGION=$1
|
||||||
|
_aws_update_state
|
||||||
|
}
|
||||||
|
|
||||||
# AWS profile switch
|
# AWS profile switch
|
||||||
function acp() {
|
function acp() {
|
||||||
if [[ -z "$1" ]]; then
|
if [[ -z "$1" ]]; then
|
||||||
|
@ -135,21 +186,69 @@ function aws_change_access_key() {
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Insert the credentials when asked."
|
local profile="$1"
|
||||||
asp "$1" || return 1
|
# Get current access key
|
||||||
AWS_PAGER="" aws iam create-access-key
|
local original_aws_access_key_id="$(aws configure get aws_access_key_id --profile $profile)"
|
||||||
AWS_PAGER="" aws configure --profile "$1"
|
|
||||||
|
|
||||||
echo "You can now safely delete the old access key running \`aws iam delete-access-key --access-key-id ID\`"
|
asp "$profile" || return 1
|
||||||
|
echo "Generating a new access key pair for you now."
|
||||||
|
if aws --no-cli-pager iam create-access-key; then
|
||||||
|
echo "Insert the newly generated credentials when asked."
|
||||||
|
aws --no-cli-pager configure --profile $profile
|
||||||
|
else
|
||||||
|
echo "Current access keys:"
|
||||||
|
aws --no-cli-pager iam list-access-keys
|
||||||
|
echo "Profile \"${profile}\" is currently using the $original_aws_access_key_id key. You can delete an old access key by running \`aws --profile $profile iam delete-access-key --access-key-id AccessKeyId\`"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
read -q "yn?Would you like to disable your previous access key (${original_aws_access_key_id}) now? "
|
||||||
|
case $yn in
|
||||||
|
[Yy]*)
|
||||||
|
echo -n "\nDisabling access key ${original_aws_access_key_id}..."
|
||||||
|
if aws --no-cli-pager iam update-access-key --access-key-id ${original_aws_access_key_id} --status Inactive; then
|
||||||
|
echo "done."
|
||||||
|
else
|
||||||
|
echo "\nFailed to disable ${original_aws_access_key_id} key."
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo ""
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
echo "You can now safely delete the old access key by running \`aws --profile $profile iam delete-access-key --access-key-id ${original_aws_access_key_id}\`"
|
||||||
echo "Your current keys are:"
|
echo "Your current keys are:"
|
||||||
AWS_PAGER="" aws iam list-access-keys
|
aws --no-cli-pager iam list-access-keys
|
||||||
|
}
|
||||||
|
|
||||||
|
function aws_regions() {
|
||||||
|
local region
|
||||||
|
if [[ $AWS_DEFAULT_REGION ]];then
|
||||||
|
region="$AWS_DEFAULT_REGION"
|
||||||
|
elif [[ $AWS_REGION ]];then
|
||||||
|
region="$AWS_REGION"
|
||||||
|
else
|
||||||
|
region="us-west-1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $AWS_DEFAULT_PROFILE || $AWS_PROFILE ]];then
|
||||||
|
aws ec2 describe-regions --region $region |grep RegionName | awk -F ':' '{gsub(/"/, "", $2);gsub(/,/, "", $2);gsub(/ /, "", $2); print $2}'
|
||||||
|
else
|
||||||
|
echo "You must specify a AWS profile."
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
function aws_profiles() {
|
function aws_profiles() {
|
||||||
|
aws --no-cli-pager configure list-profiles 2> /dev/null && return
|
||||||
[[ -r "${AWS_CONFIG_FILE:-$HOME/.aws/config}" ]] || return 1
|
[[ -r "${AWS_CONFIG_FILE:-$HOME/.aws/config}" ]] || return 1
|
||||||
grep --color=never -Eo '\[.*\]' "${AWS_CONFIG_FILE:-$HOME/.aws/config}" | sed -E 's/^[[:space:]]*\[(profile)?[[:space:]]*([-_[:alnum:]\.@]+)\][[:space:]]*$/\2/g'
|
grep --color=never -Eo '\[.*\]' "${AWS_CONFIG_FILE:-$HOME/.aws/config}" | sed -E 's/^[[:space:]]*\[(profile)?[[:space:]]*([^[:space:]]+)\][[:space:]]*$/\2/g'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _aws_regions() {
|
||||||
|
reply=($(aws_regions))
|
||||||
|
}
|
||||||
|
compctl -K _aws_regions asr
|
||||||
|
|
||||||
function _aws_profiles() {
|
function _aws_profiles() {
|
||||||
reply=($(aws_profiles))
|
reply=($(aws_profiles))
|
||||||
}
|
}
|
||||||
|
@ -157,14 +256,40 @@ compctl -K _aws_profiles asp acp aws_change_access_key
|
||||||
|
|
||||||
# AWS prompt
|
# AWS prompt
|
||||||
function aws_prompt_info() {
|
function aws_prompt_info() {
|
||||||
[[ -n "$AWS_PROFILE" ]] || return
|
local _aws_to_show
|
||||||
echo "${ZSH_THEME_AWS_PREFIX=<aws:}${AWS_PROFILE:gs/%/%%}${ZSH_THEME_AWS_SUFFIX=>}"
|
local region="${AWS_REGION:-${AWS_DEFAULT_REGION:-$AWS_PROFILE_REGION}}"
|
||||||
|
|
||||||
|
if [[ -n "$AWS_PROFILE" ]];then
|
||||||
|
_aws_to_show+="${ZSH_THEME_AWS_PROFILE_PREFIX="<aws:"}${AWS_PROFILE}${ZSH_THEME_AWS_PROFILE_SUFFIX=">"}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n "$region" ]]; then
|
||||||
|
[[ -n "$_aws_to_show" ]] && _aws_to_show+="${ZSH_THEME_AWS_DIVIDER=" "}"
|
||||||
|
_aws_to_show+="${ZSH_THEME_AWS_REGION_PREFIX="<region:"}${region}${ZSH_THEME_AWS_REGION_SUFFIX=">"}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "$_aws_to_show"
|
||||||
}
|
}
|
||||||
|
|
||||||
if [[ "$SHOW_AWS_PROMPT" != false && "$RPROMPT" != *'$(aws_prompt_info)'* ]]; then
|
if [[ "$SHOW_AWS_PROMPT" != false && "$RPROMPT" != *'$(aws_prompt_info)'* ]]; then
|
||||||
RPROMPT='$(aws_prompt_info)'"$RPROMPT"
|
RPROMPT='$(aws_prompt_info)'"$RPROMPT"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ "$AWS_PROFILE_STATE_ENABLED" == true ]]; then
|
||||||
|
AWS_STATE_FILE="${AWS_STATE_FILE:-/tmp/.aws_current_profile}"
|
||||||
|
test -s "${AWS_STATE_FILE}" || return
|
||||||
|
|
||||||
|
aws_state=($(cat $AWS_STATE_FILE))
|
||||||
|
|
||||||
|
export AWS_DEFAULT_PROFILE="${aws_state[1]}"
|
||||||
|
export AWS_PROFILE="$AWS_DEFAULT_PROFILE"
|
||||||
|
export AWS_EB_PROFILE="$AWS_DEFAULT_PROFILE"
|
||||||
|
|
||||||
|
test -z "${aws_state[2]}" && AWS_REGION=$(aws configure get region)
|
||||||
|
|
||||||
|
export AWS_REGION=${AWS_REGION:-$aws_state[2]}
|
||||||
|
export AWS_DEFAULT_REGION="$AWS_REGION"
|
||||||
|
fi
|
||||||
|
|
||||||
# Load awscli completions
|
# Load awscli completions
|
||||||
|
|
||||||
|
@ -210,3 +335,4 @@ else
|
||||||
[[ -r $_aws_zsh_completer_path ]] && source $_aws_zsh_completer_path
|
[[ -r $_aws_zsh_completer_path ]] && source $_aws_zsh_completer_path
|
||||||
unset _aws_zsh_completer_path _brew_prefix
|
unset _aws_zsh_completer_path _brew_prefix
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
49
plugins/azure/README.md
Normal file
49
plugins/azure/README.md
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
# azure
|
||||||
|
|
||||||
|
This plugin provides completion support for [azure cli](https://docs.microsoft.com/en-us/cli/azure/)
|
||||||
|
and a few utilities to manage azure subscriptions and display them in the prompt.
|
||||||
|
|
||||||
|
To use it, add `azure` to the plugins array in your zshrc file.
|
||||||
|
|
||||||
|
```zsh
|
||||||
|
plugins=(... azure)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Plugin commands
|
||||||
|
|
||||||
|
|
||||||
|
* `az_subscriptions`: lists the available subscriptions in the `AZURE_CONFIG_DIR` (default: `~/.azure/`).
|
||||||
|
Used to provide completion for the `azss` function.
|
||||||
|
|
||||||
|
* `azgs`: gets the current value of `$azure_subscription`.
|
||||||
|
|
||||||
|
* `azss [<subscription>]`: sets the `$azure_subscription`.
|
||||||
|
|
||||||
|
|
||||||
|
NOTE : because azure keeps the state of active subscription in ${AZURE_CONFIG_DIR:-$HOME/.azure/azureProfile.json}, the prompt command requires `jq` to be enabled to parse the file. If jq is not in the path the prompt will show nothing
|
||||||
|
|
||||||
|
## Theme
|
||||||
|
|
||||||
|
The plugin creates an `azure_prompt_info` function that you can use in your theme, which displays
|
||||||
|
the current `$azure_subscription`. It uses two variables to control how that is shown:
|
||||||
|
|
||||||
|
- ZSH_THEME_AZURE_PREFIX: sets the prefix of the azure_subscription. Defaults to `<az:`.
|
||||||
|
|
||||||
|
- ZSH_THEME_azure_SUFFIX: sets the suffix of the azure_subscription. Defaults to `>`.
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
RPROMPT='$(azure_prompt_info)'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Develop
|
||||||
|
|
||||||
|
On ubuntu get a working environment with :
|
||||||
|
|
||||||
|
` docker run -it -v $(pwd):/mnt -w /mnt ubuntu bash`
|
||||||
|
|
||||||
|
```
|
||||||
|
apt install -y curl jq zsh git vim
|
||||||
|
sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
|
||||||
|
curl -sL https://aka.ms/InstallAzureCLIDeb | bash
|
||||||
|
```
|
60
plugins/azure/azure.plugin.zsh
Normal file
60
plugins/azure/azure.plugin.zsh
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
# AZ Get Subscriptions
|
||||||
|
function azgs() {
|
||||||
|
az account show --output tsv --query 'name' 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
# AZ Subscription Selection
|
||||||
|
alias azss="az account set --subscription"
|
||||||
|
|
||||||
|
|
||||||
|
function az_subscriptions() {
|
||||||
|
az account list --all --output tsv --query '[*].name' 2> /dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
function _az_subscriptions() {
|
||||||
|
reply=($(az_subscriptions))
|
||||||
|
}
|
||||||
|
compctl -K _az_subscriptions azss
|
||||||
|
|
||||||
|
# Azure prompt
|
||||||
|
function azure_prompt_info() {
|
||||||
|
[[ ! -f "${AZURE_CONFIG_DIR:-$HOME/.azure}/azureProfile.json" ]] && return
|
||||||
|
# azgs is too expensive, if we have jq, we enable the prompt
|
||||||
|
(( $+commands[jq] )) || return 1
|
||||||
|
azgs=$(jq -r '.subscriptions[] | select(.isDefault==true) .name' "${AZURE_CONFIG_DIR:-$HOME/.azure}/azureProfile.json")
|
||||||
|
echo "${ZSH_THEME_AZURE_PREFIX:=<az:}${azgs}${ZSH_THEME_AZURE_SUFFIX:=>}"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Load az completions
|
||||||
|
function _az-homebrew-installed() {
|
||||||
|
# check if Homebrew is installed
|
||||||
|
(( $+commands[brew] )) || return 1
|
||||||
|
|
||||||
|
# if so, we assume it's default way to install brew
|
||||||
|
if [[ ${commands[brew]:t2} == bin/brew ]]; then
|
||||||
|
_brew_prefix="${commands[brew]:h:h}" # remove trailing /bin/brew
|
||||||
|
else
|
||||||
|
# ok, it is not in the default prefix
|
||||||
|
# this call to brew is expensive (about 400 ms), so at least let's make it only once
|
||||||
|
_brew_prefix=$(brew --prefix)
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# get az.completion.sh location from $PATH
|
||||||
|
_az_zsh_completer_path="$commands[az_zsh_completer.sh]"
|
||||||
|
|
||||||
|
# otherwise check common locations
|
||||||
|
if [[ -z $_az_zsh_completer_path ]]; then
|
||||||
|
# Homebrew
|
||||||
|
if _az-homebrew-installed; then
|
||||||
|
_az_zsh_completer_path=$_brew_prefix/etc/bash_completion.d/az
|
||||||
|
# Linux
|
||||||
|
else
|
||||||
|
_az_zsh_completer_path=/etc/bash_completion.d/azure-cli
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
[[ -r $_az_zsh_completer_path ]] && autoload -U +X bashcompinit && bashcompinit && source $_az_zsh_completer_path
|
||||||
|
unset _az_zsh_completer_path _brew_prefix
|
|
@ -12,6 +12,13 @@ Then, add the `battery_pct_prompt` function to your custom theme. For example:
|
||||||
RPROMPT='$(battery_pct_prompt) ...'
|
RPROMPT='$(battery_pct_prompt) ...'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Also, you set the `BATTERY_CHARGING` variable to your favor.
|
||||||
|
For example:
|
||||||
|
|
||||||
|
```zsh
|
||||||
|
BATTERY_CHARGING="⚡️"
|
||||||
|
```
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
- On Linux, you must have the `acpi` or `acpitool` commands installed on your operating system.
|
- On Linux, you must have the `acpi` or `acpitool` commands installed on your operating system.
|
||||||
|
|
|
@ -13,6 +13,10 @@
|
||||||
# Author: Avneet Singh (kalsi-avneet) #
|
# Author: Avneet Singh (kalsi-avneet) #
|
||||||
# Modified to add support for Android #
|
# Modified to add support for Android #
|
||||||
###########################################
|
###########################################
|
||||||
|
# Author: Not Pua (im-notpua) #
|
||||||
|
# Modified to add support for OpenBSD #
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
|
||||||
if [[ "$OSTYPE" = darwin* ]]; then
|
if [[ "$OSTYPE" = darwin* ]]; then
|
||||||
function battery_is_charging() {
|
function battery_is_charging() {
|
||||||
|
@ -54,7 +58,7 @@ if [[ "$OSTYPE" = darwin* ]]; then
|
||||||
fi
|
fi
|
||||||
echo "%{$fg[$color]%}[${battery_pct}%%]%{$reset_color%}"
|
echo "%{$fg[$color]%}[${battery_pct}%%]%{$reset_color%}"
|
||||||
else
|
else
|
||||||
echo "∞"
|
echo "${BATTERY_CHARGING-⚡️}"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,6 +143,46 @@ elif [[ "$OSTYPE" = linux-android ]] && (( ${+commands[termux-battery-status]} )
|
||||||
echo "%{$fg[$color]%}${battery_pct}%%%{$reset_color%}"
|
echo "%{$fg[$color]%}${battery_pct}%%%{$reset_color%}"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
elif [[ "$OSTYPE" = openbsd* ]]; then
|
||||||
|
function battery_is_charging() {
|
||||||
|
[[ $(apm -b) -eq 3 ]]
|
||||||
|
}
|
||||||
|
function battery_pct() {
|
||||||
|
apm -l
|
||||||
|
}
|
||||||
|
function battery_pct_remaining() {
|
||||||
|
if ! battery_is_charging; then
|
||||||
|
battery_pct
|
||||||
|
else
|
||||||
|
echo "External Power"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
function battery_time_remaining() {
|
||||||
|
local remaining_time
|
||||||
|
remaining_time=$(apm -m)
|
||||||
|
if [[ $remaining_time -ge 0 ]]; then
|
||||||
|
((hour = $remaining_time / 60 ))
|
||||||
|
((minute = $remaining_time % 60 ))
|
||||||
|
printf %02d:%02d $hour $minute
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
function battery_pct_prompt() {
|
||||||
|
local battery_pct color
|
||||||
|
battery_pct=$(battery_pct_remaining)
|
||||||
|
if battery_is_charging; then
|
||||||
|
echo "∞"
|
||||||
|
else
|
||||||
|
if [[ $battery_pct -gt 50 ]]; then
|
||||||
|
color='green'
|
||||||
|
elif [[ $battery_pct -gt 20 ]]; then
|
||||||
|
color='yellow'
|
||||||
|
else
|
||||||
|
color='red'
|
||||||
|
fi
|
||||||
|
echo "%{$fg[$color]%}${battery_pct}%%%{$reset_color%}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
elif [[ "$OSTYPE" = linux* ]]; then
|
elif [[ "$OSTYPE" = linux* ]]; then
|
||||||
function battery_is_charging() {
|
function battery_is_charging() {
|
||||||
if (( $+commands[acpitool] )); then
|
if (( $+commands[acpitool] )); then
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
# Bazel plugin
|
# Bazel plugin
|
||||||
|
|
||||||
This plugin adds completion for [bazel](https://bazel.build), an open-source build and
|
This plugin adds completion and aliases for [bazel](https://bazel.build), an open-source build and test tool that scalably supports multi-language and multi-platform projects.
|
||||||
test tool that scalably supports multi-language and multi-platform projects.
|
|
||||||
|
|
||||||
To use it, add `bazel` to the plugins array in your zshrc file:
|
To use it, add `bazel` to the plugins array in your zshrc file:
|
||||||
|
|
||||||
|
@ -12,3 +11,12 @@ plugins=(... bazel)
|
||||||
The plugin has a copy of [the completion script from the git repository][1].
|
The plugin has a copy of [the completion script from the git repository][1].
|
||||||
|
|
||||||
[1]: https://github.com/bazelbuild/bazel/blob/master/scripts/zsh_completion/_bazel
|
[1]: https://github.com/bazelbuild/bazel/blob/master/scripts/zsh_completion/_bazel
|
||||||
|
|
||||||
|
## Aliases
|
||||||
|
|
||||||
|
| Alias | Command | Description |
|
||||||
|
| ------- | -------------------------------------- | ------------------------------------------------------ |
|
||||||
|
| bzb | `bazel build` | The `bazel build` command |
|
||||||
|
| bzt | `bazel test` | The `bazel test` command |
|
||||||
|
| bzr | `bazel run` | The `bazel run` command |
|
||||||
|
| bzq | `bazel query` | The `bazel query` command |
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#compdef bazel
|
#compdef bazel bazelisk
|
||||||
|
|
||||||
# Copyright 2015 The Bazel Authors. All rights reserved.
|
# Copyright 2015 The Bazel Authors. All rights reserved.
|
||||||
#
|
#
|
||||||
|
|
5
plugins/bazel/bazel.plugin.zsh
Normal file
5
plugins/bazel/bazel.plugin.zsh
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
# Aliases for bazel
|
||||||
|
alias bzb='bazel build'
|
||||||
|
alias bzt='bazel test'
|
||||||
|
alias bzr='bazel run'
|
||||||
|
alias bzq='bazel query'
|
|
@ -1,19 +1,19 @@
|
||||||
# bgnotify zsh plugin
|
# bgnotify zsh plugin
|
||||||
|
|
||||||
cross-platform background notifications for long running commands! Supports OSX and Ubuntu linux.
|
cross-platform background notifications for long running commands! Supports OSX and Linux.
|
||||||
|
|
||||||
Standalone homepage: [t413/zsh-background-notify](https://github.com/t413/zsh-background-notify)
|
Standalone homepage: [t413/zsh-background-notify](https://github.com/t413/zsh-background-notify)
|
||||||
|
|
||||||
----------------------------------
|
---
|
||||||
|
|
||||||
## How to use!
|
## How to use
|
||||||
|
|
||||||
Just add bgnotify to your plugins list in your `.zshrc`
|
Just add bgnotify to your plugins list in your `.zshrc`
|
||||||
|
|
||||||
- On OS X you'll need [terminal-notifier](https://github.com/alloy/terminal-notifier)
|
- On OS X you'll need [terminal-notifier](https://github.com/alloy/terminal-notifier)
|
||||||
* `brew install terminal-notifier` (or `gem install terminal-notifier`)
|
* `brew install terminal-notifier` (or `gem install terminal-notifier`)
|
||||||
- On ubuntu you're already all set!
|
- On Linux, make sure you have `notify-send` or `kdialog` installed. If you're using Ubuntu you should already be all set!
|
||||||
- On windows you can use [notifu](https://www.paralint.com/projects/notifu/) or the Cygwin Ports libnotify package
|
- On Windows you can use [notifu](https://www.paralint.com/projects/notifu/) or the Cygwin Ports libnotify package
|
||||||
|
|
||||||
|
|
||||||
## Screenshots
|
## Screenshots
|
||||||
|
@ -35,20 +35,29 @@ Just add bgnotify to your plugins list in your `.zshrc`
|
||||||
|
|
||||||
One can configure a few things:
|
One can configure a few things:
|
||||||
|
|
||||||
|
- `bgnotify_bell` enabled or disables the terminal bell (default true)
|
||||||
- `bgnotify_threshold` sets the notification threshold time (default 6 seconds)
|
- `bgnotify_threshold` sets the notification threshold time (default 6 seconds)
|
||||||
- `function bgnotify_formatted` lets you change the notification
|
- `function bgnotify_formatted` lets you change the notification. You can for instance customize the message and pass in an icon.
|
||||||
|
|
||||||
Use these by adding a function definition before the your call to source. Example:
|
Use these by adding a function definition before the your call to source. Example:
|
||||||
|
|
||||||
~~~ sh
|
```sh
|
||||||
|
bgnotify_bell=false ## disable terminal bell
|
||||||
bgnotify_threshold=4 ## set your own notification threshold
|
bgnotify_threshold=4 ## set your own notification threshold
|
||||||
|
|
||||||
function bgnotify_formatted {
|
function bgnotify_formatted {
|
||||||
## $1=exit_status, $2=command, $3=elapsed_time
|
## $1=exit_status, $2=command, $3=elapsed_time
|
||||||
[ $1 -eq 0 ] && title="Holy Smokes Batman!" || title="Holy Graf Zeppelin!"
|
|
||||||
bgnotify "$title -- after $3 s" "$2";
|
# Humanly readable elapsed time
|
||||||
|
local elapsed="$(( $3 % 60 ))s"
|
||||||
|
(( $3 < 60 )) || elapsed="$((( $3 % 3600) / 60 ))m $elapsed"
|
||||||
|
(( $3 < 3600 )) || elapsed="$(( $3 / 3600 ))h $elapsed"
|
||||||
|
|
||||||
|
[ $1 -eq 0 ] && title="Holy Smokes Batman" || title="Holy Graf Zeppelin"
|
||||||
|
[ $1 -eq 0 ] && icon="$HOME/icons/success.png" || icon="$HOME/icons/fail.png"
|
||||||
|
bgnotify "$title - took ${elapsed}" "$2" "$icon"
|
||||||
}
|
}
|
||||||
|
|
||||||
plugins=(git bgnotify) ## add to plugins list
|
plugins=(git bgnotify) ## add to plugins list
|
||||||
source $ZSH/oh-my-zsh.sh ## existing source call
|
source $ZSH/oh-my-zsh.sh ## existing source call
|
||||||
~~~
|
```
|
||||||
|
|
|
@ -1,93 +1,141 @@
|
||||||
#!/usr/bin/env zsh
|
#!/usr/bin/env zsh
|
||||||
|
|
||||||
## setup ##
|
## Setup
|
||||||
|
|
||||||
[[ -o interactive ]] || return #interactive only!
|
[[ -o interactive ]] || return # don't load on non-interactive shells
|
||||||
zmodload zsh/datetime || { print "can't load zsh/datetime"; return } # faster than date()
|
[[ -z "$SSH_CLIENT" && -z "$SSH_TTY" ]] || return # don't load on a SSH connection
|
||||||
autoload -Uz add-zsh-hook || { print "can't add zsh hook!"; return }
|
|
||||||
|
|
||||||
(( ${+bgnotify_threshold} )) || bgnotify_threshold=5 #default 10 seconds
|
zmodload zsh/datetime # faster than `date`
|
||||||
|
|
||||||
|
|
||||||
## definitions ##
|
## Zsh Hooks
|
||||||
|
|
||||||
if ! (type bgnotify_formatted | grep -q 'function'); then ## allow custom function override
|
function bgnotify_begin {
|
||||||
function bgnotify_formatted { ## args: (exit_status, command, elapsed_seconds)
|
|
||||||
elapsed="$(( $3 % 60 ))s"
|
|
||||||
(( $3 >= 60 )) && elapsed="$((( $3 % 3600) / 60 ))m $elapsed"
|
|
||||||
(( $3 >= 3600 )) && elapsed="$(( $3 / 3600 ))h $elapsed"
|
|
||||||
[ $1 -eq 0 ] && bgnotify "#win (took $elapsed)" "$2" || bgnotify "#fail (took $elapsed)" "$2"
|
|
||||||
}
|
|
||||||
fi
|
|
||||||
|
|
||||||
currentAppId () {
|
|
||||||
if (( $+commands[osascript] )); then
|
|
||||||
osascript -e 'tell application (path to frontmost application as text) to id' 2>/dev/null
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
currentWindowId () {
|
|
||||||
if hash osascript 2>/dev/null; then #osx
|
|
||||||
osascript -e 'tell application (path to frontmost application as text) to id of front window' 2&> /dev/null || echo "0"
|
|
||||||
elif (hash notify-send 2>/dev/null || hash kdialog 2>/dev/null); then #ubuntu!
|
|
||||||
xprop -root 2> /dev/null | awk '/NET_ACTIVE_WINDOW/{print $5;exit} END{exit !$5}' || echo "0"
|
|
||||||
else
|
|
||||||
echo $EPOCHSECONDS #fallback for windows
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
bgnotify () { ## args: (title, subtitle)
|
|
||||||
if hash terminal-notifier 2>/dev/null; then #osx
|
|
||||||
local term_id="$bgnotify_appid"
|
|
||||||
if [[ -z "$term_id" ]]; then
|
|
||||||
case "$TERM_PROGRAM" in
|
|
||||||
iTerm.app) term_id='com.googlecode.iterm2' ;;
|
|
||||||
Apple_Terminal) term_id='com.apple.terminal' ;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
|
|
||||||
## now call terminal-notifier, (hopefully with $term_id!)
|
|
||||||
if [[ -z "$term_id" ]]; then
|
|
||||||
terminal-notifier -message "$2" -title "$1" >/dev/null
|
|
||||||
else
|
|
||||||
terminal-notifier -message "$2" -title "$1" -activate "$term_id" -sender "$term_id" >/dev/null
|
|
||||||
fi
|
|
||||||
elif hash growlnotify 2>/dev/null; then #osx growl
|
|
||||||
growlnotify -m "$1" "$2"
|
|
||||||
elif hash notify-send 2>/dev/null; then #ubuntu gnome!
|
|
||||||
notify-send "$1" "$2"
|
|
||||||
elif hash kdialog 2>/dev/null; then #ubuntu kde!
|
|
||||||
kdialog --title "$1" --passivepopup "$2" 5
|
|
||||||
elif hash notifu 2>/dev/null; then #cygwyn support!
|
|
||||||
notifu /m "$2" /p "$1"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
## Zsh hooks ##
|
|
||||||
|
|
||||||
bgnotify_begin() {
|
|
||||||
bgnotify_timestamp=$EPOCHSECONDS
|
bgnotify_timestamp=$EPOCHSECONDS
|
||||||
bgnotify_lastcmd="${1:-$2}"
|
bgnotify_lastcmd="${1:-$2}"
|
||||||
bgnotify_appid="$(currentAppId)"
|
|
||||||
bgnotify_windowid=$(currentWindowId)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bgnotify_end() {
|
function bgnotify_end {
|
||||||
didexit=$?
|
{
|
||||||
elapsed=$(( EPOCHSECONDS - bgnotify_timestamp ))
|
local exit_status=$?
|
||||||
past_threshold=$(( elapsed >= bgnotify_threshold ))
|
local elapsed=$(( EPOCHSECONDS - bgnotify_timestamp ))
|
||||||
if (( bgnotify_timestamp > 0 )) && (( past_threshold )); then
|
|
||||||
if [[ $(currentAppId) != "$bgnotify_appid" || $(currentWindowId) != "$bgnotify_windowid" ]]; then
|
# check time elapsed
|
||||||
print -n "\a"
|
[[ $bgnotify_timestamp -gt 0 ]] || return 0
|
||||||
bgnotify_formatted "$didexit" "$bgnotify_lastcmd" "$elapsed"
|
[[ $elapsed -ge $bgnotify_threshold ]] || return 0
|
||||||
fi
|
|
||||||
|
# check if Terminal app is not active
|
||||||
|
[[ $(bgnotify_appid) != "$bgnotify_termid" ]] || return 0
|
||||||
|
|
||||||
|
bgnotify_formatted "$exit_status" "$bgnotify_lastcmd" "$elapsed"
|
||||||
|
} always {
|
||||||
|
bgnotify_timestamp=0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
autoload -Uz add-zsh-hook
|
||||||
|
add-zsh-hook preexec bgnotify_begin
|
||||||
|
add-zsh-hook precmd bgnotify_end
|
||||||
|
|
||||||
|
|
||||||
|
## Functions
|
||||||
|
|
||||||
|
# allow custom function override
|
||||||
|
(( ${+functions[bgnotify_formatted]} )) || \
|
||||||
|
function bgnotify_formatted {
|
||||||
|
local exit_status=$1
|
||||||
|
local cmd="$2"
|
||||||
|
|
||||||
|
# humanly readable elapsed time
|
||||||
|
local elapsed="$(( $3 % 60 ))s"
|
||||||
|
(( $3 < 60 )) || elapsed="$((( $3 % 3600) / 60 ))m $elapsed"
|
||||||
|
(( $3 < 3600 )) || elapsed="$(( $3 / 3600 ))h $elapsed"
|
||||||
|
|
||||||
|
[[ $bgnotify_bell = true ]] && printf '\a' # beep sound
|
||||||
|
if [[ $exit_status -eq 0 ]]; then
|
||||||
|
bgnotify "#win (took $elapsed)" "$cmd"
|
||||||
|
else
|
||||||
|
bgnotify "#fail (took $elapsed)" "$cmd"
|
||||||
fi
|
fi
|
||||||
bgnotify_timestamp=0 #reset it to 0!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
## only enable if a local (non-ssh) connection
|
function bgnotify_appid {
|
||||||
if [ -z "$SSH_CLIENT" ] && [ -z "$SSH_TTY" ]; then
|
if (( ${+commands[osascript]} )); then
|
||||||
add-zsh-hook preexec bgnotify_begin
|
osascript -e "tell application id \"$(bgnotify_programid)\" to get the {id, frontmost, id of front window, visible of front window}" 2>/dev/null
|
||||||
add-zsh-hook precmd bgnotify_end
|
elif [[ -n $WAYLAND_DISPLAY ]] && (( ${+commands[swaymsg]} )); then # wayland+sway
|
||||||
fi
|
local app_id=$(bgnotify_find_sway_appid)
|
||||||
|
[[ -n "$app_id" ]] && echo "$app_id" || echo $EPOCHSECONDS
|
||||||
|
elif [[ -z $WAYLAND_DISPLAY ]] && [[ -n $DISPLAY ]] && (( ${+commands[xprop]} )); then
|
||||||
|
xprop -root _NET_ACTIVE_WINDOW 2>/dev/null | cut -d' ' -f5
|
||||||
|
else
|
||||||
|
echo $EPOCHSECONDS
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function bgnotify_find_sway_appid {
|
||||||
|
# output is "app_id,container_id", for example "Alacritty,1694"
|
||||||
|
# see example swaymsg output: https://github.com/ohmyzsh/ohmyzsh/files/13463939/output.json
|
||||||
|
if (( ${+commands[jq]} )); then
|
||||||
|
swaymsg -t get_tree | jq '.. | select(.type?) | select(.focused==true) | {app_id, id} | join(",")'
|
||||||
|
else
|
||||||
|
swaymsg -t get_tree | awk '
|
||||||
|
BEGIN { Id = ""; Appid = ""; FocusNesting = -1; Nesting = 0 }
|
||||||
|
{
|
||||||
|
# Enter a block
|
||||||
|
if ($0 ~ /.*{$/) Nesting++
|
||||||
|
|
||||||
|
# Exit a block. If Nesting is now less than FocusNesting, we have the data we are looking for
|
||||||
|
if ($0 ~ /^[[:blank:]]*}.*/) { Nesting--; if (FocusNesting > 0 && Nesting < FocusNesting) exit 0 }
|
||||||
|
|
||||||
|
# Save the Id, it is potentially what we are looking for
|
||||||
|
if ($0 ~ /^[[:blank:]]*"id": [0-9]*,?$/) { sub(/^[[:blank:]]*"id": /, ""); sub(/,$/, ""); Id = $0 }
|
||||||
|
|
||||||
|
# Save the Appid, it is potentially what we are looking for
|
||||||
|
if ($0 ~ /^[[:blank:]]*"app_id": ".*",?$/) { sub(/^[[:blank:]]*"app_id": "/, ""); sub(/",$/, ""); Appid = $0 }
|
||||||
|
|
||||||
|
# Window is focused, this nesting block contains the Id and Appid we want!
|
||||||
|
if ($0 ~ /^[[:blank:]]*"focused": true,?$/) { FocusNesting = Nesting }
|
||||||
|
}
|
||||||
|
END {
|
||||||
|
if (Appid != "" && Id != "" && FocusNesting != -1) print Appid "," Id
|
||||||
|
else print ""
|
||||||
|
}'
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function bgnotify_programid {
|
||||||
|
case "$TERM_PROGRAM" in
|
||||||
|
iTerm.app) echo 'com.googlecode.iterm2' ;;
|
||||||
|
Apple_Terminal) echo 'com.apple.terminal' ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
function bgnotify {
|
||||||
|
local title="$1"
|
||||||
|
local message="$2"
|
||||||
|
local icon="$3"
|
||||||
|
if (( ${+commands[terminal-notifier]} )); then # macOS
|
||||||
|
local term_id=$(bgnotify_programid)
|
||||||
|
terminal-notifier -message "$message" -title "$title" ${=icon:+-appIcon "$icon"} ${=term_id:+-activate "$term_id"} &>/dev/null
|
||||||
|
elif (( ${+commands[growlnotify]} )); then # macOS growl
|
||||||
|
growlnotify -m "$title" "$message"
|
||||||
|
elif (( ${+commands[notify-send]} )); then
|
||||||
|
notify-send "$title" "$message" ${=icon:+--icon "$icon"}
|
||||||
|
elif (( ${+commands[kdialog]} )); then # KDE
|
||||||
|
kdialog --title "$title" --passivepopup "$message" 5
|
||||||
|
elif (( ${+commands[notifu]} )); then # cygwin
|
||||||
|
notifu /m "$message" /p "$title" ${=icon:+/i "$icon"}
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
## Defaults
|
||||||
|
|
||||||
|
# enable terminal bell on notify by default
|
||||||
|
bgnotify_bell=${bgnotify_bell:-true}
|
||||||
|
|
||||||
|
# notify if command took longer than 5s by default
|
||||||
|
bgnotify_threshold=${bgnotify_threshold:-5}
|
||||||
|
|
||||||
|
# bgnotify_appid is slow in macOS and the terminal ID won't change, so cache it at startup
|
||||||
|
bgnotify_termid="$(bgnotify_appid)"
|
||||||
|
|
|
@ -8,23 +8,36 @@ To use it, add `brew` to the plugins array of your zshrc file:
|
||||||
plugins=(... brew)
|
plugins=(... brew)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Shellenv
|
||||||
|
|
||||||
|
If `brew` is not found in the PATH, this plugin will attempt to find it in common locations, and execute
|
||||||
|
`brew shellenv` to set the environment appropriately. This plugin will also export
|
||||||
|
`HOMEBREW_PREFIX="$(brew --prefix)"` if not previously defined for convenience.
|
||||||
|
|
||||||
|
In case you installed `brew` in a non-common location, you can still set `BREW_LOCATION` variable pointing to
|
||||||
|
the `brew` binary before sourcing `oh-my-zsh.sh` and it'll set up the environment.
|
||||||
|
|
||||||
## Aliases
|
## Aliases
|
||||||
|
|
||||||
| Alias | Command | Description |
|
| Alias | Command | Description |
|
||||||
|----------|---------------------------------------|---------------------------------------------------------------------|
|
| -------- | --------------------------------------- | ------------------------------------------------------------------- |
|
||||||
| `brewp` | `brew pin` | Pin a specified formula so that it's not upgraded. |
|
| `bcubc` | `brew upgrade --cask && brew cleanup` | Update outdated casks, then run cleanup. |
|
||||||
| `brews` | `brew list -1` | List installed formulae or the installed files for a given formula. |
|
| `bcubo` | `brew update && brew outdated --cask` | Update Homebrew data, then list outdated casks. |
|
||||||
| `brewsp` | `brew list --pinned` | List pinned formulae, or show the version of a given formula. |
|
| `brewp` | `brew pin` | Pin a specified formula so that it's not upgraded. |
|
||||||
| `bubo` | `brew update && brew outdated` | Update Homebrew data, then list outdated formulae and casks. |
|
| `brews` | `brew list -1` | List installed formulae or the installed files for a given formula. |
|
||||||
| `bubc` | `brew upgrade && brew cleanup` | Upgrade outdated formulae and casks, then run cleanup. |
|
| `brewsp` | `brew list --pinned` | List pinned formulae, or show the version of a given formula. |
|
||||||
| `bubu` | `bubo && bubc` | Do the last two operations above. |
|
| `bubc` | `brew upgrade && brew cleanup` | Upgrade outdated formulae and casks, then run cleanup. |
|
||||||
| `buf` | `brew upgrade --formula` | Upgrade only formulas (not casks). |
|
| `bugbc` | `brew upgrade --greedy && brew cleanup` | Upgrade outdated formulae and casks (greedy), then run cleanup. |
|
||||||
| `bcubo` | `brew update && brew outdated --cask` | Update Homebrew data, then list outdated casks. |
|
| `bubo` | `brew update && brew outdated` | Update Homebrew data, then list outdated formulae and casks. |
|
||||||
| `bcubc` | `brew upgrade --cask && brew cleanup` | Update outdated casks, then run cleanup. |
|
| `bubu` | `bubo && bubc` | Do the last two operations above. |
|
||||||
|
| `bfu` | `brew upgrade --formula` | Upgrade only formulas (not casks). |
|
||||||
|
| `buz` | `brew uninstall --zap` | Remove all files associated with a cask. |
|
||||||
|
|
||||||
## Completion
|
## Completion
|
||||||
|
|
||||||
With the release of Homebrew 1.0, they decided to bundle the zsh completion as part of the
|
This plugin configures paths with Homebrew's completion functions automatically, so you don't need to do it
|
||||||
brew installation, so we no longer ship it with the brew plugin; now it only has brew
|
manually. See: https://docs.brew.sh/Shell-Completion#configuring-completions-in-zsh.
|
||||||
aliases. If you find that brew completion no longer works, make sure you have your Homebrew
|
|
||||||
installation fully up to date.
|
With the release of Homebrew 1.0, they decided to bundle the zsh completion as part of the brew installation,
|
||||||
|
so we no longer ship it with the brew plugin; now it only has brew aliases. If you find that brew completion
|
||||||
|
no longer works, make sure you have your Homebrew installation fully up to date.
|
||||||
|
|
|
@ -1,15 +1,54 @@
|
||||||
|
if (( ! $+commands[brew] )); then
|
||||||
|
if [[ -n "$BREW_LOCATION" ]]; then
|
||||||
|
if [[ ! -x "$BREW_LOCATION" ]]; then
|
||||||
|
echo "[oh-my-zsh] $BREW_LOCATION is not executable"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
elif [[ -x /opt/homebrew/bin/brew ]]; then
|
||||||
|
BREW_LOCATION="/opt/homebrew/bin/brew"
|
||||||
|
elif [[ -x /usr/local/bin/brew ]]; then
|
||||||
|
BREW_LOCATION="/usr/local/bin/brew"
|
||||||
|
elif [[ -x /home/linuxbrew/.linuxbrew/bin/brew ]]; then
|
||||||
|
BREW_LOCATION="/home/linuxbrew/.linuxbrew/bin/brew"
|
||||||
|
elif [[ -x "$HOME/.linuxbrew/bin/brew" ]]; then
|
||||||
|
BREW_LOCATION="$HOME/.linuxbrew/bin/brew"
|
||||||
|
else
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Only add Homebrew installation to PATH, MANPATH, and INFOPATH if brew is
|
||||||
|
# not already on the path, to prevent duplicate entries. This aligns with
|
||||||
|
# the behavior of the brew installer.sh post-install steps.
|
||||||
|
eval "$("$BREW_LOCATION" shellenv)"
|
||||||
|
unset BREW_LOCATION
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$HOMEBREW_PREFIX" ]]; then
|
||||||
|
# Maintain compatability with potential custom user profiles, where we had
|
||||||
|
# previously relied on always sourcing shellenv. OMZ plugins should not rely
|
||||||
|
# on this to be defined due to out of order processing.
|
||||||
|
export HOMEBREW_PREFIX="$(brew --prefix)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -d "$HOMEBREW_PREFIX/share/zsh/site-functions" ]]; then
|
||||||
|
fpath+=("$HOMEBREW_PREFIX/share/zsh/site-functions")
|
||||||
|
fi
|
||||||
|
|
||||||
|
alias bcubc='brew upgrade --cask && brew cleanup'
|
||||||
|
alias bcubo='brew update && brew outdated --cask'
|
||||||
alias brewp='brew pin'
|
alias brewp='brew pin'
|
||||||
alias brewsp='brew list --pinned'
|
alias brewsp='brew list --pinned'
|
||||||
alias bubo='brew update && brew outdated'
|
|
||||||
alias bubc='brew upgrade && brew cleanup'
|
alias bubc='brew upgrade && brew cleanup'
|
||||||
|
alias bugbc='brew upgrade --greedy && brew cleanup'
|
||||||
|
alias bubo='brew update && brew outdated'
|
||||||
alias bubu='bubo && bubc'
|
alias bubu='bubo && bubc'
|
||||||
alias buf='brew upgrade --formula'
|
alias bubug='bubo && bugbc'
|
||||||
alias bcubo='brew update && brew outdated --cask'
|
alias bfu='brew upgrade --formula'
|
||||||
alias bcubc='brew upgrade --cask && brew cleanup'
|
alias buz='brew uninstall --zap'
|
||||||
|
|
||||||
function brews() {
|
function brews() {
|
||||||
local formulae="$(brew leaves | xargs brew deps --installed --for-each)"
|
local formulae="$(brew leaves | xargs brew deps --installed --for-each)"
|
||||||
local casks="$(brew list --cask)"
|
local casks="$(brew list --cask 2>/dev/null)"
|
||||||
|
|
||||||
local blue="$(tput setaf 4)"
|
local blue="$(tput setaf 4)"
|
||||||
local bold="$(tput bold)"
|
local bold="$(tput bold)"
|
||||||
|
|
26
plugins/bridgetown/README.md
Normal file
26
plugins/bridgetown/README.md
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
# Bridgetown plugin
|
||||||
|
|
||||||
|
This plugin adds some aliases and autocompletion for common [Bridgetown](https://bridgetownrb.com/) commands.
|
||||||
|
|
||||||
|
To use it, add `bridgetown` to the plugins array in your zshrc file:
|
||||||
|
|
||||||
|
```zsh
|
||||||
|
plugins=(... bridgetown)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Aliases
|
||||||
|
|
||||||
|
| Alias | Command |
|
||||||
|
|-------|----------------------------|
|
||||||
|
| br | `bridgetown` |
|
||||||
|
| bra | `bin/bridgetown apply` |
|
||||||
|
| brb | `bin/bridgetown build` |
|
||||||
|
| brc | `bin/bridgetown console` |
|
||||||
|
| brclean | `bin/bridgetown clean` |
|
||||||
|
| brd | `bin/bridgetown deploy` |
|
||||||
|
| brdoc | `bin/bridgetown doctor` |
|
||||||
|
| brh | `bin/bridgetown help` |
|
||||||
|
| brn | `bridgetown new` |
|
||||||
|
| brp | `bridgetown plugins` |
|
||||||
|
| brpl | `bridgetown plugins list` |
|
||||||
|
| brs | `bin/bridgetown start` |
|
12
plugins/bridgetown/bridgetown.plugin.zsh
Normal file
12
plugins/bridgetown/bridgetown.plugin.zsh
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
alias br='bridgetown'
|
||||||
|
alias bra='bin/bridgetown apply'
|
||||||
|
alias brb='bin/bridgetown build'
|
||||||
|
alias brc='bin/bridgetown console'
|
||||||
|
alias brclean='bin/bridgetown clean'
|
||||||
|
alias brd='bin/bridgetown deploy'
|
||||||
|
alias brdoc='bin/bridgetown doctor'
|
||||||
|
alias brh='bin/bridgetown help'
|
||||||
|
alias brn='bridgetown new'
|
||||||
|
alias brp='bridgetown plugins'
|
||||||
|
alias brpl='bridgetown plugins list'
|
||||||
|
alias brs='bin/bridgetown start'
|
20
plugins/bun/README.md
Normal file
20
plugins/bun/README.md
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# Bun Plugin
|
||||||
|
|
||||||
|
This plugin sets up completion for [Bun](https://bun.sh).
|
||||||
|
|
||||||
|
To use it, add `bun` to the plugins array in your zshrc file:
|
||||||
|
|
||||||
|
```zsh
|
||||||
|
plugins=(... bun)
|
||||||
|
```
|
||||||
|
|
||||||
|
This plugin does not add any aliases.
|
||||||
|
|
||||||
|
## Cache
|
||||||
|
|
||||||
|
This plugin caches the completion script and is automatically updated when the
|
||||||
|
plugin is loaded, which is usually when you start up a new terminal emulator.
|
||||||
|
|
||||||
|
The cache is stored at:
|
||||||
|
|
||||||
|
- `$ZSH_CACHE_DIR/completions/_bun_` completions script
|
14
plugins/bun/bun.plugin.zsh
Normal file
14
plugins/bun/bun.plugin.zsh
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
# If Bun is not found, don't do the rest of the script
|
||||||
|
if (( ! $+commands[bun] )); then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If the completion file doesn't exist yet, we need to autoload it and
|
||||||
|
# bind it to `bun`. Otherwise, compinit will have already done that.
|
||||||
|
if [[ ! -f "$ZSH_CACHE_DIR/completions/_bun" ]]; then
|
||||||
|
typeset -g -A _comps
|
||||||
|
autoload -Uz _bun
|
||||||
|
_comps[bun]=_bun
|
||||||
|
fi
|
||||||
|
|
||||||
|
SHELL=zsh bun completions >| "$ZSH_CACHE_DIR/completions/_bun" &|
|
|
@ -1,4 +1,4 @@
|
||||||
#compdef bundle
|
#compdef bundle bundler
|
||||||
|
|
||||||
local curcontext="$curcontext" state line _gems _opts ret=1
|
local curcontext="$curcontext" state line _gems _opts ret=1
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
# CakePHP 3 basic command completion
|
# CakePHP 3 basic command completion
|
||||||
_cakephp3_get_command_list () {
|
_cakephp3_get_command_list () {
|
||||||
bin/cake Completion commands
|
bin/cake completion commands
|
||||||
}
|
}
|
||||||
|
|
||||||
_cakephp3_get_sub_command_list () {
|
_cakephp3_get_sub_command_list () {
|
||||||
bin/cake Completion subcommands ${words[2]}
|
bin/cake completion subcommands ${words[2]}
|
||||||
}
|
}
|
||||||
|
|
||||||
_cakephp3_get_3rd_argument () {
|
_cakephp3_get_3rd_argument () {
|
||||||
|
@ -34,5 +34,5 @@ compdef _cakephp3 cake
|
||||||
|
|
||||||
#Alias
|
#Alias
|
||||||
alias c3='bin/cake'
|
alias c3='bin/cake'
|
||||||
alias c3cache='bin/cake orm_cache clear'
|
alias c3cache='bin/cake schema_cache clear'
|
||||||
alias c3migrate='bin/cake migrations migrate'
|
alias c3migrate='bin/cake migrations migrate'
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# catimg
|
# catimg
|
||||||
|
|
||||||
Plugin for displaying images on the terminal using the the `catimg.sh` script provided by [posva](https://github.com/posva/catimg)
|
Plugin for displaying images on the terminal using the `catimg.sh` script provided by [posva](https://github.com/posva/catimg)
|
||||||
|
|
||||||
To use it, add `catimg` to the plugins array in your zshrc file:
|
To use it, add `catimg` to the plugins array in your zshrc file:
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#compdef coffee
|
#compdef coffee
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Copyright (c) 2011 Github zsh-users - https://github.com/zsh-users
|
# Copyright (c) 2011 GitHub zsh-users - https://github.com/zsh-users
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
|
|
@ -36,6 +36,7 @@ function colored() {
|
||||||
# Prefer `less` whenever available, since we specifically configured
|
# Prefer `less` whenever available, since we specifically configured
|
||||||
# environment for it.
|
# environment for it.
|
||||||
environment+=( PAGER="${commands[less]:-$PAGER}" )
|
environment+=( PAGER="${commands[less]:-$PAGER}" )
|
||||||
|
environment+=( GROFF_NO_SGR=1 )
|
||||||
|
|
||||||
# See ./nroff script.
|
# See ./nroff script.
|
||||||
if [[ "$OSTYPE" = solaris* ]]; then
|
if [[ "$OSTYPE" = solaris* ]]; then
|
||||||
|
|
|
@ -23,7 +23,7 @@ colorize_check_requirements() {
|
||||||
if [[ ${available_tools[(Ie)$ZSH_COLORIZE_TOOL]} -eq 0 ]]; then
|
if [[ ${available_tools[(Ie)$ZSH_COLORIZE_TOOL]} -eq 0 ]]; then
|
||||||
echo "ZSH_COLORIZE_TOOL '$ZSH_COLORIZE_TOOL' not recognized. Available options are 'pygmentize' and 'chroma'." >&2
|
echo "ZSH_COLORIZE_TOOL '$ZSH_COLORIZE_TOOL' not recognized. Available options are 'pygmentize' and 'chroma'." >&2
|
||||||
return 1
|
return 1
|
||||||
elif (( $+commands["$ZSH_COLORIZE_TOOL"] )); then
|
elif ! (( $+commands[$ZSH_COLORIZE_TOOL] )); then
|
||||||
echo "Package '$ZSH_COLORIZE_TOOL' is not installed!" >&2
|
echo "Package '$ZSH_COLORIZE_TOOL' is not installed!" >&2
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -30,5 +30,6 @@ It works out of the box with the command-not-found packages for:
|
||||||
- [NixOS](https://github.com/NixOS/nixpkgs/tree/master/nixos/modules/programs/command-not-found)
|
- [NixOS](https://github.com/NixOS/nixpkgs/tree/master/nixos/modules/programs/command-not-found)
|
||||||
- [Termux](https://github.com/termux/command-not-found)
|
- [Termux](https://github.com/termux/command-not-found)
|
||||||
- [SUSE](https://www.unix.com/man-page/suse/1/command-not-found/)
|
- [SUSE](https://www.unix.com/man-page/suse/1/command-not-found/)
|
||||||
|
- [Gentoo](https://github.com/AndrewAmmerlaan/command-not-found-gentoo/tree/main)
|
||||||
|
|
||||||
You can add support for other platforms by submitting a Pull Request.
|
You can add support for other platforms by submitting a Pull Request.
|
||||||
|
|
|
@ -3,9 +3,10 @@
|
||||||
for file (
|
for file (
|
||||||
# Arch Linux. Must have pkgfile installed: https://wiki.archlinux.org/index.php/Pkgfile#Command_not_found
|
# Arch Linux. Must have pkgfile installed: https://wiki.archlinux.org/index.php/Pkgfile#Command_not_found
|
||||||
/usr/share/doc/pkgfile/command-not-found.zsh
|
/usr/share/doc/pkgfile/command-not-found.zsh
|
||||||
# macOS (M1 and classic Homebrew): https://github.com/Homebrew/homebrew-command-not-found
|
# Homebrew: https://github.com/Homebrew/homebrew-command-not-found
|
||||||
/opt/homebrew/Library/Taps/homebrew/homebrew-command-not-found/handler.sh
|
/opt/homebrew/Library/Taps/homebrew/homebrew-command-not-found/handler.sh
|
||||||
/usr/local/Homebrew/Library/Taps/homebrew/homebrew-command-not-found/handler.sh
|
/usr/local/Homebrew/Library/Taps/homebrew/homebrew-command-not-found/handler.sh
|
||||||
|
/home/linuxbrew/.linuxbrew/Homebrew/Library/Taps/homebrew/homebrew-command-not-found/handler.sh
|
||||||
); do
|
); do
|
||||||
if [[ -r "$file" ]]; then
|
if [[ -r "$file" ]]; then
|
||||||
source "$file"
|
source "$file"
|
||||||
|
|
|
@ -35,9 +35,11 @@ plugins=(... common-aliases)
|
||||||
| mv | `mv -i` | Move a file |
|
| mv | `mv -i` | Move a file |
|
||||||
| zshrc | `${=EDITOR} ~/.zshrc` | Quickly access the ~/.zshrc file |
|
| zshrc | `${=EDITOR} ~/.zshrc` | Quickly access the ~/.zshrc file |
|
||||||
| dud | `du -d 1 -h` | Display the size of files at depth 1 in current location in human-readable form |
|
| dud | `du -d 1 -h` | Display the size of files at depth 1 in current location in human-readable form |
|
||||||
| duf | `du -sh` | Display the size of files in current location in human-readable form |
|
| duf\* | `du -sh` | Display the size of files in current location in human-readable form |
|
||||||
| t | `tail -f` | Shorthand for tail which outputs the last part of a file |
|
| t | `tail -f` | Shorthand for tail which outputs the last part of a file |
|
||||||
|
|
||||||
|
\* Only if the [`duf`](https://github.com/muesli/duf) command isn't installed.
|
||||||
|
|
||||||
### find and grep
|
### find and grep
|
||||||
|
|
||||||
| Alias | Command | Description |
|
| Alias | Command | Description |
|
||||||
|
@ -66,12 +68,15 @@ These aliases are expanded in any position in the command line, meaning you can
|
||||||
end of the command you've typed. Examples:
|
end of the command you've typed. Examples:
|
||||||
|
|
||||||
Quickly pipe to less:
|
Quickly pipe to less:
|
||||||
|
|
||||||
```zsh
|
```zsh
|
||||||
$ ls -l /var/log L
|
$ ls -l /var/log L
|
||||||
# will run
|
# will run
|
||||||
$ ls -l /var/log | less
|
$ ls -l /var/log | less
|
||||||
```
|
```
|
||||||
|
|
||||||
Silences stderr output:
|
Silences stderr output:
|
||||||
|
|
||||||
```zsh
|
```zsh
|
||||||
$ find . -type f NE
|
$ find . -type f NE
|
||||||
# will run
|
# will run
|
||||||
|
|
|
@ -35,7 +35,7 @@ alias -g NUL="> /dev/null 2>&1"
|
||||||
alias -g P="2>&1| pygmentize -l pytb"
|
alias -g P="2>&1| pygmentize -l pytb"
|
||||||
|
|
||||||
alias dud='du -d 1 -h'
|
alias dud='du -d 1 -h'
|
||||||
alias duf='du -sh *'
|
(( $+commands[duf] )) || alias duf='du -sh *'
|
||||||
(( $+commands[fd] )) || alias fd='find . -type d -name'
|
(( $+commands[fd] )) || alias fd='find . -type d -name'
|
||||||
alias ff='find . -type f -name'
|
alias ff='find . -type f -name'
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# `copybuffer` plugin
|
# `copybuffer` plugin
|
||||||
|
|
||||||
This plugin binds the ctrl-o keyboard shortcut to a command that copies the text
|
This plugin adds the <kbd>ctrl-o</kbd> keyboard shortcut to copy the current text
|
||||||
that is currently typed in the command line ($BUFFER) to the system clipboard.
|
in the command line to the system clipboard.
|
||||||
|
|
||||||
This is useful if you type a command - and before you hit enter to execute it - want
|
This is useful if you type a command - and before you hit enter to execute it - want
|
||||||
to copy it maybe so you can paste it into a script, gist or whatnot.
|
to copy it maybe so you can paste it into a script, gist or whatnot.
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
# onto the system clipboard
|
# onto the system clipboard
|
||||||
|
|
||||||
copybuffer () {
|
copybuffer () {
|
||||||
if which clipcopy &>/dev/null; then
|
if builtin which clipcopy &>/dev/null; then
|
||||||
printf "%s" "$BUFFER" | clipcopy
|
printf "%s" "$BUFFER" | clipcopy
|
||||||
else
|
else
|
||||||
zle -M "clipcopy not found. Please make sure you have Oh My Zsh installed correctly."
|
zle -M "clipcopy not found. Please make sure you have Oh My Zsh installed correctly."
|
||||||
|
|
29
plugins/dbt/README.md
Normal file
29
plugins/dbt/README.md
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
# dbt plugin
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
The `dbt plugin` adds several aliases for useful [dbt](https://docs.getdbt.com/) commands and
|
||||||
|
[aliases](#aliases).
|
||||||
|
|
||||||
|
To use it, add `dbt` to the plugins array of your zshrc file:
|
||||||
|
|
||||||
|
```
|
||||||
|
plugins=(... dbt)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Aliases
|
||||||
|
|
||||||
|
| Alias | Command | Description |
|
||||||
|
| ------ | ------------------------------------------------ | ---------------------------------------------------- |
|
||||||
|
| dbtlm | `dbt ls -s state:modified` | List modified models only |
|
||||||
|
| dbtrm | `dbt run -s state:modified` | Run modified models only |
|
||||||
|
| dbttm | `dbt test -m state:modified` | Test modified models only |
|
||||||
|
| dbtrtm | `dbtrm && dbttm` | Run and test modified models only |
|
||||||
|
| dbtrs | `dbt clean; dbt deps; dbt seed` | Re-seed data |
|
||||||
|
| dbtfrt | `dbtrs; dbt run --full-refresh; dbt test` | Perform a full fresh run with tests |
|
||||||
|
| dbtcds | `dbt docs generate; dbt docs serve` | Generate docs without compiling |
|
||||||
|
| dbtds | `dbt docs generate --no-compile; dbt docs serve` | Generate and serve docs skipping doc. re-compilation |
|
||||||
|
|
||||||
|
## Maintainer
|
||||||
|
|
||||||
|
### [msempere](https://github.com/msempere)
|
23
plugins/dbt/dbt.plugin.zsh
Normal file
23
plugins/dbt/dbt.plugin.zsh
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
# list modified models only
|
||||||
|
alias dbtlm="dbt ls -s state:modified"
|
||||||
|
|
||||||
|
# run modified models only
|
||||||
|
alias dbtrm="dbt run -s state:modified"
|
||||||
|
|
||||||
|
# test modified models only
|
||||||
|
alias dbttm="dbt test -m state:modified"
|
||||||
|
|
||||||
|
# run and test modified models only
|
||||||
|
alias dbtrtm="dbtrm && dbttm"
|
||||||
|
|
||||||
|
# re-seed data
|
||||||
|
alias dbtrs="dbt clean; dbt deps; dbt seed"
|
||||||
|
|
||||||
|
# perform a full fresh run with tests
|
||||||
|
alias dbtfrt="dbtrs; dbt run --full-refresh; dbt test"
|
||||||
|
|
||||||
|
# generate and serve docs
|
||||||
|
alias dbtcds="dbt docs generate; dbt docs serve"
|
||||||
|
|
||||||
|
# generate and serve docs skipping doc. re-compilation
|
||||||
|
alias dbtds="dbt docs generate --no-compile; dbt docs serve"
|
|
@ -13,7 +13,12 @@ plugins=(... debian)
|
||||||
- `$apt_pref`: use aptitude or apt if installed, fallback is apt-get.
|
- `$apt_pref`: use aptitude or apt if installed, fallback is apt-get.
|
||||||
- `$apt_upgr`: use upgrade or safe-upgrade (for aptitude).
|
- `$apt_upgr`: use upgrade or safe-upgrade (for aptitude).
|
||||||
|
|
||||||
Set `$apt_pref` and `$apt_upgr` to whatever command you want (before sourcing Oh My Zsh) to override this behavior.
|
Set **both** `$apt_pref` and `$apt_upgr` to whatever command you want (before sourcing Oh My Zsh) to override this behavior, e.g.:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
apt_pref='apt'
|
||||||
|
apt_upgr='full-upgrade'
|
||||||
|
```
|
||||||
|
|
||||||
## Common Aliases
|
## Common Aliases
|
||||||
|
|
||||||
|
@ -30,26 +35,25 @@ Set `$apt_pref` and `$apt_upgr` to whatever command you want (before sourcing Oh
|
||||||
|
|
||||||
## Superuser Operations Aliases
|
## Superuser Operations Aliases
|
||||||
|
|
||||||
| Alias | Command | Description |
|
| Alias | Command | Description |
|
||||||
| -------- | -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
|
| -------- | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
|
||||||
| `aac` | `sudo $apt_pref autoclean` | Clears out the local repository of retrieved package files |
|
| `aac` | `sudo $apt_pref autoclean` | Clears out the local repository of retrieved package files |
|
||||||
| `aar` | `sudo $apt_pref autoremove` | Removes packages installed automatically that are no longer needed |
|
| `aar` | `sudo $apt_pref autoremove` | Removes packages installed automatically that are no longer needed |
|
||||||
| `abd` | `sudo $apt_pref build-dep` | Installs all dependencies for building packages |
|
| `abd` | `sudo $apt_pref build-dep` | Installs all dependencies for building packages |
|
||||||
| `ac` | `sudo $apt_pref clean` | Clears out the local repository of retrieved package files except lock files |
|
| `ac` | `sudo $apt_pref clean` | Clears out the local repository of retrieved package files except lock files |
|
||||||
| `ad` | `sudo $apt_pref update` | Updates the package lists for upgrades for packages |
|
| `ad` | `sudo $apt_pref update` | Updates the package lists for upgrades for packages |
|
||||||
| `adg` | `sudo $apt_pref update && sudo $apt_pref $apt_upgr` | Update and upgrade packages |
|
| `adg` | `sudo $apt_pref update && sudo $apt_pref $apt_upgr` | Update and upgrade packages |
|
||||||
| `ads` | `sudo apt-get dselect-upgrade` | Installs packages from list and removes all not in the list |
|
| `ads` | `sudo apt-get dselect-upgrade` | Installs packages from list and removes all not in the list |
|
||||||
| `adu` | `sudo $apt_pref update && sudo $apt_pref dist-upgrade` | Smart upgrade that handles dependencies |
|
| `adu` | `sudo $apt_pref update && sudo $apt_pref dist-upgrade` | Smart upgrade that handles dependencies |
|
||||||
| `afu` | `sudo apt-file update` | Update the files in packages |
|
| `afu` | `sudo apt-file update` | Update the files in packages |
|
||||||
| `ai` | `sudo $apt_pref install` | Command-line tool to install package |
|
| `ai` | `sudo $apt_pref install` | Command-line tool to install package |
|
||||||
| `ail` | `sed -e 's/ */ /g' -e 's/ *//' \| cut -s -d ' ' -f 1 \| xargs sudo $apt_pref install` | Install all packages given on the command line while using only the first word of each line |
|
| `ail` | `sed -e 's/ */ /g' -e 's/ *//' \| cut -s -d ' ' -f 1 \| xargs sudo $apt_pref install` | Install all packages given on the command line while using only the first word of each line |
|
||||||
| `alu` | `sudo apt update && apt list -u && sudo apt upgrade` | Update, list and upgrade packages |
|
| `alu` | `sudo apt update && apt list -u && sudo apt upgrade` | Update, list and upgrade packages |
|
||||||
| `ap` | `sudo $apt_pref purge` | Removes packages along with configuration files |
|
| `ap` | `sudo $apt_pref purge` | Removes packages along with configuration files |
|
||||||
| `ar` | `sudo $apt_pref remove` | Removes packages, keeps the configuration files |
|
| `au` | `sudo $apt_pref $apt_upgr` | Install package upgrades |
|
||||||
| `au` | `sudo $apt_pref $apt_upgr` | Install package upgrades |
|
| `di` | `sudo dpkg -i` | Install all .deb files in the current directory |
|
||||||
| `di` | `sudo dpkg -i` | Install all .deb files in the current directory |
|
| `dia` | `sudo dpkg -i ./*.deb` | Install all .deb files in the current directory |
|
||||||
| `dia` | `sudo dpkg -i ./*.deb` | Install all .deb files in the current directory |
|
| `kclean` | `sudo aptitude remove -P ?and(~i~nlinux-(ima\|hea) ?not(~n$(uname -r)))` | Remove ALL kernel images and headers EXCEPT the one in use |
|
||||||
| `kclean` | `sudo aptitude remove -P ?and(~i~nlinux-(ima\|hea) ?not(~n$(uname -r)))` | Remove ALL kernel images and headers EXCEPT the one in use |
|
|
||||||
|
|
||||||
## Aliases - Commands using `su`
|
## Aliases - Commands using `su`
|
||||||
|
|
||||||
|
|
|
@ -51,11 +51,10 @@ if [[ $use_sudo -eq 1 ]]; then
|
||||||
alias au="sudo $apt_pref $apt_upgr"
|
alias au="sudo $apt_pref $apt_upgr"
|
||||||
alias ai="sudo $apt_pref install"
|
alias ai="sudo $apt_pref install"
|
||||||
# Install all packages given on the command line while using only the first word of each line:
|
# Install all packages given on the command line while using only the first word of each line:
|
||||||
# acs ... | ail
|
# acse ... | ail
|
||||||
|
|
||||||
alias ail="sed -e 's/ */ /g' -e 's/ *//' | cut -s -d ' ' -f 1 | xargs sudo $apt_pref install"
|
alias ail="sed -e 's/ */ /g' -e 's/ *//' | cut -s -d ' ' -f 1 | xargs sudo $apt_pref install"
|
||||||
alias ap="sudo $apt_pref purge"
|
alias ap="sudo $apt_pref purge"
|
||||||
alias ar="sudo $apt_pref remove"
|
|
||||||
alias aar="sudo $apt_pref autoremove"
|
alias aar="sudo $apt_pref autoremove"
|
||||||
|
|
||||||
# apt-get only
|
# apt-get only
|
||||||
|
@ -89,22 +88,17 @@ else
|
||||||
alias afu="su -lc '$apt-file update'"
|
alias afu="su -lc '$apt-file update'"
|
||||||
alias au="su -lc '$apt_pref $apt_upgr' root"
|
alias au="su -lc '$apt_pref $apt_upgr' root"
|
||||||
function ai() {
|
function ai() {
|
||||||
cmd="su -lc 'aptitude -P install $@' root"
|
cmd="su -lc '$apt_pref install $@' root"
|
||||||
print "$cmd"
|
print "$cmd"
|
||||||
eval "$cmd"
|
eval "$cmd"
|
||||||
}
|
}
|
||||||
function ap() {
|
function ap() {
|
||||||
cmd="su -lc '$apt_pref -P purge $@' root"
|
cmd="su -lc '$apt_pref purge $@' root"
|
||||||
print "$cmd"
|
|
||||||
eval "$cmd"
|
|
||||||
}
|
|
||||||
function ar() {
|
|
||||||
cmd="su -lc '$apt_pref -P remove $@' root"
|
|
||||||
print "$cmd"
|
print "$cmd"
|
||||||
eval "$cmd"
|
eval "$cmd"
|
||||||
}
|
}
|
||||||
function aar() {
|
function aar() {
|
||||||
cmd="su -lc '$apt_pref -P autoremove $@' root"
|
cmd="su -lc '$apt_pref autoremove $@' root"
|
||||||
print "$cmd"
|
print "$cmd"
|
||||||
eval "$cmd"
|
eval "$cmd"
|
||||||
}
|
}
|
||||||
|
@ -147,7 +141,6 @@ apt_pref_compdef au "$apt_upgr"
|
||||||
apt_pref_compdef ai "install"
|
apt_pref_compdef ai "install"
|
||||||
apt_pref_compdef ail "install"
|
apt_pref_compdef ail "install"
|
||||||
apt_pref_compdef ap "purge"
|
apt_pref_compdef ap "purge"
|
||||||
apt_pref_compdef ar "remove"
|
|
||||||
apt_pref_compdef aar "autoremove"
|
apt_pref_compdef aar "autoremove"
|
||||||
apt_pref_compdef ads "dselect-upgrade"
|
apt_pref_compdef ads "dselect-upgrade"
|
||||||
|
|
||||||
|
|
|
@ -4,16 +4,17 @@ This plugin sets up completion and aliases for [Deno](https://deno.land).
|
||||||
|
|
||||||
## Aliases
|
## Aliases
|
||||||
|
|
||||||
| Alias | Full command |
|
| Alias | Full command |
|
||||||
| ----- | ---------------- |
|
| ----- | ------------------- |
|
||||||
| db | deno bundle |
|
| db | deno bundle |
|
||||||
| dc | deno compile |
|
| dc | deno compile |
|
||||||
| dca | deno cache |
|
| dca | deno cache |
|
||||||
| dfmt | deno fmt |
|
| dfmt | deno fmt |
|
||||||
| dh | deno help |
|
| dh | deno help |
|
||||||
| dli | deno lint |
|
| dli | deno lint |
|
||||||
| drn | deno run |
|
| drn | deno run |
|
||||||
| drA | deno run -A |
|
| drA | deno run -A |
|
||||||
| drw | deno run --watch |
|
| drw | deno run --watch |
|
||||||
| dts | deno test |
|
| dru | deno run --unstable |
|
||||||
| dup | deno upgrade |
|
| dts | deno test |
|
||||||
|
| dup | deno upgrade |
|
||||||
|
|
|
@ -8,6 +8,7 @@ alias dli='deno lint'
|
||||||
alias drn='deno run'
|
alias drn='deno run'
|
||||||
alias drA='deno run -A'
|
alias drA='deno run -A'
|
||||||
alias drw='deno run --watch'
|
alias drw='deno run --watch'
|
||||||
|
alias dru='deno run --unstable'
|
||||||
alias dts='deno test'
|
alias dts='deno test'
|
||||||
alias dup='deno upgrade'
|
alias dup='deno upgrade'
|
||||||
|
|
||||||
|
|
|
@ -7,10 +7,10 @@ _direnv_hook() {
|
||||||
trap - SIGINT;
|
trap - SIGINT;
|
||||||
}
|
}
|
||||||
typeset -ag precmd_functions;
|
typeset -ag precmd_functions;
|
||||||
if [[ -z ${precmd_functions[(r)_direnv_hook]} ]]; then
|
if [[ -z "${precmd_functions[(r)_direnv_hook]+1}" ]]; then
|
||||||
precmd_functions=( _direnv_hook ${precmd_functions[@]} )
|
precmd_functions=( _direnv_hook ${precmd_functions[@]} )
|
||||||
fi
|
fi
|
||||||
typeset -ag chpwd_functions;
|
typeset -ag chpwd_functions;
|
||||||
if [[ -z ${chpwd_functions[(r)_direnv_hook]} ]]; then
|
if [[ -z "${chpwd_functions[(r)_direnv_hook]+1}" ]]; then
|
||||||
chpwd_functions=( _direnv_hook ${chpwd_functions[@]} )
|
chpwd_functions=( _direnv_hook ${chpwd_functions[@]} )
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -19,15 +19,17 @@ export DIRHISTORY_SIZE=30
|
||||||
# Returns the element if the array was not empty,
|
# Returns the element if the array was not empty,
|
||||||
# otherwise returns empty string.
|
# otherwise returns empty string.
|
||||||
function pop_past() {
|
function pop_past() {
|
||||||
typeset -g $1="${dirhistory_past[$#dirhistory_past]}"
|
setopt localoptions no_ksh_arrays
|
||||||
if [[ $#dirhistory_past -gt 0 ]]; then
|
if [[ $#dirhistory_past -gt 0 ]]; then
|
||||||
|
typeset -g $1="${dirhistory_past[$#dirhistory_past]}"
|
||||||
dirhistory_past[$#dirhistory_past]=()
|
dirhistory_past[$#dirhistory_past]=()
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
function pop_future() {
|
function pop_future() {
|
||||||
typeset -g $1="${dirhistory_future[$#dirhistory_future]}"
|
setopt localoptions no_ksh_arrays
|
||||||
if [[ $#dirhistory_future -gt 0 ]]; then
|
if [[ $#dirhistory_future -gt 0 ]]; then
|
||||||
|
typeset -g $1="${dirhistory_future[$#dirhistory_future]}"
|
||||||
dirhistory_future[$#dirhistory_future]=()
|
dirhistory_future[$#dirhistory_future]=()
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
@ -35,6 +37,7 @@ function pop_future() {
|
||||||
# Push a new element onto the end of dirhistory_past. If the size of the array
|
# Push a new element onto the end of dirhistory_past. If the size of the array
|
||||||
# is >= DIRHISTORY_SIZE, the array is shifted
|
# is >= DIRHISTORY_SIZE, the array is shifted
|
||||||
function push_past() {
|
function push_past() {
|
||||||
|
setopt localoptions no_ksh_arrays
|
||||||
if [[ $#dirhistory_past -ge $DIRHISTORY_SIZE ]]; then
|
if [[ $#dirhistory_past -ge $DIRHISTORY_SIZE ]]; then
|
||||||
shift dirhistory_past
|
shift dirhistory_past
|
||||||
fi
|
fi
|
||||||
|
@ -44,6 +47,7 @@ function push_past() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function push_future() {
|
function push_future() {
|
||||||
|
setopt localoptions no_ksh_arrays
|
||||||
if [[ $#dirhistory_future -ge $DIRHISTORY_SIZE ]]; then
|
if [[ $#dirhistory_future -ge $DIRHISTORY_SIZE ]]; then
|
||||||
shift dirhistory_future
|
shift dirhistory_future
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -10,6 +10,9 @@ To use it, add `dnf` to the plugins array in your zshrc file:
|
||||||
plugins=(... dnf)
|
plugins=(... dnf)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Classic `dnf` is getting superseded by `dnf5`; this plugin detects the presence
|
||||||
|
of `dnf5` and uses it as drop-in alternative to the slower `dnf`.
|
||||||
|
|
||||||
## Aliases
|
## Aliases
|
||||||
|
|
||||||
| Alias | Command | Description |
|
| Alias | Command | Description |
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue