Compare commits

...

47 Commits

Author SHA1 Message Date
731b96a021 fix(common): validate log level after error function (#133) 2025-06-30 03:32:04 +03:00
b0c647009d docs: add shellcheck and pre-commit setup guide (#131) 2025-06-30 03:32:04 +03:00
1f4f046bb1 docs(utils): clarify in_path usage (#129) 2025-06-30 03:32:04 +03:00
a0ae26bb21 chore(cr): source core libs in install 2025-06-30 03:32:04 +03:00
b1366dd982 chore(lint): consolidate naming, fix command shadowing 2025-06-30 03:32:04 +03:00
Ismo Vuorinen
5c59ed707e chore(deps): upgrade npm packages 2025-06-30 03:32:04 +03:00
14ab12ceda fix(lint): apply suggestions from code review
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Signed-off-by: Ismo Vuorinen <ismo@ivuorinen.net>
2025-06-30 03:32:04 +03:00
Ismo Vuorinen
a213dbf31f fix(lint): cr comment 2025-06-30 03:32:04 +03:00
Ismo Vuorinen
7ac2e2f1bf fix(lint): packages, helpers, common 2025-06-30 03:32:04 +03:00
Ismo Vuorinen
b6841a3ae0 fix: add missing error code 2025-06-30 03:32:04 +03:00
1d0ea5ace4 fix(dfm): update traps and tests (#124)
* fix(dfm): update traps and tests

* fix(dfm): initialize defaults and secure tests

* fix(tests): secure helper quoting and extend install coverage

* fix(utils): avoid double extension when resolving command

* fix(tests): quote paths and add strict mode

* fix(utils): escape function name in regex
2025-06-30 03:32:04 +03:00
76076fdaa4 feat(install): add automation and skip flags (#121)
* feat(install): add automation and skip flags

* fix(install): avoid resetting flags in cargo

* fix(install): avoid option reset

* fix(install): preserve parsed options
2025-06-30 03:32:04 +03:00
5a832d1478 fix(utils): improve get_function_description file resolution (#122) 2025-06-30 03:32:04 +03:00
6155891fa4 test: use PROJECT_ROOT in dfm tests (#123) 2025-06-30 03:32:04 +03:00
coderabbitai[bot]
066b38926a chore: add docstrings to feat/dfm (#84)
Docstrings generation was requested by @ivuorinen.

* https://github.com/ivuorinen/dotfiles/pull/59#issuecomment-2564381679

The following files were modified:

* `local/dfm/cmd/install.sh`
* `local/dfm/lib/common.sh`
* `local/dfm/lib/utils.sh`

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-06-30 03:32:04 +03:00
35e812baa2 chore: fix used var in local/dfm/lib/utils.sh
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Signed-off-by: Ismo Vuorinen <ismo@ivuorinen.net>
2025-06-30 03:32:04 +03:00
0037067722 chore(dfm): cleanup, fixes 2025-06-30 03:32:04 +03:00
573fc9faf4 chore(dfm): cleanup, fixes 2025-06-30 03:32:04 +03:00
359ac4e2c0 chore(dfm): cleanup, fixes 2025-06-30 03:32:04 +03:00
255c8fdce7 feat(dfm): modularize dfm, add utils, logger, etc. 2025-06-30 03:32:04 +03:00
1531647e01 feat(ci): use pr-lint action instead of reviewdog (#136) 2025-06-30 03:21:47 +03:00
github-actions[bot]
15aff17f03 chore: update pre-commit hooks (#138)
Co-authored-by: ivuorinen <11024+ivuorinen@users.noreply.github.com>
2025-06-26 10:21:22 +03:00
renovate[bot]
42a5b79048 chore(deps): update node.js to v22.17.0 (#137) 2025-06-25 17:13:11 +03:00
a72c8ff33a chore(config): zed config update 2025-06-24 04:42:23 +03:00
19d9035214 chore(config): don't format config/op/plugins 2025-06-23 20:04:50 +03:00
7ca077c852 fix(ci): typo
Signed-off-by: Ismo Vuorinen <ismo@ivuorinen.net>
2025-06-23 20:00:04 +03:00
48604d81d6 fix(ci): add actions/setup-node to linters.yml
Signed-off-by: Ismo Vuorinen <ismo@ivuorinen.net>
2025-06-23 19:57:34 +03:00
github-actions[bot]
405e68f895 chore: update pre-commit hooks (#135) 2025-06-23 10:18:13 +03:00
6d62352127 chore(deps): update fisher plugins, add jgusta/paths 2025-06-22 11:44:41 +03:00
017d82abc5 fix(bin): path append quoting (#130) 2025-06-21 21:32:23 +03:00
github-actions[bot]
24ad4bf5b7 chore: update pre-commit hooks (#128)
Co-authored-by: ivuorinen <11024+ivuorinen@users.noreply.github.com>
2025-06-19 13:10:14 +03:00
07264c594f chore(config): ideavim config tweaks
Signed-off-by: Ismo Vuorinen <ismo@ivuorinen.net>
2025-06-16 14:03:00 +03:00
github-actions[bot]
7b58f660ac chore: update pre-commit hooks (#127) 2025-06-16 07:33:21 +03:00
renovate[bot]
b000f2b0c4 fix(container): update image python (3.13.4 → 3.13.5) (#126) 2025-06-14 09:53:35 +03:00
4d548687e1 chore(lint): prettier
Signed-off-by: Ismo Vuorinen <ismo@ivuorinen.net>
2025-06-12 10:20:58 +03:00
519d8398de chore(deps): remove bundle-audit, add @types/node and typescript, upgrade
Signed-off-by: Ismo Vuorinen <ismo@ivuorinen.net>
2025-06-12 10:16:53 +03:00
2203bb3957 chore(config): ideavim harpoon config
Signed-off-by: Ismo Vuorinen <ismo@ivuorinen.net>
2025-06-12 09:19:09 +03:00
github-actions[bot]
ddafdfe3c9 chore: update pre-commit hooks (#125) 2025-06-12 07:32:53 +03:00
a3f35b2d18 feat(fish): add nickeb96/puffer-fish
Signed-off-by: Ismo Vuorinen <ismo@ivuorinen.net>
2025-06-11 13:40:36 +03:00
90020a4998 chore(config): zed config update 2025-06-11 08:18:33 +03:00
0f806c172d chore(tmux): move resurrect and continuum last 2025-06-11 08:18:33 +03:00
renovate[bot]
e8eb9b98b2 feat(github-action): update softprops/action-gh-release (v2.2.2 → v2.3.2)
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-11 00:09:23 +00:00
7e0a88cf8f feat(nvim): add m4xshen/hardtime.nvim
Signed-off-by: Ismo Vuorinen <ismo@ivuorinen.net>
2025-06-10 12:01:19 +03:00
f72f57ebf0 chore(nvim): remove volar, prefix lsp commands with leader
Signed-off-by: Ismo Vuorinen <ismo@ivuorinen.net>
2025-06-10 12:00:49 +03:00
b5e56e2cbb feat(config): fish: meaningful-ooo/sponge
Signed-off-by: Ismo Vuorinen <ismo@ivuorinen.net>
2025-06-10 09:57:18 +03:00
github-actions[bot]
179938132c chore: update pre-commit hooks (#120) 2025-06-09 08:06:27 +03:00
renovate[bot]
bae84c176c fix(container): update image python (3.13.3 → 3.13.4) (#119)
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-05 07:45:53 +03:00
104 changed files with 3079 additions and 8912 deletions

View File

@@ -28,7 +28,7 @@ indent_size = 1
indent_size = 1
indent_style = tab
[{local/bin/*,**/*.sh,**/zshrc,config/*,scripts/*}]
[{local/bin/*,local/dfm/*,**/*.sh,**/zshrc,config/*,scripts/*}]
indent_size = 2
tab_width = 2
shell_variant = bash # --language-variant

8
.github/README.md vendored
View File

@@ -16,9 +16,11 @@ see what interesting stuff you've done with it. Sharing is caring.
### First time setup
1. Clone this repository to `$HOME/.dotfiles`
2. `./install`
3. ???
4. Profit
2. Install [shellcheck](https://github.com/koalaman/shellcheck) and [pre-commit](https://pre-commit.com/)
3. Run `pre-commit install` to enable Git hooks
4. `./install`
5. ???
6. Profit
### Updates

View File

@@ -1,5 +1,5 @@
---
# yaml-language-server: https://json.schemastore.org/github-workflow.json
# $schema: "https://json.schemastore.org/github-workflow.json"
name: Debug Changelog # Workflow name displayed on GitHub
on:

View File

@@ -1,8 +1,10 @@
---
# yaml-language-server: https://json.schemastore.org/github-workflow.json
name: Reviewdog
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
name: Lint Code Base
on: [push]
on:
pull_request:
branches: [master, main]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
@@ -11,48 +13,24 @@ concurrency:
permissions: read-all
jobs:
linters:
name: Linters
runs-on: self-hosted
permissions: write-all
Linter:
name: PR Lint
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
statuses: write
contents: read
packages: read
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: GitHub Actions
uses: reviewdog/action-actionlint@a5524e1c19e62881d79c1f1b9b6f09f16356e281 # v1.65.2
- name: Yarn Lock Changes
uses: Simek/yarn-lock-changes@34017425198654c20162a4dfd4f238fbece9636f # v0.12.1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
reporter: github-pr-review
token: ${{ secrets.GITHUB_TOKEN }}
- name: detect-secrets
uses: reviewdog/action-detect-secrets@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
reporter: github-pr-review
- name: markdownlint
uses: reviewdog/action-markdownlint@3667398db9118d7e78f7a63d10e26ce454ba5f58 # v0.26.2
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
reporter: github-pr-review
- name: shfmt
uses: reviewdog/action-shfmt@d8f080930b9be5847b4f97e9f4122b81a82aaeac # v1.0.4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
shfmt_flags: |
--find
--list
--write
--diff
--simplify
--language-dialect bash
--indent 2
--binary-next-line
--case-indent
--space-redirects
--func-next-line
- name: Run PR Lint
# https://github.com/ivuorinen/actions
uses: ivuorinen/actions/pr-lint@9480614ba2231013d99dd5b9c730d2b105b9e160 # 25.6.25

View File

@@ -1,5 +1,5 @@
---
# yaml-language-server: https://json.schemastore.org/github-workflow.json
# $schema: "https://json.schemastore.org/github-workflow.json"
name: Release Daily State
on:
@@ -40,7 +40,7 @@ jobs:
- name: Create release
if: steps.daily-version.outputs.created
uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 # v2.2.2
uses: softprops/action-gh-release@72f2c25fcb47643c292f7107632f7a47c1df5cd8 # v2.3.2
with:
token: ${{ secrets.GITHUB_TOKEN }}
tag_name: ${{ steps.daily-version.outputs.version }}

View File

@@ -1,11 +1,11 @@
---
# yaml-language-server: https://json.schemastore.org/github-workflow.json
# $schema: "https://json.schemastore.org/github-workflow.json"
name: Pre-commit autoupdate
on:
schedule:
# At 04:00 on Monday and Thursday.
- cron: "0 4 * * 1,4"
- cron: '0 4 * * 1,4'
workflow_dispatch:
concurrency:
@@ -16,7 +16,7 @@ permissions: read-all
jobs:
auto-update:
runs-on: ubuntu-latest
runs-on: self-hosted
permissions:
contents: write
@@ -33,6 +33,6 @@ jobs:
with:
token: ${{ secrets.GITHUB_TOKEN }}
branch: update/pre-commit-hooks
title: "chore: update pre-commit hooks"
commit-message: "chore: update pre-commit hooks"
title: 'chore: update pre-commit hooks'
commit-message: 'chore: update pre-commit hooks'
body: Update versions of pre-commit hooks to latest version.

View File

@@ -1,5 +1,5 @@
---
# yaml-language-server: https://json.schemastore.org/github-workflow.json
# $schema: "https://json.schemastore.org/github-workflow.json"
name: Semantic PR
on:

View File

@@ -1,5 +1,5 @@
---
# yaml-language-server: https://json.schemastore.org/github-workflow.json
# $schema: "https://json.schemastore.org/github-workflow.json"
name: Sync labels
# yamllint disable-line rule:truthy
@@ -11,7 +11,7 @@ on:
- .github/workflows/sync-labels.yml
- .github/labels.yml
schedule:
- cron: "34 5 * * *"
- cron: '34 5 * * *'
workflow_call:
workflow_dispatch:
@@ -23,10 +23,10 @@ permissions: read-all
jobs:
SyncLabels:
runs-on: ubuntu-latest
runs-on: self-hosted
permissions:
issues: write
steps:
- uses: ivuorinen/actions/sync-labels@main
- uses: ivuorinen/actions/sync-labels@99f3911475dbb5b8d43d314b24c0882997433868 # 25.6.23

View File

@@ -1,11 +1,11 @@
---
# yaml-language-server: https://json.schemastore.org/github-workflow.json
# $schema: "https://json.schemastore.org/github-workflow.json"
name: Update submodules
on:
schedule:
# At 04:00 on Monday and Thursday.
- cron: "0 4 * * 1"
- cron: '0 4 * * 1'
workflow_dispatch:
concurrency:
@@ -21,7 +21,6 @@ jobs:
permissions: write-all
steps:
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:

View File

@@ -1,5 +1,3 @@
{
"diagnostics.globals": [
"vim"
]
"diagnostics.globals": ["vim"]
}

View File

@@ -1,6 +1,7 @@
# only care about files that are directly under our control
config/cheat/cheatsheets/community/*
config/cheat/cheatsheets/tldr/*
config/op/plugins/used_plugins/*
config/tmux/plugins/*
local/bin/asdf/*
tools/*

29
.mega-linter.yml Normal file
View File

@@ -0,0 +1,29 @@
---
# Configuration file for MegaLinter
# See all available variables at
# https://megalinter.io/configuration/ and in linters documentation
APPLY_FIXES: all
SHOW_ELAPSED_TIME: false # Show elapsed time at the end of MegaLinter run
PARALLEL: true
VALIDATE_ALL_CODEBASE: true
FILEIO_REPORTER: false # Generate file.io report
GITHUB_STATUS_REPORTER: true # Generate GitHub status report
IGNORE_GENERATED_FILES: true # Ignore generated files
JAVASCRIPT_DEFAULT_STYLE: prettier # Default style for JavaScript
PRINT_ALPACA: false # Print Alpaca logo in console
SARIF_REPORTER: true # Generate SARIF report
SHOW_SKIPPED_LINTERS: false # Show skipped linters in MegaLinter log
TYPESCRIPT_DEFAULT_STYLE: prettier # Default style for TypeScript
DISABLE_LINTERS:
- REPOSITORY_DEVSKIM
YAML_YAMLLINT_CONFIG_FILE: .yamllint.yml
MARKDOWN_MARKDOWNLINT_CONFIG_FILE: .markdownlint.json
JAVASCRIPT_ES_CONFIG_FILE: .eslintrc.json
TYPESCRIPT_ES_CONFIG_FILE: .eslintrc.json
FILTER_REGEX_EXCLUDE: >
(node_modules|tools|config/cheat/cheatsheets/community|config/cheat/cheatsheets/tldr|config/fzf|config/zsh|config/tmux/plugins)

2
.nvmrc
View File

@@ -1 +1 @@
22.16.0
22.17.0

View File

@@ -49,7 +49,7 @@ repos:
- id: actionlint
- repo: https://github.com/renovatebot/pre-commit-hooks
rev: 40.36.8
rev: 41.11.1
hooks:
- id: renovate-config-validator

View File

@@ -5,6 +5,7 @@ config/cheat/cheatsheets/community
config/cheat/cheatsheets/tldr
config/fzf/*
config/nvim/*
config/op/plugins/used_plugins/*
config/tmux/plugins/*
config/zsh/*
lazy-lock.json

View File

@@ -1 +1 @@
3.13.3
3.13.5

View File

@@ -8,8 +8,8 @@
# supported_envs:
# - all
registries:
- type: standard
ref: v4.346.0 # renovate: depName=aquaproj/aqua-registry
- type: standard
ref: v4.346.0 # renovate: depName=aquaproj/aqua-registry
packages:
- name: cli/cli
version: 'v2.69.0'
- name: cli/cli
version: 'v2.69.0'

View File

@@ -75,7 +75,6 @@ cheatpaths:
path: ~/.dotfiles/config/cheat/cheatsheets/personal
tags: [personal]
readonly: false
# While it requires no configuration here, it's also worth noting that
# cheat will automatically append directories named '.cheat' within the
# current working directory to the 'cheatpath'. This can be very useful if

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/completions/app.fish:v7.0.0
# @halostatue/fish-macos/completions/app.fish:v7.0.1
complete --command app --erase

View File

@@ -1,235 +0,0 @@
# fish completion for docker -*- shell-script -*-
function __docker_debug
set -l file "$BASH_COMP_DEBUG_FILE"
if test -n "$file"
echo "$argv" >> $file
end
end
function __docker_perform_completion
__docker_debug "Starting __docker_perform_completion"
# Extract all args except the last one
set -l args (commandline -opc)
# Extract the last arg and escape it in case it is a space
set -l lastArg (string escape -- (commandline -ct))
__docker_debug "args: $args"
__docker_debug "last arg: $lastArg"
# Disable ActiveHelp which is not supported for fish shell
set -l requestComp "DOCKER_ACTIVE_HELP=0 $args[1] __complete $args[2..-1] $lastArg"
__docker_debug "Calling $requestComp"
set -l results (eval $requestComp 2> /dev/null)
# Some programs may output extra empty lines after the directive.
# Let's ignore them or else it will break completion.
# Ref: https://github.com/spf13/cobra/issues/1279
for line in $results[-1..1]
if test (string trim -- $line) = ""
# Found an empty line, remove it
set results $results[1..-2]
else
# Found non-empty line, we have our proper output
break
end
end
set -l comps $results[1..-2]
set -l directiveLine $results[-1]
# For Fish, when completing a flag with an = (e.g., <program> -n=<TAB>)
# completions must be prefixed with the flag
set -l flagPrefix (string match -r -- '-.*=' "$lastArg")
__docker_debug "Comps: $comps"
__docker_debug "DirectiveLine: $directiveLine"
__docker_debug "flagPrefix: $flagPrefix"
for comp in $comps
printf "%s%s\n" "$flagPrefix" "$comp"
end
printf "%s\n" "$directiveLine"
end
# this function limits calls to __docker_perform_completion, by caching the result behind $__docker_perform_completion_once_result
function __docker_perform_completion_once
__docker_debug "Starting __docker_perform_completion_once"
if test -n "$__docker_perform_completion_once_result"
__docker_debug "Seems like a valid result already exists, skipping __docker_perform_completion"
return 0
end
set --global __docker_perform_completion_once_result (__docker_perform_completion)
if test -z "$__docker_perform_completion_once_result"
__docker_debug "No completions, probably due to a failure"
return 1
end
__docker_debug "Performed completions and set __docker_perform_completion_once_result"
return 0
end
# this function is used to clear the $__docker_perform_completion_once_result variable after completions are run
function __docker_clear_perform_completion_once_result
__docker_debug ""
__docker_debug "========= clearing previously set __docker_perform_completion_once_result variable =========="
set --erase __docker_perform_completion_once_result
__docker_debug "Successfully erased the variable __docker_perform_completion_once_result"
end
function __docker_requires_order_preservation
__docker_debug ""
__docker_debug "========= checking if order preservation is required =========="
__docker_perform_completion_once
if test -z "$__docker_perform_completion_once_result"
__docker_debug "Error determining if order preservation is required"
return 1
end
set -l directive (string sub --start 2 $__docker_perform_completion_once_result[-1])
__docker_debug "Directive is: $directive"
set -l shellCompDirectiveKeepOrder 32
set -l keeporder (math (math --scale 0 $directive / $shellCompDirectiveKeepOrder) % 2)
__docker_debug "Keeporder is: $keeporder"
if test $keeporder -ne 0
__docker_debug "This does require order preservation"
return 0
end
__docker_debug "This doesn't require order preservation"
return 1
end
# This function does two things:
# - Obtain the completions and store them in the global __docker_comp_results
# - Return false if file completion should be performed
function __docker_prepare_completions
__docker_debug ""
__docker_debug "========= starting completion logic =========="
# Start fresh
set --erase __docker_comp_results
__docker_perform_completion_once
__docker_debug "Completion results: $__docker_perform_completion_once_result"
if test -z "$__docker_perform_completion_once_result"
__docker_debug "No completion, probably due to a failure"
# Might as well do file completion, in case it helps
return 1
end
set -l directive (string sub --start 2 $__docker_perform_completion_once_result[-1])
set --global __docker_comp_results $__docker_perform_completion_once_result[1..-2]
__docker_debug "Completions are: $__docker_comp_results"
__docker_debug "Directive is: $directive"
set -l shellCompDirectiveError 1
set -l shellCompDirectiveNoSpace 2
set -l shellCompDirectiveNoFileComp 4
set -l shellCompDirectiveFilterFileExt 8
set -l shellCompDirectiveFilterDirs 16
if test -z "$directive"
set directive 0
end
set -l compErr (math (math --scale 0 $directive / $shellCompDirectiveError) % 2)
if test $compErr -eq 1
__docker_debug "Received error directive: aborting."
# Might as well do file completion, in case it helps
return 1
end
set -l filefilter (math (math --scale 0 $directive / $shellCompDirectiveFilterFileExt) % 2)
set -l dirfilter (math (math --scale 0 $directive / $shellCompDirectiveFilterDirs) % 2)
if test $filefilter -eq 1; or test $dirfilter -eq 1
__docker_debug "File extension filtering or directory filtering not supported"
# Do full file completion instead
return 1
end
set -l nospace (math (math --scale 0 $directive / $shellCompDirectiveNoSpace) % 2)
set -l nofiles (math (math --scale 0 $directive / $shellCompDirectiveNoFileComp) % 2)
__docker_debug "nospace: $nospace, nofiles: $nofiles"
# If we want to prevent a space, or if file completion is NOT disabled,
# we need to count the number of valid completions.
# To do so, we will filter on prefix as the completions we have received
# may not already be filtered so as to allow fish to match on different
# criteria than the prefix.
if test $nospace -ne 0; or test $nofiles -eq 0
set -l prefix (commandline -t | string escape --style=regex)
__docker_debug "prefix: $prefix"
set -l completions (string match -r -- "^$prefix.*" $__docker_comp_results)
set --global __docker_comp_results $completions
__docker_debug "Filtered completions are: $__docker_comp_results"
# Important not to quote the variable for count to work
set -l numComps (count $__docker_comp_results)
__docker_debug "numComps: $numComps"
if test $numComps -eq 1; and test $nospace -ne 0
# We must first split on \t to get rid of the descriptions to be
# able to check what the actual completion will be.
# We don't need descriptions anyway since there is only a single
# real completion which the shell will expand immediately.
set -l split (string split --max 1 \t $__docker_comp_results[1])
# Fish won't add a space if the completion ends with any
# of the following characters: @=/:.,
set -l lastChar (string sub -s -1 -- $split)
if not string match -r -q "[@=/:.,]" -- "$lastChar"
# In other cases, to support the "nospace" directive we trick the shell
# by outputting an extra, longer completion.
__docker_debug "Adding second completion to perform nospace directive"
set --global __docker_comp_results $split[1] $split[1].
__docker_debug "Completions are now: $__docker_comp_results"
end
end
if test $numComps -eq 0; and test $nofiles -eq 0
# To be consistent with bash and zsh, we only trigger file
# completion when there are no other completions
__docker_debug "Requesting file completion"
return 1
end
end
return 0
end
# Since Fish completions are only loaded once the user triggers them, we trigger them ourselves
# so we can properly delete any completions provided by another script.
# Only do this if the program can be found, or else fish may print some errors; besides,
# the existing completions will only be loaded if the program can be found.
if type -q "docker"
# The space after the program name is essential to trigger completion for the program
# and not completion of the program name itself.
# Also, we use '> /dev/null 2>&1' since '&>' is not supported in older versions of fish.
complete --do-complete "docker " > /dev/null 2>&1
end
# Remove any pre-existing completions for the program since we will be handling all of them.
complete -c docker -e
# this will get called after the two calls below and clear the $__docker_perform_completion_once_result global
complete -c docker -n '__docker_clear_perform_completion_once_result'
# The call to __docker_prepare_completions will setup __docker_comp_results
# which provides the program's completion choices.
# If this doesn't require order preservation, we don't use the -k flag
complete -c docker -n 'not __docker_requires_order_preservation && __docker_prepare_completions' -f -a '$__docker_comp_results'
# otherwise we use the -k flag
complete -k -c docker -n '__docker_requires_order_preservation && __docker_prepare_completions' -f -a '$__docker_comp_results'

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/completions/finder.fish:v7.0.0
# @halostatue/fish-macos/completions/finder.fish:v7.0.1
complete --command finder --erase

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/completions/mac.fish:v7.0.0
# @halostatue/fish-macos/completions/mac.fish:v7.0.1
complete --command mac --erase

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/completions/manp.fish:v7.0.0
# @halostatue/fish-macos/completions/manp.fish:v7.0.1
complete --command manp --erase
complete --command manp --wraps man

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/completions/ql.fish:v7.0.0
# @halostatue/fish-macos/completions/ql.fish:v7.0.1
complete --erase --command ql
complete --command ql --wraps qlmanage

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/conf.d/halostatue_fish_macos.fish:v7.0.0
# @halostatue/fish-macos/conf.d/halostatue_fish_macos.fish:v7.0.1
function _halostatue_fish_macos_uninstall -e halostatue_fish_macos_uninstall
set --function functions app finder has_app mac manp note ql remind

View File

@@ -0,0 +1,22 @@
function ___paths_plugin_set_colors
if not set -q ___paths_plugin_colors
set -Ux ___paths_plugin_colors 27e6ff 29e0ff 5cd8ff 77d0ff 8ac8ff 9cbfff afb5ff c5a7ff d99bfe ea8feb f684d5 fe7abd ff73a3 ff708a fa7070 ff708a ff73a3 fe7abd f684d5 ea8feb d99bfe c5a7ff afb5ff 9cbfff 8ac8ff 77d0ff 5cd8ff 29e0ff
end
return 0
end
function _paths_uninstall --on-event paths_uninstall
for i in ___paths_plugin_wrap_color ___paths_plugin_output ___paths_plugin_handle_found_item ___paths_plugin_handle_source ___paths_plugin_cycle_color
functions -e $i
end
set -e ___paths_plugin_colors
set -e ___paths_plugin_current_color
end
function _paths_install --on-event _paths_install
___paths_plugin_set_colors
end
function _paths_update --on-event paths_update
___paths_plugin_set_colors
end

View File

@@ -0,0 +1,25 @@
status is-interactive || exit
function _puffer_fish_key_bindings --on-variable fish_key_bindings
set -l modes
if test "$fish_key_bindings" = fish_default_key_bindings
set modes default insert
else
set modes insert default
end
bind --mode $modes[1] . _puffer_fish_expand_dots
bind --mode $modes[1] ! _puffer_fish_expand_bang
bind --mode $modes[1] '$' _puffer_fish_expand_lastarg
bind --mode $modes[2] --erase . ! '$'
end
_puffer_fish_key_bindings
set -l uninstall_event puffer_fish_key_bindings_uninstall
function _$uninstall_event --on-event $uninstall_event
bind -e .
bind -e !
bind -e '$'
end

View File

@@ -0,0 +1,52 @@
# Sponge version
set --global sponge_version 1.1.0
# Allow to repeat previous command by default
if not set --query --universal sponge_delay
set --universal sponge_delay 2
end
# Purge entries both after `sponge_delay` entries and on exit by default
if not set --query --universal sponge_purge_only_on_exit
set --universal sponge_purge_only_on_exit false
end
# Add default filters
if not set --query --universal sponge_filters
set --universal sponge_filters sponge_filter_failed sponge_filter_matched
end
# Don't filter out commands that already have been in the history by default
if not set --query --universal sponge_allow_previously_successful
set --universal sponge_allow_previously_successful true
end
# Consider `0` the only successful exit code by default
if not set --query --universal sponge_successful_exit_codes
set --universal sponge_successful_exit_codes 0
end
# No active regex patterns by default
if not set --query --universal sponge_regex_patterns
set --universal sponge_regex_patterns
end
# Attach event handlers
functions --query \
_sponge_on_prompt \
_sponge_on_preexec \
_sponge_on_postexec \
_sponge_on_exit
# Initialize empty state for the first run
function _sponge_install --on-event sponge_install
set --global _sponge_current_command ''
set --global _sponge_current_command_exit_code 0
set --global _sponge_current_command_previously_in_history false
end
# Clean up variables
function _sponge_uninstall --on-event sponge_uninstall
_sponge_clear_state
set --erase sponge_version
end

View File

@@ -5,3 +5,6 @@ halostatue/fish-macos@v7
danhper/fish-ssh-agent
halostatue/fish-brew@v3
edc/bass
meaningful-ooo/sponge
nickeb96/puffer-fish
jgusta/paths

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/__macos_app_bundleid.fish:v7.0.0
# @halostatue/fish-macos/functions/__macos_app_bundleid.fish:v7.0.1
function __macos_app_bundleid
argparse --name 'app bundleid' x/exact a/all h/help q/quiet s/short -- $argv

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/__macos_app_find.fish:v7.0.0
# @halostatue/fish-macos/functions/__macos_app_find.fish:v7.0.1
function __macos_app_find
argparse --name 'app find' x/exact a/all q/quiet h/help -- $argv

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/__macos_app_frontmost.fish:v7.0.0
# @halostatue/fish-macos/functions/__macos_app_frontmost.fish:v7.0.1
function __macos_app_frontmost::info
set --function value (lsappinfo info -only $argv[2] $argv[1] | string split =)[2]

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/__macos_app_icon.fish:v7.0.0
# @halostatue/fish-macos/functions/__macos_app_icon.fish:v7.0.1
function __macos_app_icon
argparse --name 'app quit' x/exact h/help 'o/output=' 'w/width=' -- $argv

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/__macos_app_quit.fish:v7.0.0
# @halostatue/fish-macos/functions/__macos_app_quit.fish:v7.0.1
function __macos_app_quit
argparse --name 'app quit' x/exact r/restart h/help -- $argv

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/__macos_finder_cd.fish:v7.0.0
# @halostatue/fish-macos/functions/__macos_finder_cd.fish:v7.0.1
function __macos_finder_cd
argparse --name 'finder cd' h/help -- $argv

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/__macos_finder_clean.fish:v7.0.0
# @halostatue/fish-macos/functions/__macos_finder_clean.fish:v7.0.1
function __macos_finder_clean
argparse --name 'finder clean' h/help -- $argv

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/__macos_finder_column.fish:v7.0.0
# @halostatue/fish-macos/functions/__macos_finder_column.fish:v7.0.1
function __macos_finder_column
argparse --name 'finder column' h/help -- $argv

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/__macos_finder_desktop_icons.fish:v7.0.0
# @halostatue/fish-macos/functions/__macos_finder_desktop_icons.fish:v7.0.1
function __macos_finder_desktop_icons
argparse --name 'finder desktop-icons' h/help -- $argv

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/__macos_finder_hidden.fish:v7.0.0
# @halostatue/fish-macos/functions/__macos_finder_hidden.fish:v7.0.1
function __macos_finder_hidden
argparse --name 'finder hidden' h/help -- $argv

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/__macos_finder_icon.fish:v7.0.0
# @halostatue/fish-macos/functions/__macos_finder_icon.fish:v7.0.1
function __macos_finder_icon
argparse --name 'finder icon' h/help -- $argv

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/__macos_finder_list.fish:v7.0.0
# @halostatue/fish-macos/functions/__macos_finder_list.fish:v7.0.1
function __macos_finder_list
argparse --name 'finder list' h/help -- $argv

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/__macos_finder_pushd.fish:v7.0.0
# @halostatue/fish-macos/functions/__macos_finder_pushd.fish:v7.0.1
function __macos_finder_pushd
argparse --name 'finder pushd' h/help -- $argv

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/__macos_finder_pwd.fish:v7.0.0
# @halostatue/fish-macos/functions/__macos_finder_pwd.fish:v7.0.1
function __macos_finder_pwd
argparse --name 'finder pwd' h/help -- $argv

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/__macos_finder_quarantine.fish:v7.0.0
# @halostatue/fish-macos/functions/__macos_finder_quarantine.fish:v7.0.1
function __macos_finder_quarantine::run
set --query argv[1]

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/__macos_finder_selected.fish:v7.0.0
# @halostatue/fish-macos/functions/__macos_finder_selected.fish:v7.0.1
function __macos_finder_selected
argparse --name 'finder selected' h/help -- $argv

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/__macos_finder_track.fish:v7.0.0
# @halostatue/fish-macos/functions/__macos_finder_track.fish:v7.0.1
function __macos_finder_track
argparse --name 'finder track' h/help -- $argv

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/__macos_finder_untrack.fish:v7.0.0
# @halostatue/fish-macos/functions/__macos_finder_untrack.fish:v7.0.1
function __macos_finder_untrack
argparse --name 'finder untrack' h/help -- $argv

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/__macos_finder_update.fish:v7.0.0
# @halostatue/fish-macos/functions/__macos_finder_update.fish:v7.0.1
function __macos_finder_update
argparse --name 'finder update' h/help -- $argv

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/__macos_mac_airdrop.fish:v7.0.0
# @halostatue/fish-macos/functions/__macos_mac_airdrop.fish:v7.0.1
function __macos_mac_airdrop
argparse --name 'mac airdrop' h/help -- $argv

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/__macos_mac_airport.fish:v7.0.0
# @halostatue/fish-macos/functions/__macos_mac_airport.fish:v7.0.1
function __macos_mac_airport::ssid
__macos_mac_airport::run -I | string replace --filter --regex '\s+SSID: (\S+)' '$1'

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/__macos_mac_brightness.fish:v7.0.0
# @halostatue/fish-macos/functions/__macos_mac_brightness.fish:v7.0.1
function __macos_mac_brightness
argparse --name 'mac brightness' h/help -- $argv

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/__macos_mac_defaults_query.fish:v7.0.0
# @halostatue/fish-macos/functions/__macos_mac_defaults_query.fish:v7.0.1
function __macos_mac_defaults_query
if set --function value (defaults read $argv[1] $argv[2] 2>/dev/null)

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/__macos_mac_flushdns.fish:v7.0.0
# @halostatue/fish-macos/functions/__macos_mac_flushdns.fish:v7.0.1
function __macos_mac_flushdns
argparse --name 'mac flushdns' h/help -- $argv

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/__macos_mac_font_smoothing.fish:v7.0.0
# @halostatue/fish-macos/functions/__macos_mac_font_smoothing.fish:v7.0.1
function __macos_mac_font_smoothing
argparse --name 'mac font-smoothing' h/help -- $argv

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/__macos_mac_lsclean.fish:v7.0.0
# @halostatue/fish-macos/functions/__macos_mac_lsclean.fish:v7.0.1
function __macos_mac_lsclean
argparse --name 'mac lsclean' h/help -- $argv

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/__macos_mac_mail.fish:v7.0.0
# @halostatue/fish-macos/functions/__macos_mac_mail.fish:v7.0.1
# Speed up Mail.app by vacuuming the Envelope Index
# - Code from: http://web.archive.org/web/20071008123746/http://www.hawkwings.net/2007/03/03/scripts-to-automate-the-mailapp-envelope-speed-trick/

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/__macos_mac_proxy_icon.fish:v7.0.0
# @halostatue/fish-macos/functions/__macos_mac_proxy_icon.fish:v7.0.1
function __macos_mac_proxy_icon
argparse --name 'mac proxy-icon' h/help q/query -- $argv

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/__macos_mac_serialnumber.fish:v7.0.0
# @halostatue/fish-macos/functions/__macos_mac_serialnumber.fish:v7.0.1
function __macos_mac_serialnumber
argparse --name 'mac serialnumber' h/help c/copy -- $argv

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/__macos_mac_touchid.fish:v7.0.0
# @halostatue/fish-macos/functions/__macos_mac_touchid.fish:v7.0.1
function __macos_mac_touchid
argparse --name 'mac touchid' h/help q/quiet -- $argv

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/__macos_mac_touchid_sudo.fish:v7.0.0
# @halostatue/fish-macos/functions/__macos_mac_touchid_sudo.fish:v7.0.1
# Massively simplified. This version _only_ works if /etc/pam.d/sudo includes `auth
# include sudo_local` and requires manual removal of `pam_reattach` and `pam_tid` from

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/__macos_mac_transparency.fish:v7.0.0
# @halostatue/fish-macos/functions/__macos_mac_transparency.fish:v7.0.1
function __macos_mac_transparency
argparse --name 'mac transparency' h/help q/query -- $argv

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/__macos_mac_version.fish:v7.0.0
# @halostatue/fish-macos/functions/__macos_mac_version.fish:v7.0.1
function __macos_mac_version
argparse \

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/__macos_mac_vol.fish:v7.0.0
# @halostatue/fish-macos/functions/__macos_mac_vol.fish:v7.0.1
function __macos_mac_vol
argparse --name 'mac vol' h/help -- $argv

View File

@@ -0,0 +1,9 @@
function _puffer_fish_expand_bang
switch (commandline -t)
case '!'
commandline -t $history[1]
case '*'
commandline -i '!'
end
end

View File

@@ -0,0 +1,9 @@
function _puffer_fish_expand_dots -d 'expand ... to ../.. etc'
set -l cmd (commandline --cut-at-cursor)
set -l split (string split -- ' ' $cmd)
if string match --quiet --regex -- '^(\.\./)*\.\.$' $split[-1]
commandline --insert '/..'
else
commandline --insert '.'
end
end

View File

@@ -0,0 +1,9 @@
function _puffer_fish_expand_lastarg
switch (commandline -t)
case '!'
commandline -t ""
commandline -f history-token-search-backward
case '*'
commandline -i '$'
end
end

View File

@@ -0,0 +1,5 @@
function _sponge_clear_state
set --erase --global _sponge_current_command
set --erase --global _sponge_current_command_exit_code
set --erase --global _sponge_current_command_previously_in_history
end

View File

@@ -0,0 +1,3 @@
function _sponge_on_exit --on-event fish_exit
sponge_delay=0 _sponge_remove_from_history
end

View File

@@ -0,0 +1,24 @@
function _sponge_on_postexec --on-event fish_postexec
set --global _sponge_current_command_exit_code $status
# Remove command from the queue if it's been added previously
if set --local index (contains --index -- $_sponge_current_command $_sponge_queue)
set --erase _sponge_queue[$index]
end
# Ignore empty commands
if test -n $_sponge_current_command
set --local command ''
# Run filters
for filter in $sponge_filters
if $filter \
$_sponge_current_command \
$_sponge_current_command_exit_code \
$_sponge_current_command_previously_in_history
set command $_sponge_current_command
break
end
end
set --prepend --global _sponge_queue $command
end
end

View File

@@ -0,0 +1,16 @@
function _sponge_on_preexec --on-event fish_preexec \
--argument-names command
_sponge_clear_state
set --global _sponge_current_command $command
builtin history search --case-sensitive --exact --max=1 --null $command \
| read --local --null found_entries
# If a command is in the history and in the queue, ignore it, like if it wasnt in the history
if test (count $found_entries) -ne 0; and not contains $command $_sponge_queue
set --global _sponge_current_command_previously_in_history true
else
set --global _sponge_current_command_previously_in_history false
end
end

View File

@@ -0,0 +1,5 @@
function _sponge_on_prompt --on-event fish_prompt
if test $sponge_purge_only_on_exit = false
_sponge_remove_from_history
end
end

View File

@@ -0,0 +1,9 @@
function _sponge_remove_from_history
while test (count $_sponge_queue) -gt $sponge_delay
builtin history delete --case-sensitive --exact -- $_sponge_queue[-1]
set --erase _sponge_queue[-1]
end
builtin history save
end

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/app.fish:v7.0.0
# @halostatue/fish-macos/functions/app.fish:v7.0.1
function app --description 'Operate on macOS applications'
argparse --stop-nonopt h/help -- $argv

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/finder.fish:v7.0.0
# @halostatue/fish-macos/functions/finder.fish:v7.0.1
function __macos_finder_defaults::query
set --query argv[1]

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/has_app.fish:v7.0.0
# @halostatue/fish-macos/functions/has_app.fish:v7.0.1
function has_app --description 'Returns true if the named application exists'
# Suppress these flags being passed to __macos_app_find

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/mac.fish:v7.0.0
# @halostatue/fish-macos/functions/mac.fish:v7.0.1
function mac --description 'Manage several macOS functions'
argparse --stop-nonopt h/help -- $argv
@@ -36,6 +36,8 @@ Options:
__macos_mac_airdrop $argv
case airport
__macos_mac_airport $argv
case brightness
__macos_mac_brightness $argv
case flushdns
__macos_mac_flushdns $argv
case font-smoothing

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/manp.fish:v7.0.0
# @halostatue/fish-macos/functions/manp.fish:v7.0.1
# Based on man2pdf.sh created by Pico Mitchell (of Random Applications)
# on 11/16/22, licensed under the MIT license.

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/note.fish:v7.0.0
# @halostatue/fish-macos/functions/note.fish:v7.0.1
function note --description 'Add a note to Notes.app'
is_mac 'mountain lion'

View File

@@ -0,0 +1,175 @@
function ___paths_plugin_wrap_color
set_color normal
set_color "$argv[1]"
echo -n (set_color "$argv[1]")"$argv[2..]"
set_color normal
end
# duplicated in conf.d
function ___paths_plugin_set_colors
if not set -q ___paths_plugin_colors
set -Ux ___paths_plugin_colors 27e6ff 29e0ff 5cd8ff 77d0ff 8ac8ff 9cbfff afb5ff c5a7ff d99bfe ea8feb f684d5 fe7abd ff73a3 ff708a fa7070 ff708a ff73a3 fe7abd f684d5 ea8feb d99bfe c5a7ff afb5ff 9cbfff 8ac8ff 77d0ff 5cd8ff 29e0ff
end
return 0
end
function ___paths_plugin_cycle_color
if not set -q ___paths_plugin_current_color
set -Ux ___paths_plugin_current_color 1
else if test $___paths_plugin_current_color -gt (count $___paths_plugin_colors)
set -Ux ___paths_plugin_current_color 1
end
echo $___paths_plugin_colors[$___paths_plugin_current_color]
set -Ux ___paths_plugin_current_color (math $___paths_plugin_current_color + 1)
end
function ___paths_plugin_handle_found_item -a testName outFlags
set -f flags (string split -n ' ' -- "$outFlags")
set -f options (fish_opt -s c -l clean)
set -a options (fish_opt -s s -l single)
set -a options (fish_opt -s k -l no-color)
set -a options (fish_opt -s n -l inline)
argparse $options -- $flags
set -f arrow "=>"
# check if file exists
if test -e "$testName"
set -f nameOut (string trim -- "$testName")
if not set -q _flag_c # is not clean
if test -L "$testName" # is symlink
set -f __linkname (readlink -f "$testName")
set __linkname (string trim -- "$__linkname")
set testName (string trim -- "$testName")
if not set -q _flag_k # is color
set nameOut (___paths_plugin_wrap_color (___paths_plugin_cycle_color) $testName) (___paths_plugin_wrap_color "yellow" "$arrow") (___paths_plugin_wrap_color (___paths_plugin_cycle_color) $__linkname)
else # is color
set nameOut (echo -n "$testName" "$arrow" "$__linkname")
end
else # is not symlink
if not set -q _flag_k # is color
set testName (string trim -- "$testName")
set nameOut (___paths_plugin_wrap_color (___paths_plugin_cycle_color) "$testName")
else
set testName (string trim -- "$testName")
set nameOut "$testName"
end
end
set nameOut (string trim -- "$nameOut")
# do the tick
if set -q _flag_k # is not color
set nameOut "- $nameOut"
else # is color
set nameOut (___paths_plugin_wrap_color "yellow" "-") "$nameOut"
end
end
set nameOut (string trim -- "$nameOut")
echo -n $nameOut
end
end
function paths --description "Reveal the executable matches in shell paths or fish autoload."
set -f options (fish_opt -s c -l clean)
set -a options (fish_opt -s s -l single)
set -a options (fish_opt -s k -l no-color)
set -a options (fish_opt -s q -l quiet)
set -a options (fish_opt -s n -l inline)
argparse $options -- $argv
if test (count $argv) -lt 1
echo "paths - executable matches in shell paths or fish autoload."
and echo "usage: paths [-c|-s|-k] <name>"
and echo -e "\t-c or --no-color: output without color"
and echo -e "\t-s or --single: output without color or headers, the first result"
and echo -e "\t-k or --clean: output without tick marks or headers"
# and echo -e "\t-n or --inline: output without endline"
and return 1
end
set -f foundStatus 1
set -f input (string trim -- $argv)
# deprecated
if set -q _flag_q
set _flag_c True
end
if set -q _flag_s
set _flag_k True
set _flag_c True
end
set -f outFlags ''
set -q _flag_n; and set -a outFlags -n
set -q _flag_c; and set -a outFlags -c
set -q _flag_k; and set -a outFlags -k
set -q _flag_s; and set -a outFlags -s
set outFlags (string split -n " " -- "$outFlags")
___paths_plugin_set_colors
# loop over list of path lists
for pVar in VIRTUAL_ENV fisher_path fish_function_path fish_user_paths PATH
set -e acc
set -f acc ''
set -e hit
# see if variable is empty
if test -z "$pVar"
continue
end
set -f acc (begin
for t in $$pVar
for snit in "$t/$input.fish" "$t/$input"
set -f found (___paths_plugin_handle_found_item "$snit" "$outFlags")
set found (string trim -- "$found")
if test -n "$found"
set -f hit True
echo "$found"
if set -q _flag_s
break
end
end
end
if set -q _flag_s
if set -q hit
break
end
end
end
end)
# prepend source
if not set -q _flag_c
if set -q hit
set pVar (string trim -- "$pVar")
echo -e -n "$pVar\n"
end
end
if test -n "$acc"
set foundStatus 0
for fk in $acc
echo $fk
if set -q _flag_s
# stop after one
return $foundStatus
end
end
end
end
# check
set -l built (type --type $input 12&>/dev/null)
if test -n "$built"
and test "$built" = 'builtin'
set $foundStatus 0
if not set -q _flag_c
echo -e -n "builtin\n"
if set -q _flag_k
echo - "$input"
else # is color
echo (___paths_plugin_wrap_color "yellow" "-") (___paths_plugin_wrap_color (___paths_plugin_cycle_color) "$input")
end
else
echo "$input"
end
end
return $foundStatus
end

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/ql.fish:v7.0.0
# @halostatue/fish-macos/functions/ql.fish:v7.0.1
function ql --description 'QuickLook a file or directory'
# Updated based on https://gist.github.com/chockenberry/13c15466417b88e40f23e58df8091dac

View File

@@ -1,4 +1,4 @@
# @halostatue/fish-macos/functions/remind.fish:v7.0.0
# @halostatue/fish-macos/functions/remind.fish:v7.0.1
function remind --description 'Add a reminder to Reminders.app'
is_mac 'mountain lion'

View File

@@ -0,0 +1,11 @@
function sponge_filter_failed \
--argument-names command exit_code previously_in_history
if test $previously_in_history = true -a $sponge_allow_previously_successful = true
return 1
end
if contains $exit_code $sponge_successful_exit_codes
return 1
end
end

View File

@@ -0,0 +1,11 @@
function sponge_filter_matched \
--argument-names command
for pattern in $sponge_regex_patterns
if string match --regex --quiet $pattern -- $command
return
end
end
return 1
end

View File

@@ -6,10 +6,41 @@ source $HOME/.dotfiles/config/vim/vimrc
let mapleader = "\<SPACE>"
set clipboard+=unnamed
set cursorline " Highlight current line
set nocompatible " disable compatibility mode with vi
filetype off " disable filetype detection (but re-enable later, see below)
set undolevels=1000 " Number of undo levels
set backspace=indent,eol,start " Backspace behaviour
" Show a few lines of context around the cursor. Note that this makes the
" text scroll if you mouse-click near the start or end of the window.
set scrolloff=5
" Do incremental searching.
set incsearch
" Don't use Ex mode, use Q for formatting.
map Q gq
call plug#begin('~/.config/vim/plugged')
" Plug 'ayu-theme/ayu-vim'
call plug#end()
set ideajoin
set ideastatusicon=gray
set ideamarks
set idearefactormode=normal
set which-key
set mini-ai
" which-key settings
" https://github.com/TheBlob42/idea-which-key
let g:WhichKey_ShowVimActions = "true"
let g:WhichKey_DefaultDelay = 600 " make the popup appear much slower
let g:WhichKey_PrefixStyle = "bold"
" disable the timeout option
set notimeout
" Map esc to :noh
map <esc> :noh<cr>
@@ -31,7 +62,6 @@ nmap <leader>ss <Action>(GotoSymbol)
nmap <leader>fl <Action>(RecentLocations)
nmap <leader>fc <Action>(FindInPath)
nmap <leader>fr <Action>(RecentFiles)
nmap <leader>fe :NERDTreeToggle<CR>
nmap <Leader>fu :action FindUsages<CR>
nmap <Leader>ff :action GotoFile<CR>
nmap <leader>fi <Action>(SelectIn)
@@ -168,27 +198,32 @@ nnoremap 'x `X
nnoremap 'y `Y
nnoremap 'z `Z
" Harpoon
nmap <leader><C-1> :action SetHarpoon1<cr>
nmap <leader><C-2> :action SetHarpoon2<cr>
nmap <leader><C-3> :action SetHarpoon3<cr>
nmap <leader><C-4> :action SetHarpoon4<cr>
nmap <leader><C-5> :action SetHarpoon5<cr>
nmap <leader><C-6> :action SetHarpoon6<cr>
nmap <C-1> :action GotoHarpoon1<cr>
nmap <C-2> :action GotoHarpoon2<cr>
nmap <C-3> :action GotoHarpoon3<cr>
nmap <C-4> :action GotoHarpoon4<cr>
nmap <C-5> :action GotoHarpoon5<cr>
nmap <C-6> :action GotoHarpoon6<cr>
nmap <C-e> :action ShowHarpoon<cr>
nmap <C-a> :action AddToHarpoon<cr>
" ---
set cursorline " Highlight current line
set nocompatible " disable compatibility mode with vi
filetype off " disable filetype detection (but re-enable later, see below)
set undolevels=1000 " Number of undo levels
set backspace=indent,eol,start " Backspace behaviour
" Don't use Ex mode, use Q for formatting.
map Q gq
syntax enable
filetype plugin indent on
" call plug#begin('~/.config/vim/plugged')
" Plug 'ayu-theme/ayu-vim'
" call plug#end()
set termguicolors
if has('gui_running')
set macligatures
set guifont=JetBrainsMono:h14
endif
" vim: set filetype=vim :

View File

@@ -38,41 +38,46 @@ return {
-- Rename the variable under your cursor.
-- Most Language Servers support renaming across files, etc.
map('grn', vim.lsp.buf.rename, '[R]e[n]ame')
map('<leader>grn', vim.lsp.buf.rename, '[R]e[n]ame')
-- Execute a code action, usually your cursor needs to be on top of an error
-- or a suggestion from your LSP for this to activate.
map('gra', vim.lsp.buf.code_action, '[G]oto Code [A]ction', { 'n', 'x' })
map(
'<leader>gra',
vim.lsp.buf.code_action,
'[G]oto Code [A]ction',
{ 'n', 'x' }
)
-- Find references for the word under your cursor.
map('grr', tsb.lsp_references, '[G]oto [R]eferences')
map('<leader>grr', tsb.lsp_references, '[G]oto [R]eferences')
-- Jump to the implementation of the word under your cursor.
-- Useful when your language has ways of declaring types without
-- an actual implementation.
map('gri', tsb.lsp_implementations, '[G]oto [I]mplementation')
map('<leader>gri', tsb.lsp_implementations, '[G]oto [I]mplementation')
-- Jump to the definition of the word under your cursor.
-- This is where a variable was first declared, or where a function is
-- defined, etc. To jump back, press <C-t>.
map('grd', tsb.lsp_definitions, '[G]oto [D]efinition')
map('<leader>grd', tsb.lsp_definitions, '[G]oto [D]efinition')
-- WARN: This is not Goto Definition, this is Goto Declaration.
-- For example, in C this would take you to the header.
map('grD', vim.lsp.buf.declaration, '[G]oto [D]eclaration')
map('<leader>grD', vim.lsp.buf.declaration, '[G]oto [D]eclaration')
-- Fuzzy find all the symbols in your current document.
-- Symbols are things like variables, functions, types, etc.
map('gO', tsb.lsp_document_symbols, 'Open Document Symbols')
map('<leader>gO', tsb.lsp_document_symbols, 'Open Document Symbols')
-- Fuzzy find all the symbols in your current workspace.
-- Similar to document symbols, except searches over your entire project.
map('gW', tsb.lsp_dynamic_workspace_symbols, 'Open Workspace Symbols')
map('<leader>gW', tsb.lsp_dynamic_workspace_symbols, 'Open Workspace Symbols')
-- Jump to the type of the word under your cursor.
-- Useful when you're not sure what type a variable is and you want to see
-- the definition of its *type*, not where it was *defined*.
map('grt', tsb.lsp_type_definitions, '[G]oto [T]ype Definition')
map('<leader>grt', tsb.lsp_type_definitions, '[G]oto [T]ype Definition')
-- This function resolves a difference between neovim nightly
-- (version 0.11) and stable (version 0.10)
@@ -227,17 +232,6 @@ return {
tailwindcss = {},
terraformls = {},
ts_ls = {},
volar = {
settings = {
typescript = {
inlayHints = {
enumMemberValues = { enabled = true },
functionLikeReturnTypes = { enabled = true },
propertyDeclarationTypes = { enabled = true },
},
},
},
},
vimls = {},
eslint = {},
yamlls = {
@@ -270,6 +264,7 @@ return {
require('mason-lspconfig').setup {
ensure_installed = {}, -- explicitly set to an empty table
automatic_enable = true,
automatic_installation = false,
handlers = {
function(server_name)

View File

@@ -61,4 +61,13 @@ return {
-- Neovim plugin for locking a buffer to a window
-- https://github.com/stevearc/stickybuf.nvim
{ 'stevearc/stickybuf.nvim', opts = {} },
-- Break bad habits, master Vim motions
-- https://github.com/m4xshen/hardtime.nvim
{
'm4xshen/hardtime.nvim',
lazy = false,
dependencies = { 'MunifTanjim/nui.nvim' },
opts = {},
},
}

View File

@@ -112,9 +112,7 @@
{
"background": "transparent",
"foreground": "lightGreen",
"foreground_templates": [
"{{ if gt .Code 0 }}red{{ end }}"
],
"foreground_templates": ["{{ if gt .Code 0 }}red{{ end }}"],
"properties": {
"always_enabled": true
},
@@ -129,9 +127,7 @@
"transient_prompt": {
"background": "transparent",
"foreground": "lightGreen",
"foreground_templates": [
"{{ if gt .Code 0 }}red{{ end }}"
],
"foreground_templates": ["{{ if gt .Code 0 }}red{{ end }}"],
"template": "\u279c "
},
"version": 2

View File

@@ -1,15 +1,13 @@
{
"account_id": "S5Z2DMNFKJEZBPCWRHRWC4DCGI",
"entrypoint": [
"gh"
],
"credentials": [
{
"plugin": "github",
"credential_type": "personal_access_token",
"usage_id": "personal_access_token",
"vault_id": "injcin7obv3jdet3r2u3kfihfy",
"item_id": "f6vinbnc6l7ngdzvlw66ayewlq"
}
]
}
"account_id": "S5Z2DMNFKJEZBPCWRHRWC4DCGI",
"entrypoint": ["gh"],
"credentials": [
{
"plugin": "github",
"credential_type": "personal_access_token",
"usage_id": "personal_access_token",
"vault_id": "injcin7obv3jdet3r2u3kfihfy",
"item_id": "f6vinbnc6l7ngdzvlw66ayewlq"
}
]
}

View File

@@ -160,11 +160,11 @@ run-shell "$HOME/.dotfiles/config/tmux/plugins/tmux-sensible/sensible.tmux"
run-shell "$HOME/.dotfiles/config/tmux/plugins/tmux-window-name/tmux_window_name.tmux"
run-shell "$HOME/.dotfiles/config/tmux/plugins/tmux-mode-indicator/mode_indicator.tmux"
run-shell "$HOME/.dotfiles/config/tmux/plugins/tmux-suspend/suspend.tmux"
run-shell "$HOME/.dotfiles/config/tmux/plugins/tmux-continuum/continuum.tmux"
run-shell "$HOME/.dotfiles/config/tmux/plugins/tmux-resurrect/resurrect.tmux"
run-shell "$HOME/.dotfiles/config/tmux/plugins/tmux-sessionist/sessionist.tmux"
run-shell "$HOME/.dotfiles/config/tmux/plugins/tmux-yank/yank.tmux"
run-shell "$HOME/.dotfiles/config/tmux/plugins/tmux-current-pane-hostname/current_pane_hostname.tmux"
run-shell "$HOME/.dotfiles/config/tmux/plugins/tmux-fzf-url/fzf-url.tmux"
run-shell "$HOME/.dotfiles/config/tmux/plugins/tmux-resurrect/resurrect.tmux"
run-shell "$HOME/.dotfiles/config/tmux/plugins/tmux-continuum/continuum.tmux"
# run-shell "$HOME/.dotfiles/config/tmux/plugins/tmux-dark-notify/main.tmux"

View File

@@ -1,8 +1,13 @@
{
"context_servers": {
"github-activity-summarizer": {
"settings": {}
}
},
"telemetry": {
"metrics": false
},
"assistant": {
"agent": {
"always_allow_tool_actions": false,
"default_model": {
"provider": "copilot_chat",
@@ -11,6 +16,9 @@
"version": "2"
},
"languages": {
"PHP": {
"language_servers": ["intelephense", "phpactor"]
},
"Python": {
"enable_language_server": true,
"allow_rewrap": "anywhere",
@@ -25,6 +33,13 @@
"source.fixAll.eslint": true
}
},
"Markdown": {
"enable_language_server": true,
"preferred_line_length": 160,
"prettier": {
"allowed": true
}
},
"Lua": {
"enable_language_server": true,
"tab_size": 2
@@ -50,13 +65,32 @@
}
}
},
"diagnostics": {
"button": true,
"include_warnings": true,
"lsp_pull_diagnostics": {
"enabled": true,
"debounce_ms": 50
},
"inline": {
"enabled": true,
"update_debounce_ms": 150
}
},
"multi_cursor_modifier": "cmd_or_ctrl", // alias: "cmd", "ctrl"
"indent_guides": {
"enabled": true,
"coloring": "indent_aware"
},
"preferred_line_length": 100,
"soft_wrap": "bounded",
"wrap_guides": [100, 120, 160, 200],
"format_on_save": "on",
"vim_mode": true,
"theme": {
"mode": "system",
"light": "Tokyo Night Light",
"dark": "Tokyo Night Storm"
"light": "Tomorrow",
"dark": "Tomorrow at Midnight"
},
"inlay_hints": {
"enabled": true,
@@ -67,8 +101,44 @@
"ui_font_size": 16,
"buffer_font_size": 16,
"buffer_font_fallbacks": ["JetBrainsMono Nerd Font"],
"edit_predictions": {
"disabled_globs": [".env", ".env.*"]
},
"hour_format": "hour24"
"use_autoclose": false,
"hour_format": "hour24",
"auto_install_extensions": {
"angular": true,
"ansible": true,
"basher": true,
"biome": true,
"blade": true,
"csharp": true,
"css-modules-kit": true,
"dockerfile": true,
"git-firefly": true,
"github-activity-summarizer": true,
"golangci-lint": true,
"gosum": true,
"go-snippets": true,
"html": true,
"ini": true,
"json": true,
"json5": true,
"just": true,
"just-ls": true,
"lua": true,
"make": true,
"php": true,
"python-snippets": true,
"python-requirements": true,
"ruff": true,
"scss": true,
"sieve": true,
"stylelint": true,
"sql": true,
"toml": true,
"vue": true,
"vue-snippets": true,
"wakatime": true,
"xcode-themes": true,
"yaml": true,
"tomorrow-theme": true
}
}

View File

@@ -2,64 +2,64 @@
## main
| Key | Command(s) and actions |
|-----------------|-----------------------------------------------|
| alt-a | mode apps |
| alt-h | focus left |
| alt-j | focus down |
| alt-k | focus up |
| alt-l | focus right |
| alt-m | mode move |
| alt-s | mode service |
| alt-shift-1 | workspace 1 |
| alt-shift-2 | workspace 2 |
| alt-shift-tab | workspace-back-and-forth |
| ctrl-shift-1 | move-node-to-workspace 1 |
| ctrl-shift-2 | move-node-to-workspace 2 |
| ctrl-shift-tab | move-workspace-to-monitor --wrap-around prev |
| Key | Command(s) and actions |
| -------------- | -------------------------------------------- |
| alt-a | mode apps |
| alt-h | focus left |
| alt-j | focus down |
| alt-k | focus up |
| alt-l | focus right |
| alt-m | mode move |
| alt-s | mode service |
| alt-shift-1 | workspace 1 |
| alt-shift-2 | workspace 2 |
| alt-shift-tab | workspace-back-and-forth |
| ctrl-shift-1 | move-node-to-workspace 1 |
| ctrl-shift-2 | move-node-to-workspace 2 |
| ctrl-shift-tab | move-workspace-to-monitor --wrap-around prev |
## apps
| Key | Command(s) and actions |
|------|----------------------------------------------------------------------|
| b | exec-and-forget open -a /Applications/Brave Browser.app; mode main |
| c | exec-and-forget open -a /Applications/Ferdium.app; mode main |
| esc | reload-config; mode main |
| g | exec-and-forget open -a /Applications/Ghostty.app; mode main |
| o | exec-and-forget open -a /Applications/Obsidian.app; mode main |
| s | exec-and-forget open -a /Applications/Slack.app; mode main |
| t | exec-and-forget open -a /Applications/TIDAL.app; mode main |
| w | exec-and-forget open -a /Applications/WezTerm.app; mode main |
| Key | Command(s) and actions |
| --- | ------------------------------------------------------------------ |
| b | exec-and-forget open -a /Applications/Brave Browser.app; mode main |
| c | exec-and-forget open -a /Applications/Ferdium.app; mode main |
| esc | reload-config; mode main |
| g | exec-and-forget open -a /Applications/Ghostty.app; mode main |
| o | exec-and-forget open -a /Applications/Obsidian.app; mode main |
| s | exec-and-forget open -a /Applications/Slack.app; mode main |
| t | exec-and-forget open -a /Applications/TIDAL.app; mode main |
| w | exec-and-forget open -a /Applications/WezTerm.app; mode main |
## move
| Key | Command(s) and actions |
|--------------|--------------------------------------------------|
| 1 | move-node-to-workspace 1 --focus-follows-window |
| 2 | move-node-to-workspace 2 --focus-follows-window |
| ctrl-h | resize smart -70 |
| ctrl-l | resize smart +70 |
| esc | reload-config; mode main |
| h | move left |
| j | move down |
| k | move up |
| l | move right |
| r | flatten-workspace-tree; mode main |
| shift-h | join-with left |
| shift-j | join-with down |
| shift-k | join-with up |
| shift-l | join-with right |
| shift-left | resize smart +70 |
| shift-right | resize smart -70 |
| Key | Command(s) and actions |
| ----------- | ----------------------------------------------- |
| 1 | move-node-to-workspace 1 --focus-follows-window |
| 2 | move-node-to-workspace 2 --focus-follows-window |
| ctrl-h | resize smart -70 |
| ctrl-l | resize smart +70 |
| esc | reload-config; mode main |
| h | move left |
| j | move down |
| k | move up |
| l | move right |
| r | flatten-workspace-tree; mode main |
| shift-h | join-with left |
| shift-j | join-with down |
| shift-k | join-with up |
| shift-l | join-with right |
| shift-left | resize smart +70 |
| shift-right | resize smart -70 |
## service
| Key | Command(s) and actions |
|------------|-------------------------------------------|
| backspace | close-all-windows-but-current; mode main |
| esc | reload-config; mode main |
| f | layout floating tiling; mode main |
| r | flatten-workspace-tree; mode main |
| Key | Command(s) and actions |
| --------- | ---------------------------------------- |
| backspace | close-all-windows-but-current; mode main |
| esc | reload-config; mode main |
| f | layout floating tiling; mode main |
| r | flatten-workspace-tree; mode main |
File generated: 2025-01-15 13:32:41

View File

@@ -2,51 +2,51 @@
This file lists all aliases defined in `config/alias`.
| Alias | Command |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `....` | `cd ../../..` |
| `...` | `cd ../..` |
| `..` | `cd ..` |
| `.` | `cd $HOME` |
| `.b` | `cd $XDG_BIN_HOME` |
| `.c` | `cd $HOME/Code` |
| `.d` | `cd $DOTFILES` |
| `.l` | `cd $HOME/.local` |
| `.o` | `cd $HOME/Code/ivuorinen/obsidian/` |
| `art` | `[ -f artisan ] && php artisan \|\| php vendor/bin/artisan` |
| `cd..` | `cd ..` |
| `cdgr` | `cd "$(get_git_root)"` |
| `dn` | `du -chd1` |
| `flush` | `dscacheutil -flushcache` |
| `grep` | `grep --color` |
| `hide` | `defaults write com.apple.finder AppleShowAllFiles -bool false; killall Finder` |
| `ips` | `ifconfig -a \| grep -o 'inet6\? \(\([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\)\\|[a-fA-F0-9:]\+\)' \| sed -e 's/inet6* //' \| sort` |
| `irssi` | `irssi --config=$XDG_CONFIG_HOME/irssi/config --home=$XDG_CONFIG_HOME/irssi` |
| `isodate` | `date +'%Y-%m-%d'` |
| `l` | `ls -a` |
| `ll` | `ls -la` |
| `localip` | `ipconfig getifaddr en1` |
| `mirror_site` | `wget -m -k -K -E -e robots=off` |
| `peek` | `tee >(cat 1>&2)` |
| `pubkey` | `more ~/.ssh/id_rsa.pub \| pbcopy \| echo '=> Public key copied to pasteboard.'` |
| `sail` | `[ -f sail ] && bash sail \|\| bash vendor/bin/sail` |
| `show` | `defaults write com.apple.finder AppleShowAllFiles -bool true; killall Finder` |
| `sl` | `ls` |
| `svn` | `svn --config-dir $XDG_CONFIG_HOME/subversion` |
| `trivy_scan` | `docker run -v /var/run/docker.sock:/var/run/docker.sock -v $HOME/Library/Caches:/root/.cache/ aquasec/trivy` |
| `updatedb` | `sudo /usr/libexec/locate.updatedb` |
| `vi` | `nvim` |
| `vim` | `nvim` |
| `watchx` | `watch -dpbc` |
| `wget` | `wget --hsts-file=$XDG_DATA_HOME/wget-hsts` |
| `x-datetime` | `date +'%Y-%m-%d %H:%M:%S'` |
| `x-ip` | `dig +short myip.opendns.com @resolver1.opendns.com` |
| `x-timestamp` | `date +'%s'` |
| `xdg` | `xdg-ninja --skip-ok --skip-unsupported` |
| `zapall` | `zapds && zappyc` |
| `zapds` | `find . -name ".DS_Store" -print -delete` |
| `zappyc` | `find . -type f -name '*.pyc' -ls -delete` |
| `zedit` | `$EDITOR ~/.dotfiles` |
| Alias | Command |
| ------------- | ------------------------------------------------------------------------------------------------------------- | --------------------------------------------------- |
| `....` | `cd ../../..` |
| `...` | `cd ../..` |
| `..` | `cd ..` |
| `.` | `cd $HOME` |
| `.b` | `cd $XDG_BIN_HOME` |
| `.c` | `cd $HOME/Code` |
| `.d` | `cd $DOTFILES` |
| `.l` | `cd $HOME/.local` |
| `.o` | `cd $HOME/Code/ivuorinen/obsidian/` |
| `art` | `[ -f artisan ] && php artisan \|\| php vendor/bin/artisan` |
| `cd..` | `cd ..` |
| `cdgr` | `cd "$(get_git_root)"` |
| `dn` | `du -chd1` |
| `flush` | `dscacheutil -flushcache` |
| `grep` | `grep --color` |
| `hide` | `defaults write com.apple.finder AppleShowAllFiles -bool false; killall Finder` |
| `ips` | `ifconfig -a \| grep -o 'inet6\? \(\([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\)\\ | [a-fA-F0-9:]\+\)' \| sed -e 's/inet6\* //' \| sort` |
| `irssi` | `irssi --config=$XDG_CONFIG_HOME/irssi/config --home=$XDG_CONFIG_HOME/irssi` |
| `isodate` | `date +'%Y-%m-%d'` |
| `l` | `ls -a` |
| `ll` | `ls -la` |
| `localip` | `ipconfig getifaddr en1` |
| `mirror_site` | `wget -m -k -K -E -e robots=off` |
| `peek` | `tee >(cat 1>&2)` |
| `pubkey` | `more ~/.ssh/id_rsa.pub \| pbcopy \| echo '=> Public key copied to pasteboard.'` |
| `sail` | `[ -f sail ] && bash sail \|\| bash vendor/bin/sail` |
| `show` | `defaults write com.apple.finder AppleShowAllFiles -bool true; killall Finder` |
| `sl` | `ls` |
| `svn` | `svn --config-dir $XDG_CONFIG_HOME/subversion` |
| `trivy_scan` | `docker run -v /var/run/docker.sock:/var/run/docker.sock -v $HOME/Library/Caches:/root/.cache/ aquasec/trivy` |
| `updatedb` | `sudo /usr/libexec/locate.updatedb` |
| `vi` | `nvim` |
| `vim` | `nvim` |
| `watchx` | `watch -dpbc` |
| `wget` | `wget --hsts-file=$XDG_DATA_HOME/wget-hsts` |
| `x-datetime` | `date +'%Y-%m-%d %H:%M:%S'` |
| `x-ip` | `dig +short myip.opendns.com @resolver1.opendns.com` |
| `x-timestamp` | `date +'%s'` |
| `xdg` | `xdg-ninja --skip-ok --skip-unsupported` |
| `zapall` | `zapds && zappyc` |
| `zapds` | `find . -name ".DS_Store" -print -delete` |
| `zappyc` | `find . -type f -name '*.pyc' -ls -delete` |
| `zedit` | `$EDITOR ~/.dotfiles` |
Total aliases: 43
Last updated: Fri 17 Jan 2025 13:06:59 EET

View File

@@ -87,4 +87,3 @@ Leader: `<ctrl><space>`
S-Left Move the visible part of the window left
S-Right Move the visible part of the window right
```

View File

@@ -277,4 +277,4 @@ Mouse: alt_screen
```
- Generated on Thu 2 Jan 2025 17:41:13 EET
- Generated on Thu 2 Jan 2025 17:41:13 EET

View File

@@ -20,7 +20,7 @@ Some problematic code has been fixed per `shellcheck` suggestions.
## Sourced
| Script | Source |
|-------------------------|-------------------|
| ----------------------- | ----------------- |
| `x-dupes` | skx/sysadmin-util |
| `x-foreach` | mvdan/dotfiles |
| `x-multi-ping` | skx/sysadmin-util |

View File

@@ -39,6 +39,6 @@ for dir in "$@"; do
esac
# Append the directory to PATH.
export PATH="${PATH:+"$PATH:"}$dir"
export PATH="${PATH:+$PATH:}$dir"
[ "$VERBOSE" -eq 1 ] && echo "Appended '$dir' to PATH."
done

239
local/dfm/cmd/install.sh Normal file
View File

@@ -0,0 +1,239 @@
#!/usr/bin/env bash
set -euo pipefail
# Source core dfm libraries
source "$(dirname "${BASH_SOURCE[0]}")/../lib/common.sh"
source "$(dirname "${BASH_SOURCE[0]}")/../lib/utils.sh"
# Default paths can be overridden via environment variables
: "${DOTFILES:=$HOME/.dotfiles}"
: "${BREWFILE:=$DOTFILES/config/homebrew/Brewfile}"
: "${TEMP_DIR:=$(mktemp -d)}"
: "${DFM_MAX_RETRIES:=3}"
# Remove temp folder on exit
trap 'rm -rf "$TEMP_DIR"' EXIT
# Installation functions for dfm, the dotfile manager
#
# @author Ismo Vuorinen <https://github.com/ivuorinen>
# @license MIT
# Installs all required packages in the correct order.
#
# Description:
# Orchestrates the installation process for the dotfile manager by sequentially invoking
# the installation routines for fonts, Homebrew, and Rust (cargo). It logs the start of the
# overall installation process before calling each respective function.
#
# Globals:
# lib::log - Function used to log installation progress messages.
#
# Arguments:
# None.
#
# Outputs:
# Logs an informational message indicating the start of the installation process.
#
# Returns:
# None.
#
# Example:
# all
#
# @description
# Parse command line options controlling installation steps.
parse_options()
{
NO_AUTOMATION=0
SKIP_FONTS=0
SKIP_BREW=0
SKIP_CARGO=0
while [[ $# -gt 0 ]]; do
case "$1" in
--no-automation)
NO_AUTOMATION=1
;;
--no-fonts)
SKIP_FONTS=1
;;
--no-brew)
SKIP_BREW=1
;;
--no-cargo)
SKIP_CARGO=1
;;
*)
lib::error "Unknown option: $1"
return 1
;;
esac
shift
done
}
# @description
# Install all configured components by calling each individual
# installation routine unless skipped via options.
install_all()
{
parse_options "$@"
lib::log "Installing all packages..."
if [[ $SKIP_FONTS -eq 0 ]]; then
install_fonts
fi
if [[ $SKIP_BREW -eq 0 ]]; then
install_brew
fi
if [[ $SKIP_CARGO -eq 0 ]]; then
install_cargo
fi
}
# Installs fonts required by the dotfile manager.
#
# Globals:
# None.
#
# Arguments:
# None.
#
# Outputs:
# Logs a message to STDOUT indicating that the font installation process has started.
#
# Returns:
# None.
#
# Example:
# install_fonts
#
# @description Install all configured fonts from helper script, prompting the user unless automation is disabled.
install_fonts()
{
: "${SKIP_FONTS:=0}"
: "${NO_AUTOMATION:=0}"
if [[ $SKIP_FONTS -eq 1 ]]; then
lib::log "Skipping fonts installation"
return 0
fi
if [[ $NO_AUTOMATION -eq 0 ]]; then
utils::interactive::confirm "Install fonts?" || return 0
fi
lib::log "Installing fonts..."
local script="${DOTFILES}/scripts/install-fonts.sh"
if [[ ! -x "$script" ]]; then
lib::error "Font installation script not found: $script"
return 1
fi
bash "$script"
}
# Install Homebrew and set it up.
#
# Installs the Homebrew package manager on macOS.
#
# Globals:
# lib::log - Logging utility used to report installation progress.
#
# Outputs:
# Logs a message indicating the start of the Homebrew installation process.
#
# Example:
# install_brew
#
# @description Install Homebrew and declared packages using the Brewfile.
install_brew()
{
: "${SKIP_BREW:=0}"
: "${NO_AUTOMATION:=0}"
if [[ $SKIP_BREW -eq 1 ]]; then
lib::log "Skipping Homebrew installation"
return 0
fi
if [[ $NO_AUTOMATION -eq 0 ]]; then
utils::interactive::confirm "Install Homebrew packages?" || return 0
fi
lib::log "Installing Homebrew..."
if ! utils::is_installed brew; then
lib::log "Homebrew not found, installing..."
local installer="$TEMP_DIR/homebrew-install.sh"
utils::retry "$DFM_MAX_RETRIES" \
curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh \
-o "$installer"
NONINTERACTIVE=1 bash "$installer"
fi
if utils::is_installed brew; then
brew bundle install --file="$BREWFILE" --force --quiet
else
lib::error "Homebrew installation failed"
return 1
fi
}
# Installs Rust and cargo packages.
#
# Description:
# Logs the start of the installation process for Rust and cargo packages.
# The installation logic is intended to be implemented where indicated.
#
# Globals:
# Uses lib::log for logging the installation process.
#
# Example:
# install_cargo
#
# @description Install Rust tooling and cargo packages using helper scripts.
install_cargo()
{
: "${SKIP_CARGO:=0}"
: "${NO_AUTOMATION:=0}"
if [[ $SKIP_CARGO -eq 1 ]]; then
lib::log "Skipping Rust and cargo installation"
return 0
fi
if [[ $NO_AUTOMATION -eq 0 ]]; then
utils::interactive::confirm "Install Rust and cargo packages?" || return 0
fi
lib::log "Installing Rust and cargo packages..."
if ! utils::is_installed cargo; then
lib::log "Rust not found, installing rustup..."
local installer="$TEMP_DIR/rustup-init.sh"
utils::retry "$DFM_MAX_RETRIES" \
curl https://sh.rustup.rs -sSf -o "$installer"
sh "$installer" -y
source "$HOME/.cargo/env"
fi
local script="${DOTFILES}/scripts/install-cargo-packages.sh"
if [[ -x "$script" ]]; then
bash "$script"
else
lib::error "Cargo packages script not found: $script"
return 1
fi
}

104
local/dfm/dfm Executable file
View File

@@ -0,0 +1,104 @@
#!/usr/bin/env bash
# dfm - dotfiles manager
set -euo pipefail
# allow overriding core directories
DFM_SCRIPT_DIR="${DFM_SCRIPT_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)}"
readonly DFM_SCRIPT_DIR
export DFM_SCRIPT_DIR
DFM_CMD_DIR="${DFM_CMD_DIR:-${DFM_SCRIPT_DIR}/cmd}"
readonly DFM_CMD_DIR
export DFM_CMD_DIR
DFM_LIB_DIR="${DFM_LIB_DIR:-${DFM_SCRIPT_DIR}/lib}"
readonly DFM_LIB_DIR
export DFM_LIB_DIR
DFM_DEFAULT_CONFIG_PATH="${DFM_DEFAULT_CONFIG_PATH:-$HOME/.config}"
readonly DFM_DEFAULT_CONFIG_PATH
export DFM_DEFAULT_CONFIG_PATH
DFM_MAX_RETRIES="${DFM_MAX_RETRIES:-3}"
readonly DFM_MAX_RETRIES
export DFM_MAX_RETRIES
export DFM_DEFAULT_INSTALL_DIR="${DFM_DEFAULT_INSTALL_DIR:-$HOME/.local}"
export DFM_DEFAULT_VERBOSE="${DFM_DEFAULT_VERBOSE:-0}"
TEMP_DIR="${TEMP_DIR:-$(mktemp -d)}"
export TEMP_DIR
# Load the common and utility functions from the lib directory.
[[ -f "${DFM_LIB_DIR}/common.sh" ]] || {
echo "Error: Required file ${DFM_LIB_DIR}/common.sh not found"
exit 1
}
[[ -f "${DFM_LIB_DIR}/utils.sh" ]] || {
echo "Error: Required file ${DFM_LIB_DIR}/utils.sh not found"
exit 1
}
source "${DFM_LIB_DIR}/common.sh"
source "${DFM_LIB_DIR}/utils.sh"
# Display help information
#
# @return None
main::show_help()
{
cat << EOF
Usage: dfm [command] [function] [arguments]
dotfiles manager utility for installing and configuring dotfiles.
If no arguments are provided, lists all available commands.
If only a command is provided, lists available functions for that command.
If a command and function are provided, executes the specified function.
Examples:
dfm # List all available commands
dfm install # List available functions for the install command
dfm install all # Execute the 'all' function from the install command
EOF
}
# Main function for the dfm script.
#
# The function checks if any arguments were provided. If no arguments are
# provided, it lists all available commands. If a command name is provided,
# it lists the available functions for that command. If a command and function
# name are provided, it executes the function with the provided arguments.
#
# @param args The command-line arguments.
# @return None
main()
{
if [[ $# -eq 0 ]]; then
main::list_available_commands
return 0
fi
local cmd="$1"
shift
if [[ "$cmd" == "-h" || "$cmd" == "--help" ]]; then
main::show_help
return 0
fi
if [[ $# -eq 0 ]]; then
# Show the available functions for the command
local cmd_file="${DFM_CMD_DIR}/${cmd}.sh"
if [[ -f "$cmd_file" ]]; then
list::print_group "Available functions for '$cmd'"
list::loop_functions "$cmd_file"
else
lib::error "Command '$cmd' not found"
return 1
fi
return 0
fi
local func="$1"
shift
main::execute_command "$cmd" "$func" "$@"
}
main "$@"

368
local/dfm/lib/common.sh Normal file
View File

@@ -0,0 +1,368 @@
#!/usr/bin/env bash
# dfm common functions for logging and error handling, etc.
# Source this file to use the functions in your scripts.
#
# @author Ismo Vuorinen <https://github.com/ivuorinen>
# @license MIT
set -euo pipefail
declare -A ERROR_CODES=(
[SUCCESS]=0
[INVALID_ARGUMENT]=1
[COMMAND_NOT_FOUND]=2
[FUNCTION_NOT_FOUND]=3
[EXECUTION_FAILED]=4
[FILE_NOT_FOUND]=5
)
declare -A LOG_LEVELS=(
[DEBUG]=0
[INFO]=1
[WARN]=2
[ERROR]=3
)
# Simple logging function
#
# @example
# lib::log "Hello, world!"
#
# @description Log a message to the console
# @param $* Message to log
# Logs a message with a timestamp.
#
# Description:
# Outputs the provided message(s) to standard output, prepended with the current date and
# time in the format [YYYY-MM-DD HH:MM:SS]. This timestamp helps in tracking log events.
#
# Arguments:
# One or more strings that form the log message.
#
# Outputs:
# Writes the timestamped log message to standard output.
#
# Example:
# lib::log "Server started" # Outputs: [2025-02-28 09:45:00] Server started
lib::log()
{
printf '[%s] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*"
}
# Simple error logging function
#
# @example
# lib::error "Something went wrong"
#
# @description Log an error message to the console
# @param $* Error message
# Logs an error message with a timestamp to standard error.
#
# This function formats the provided message(s) by prefixing it with the current date
# and time along with an "ERROR:" label, then outputs the result to STDERR.
#
# Arguments:
# $* - The error message or messages to be logged.
#
# Outputs:
# Writes the formatted error message to STDERR.
#
# Example:
# lib::error "Failed to read the configuration file."
lib::error()
{
printf '[%s] ERROR: %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" >&2
}
LOG_LEVEL="${LOG_LEVEL:-INFO}"
if [[ -z "${LOG_LEVELS[$LOG_LEVEL]+_}" ]]; then
lib::error "Invalid LOG_LEVEL: $LOG_LEVEL"
exit "${ERROR_CODES[INVALID_ARGUMENT]}"
fi
# Handle an error by logging an error message to the console
# and exiting with an error code based on the error type.
#
# @example
# lib::error::handle $LINENO $0
#
# @description Handle an error
# @param $1 Line number
# @param $2 Command
# Logs an error message based on the previous command's exit code and the provided context.
#
# This function captures the exit code from the last executed command and, using the provided
# line number and command string, determines the appropriate error message to log based on
# predefined error codes stored in the ERROR_CODES associative array.
#
# Globals:
# ERROR_CODES - An associative array mapping error code names to numeric values.
# lib::error - Logs error messages to STDERR.
#
# Arguments:
# line_no - The line number in the script where the error occurred.
# command - The command that was executed when the error occurred.
#
# Outputs:
# Writes a descriptive error message to STDERR.
#
# Returns:
# The exit code of the failed command.
#
# Example:
# # If a command fails with an exit code corresponding to an invalid argument:
# lib::error::handle 42 "some_command"
# # This logs: "Invalid argument at line 42 in command 'some_command'" (if the exit code matches ERROR_CODES[INVALID_ARGUMENT])
lib::error::handle()
{
local exit_code=$?
local line_no=$1
local command=$2
case $exit_code in
"${ERROR_CODES[INVALID_ARGUMENT]}")
lib::error "Invalid argument at line $line_no in command '$command'"
;;
"${ERROR_CODES[COMMAND_NOT_FOUND]}")
lib::error "Command not found at line $line_no"
;;
"${ERROR_CODES[FUNCTION_NOT_FOUND]}")
lib::error "Function not found at line $line_no in command '$command'"
;;
"${ERROR_CODES[EXECUTION_FAILED]}")
lib::error "Execution failed at line $line_no in command '$command'"
;;
*)
lib::error "Unknown error ($exit_code) at line $line_no in command '$command'"
;;
esac
return $exit_code
}
# Throw an error by logging an error message to the console and exiting
# with an error code based on the error type. The error code name is used
# to determine the error code from the ERROR_CODES associative array.
# The error message is passed as arguments to the function.
#
# @example
# lib::error::throw INVALID_ARGUMENT "Invalid argument"
# lib::error::throw COMMAND_NOT_FOUND "Command not found"
# lib::error::throw FUNCTION_NOT_FOUND "Function not found"
# lib::error::throw EXECUTION_FAILED "Execution failed"
#
# @description Throw an error
# @param $1 Error code name
# @param $* Error message
# Logs an error message and terminates the script by performing cleanup with a specified error code.
#
# Globals:
# ERROR_CODES - Associative array mapping error code names to numeric exit values.
#
# Arguments:
# code_name - The key to retrieve the error code from the ERROR_CODES array.
# message - The error message to log, constructed from all subsequent arguments.
#
# Outputs:
# Logs the error message to standard error.
#
# Returns:
# Exits the script via the cleanup function; does not return.
#
# Example:
# lib::error::throw "FILE_NOT_FOUND" "Required file not found: /path/to/file"
lib::error::throw()
{
local code_name=$1
shift
local message=$*
if [[ -z "${ERROR_CODES[$code_name]+_}" ]]; then
lib::error "Unknown error code: $code_name"
cleanup "${ERROR_CODES[INVALID_ARGUMENT]}"
fi
lib::error "$message"
cleanup "${ERROR_CODES[$code_name]}"
}
# Logs a message to the console if the current log level is set so that the
# message is displayed. The log level is compared to the log level of the
# message and if the message log level is greater than or equal to the current
# log level, the message is displayed.
# The log levels are defined in the LOG_LEVELS associative array.
#
# @example
# logger::log "INFO" "This is an info message"
# logger::log "DEBUG" "This is a debug message"
# logger::log "WARN" "This is a warning message"
# logger::log "ERROR" "This is an error message"
#
# @description Log a message to the console based on the log level setting.
# @param $1 Log level
# @param $2 Message
# Logs a message if its severity meets or exceeds the global log level.
#
# Globals:
# LOG_LEVELS - Associative array mapping log level names to severity values.
# LOG_LEVEL - The current log level threshold.
#
# Arguments:
# level: A string representing the log severity (e.g., DEBUG, INFO, WARN, ERROR).
# msg: The message to log.
#
# Outputs:
# Prints a formatted log message with a timestamp to STDERR when the specified level qualifies.
#
# Example:
# logger::log INFO "Initialization complete"
logger::log()
{
local level=$1
if [[ -z "${LOG_LEVELS[$level]:-}" ]]; then
lib::error "Invalid log level: $level"
return 1
fi
shift
local msg="$*"
if [[ ${LOG_LEVELS[$level]} -ge ${LOG_LEVELS[$LOG_LEVEL]} ]]; then
printf '[%s] [%s]: %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$level" "$msg" >&2
fi
}
# Logs a debug message to the console, if the current log level is set to DEBUG or greater.
# The message is passed as arguments to the function.
# The function is defined above.
#
# @example
# logger::debug "This is a debug message"
#
# @description Log a debug message to the console
# @param $* Message
# Logs a debug-level message.
#
# This function logs a message at the DEBUG level by delegating to logger::log.
# It accepts one or more arguments that form the debug message, which are passed along
# to the underlying logger::log function.
#
# Example:
# logger::debug "Debug info for variable x:" "$x"
logger::debug()
{
logger::log "DEBUG" "$@"
}
# Logs an info message to the console, if the current log level is set to INFO or greater.
# The message is passed as arguments to the function.
# The function is defined above.
#
# @example
# logger::info "This is an info message"
#
# @description Log an info message to the console
# @param $* Message
# Logs an informational message to the console.
#
# Description:
# This function wraps the logger::log function to log messages at the "INFO" level. All provided arguments are
# forwarded to logger::log, where the message is formatted and output based on the current logging configuration.
#
# Arguments:
# A message string followed by optional additional parameters used to format the message.
#
# Outputs:
# The formatted informational message is written to STDOUT if the INFO log level is enabled.
#
# Example:
# logger::info "Service started successfully on port" 8080
logger::info()
{
logger::log "INFO" "$@"
}
# Logs a warning message to the console, if the current log level is set to WARN or greater.
# The message is passed as arguments to the function.
# The function is defined above.
#
# @example
# logger::warn "This is a warning message"
#
# @description Log a warning message to the console
# @param $* Message
# Logs a warning message.
#
# This function acts as a wrapper around `logger::log` by setting the log level to "WARN"
# for all provided message arguments. It forwards the given messages to the logger for output.
#
# Arguments:
# A variable list of strings representing the warning message.
#
# Outputs:
# Writes a formatted warning message to the console.
#
# Example:
# logger::warn "Low disk space" "Free up some space to avoid issues"
logger::warn()
{
logger::log "WARN" "$@"
}
# Logs an error message to the console, if the current log level is set to ERROR or greater.
# The message is passed as arguments to the function.
# The function is defined above.
#
# @example
# logger::error "This is an error message"
#
# @description Log an error message to the console
# @param $* Message
# Logs an error message at the ERROR level.
#
# This function wraps the generic logging mechanism to record error messages by automatically
# specifying the ERROR severity level. It passes all provided arguments to the underlying logging function.
#
# Arguments:
# Error message(s) One or more strings that describe the error.
#
# Example:
# logger::error "Unable to open file" "/path/to/file"
logger::error()
{
logger::log "ERROR" "$@"
}
# Cleanup function to remove temporary files and directories
# when the script exits or is interrupted by a signal (e.g. Ctrl+C).
# The function is registered with the `EXIT` trap.
#
# @description Remove temporary files and directories
# Cleans up temporary resources before exiting.
#
# Globals:
# TEMP_DIR - Path to the temporary directory to be removed if it exists.
#
# Returns:
# Exits the script with the original exit code.
#
# Example:
# trap cleanup EXIT
cleanup() {
local exit_code=${1:-$?}
if [[ -n ${TEMP_DIR:-} && -d $TEMP_DIR ]]; then
rm -rf "$TEMP_DIR"
fi
exit "$exit_code"
}
# Register the cleanup function to run on EXIT signal.
# This ensures temporary files and directories are removed
# when the script exits or is interrupted.
trap cleanup EXIT
# Handle errors by logging an error message to the console.
# The `ERR` trap passes the line number and command to lib::error::handle.
#
# Example:
# lib::error::handle ${LINENO} "$BASH_COMMAND"
trap 'lib::error::handle ${LINENO} "$BASH_COMMAND"' ERR

806
local/dfm/lib/utils.sh Normal file
View File

@@ -0,0 +1,806 @@
#!/usr/bin/env bash
# dfm utility functions for common tasks
# Source this file to use the functions in your scripts.
#
# @author Ismo Vuorinen <https://github.com/ivuorinen>
# @license MIT
set -euo pipefail
# ANSI escape codes
readonly RESET="\033[0m"
readonly BOLD="\033[1m"
readonly DIM="\033[2m"
readonly ITALIC="\033[3m"
readonly UNDERLINE="\033[4m"
# Colors
readonly BLACK="\033[30m"
readonly RED="\033[31m"
readonly GREEN="\033[32m"
readonly YELLOW="\033[33m"
readonly BLUE="\033[34m"
readonly MAGENTA="\033[35m"
readonly CYAN="\033[36m"
readonly WHITE="\033[37m"
# Prints the provided text in black color using ANSI escape codes.
#
# Globals:
# BLACK - ANSI escape code for black text.
# RESET - ANSI escape code to reset terminal formatting.
#
# Arguments:
# One or more strings that will be concatenated and printed.
#
# Outputs:
# Writes the colored text to STDOUT (without a trailing newline).
#
# Example:
# clr::black "This text will appear in black."
clr::black()
{
printf "${BLACK}%s${RESET}" "$*"
}
# Prints the provided text in red using ANSI escape codes.
#
# Globals:
# RED - ANSI escape code for red.
# RESET - ANSI escape code to reset terminal formatting.
#
# Arguments:
# One or more strings that will be printed in red.
#
# Outputs:
# Writes the red formatted text to STDOUT.
#
# Example:
# clr::red "Error: Invalid input"
clr::red()
{
printf "${RED}%s${RESET}" "$*"
}
# Prints the given text in green using ANSI escape codes.
#
# Arguments:
# * One or more strings to output in green. Multiple arguments are concatenated.
#
# Outputs:
# Writes the formatted green text to STDOUT without a trailing newline.
#
# Example:
# clr::green "Operation successful"
clr::green()
{
printf "${GREEN}%s${RESET}" "$*"
}
# Prints the provided text in yellow color.
#
# Globals:
# YELLOW - ANSI escape code for yellow text.
# RESET - ANSI escape code to reset text formatting.
#
# Arguments:
# Any text passed as parameters will be printed in yellow.
#
# Outputs:
# Colored text printed to STDOUT.
#
# Example:
# clr::yellow "Hello, World!"
clr::yellow()
{
printf "${YELLOW}%s${RESET}" "$*"
}
# Prints the provided text in blue using ANSI escape codes.
#
# Globals:
# BLUE ANSI escape sequence for blue text.
# RESET ANSI escape sequence to reset text formatting.
#
# Arguments:
# $@ One or more strings to be printed in blue.
#
# Outputs:
# Prints the input text in blue to STDOUT.
#
# Example:
# clr::blue "Hello, World!"
clr::blue()
{
printf "${BLUE}%s${RESET}" "$*"
}
# Prints the provided text in magenta color.
#
# This function outputs one or more strings wrapped in ANSI escape sequences
# to display them in magenta. It uses the global variables MAGENTA for the color
# and RESET to revert to the default formatting.
#
# Globals:
# MAGENTA - ANSI escape sequence for magenta.
# RESET - ANSI escape code to reset formatting.
#
# Arguments:
# One or more strings to print in magenta.
#
# Outputs:
# Writes the formatted string directly to STDOUT.
#
# Example:
# clr::magenta "Hello, World!"
clr::magenta()
{
printf "${MAGENTA}%s${RESET}" "$*"
}
# Prints the provided text in white color using ANSI escape codes.
#
# Globals:
# WHITE - ANSI escape code for white.
# RESET - ANSI escape code to reset text formatting.
#
# Arguments:
# Any text passed as arguments will be concatenated and printed.
#
# Outputs:
# Writes the formatted text to STDOUT.
#
# Example:
# clr::white "Hello, World!"
clr::white()
{
printf "${WHITE}%s${RESET}" "$*"
}
# Applies bold styling to the provided text and prints it to STDOUT.
#
# Globals:
# BOLD - ANSI escape code for enabling bold text.
# RESET - ANSI escape code for resetting text formatting.
#
# Arguments:
# One or more strings to be printed in bold.
#
# Outputs:
# Bold-formatted text is printed to STDOUT.
#
# Example:
# style::bold "This is bold text"
style::bold()
{
printf "${BOLD}%s${RESET}" "$*"
}
# Print the provided text in a dim style using ANSI escape codes.
#
# Globals:
# DIM - ANSI escape code for applying dim styling.
# RESET - ANSI escape code to reset text formatting.
#
# Arguments:
# $* - The text to be printed in dim style.
#
# Outputs:
# Writes the formatted dim text to STDOUT.
#
# Example:
# style::dim "This text will appear dimmed"
style::dim()
{
printf "${DIM}%s${RESET}" "$*"
}
# Prints the provided text in italic style using ANSI escape sequences.
#
# Globals:
# ITALIC - ANSI escape sequence for italic text styling.
# RESET - ANSI escape sequence to reset text styling.
#
# Arguments:
# All passed arguments are combined and printed in italic formatting.
#
# Outputs:
# The styled text is printed to STDOUT without an automatic newline.
#
# Example:
# style::italic "Hello, world!"
style::italic()
{
printf "${ITALIC}%s${RESET}" "$*"
}
# Underlines the provided text using ANSI escape codes.
#
# Globals:
# UNDERLINE - ANSI escape sequence to start underlining.
# RESET - ANSI escape sequence to reset text formatting.
#
# Arguments:
# $* - The text to be underlined.
#
# Outputs:
# Prints the underlined text to STDOUT.
#
# Example:
# style::underline "Underlined text"
style::underline()
{
printf "${UNDERLINE}%s${RESET}" "$*"
}
# Prints a formatted line to STDOUT using the provided format string and arguments.
#
# Globals:
# RESET - ANSI escape code to reset text formatting.
#
# Arguments:
# $1 - A format string that may include ANSI styling codes (do not include a conversion specifier for the text).
# $@ - The text to be formatted and printed.
#
# Outputs:
# Writes the formatted text to STDOUT with an appended newline, ensuring that styling is reset afterward.
#
# Example:
# list::print_formatted "${BOLD}" "Bold Text"
list::print_formatted()
{
local format=$1
shift
printf "${format}%s${RESET}\n" "$@"
}
# Prints a formatted header with a decorative underline.
#
# Globals:
# BOLD - ANSI escape code for bold text.
# BLUE - ANSI escape code for blue text.
# RESET - ANSI escape code to reset text formatting.
#
# Arguments:
# $1 - The header title to be displayed.
#
# Outputs:
# Writes a styled header to STDOUT, including the title in bold blue and a subsequent decorative line.
#
# Example:
# list::print_header "Available Commands"
list::print_header()
{
printf "\n ${BOLD}${BLUE}%s${RESET}\n" "$1"
printf "%s\n" " $(printf '%.s─' {1..60})"
}
# Prints a group header with bold yellow formatting.
#
# Globals:
# YELLOW - ANSI escape code for yellow color.
# BOLD - ANSI escape code for bold text.
# RESET - ANSI escape code to reset text formatting.
#
# Arguments:
# group - The title text to display as the group header.
#
# Outputs:
# Writes the formatted group header to STDOUT.
#
# Example:
# list::print_group "My Group"
list::print_group()
{
local group=$1
printf "\n ${YELLOW}${BOLD}%s${RESET}\n\n" "$group"
}
# Prints a formatted command with an optional description.
#
# Globals:
# BOLD - ANSI escape sequence for bold text.
# CYAN - ANSI escape sequence for cyan text.
# RESET - ANSI escape sequence to reset text formatting.
# DIM - ANSI escape sequence for dim text.
#
# Arguments:
# cmd - The command name to display.
# desc - Optional description of the command (defaults to an empty string).
#
# Outputs:
# Writes the formatted command and description to STDOUT.
#
# Example:
# list::print_command "ls" "List directory contents"
list::print_command()
{
local cmd=$1
local desc=${2:-""}
printf " ${BOLD}${CYAN}%-15s${RESET} ${DIM}%s${RESET}\n" "$cmd" "$desc"
}
# Prints a subcommand in a formatted style.
#
# This function displays a subcommand name in green with a fixed width for neat alignment,
# followed by an optional description text. The ANSI escape codes for green text and reset
# styling are used to highlight the subcommand.
#
# Globals:
# GREEN - ANSI escape code applied to the subcommand name.
# RESET - ANSI escape code used to reset text formatting.
#
# Arguments:
# cmd - The subcommand name to print.
# desc - (Optional) A description string for the subcommand. Defaults to empty if not provided.
#
# Outputs:
# Prints the formatted subcommand and optional description to STDOUT.
#
# Example:
# list::print_subcommand "deploy" "Deploy the application to the production server"
list::print_subcommand()
{
local cmd=$1
local desc=${2:-""}
printf " ${GREEN}%-13s${RESET} ${desc}\n" "$cmd"
}
# Iterates over functions defined in a command file and prints each as a formatted subcommand.
#
# This function reads function names from the specified command file, retrieves their descriptions
# (removing any '@description' prefix), and prints each function name as a bullet point with its
# associated description if available.
#
# Arguments:
# cmd_file - The path to the command file containing function definitions.
#
# Outputs:
# Prints formatted subcommand entries to STDOUT.
#
# Example:
# list::loop_functions "/path/to/command_file.sh"
list::loop_functions()
{
local cmd_file="$1"
while IFS= read -r func; do
# Get the function description from the function definition in the
# command file. If no description is found, print only the function name.
# The description is printed without the @description prefix.
# If the function is not found, print only the function name.
# The function name is printed with a bullet point.
local doc
doc=$(main::get_function_description "$cmd_file" "$func")
if [[ -n "$doc" ]]; then
list::print_subcommand "$func:" "${doc#*@description}"
else
list::print_subcommand "$func" ""
fi
done < <(main::get_command_functions "$cmd_file")
}
# Extracts and prints the documentation associated with a specific function from a command file.
#
# Globals:
# None
#
# Arguments:
# cmd_file - The file containing function definitions and their associated documentation.
# func - The name of the function whose documentation should be extracted.
#
# Outputs:
# Writes the extracted documentation tags and their content to STDOUT.
#
# Returns:
# None
#
# Example:
# list::get_function_docs "commands.sh" "build_project"
list::get_function_docs()
{
local cmd_file="$1"
local func="$2"
awk -v func="$func" '
# Start collecting documentation when a function is found and the line contains @
/^[[:space:]]*#[[:space:]]*@/ {
tag = $2
sub(/^[[:space:]]*#[[:space:]]*@[[:space:]]*[a-zA-Z]+[[:space:]]*/, "")
docs[tag] = $0
last_tag = tag
}
# Collect multi-line documentation
/^[[:space:]]*#/ && last_tag && !/^[[:space:]]*#[[:space:]]*@/ {
sub(/^[[:space:]]*#[[:space:]]*/, "")
docs[last_tag] = docs[last_tag] " " $0
}
# Empty line or comment line ends documentation
!/^[[:space:]]*#/ {
last_tag = ""
}
# When the function is found, print the documentation
$0 ~ "^[[:space:]]*(function[[:space:]]+)?" func "\\(\\)" {
for (tag in docs) {
printf "@%s %s\n", tag, docs[tag]
}
}
' "$cmd_file"
}
# Check if a command exists in the current environment and return 0 if it does.
# Otherwise, return 1.
#
# @example
# if utils::is_installed curl; then
# echo "curl is installed"
# else
# echo "curl is not installed"
# fi
#
# @description Check if a command exists
# @param $1 Command to check
# Checks if a specified command is available in the system.
#
# Arguments:
# $1 - Command name to check.
#
# Returns:
# 0 if the command is found in the system's PATH, 1 otherwise.
#
# Example:
# utils::is_installed "git" && echo "Git is installed" || echo "Git is not installed"
utils::is_installed()
{
command -v "$1" > /dev/null 2>&1
}
# Check if an executable exists in one of the directories listed in PATH and
# return 0 if it does. Otherwise, return 1.
#
# @example
# if utils::in_path ls; then
# echo "ls is available in PATH"
# else
# echo "ls is not available in PATH"
# fi
#
# @description Check if an executable is in PATH
# @param $1 Command to check
# Checks if a specified executable is available in one of the directories in the PATH.
#
# Globals:
# PATH - The system's PATH environment variable listing directories to search.
#
# Arguments:
# cmd: The name of the executable file to look for.
#
# Returns:
# 0 if the executable is found in one of the PATH directories, 1 otherwise.
#
# Example:
# utils::in_path ls && echo "ls is available in PATH"
utils::in_path()
{
local cmd=$1
local result=1
IFS=: read -ra path <<< "$PATH"
for p in "${path[@]}"; do
if [[ -x "$p/$cmd" ]]; then
result=0
break
fi
done
return $result
}
# Retry a command until it succeeds or the maximum number of retries is reached.
# Logs a warning message if the command fails and is retried after a short delay.
#
# @example
# if utils::retry 3 curl -sSL https://example.com; then
# echo "Success"
# else
# echo "Failed"
# fi
#
# @description Retry a command
# @param $1 Maximum number of retries
# @param $2.. Command to run
# @return 0 if the command succeeds, 1 otherwise
# Retries a command until it succeeds or the maximum number of attempts is reached.
#
# Arguments:
# tries - Maximum number of attempts to execute the command.
# command and its args - The command to run and any arguments to pass.
#
# Globals:
# logger::warn - Logs a warning message for each failed attempt.
#
# Outputs:
# Warning messages are printed to STDERR for each retry.
#
# Returns:
# 0 if the command eventually succeeds; 1 if all attempts fail.
#
# Example:
# utils::retry 3 my_command --option value
#
# Dependencies:
# logger::warn
utils::retry()
{
local tries=$1
shift
local count=1
until "$@"; do
[[ $count -gt $tries ]] && return 1
logger::warn "Failed, retry $count/$tries"
((count++))
sleep 1
done
return 0
}
# Ask for confirmation before proceeding. The default value is used if the user
# presses Enter without providing an answer.
#
# @example
# if utils::interactive::confirm "Are you sure?"; then
# echo "Confirmed"
# else
# echo "Not confirmed"
# fi
#
# @description Confirm an action
# @param $1 Prompt message
# @param $2 Default value
# Prompts the user for confirmation with a yes/no question.
#
# Arguments:
# prompt: The message displayed to the user when asking for confirmation.
# default: An optional default answer used if no input is provided (defaults to "Y").
#
# Outputs:
# Repeatedly prompts the user until a valid yes or no answer is received.
# An error message is displayed for any invalid response.
#
# Returns:
# 0 if the user confirms (answers yes), 1 if the user declines (answers no).
#
# Example:
# if utils::interactive::confirm "Do you want to proceed?"; then
# echo "Proceeding..."
# else
# echo "Operation cancelled."
# fi
utils::interactive::confirm()
{
local prompt=$1
local default=${2:-Y}
while true; do
read -rp "$prompt [Y/n]: " response
case ${response:-$default} in
[Yy]*) return 0 ;;
[Nn]*) return 1 ;;
*) echo "Please answer yes or no" ;;
esac
done
}
# Find all command files in the cmd directory and return them
# as a space-separated string of filenames (e.g. "cmd1.sh cmd2.sh").
#
# The function uses a while loop to read the output of the find command
# line by line. The -print0 option is used to separate the filenames with
# a null character (\0) instead of a newline. This is necessary to handle
# filenames with spaces correctly.
#
# The read command reads the null-separated filenames and appends them to
# the cmd_files array. Finally, the function prints the array elements
# separated by a space.
#
# Finds all command script files (*.sh) in the directory specified by DFM_CMD_DIR.
#
# Globals:
# DFM_CMD_DIR - The directory to search for command files.
#
# Outputs:
# Echoes a space-separated list of command file paths.
#
# Example:
# files=$(main::find_commands)
# echo "$files" # Displays the list of found command files.
main::find_commands()
{
local cmd_files=()
while IFS= read -r -d '' file; do
cmd_files+=("$file")
done < <(find "$DFM_CMD_DIR" -type f -name "*.sh" -print0)
echo "${cmd_files[@]}"
}
# Get the function names from a command file.
#
# The function uses grep to find function definitions (function xxx() or xxx())
# and sed to extract the function names. The function names are printed one per
# line.
#
# @param cmd_file The command file to extract function names from.
# Extracts the names of functions defined in the specified command file.
#
# This function parses the provided file for Bash function definitions using
# regex patterns matching both "function name() {" and "name() {" styles.
# It outputs the names of the functions, one per line.
#
# Globals:
# None.
#
# Arguments:
# cmd_file - Path to the file containing Bash function definitions.
#
# Outputs:
# Writes the list of function names to STDOUT.
#
# Returns:
# A list of function names extracted from the file.
#
# Example:
# main::get_command_functions "/path/to/command_file.sh"
main::get_command_functions()
{
local cmd_file="$1"
# Find function definitions (function xxx() or xxx())
grep -E '^[[:space:]]*(function[[:space:]]+)?[a-zA-Z0-9_]+\(\)[[:space:]]*{' "$cmd_file" \
| sed -E 's/^[[:space:]]*(function[[:space:]]+)?([a-zA-Z0-9_]+).*/\2/'
}
# Get the description of a function from a command file.
#
# The function uses grep to find the function definition and sed to extract
# the description. The description is printed without the @description prefix.
#
# @param cmd_file The command file to extract the function description from.
# @param func The function name.
# Retrieves the annotated description of a specified function from a command file.
#
# This function searches the provided command file for an "@description" comment
# preceding the definition of the designated function. It then extracts and prints
# the description text. If no description is found, nothing is printed.
#
# Arguments:
# cmd - Command name or path to the file containing the function definitions.
# func - Name of the function whose description is to be extracted.
#
# Outputs:
# The extracted description text is printed to STDOUT.
#
# Example:
# desc=$(main::get_function_description "install" "my_function")
main::get_function_description()
{
local cmd_file="$1"
local func="$2"
if [[ ! -f "$cmd_file" ]]; then
[[ -n ${DFM_CMD_DIR:-} ]] || return 1
cmd_file="${DFM_CMD_DIR}/${cmd_file}"
[[ "$cmd_file" == *.sh ]] || cmd_file="${cmd_file}.sh"
fi
[[ -f "$cmd_file" ]] || return 1
local escaped_func
escaped_func=$(printf '%s' "$func" | sed 's/[][\\.^$*+?(){}|]/\\&/g')
grep -B5 -E "^[[:space:]]*(function[[:space:]]*)?${escaped_func}[[:space:]]*\\(\\)[[:space:]]*(\\{)?[[:space:]]*$" "$cmd_file" \
| grep "@description" \
| sed -E 's/^[[:space:]]*#[[:space:]]*@description[[:space:]]*//'
}
# List all available commands and their functions.
#
# The function uses main::find_commands to get a list of command files.
# It then iterates over the files and prints the command name and
# its functions.
#
# Lists all available commands and their subcommands.
#
# Description:
# Uses main::find_commands to locate command files and prints a header followed by a group title.
# For each command file, extracts the command name (removing the '.sh' extension) and prints it,
# then calls list::loop_functions to display detailed subcommands.
#
# Globals:
# None.
#
# Arguments:
# None.
#
# Outputs:
# Writes the formatted list of commands and associated subcommands to STDOUT.
#
# Example:
# main::list_available_commands
main::list_available_commands()
{
local cmd_files
cmd_files=$(main::find_commands)
list::print_header "dfm - dotfiles manager"
list::print_group "Available commands"
for cmd_file in $cmd_files; do
local cmd_name
cmd_name=$(basename "$cmd_file" .sh)
list::print_command "$cmd_name"
list::loop_functions "$cmd_file"
done
}
# Execute a command function.
#
# The function loads the command file and checks if the function exists.
# If the function exists, it executes the function with the provided arguments.
#
# @param cmd The command name.
# @param func The function name.
# @param args The function arguments.
# Executes a specified function from a command file.
#
# This function validates and runs a function defined within a command file. It checks that both
# the command and function names contain only allowed characters (alphanumeric, underscores, or dashes),
# verifies that the command file (located in DFM_CMD_DIR) exists, is readable, and is free of syntax errors,
# and then sources the file. If the specified function exists in the file, it is executed with any additional
# arguments provided.
#
# Globals:
# DFM_CMD_DIR - Directory containing command files.
#
# Arguments:
# command: The command file name (without .sh extension) to execute. Must match ^[a-zA-Z0-9_-]+$.
# function: The function name to be executed from the command file. Must match ^[a-zA-Z0-9_-]+$.
# [additional arguments]: Extra parameters to pass to the executed function.
#
# Outputs:
# Any output generated by the executed function. Error messages are output via lib::error.
#
# Returns:
# 0 if the function executes successfully; 1 if an error occurs (e.g., invalid names, missing or unreadable
# command file, syntax errors in the command file, or if the specified function is not found).
#
# Example:
# main::execute_command "deploy" "run_deploy" "arg1" "arg2"
main::execute_command()
{
local cmd="$1"
shift
local func="$1"
shift
# Validate input
if [[ ! "$cmd" =~ ^[a-zA-Z0-9_-]+$ ]] || [[ ! "$func" =~ ^[a-zA-Z0-9_-]+$ ]]; then
lib::error "Invalid command or function name"
return 1
fi
local cmd_file="${DFM_CMD_DIR}/${cmd}.sh"
if [[ ! -f "$cmd_file" ]] || [[ ! -r "$cmd_file" ]]; then
lib::error "Command '$cmd' not found"
return 1
fi
# Validate command file
if ! bash -n "$cmd_file"; then
lib::error "Command file '$cmd' contains syntax errors"
return 1
fi
# Source the command file
# shellcheck source=/dev/null
source "$cmd_file"
# Check if the function exists
if ! declare -f "$func" > /dev/null; then
lib::error "Function '$func' not found in command '$cmd'"
return 1
fi
# Run the function with the provided arguments
"$func" "$@"
}

Some files were not shown because too many files have changed in this diff Show More