From fef1f8e51fa8b4a6d4a31586022ead2bc066678a Mon Sep 17 00:00:00 2001 From: John D Pell Date: Sun, 13 Feb 2022 17:25:13 -0800 Subject: [PATCH] main: Glob for *.bash properly when path contains spaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - `shfmt`, `shellcheck` - Clean up legacy/compatibility code to simpler control flow - Move theme stuff down to where themes are handled - Don't use `**` as _Bash It_ has never before set `globstar`; this eliminates varying behavior by environment; this alsö fixes users having any not-enabled themes under their custom dir. - Lose weird Mac-specific alternate shell startup file (Bash loads startup files on Mac the same as it does on any other *nix system.) - Place `composure.sh` init all in one place - remove 10-years-deprecated backwards compatibility: Deprecated in `b59ee658f78ec6ff8c6c2754216e0322b7fe18e2` dated 2011-10-29. main: adopt `_bash-it-log-prefix-by-path()` main: variable name cleanup pathmunge tests lib/appearance: `shellcheck` && `shfmt` lib/preview: `shfmt` && `shellcheck` Fix theme file path globbing when $BASH_IT contains any spaces. My apologies to future `git blame` hunters ♥ uninstall: `shellcheck` && `shfmt` lint: add lib to clean_files.txt lib/theme: `shfmt` && `shellcheck` My apologies to future `git blame` hunters ♥ lib/p4helpers: `shfmt` My apologies to future `git blame` hunters ♥ lib/githelpers: `shfmt` && `shellcheck` My apologies to future `git blame` hunters ♥ lib/theme: don't redefine battery_char() Combine the two definitions for `battery_char()` so the second one doesn't just overwrite the first one. Do one or the other, not both. Don't evaluate if `battery_percentage()` is available at load time, evaluate it at run time. lib/command_duration: `shfmt` && `shellcheck` My apologies to future `git blame` hunters ♥ lib/theme: `shellcheck` SC2154 These variables are referenced by themes already linted. lib/theme.githelpers: unbound varbl lib/theme: don't use `date` for `$THEME_CLOCK_FORMAT` lib: delete `appearance.bash` This adds *three* lines to `bash_it.sh`, and two to `plugin/base`. Just not worth an extra file requiring special handling. make aliases load very late ...and update all the tests... plugins/go: simplify _bash-it-gopath-pathmunge() plugin/history: no need to set a trap Instead of globbally clearing `$HISTTIMEFORMAT` and setting a return trap to re-enable it, just make it local to the function. Also, set the defaults in a way that is happy with read-only parameters. aliases/general: minor fixes - Don't define some aliases if the target isn't installed, use _command_exists to check instead of `type` and `which`. - Use `$EDITOR` for the editor for aliases about editing, excep the `sudo` ones because maybe you want those specifically? - Fix `ls` aliases to match their common definitions (-A instead of -a: don't show '.' and '..' when displaying hidden files). completion/grunt: shellcheck plugins/xterm: not just Xterm lib/battery: rename `plugin/battery` This plugin *only* provides utility functions, so it has zero cost to just being enabled. This allows us to eliminate assumptions from `lib/theme` and several themes. main: load custom theme Allow for simpler directory strucutre when loading theme from `$CUSTOM_THEME_DIR`/`$BASH_IT_CUSTOM` completion/fabric: no need for `_command_exists` If we're already inside the completion handler for `fab`...then it's a bit silly to check if `fab` is installed. themes/base: use `type -P` instead of `which` Avoid external binary `which`. Use built-in `type -P` instead. Uppercase `-P` forces a path search to avoid hashed matches and functions/aliases and whatnot. plugins/todo: lint plugin/base: use `_bash-it-component-item-is-enabled()` plugins/alias: remove old `SC2154` flag This is no logner needed because the `local` keyword was moved higher up in the function. install: use `.bashrc` and notify user The logic to guess whether to use `.bash_profile` or `.bashrc` was buggy and wrong. Just use `.bashrc` and either automatically fill in a `.bash_profile`, or notify the user that they need to edit their `.bash_profile`. lib/search: code style cleanup Couldn't even `shellcheck` until I did a first pass...too much noise! ♥ lib/search: `shellcheck` SC2076 SC2091 SC2004 SC2086 SC2207 lib/search: fix `_bash-it-flash-term()` 1. `$text_black` isn't a parameter provided by _Bash It_. Typo? 2. `$bold_yellow` is meant for prompt strings and putputs `\[`; ditto `$bold_red`. 3. The color was never returned to normal after. lib/search: fix usage statement `_bash-it-search()` SC2154 lib/search: `shfmt` My apologies to future `git blame` hunters ♥ lib/search: code cleanup Improve `_bash-it-erase-term()`, `_bash-it-flash-term()`, `_bash-it-rewind()`, `_bash-it-search-result()`, and `_bash-it-search-component()`. Minor tweaks to `_bash-it-is-partial-match()`, and `_bash-it-search()`. pathmunge tests main: Glob for *.bash properly when path contains spaces - `shfmt`, `shellcheck` - Clean up legacy/compatibility code to simpler control flow - Move theme stuff down to where themes are handled - Don't use `**` as _Bash It_ has never before set `globstar`; this eliminates varying behavior by environment; this alsö fixes users having any not-enabled themes under their custom dir. - Lose weird Mac-specific alternate shell startup file (Bash loads startup files on Mac the same as it does on any other *nix system.) - Place `composure.sh` init all in one place main: adopt `_bash-it-log-prefix-by-path()` lib/reloader: adopt `_bash-it-log-prefix-by-path()` lib/appearance: `shellcheck` && `shfmt` reloader: `shellcheck` && `shfmt` Rewrite globbing per `shellcheck`'s SC2013 recommendations, and standardize whitespace. lib/preview: `shfmt` && `shellcheck` Fix theme file path globbing when $BASH_IT contains any spaces. My apologies to future `git blame` hunters ♥ uninstall: `shellcheck` && `shfmt` lint: add lib to clean_files.txt lib/theme: `shfmt` && `shellcheck` My apologies to future `git blame` hunters ♥ lib/colors: `shellcheck` && `shfmt` Alsö, clean up `__color_rgb` to just use a regular if block. lib/p4helpers: `shfmt` My apologies to future `git blame` hunters ♥ lib/githelpers: `shfmt` && `shellcheck` My apologies to future `git blame` hunters ♥ lib/theme: don't redefine battery_char() Combine the two definitions for `battery_char()` so the second one doesn't just overwrite the first one. Do one or the other, not both. Don't evaluate if `battery_percentage()` is available at load time, evaluate it at run time. lib/command_duration: `shfmt` && `shellcheck` My apologies to future `git blame` hunters ♥ lib/theme: `shellcheck` SC2154 These variables are referenced by themes already linted. lib/theme.githelpers: unbound varbl lib/theme: don't use `date` for `$THEME_CLOCK_FORMAT` main: simplify flow of lib loader loop Eliminate the separate loop for `vendor/init.d` since it's just as easy to glob it in the `lib` loop. lib: delete `appearance.bash` This adds *three* lines to `bash_it.sh`, and two to `plugin/base`. Just not worth an extra file requiring special handling. main: load custom theme Allow for simpler directory strucutre when loading theme from `$CUSTOM_THEME_DIR`/`$BASH_IT_CUSTOM` make aliases load very late ...and update all the tests... preexec: add helper functions to loader Define the helper functions for `bash-preexec.sh` immediately after importing it, rather than in `lib/theme`. - `__check_precmd_conflict()` and `save_append_prompt_command()` are generally useful and not theme-specific. - Add matching `__check_preexec_conflict()` like `__check_precmd_conflict()`, and alsö `safe_append_preexec()`. preexec: work around upstream Alsö, move `set +T` in here. test/theme: make fewer assumptions Literally copying a line from the source to be tested is perhaps not the best way to test that code. 😉 That said, we do want to verify that the function was actually loaded. TODO: actually test the function. install: use `.bashrc` and notify user The logic to guess whether to use `.bash_profile` or `.bashrc` was buggy and wrong. Just use `.bashrc` and either automatically fill in a `.bash_profile`, or notify the user that they need to edit their `.bash_profile`. completions/sqlmap: use `_command_exists` Addresses bash-it/bash-it#1632 completion/fabric: no need for `_command_exists` If we're already inside the completion handler for `fab`...then it's a bit silly to check if `fab` is installed. plugins/go: simplify _bash-it-gopath-pathmunge() plugin/history: no need to set a trap Instead of globbally clearing `$HISTTIMEFORMAT` and setting a return trap to re-enable it, just make it local to the function. Also, set the defaults in a way that is happy with read-only parameters. aliases/general: minor fixes - Don't define some aliases if the target isn't installed, use _command_exists to check instead of `type` and `which`. - Use `$EDITOR` for the editor for aliases about editing, excep the `sudo` ones because maybe you want those specifically? - Fix `ls` aliases to match their common definitions (-A instead of -a: don't show '.' and '..' when displaying hidden files). themes/base: use `type -P` instead of `which` Avoid external binary `which`. Use built-in `type -P` instead. Uppercase `-P` forces a path search to avoid hashed matches and functions/aliases and whatnot. completion/grunt: shellcheck completion/subversion: load system completion Load the completion script from the subversion package installed on the system, instead of bundling a copy. This addresses Bash-it/bash-it#1818. NOTE: If `completions/system` is enabled, then it will load this same file anyway automatically. plugins/battery: lint plugins/xterm: not just Xterm plugins/thefuck: lint plugins/todo: lint plugin/base: use `_bash-it-component-item-is-enabled()` completion/git: use `_completion_exists()` plugins/alias: remove old `SC2154` flag This is no logner needed because the `local` keyword was moved higher up in the function. BATS: enable strict mode lint: add lib and scripts to clean_files.txt and disable `shfmt` for now pending upstream mvdan/sh#721 Let function blocks begin on new lines so that the opennign and closing braces align. lib/helpers: new functions `_bash_it_history_auto_*()` Two new functions `_bash_it_history_auto_save()` and `_bash_it_history_auto_load()`, which append new history to disk and load new history from disk, respectively. See bash-it/bash-it#1595 for discussion. Reduce environmental pollution Don’t `export` every single variable… Only variables that need to be seen by child processes need to be `export`ed. lib: avoid duplicate inclusion For lib/log and lib/utilities, add double-inclusion protection as we're so early in startup that these are loaded explicitly rather than through `reloader.sh` or even the early lib load loop. This *slightly* improves performance, but alsö improves debugging by reducing surface area. lint defaults and base No need for `cat` The input redirection can go at the beginning, it doens't need to go at the end. main: add some debugging alsö, clear a loop variable and set BASH_IT_LOG_PREFIX after reloader. main: move Jekyll stuff to plugins/jekyll If the user doesn't load the Jekyll plugin, then don't load any Jeykll stuff. lib/utilities: s/defined/loaded lib/helpers: define `pathmunge()` unconditionally plugins/history: Add `autoshare` to `$HISTCONTROL` lib/theme: simplify default variables and avoid binary execution Use `type -P` instead of `which` to get the path-on-disk (not alias or function) without having to invoke an external binary. Alsö, simplify some parameter defaults. theme/powerline: fix source path for theme base completion/system: correctly load version when not linked - Load the correct version of `bash-completion` even when not "linked". preexec: work around upstream Alsö, move `set +T` in here. test/theme: make fewer assumptions Literally copying a line from the source to be tested is perhaps not the best way to test that code. 😉 That said, we do want to verify that the function was actually loaded. TODO: actually test the function. completions/sqlmap: use `_command_exists` Addresses bash-it/bash-it#1632 lib/search: simplify `read` usage Avoid having to loop by abusing *both* `$IFS` _and_ `-d ''`: this makes `read` intake the entire file, and split in to an array by line. plugins/fuck: aliases Add themes/*.bash to lint Lint everything (add dirs to `clean_files.txt`) theme/barbuk: fix SC2154, and clean up Handle all unbound parameters, even colors! Alsö, fix some local variables and variable assignments. The unicode/emoji symbols don’t show up for me so that makes me think they won’t work, but it *looks* like the history has these characters in them so…I dunno theme/binaryanomaly: SC2154 Handle all unbound parameters, even colors! Local some variables, &c theme/brainy: work-in-progress Handle all unbound parameters, even colors! theme/modern: SC2154 Handle all unbound parameters, even colors! theme/brainy theme/binaryanomaly lib/helpers: remove log message from `_command_exists()` et al - and move them to `lib/utilities` lib/helpers: first `shellcheck` pass Quote things, SC2268, SC2143, SC2181, SC2162, SC2016, SC2013, &c. Rewrite globbing per `shellcheck`’s SC2013, and alsö s/typeset/local/g. Eliminate `compgen` where possible. Alsö: use the existing utility functions `_bash-it-get-component-type-from-path` and `_bash-it-get-component-name-from-path`, which just use parameter substitution anyway. Why was `sed` here? Use `[[` for conditional evaluation. lib/helpers: fix `_command_exists()` The weird subshell is weird AF. Just do a normal `if`. Ditto `_binary_exists()`, `_completion_exists()`, and `_is_function()`! lib/helpers: second `shellcheck` pass lib/helpers: lint `_bash-it-migrate()` lib/helpers: lint `_disable-thing()` lib/helpers: lint `_enable-thing()` lib/helpers: lint `_help-list-aliases()` lib/helpers: lint `_help-plugins()` lib/helpers: some SC2034 fixes And SC2154 in `_make_reload_alias()` lib/helpers: lint `all_groups()` lib/helpers: `shfmt` My apologies to future `git blame` hunters ♥ lib/helpers: fix `all_groups()` - Don't write to disk, just pipe. - Don't loop, just do all functions. Performance of old implementation on my system: ``` real 0m9.996s user 0m5.318s sys 0m9.126s ``` Performance of new implementation on my system: ``` real 0m0.052s user 0m0.069s sys 0m0.025s ``` lib/helpers: cleanup - Improve `pushd`/`popd` somewhat - local some parameters - Lose weird Mac-specific alternate shell startup file (Bash loads startup files on Mac the same as it does on any other *nix system.) - remove `compgen` from `_bash-it-describe()` lib/helpers: fix `_bash-it-describe()` plugins/go: update tests Update tests for `plugins/go` to account for non-existing directories being ignored by `pathmunge()`. plugins/ruby: update tests Account for non-existing directory not added to path. plugins/ruby: tests on Mac OS X Test was failing only on Mac OS X for some reason, so refactor a little. lib/search: code style cleanup Couldn't even `shellcheck` until I did a first pass...too much noise! ♥ lib/search: `shellcheck` SC2076 SC2091 SC2004 SC2086 SC2207 lib/search: fix `_bash-it-flash-term()` 1. `$text_black` isn't a parameter provided by _Bash It_. Typo? 2. `$bold_yellow` is meant for prompt strings and putputs `\[`; ditto `$bold_red`. 3. The color was never returned to normal after. lib/search: fix SC2154 lib/search: adjust spacing on test assertions lib/search: `shfmt` My apologies to future `git blame` hunters ♥ lib/log: shellcheck lib/log: use builtin [[ for test evaluation lib/log: `shfmt` My apologies to future `git blame` hunters ♥ lib/log: short-circuit _has_colors() If we already looked up colors, and we already have them, then don't run `tput` again. main: Glob for *.bash properly when path contains spaces - `shfmt`, `shellcheck` - Clean up legacy/compatibility code to simpler control flow - Move theme stuff down to where themes are handled - Don't use `**` as _Bash It_ has never before set `globstar`; this eliminates varying behavior by environment; this alsö fixes users having any not-enabled themes under their custom dir. - Lose weird Mac-specific alternate shell startup file (Bash loads startup files on Mac the same as it does on any other *nix system.) reloader: `shellcheck` && `shfmt` Rewrite globbing per `shellcheck`'s SC2013 recommendations, and standardize whitespace. lib/preview: `shfmt` && `shellcheck` Fix theme file path globbing when $BASH_IT contains any spaces. My apologies to future `git blame` hunters ♥ lib/appearance: `shellcheck` && `shfmt` uninstall: `shellcheck` && `shfmt` lint: add lib to clean_files.txt Move `_set-prefix-based-on-path()` Instead of defining `_set-prefix-based-on-path()` in `scripts/reloader`, define it in `lib/utilities` so it can be helpful elsewhere too lib/utilities: XDG_CACHE_HOME Use $XDG_CACHE_HOME environment constant instead of placing a tmp/cache folder inside the bash-it data repo. If not defined, fall back to current behavior. plugins/dirs: use XDG_STATE_HOME Locate the bookmarks file in $XDG_STATE_HOME, and migrate an existing file from the old location if it exists. plugin/dirs: `shfmt` && `shellcheck` lib/theme: `shfmt` && `shellcheck` My apologies to future `git blame` hunters ♥ lib/colors: `shellcheck` && `shfmt` Alsö, clean up `__color_rgb` to just use a regular if block. lib/command_duration: `shfmt` && `shellcheck` My apologies to future `git blame` hunters ♥ lib/p4helpers: `shfmt` My apologies to future `git blame` hunters ♥ lib/githelpers: `shfmt` && `shellcheck` My apologies to future `git blame` hunters ♥ Add themes/*.bash to lint lib: move generic helper functions to helpers.bash `__check_precmd_conflict()`, `save_append_prompt_command()`, and `_save-and-reload-history()` are generally useful and not theme-specific. lib/helpers: add preexec functions Add matching `check_preexec_conflict()` with `check_precmd_conflict()` and alsö `safe_append_preexec()` lib/command_duration Remove use of temporary files. lib/command_duration: first pass at logging lib/command_duration: dynamic clock hand Calculate the position (from 1 to 12) of the hour hand on the clock emoji used for the _command_duration string. Expressly handle COMMAND_DURATION_COLOR as blank when undefined. lib/command_duration: Refactor using `$EPOCHREALTIME` Fallback to `$SECONDS` for older versions of _Bash_. Instead of shortcircuiting the definition, just short-circuit the function. This allows the variable to be set later, e.g. on theme change. plugin/cmd-returned-notify: Rewrite to match/use `lib/command_duration` Use `$EPOCHREALTIME` (or `$SECONDS`) built-in variable provided by Bash instead of `date +%s`. We're only measuing the difference in seconds, so avoid both the binary invocation as well as the subshell. Alsö, Reduce environmental pollution by not exporting every variable, and unsetting when done. Change variable names to match lib/command-duration Rename `preexec_return_notification()` to match lib/command-duration's `_command_duration_pre_exec()`, and guard against redefining it. This should now use the same preexec hook and variables as the theme library `command_duration`. tests: handle nanoseconds lib/command_duration: `shfmt` My apologies to future `git blame` hungers ♥ plugins/proxy: use `_command_exists` Addresses bash-it/bash-it#1632 Alsö, use `_log_notice`, quote variables, handle unbound parameters, &c. completions/sqlmap: use `_command_exists` Addresses bash-it/bash-it#1632 completion/fabric: no need for `_command_exists` If we're already inside the completion handler for `fab`...then it's a bit silly to check if `fab` is installed. plugins/java: quote path plugins/jekyll: simplify command flow Use bashisms, remove suplerfous variable, use parameter default value replacement plugins/latex: 2009 was 12 years ago Glob the currently installed edition, instead of transpoting us back to undergrad. plugins/osx-timemachine: code style cleanups Use bash functionality rather than external binaries, or even builtins. Alsö, if $SUDO_ASKPASS is set then pass -A to sudo. plugins/osx: code style improvements #TODO #TODO Avoid external binaries plugins/python: code style improvements Use shell functionality to avoid invoking external binaries, and quote some stuff. Alsö, use $EDITOR and related variables in order to fall through if some aren't defined. plugins/osx: unbound PROMPT_COMMAND Expressly handle undefined PROMPT_COMMAND as empty plugins/osx: dead code removal No need for gymnastics to determine if variable had been exported priort to modification. If it was, then it still is. See man bash(1). plugins/osx: unbound PROMPT_COMMAND I don't think this is possible given bash-preexec.sh dependency and early load. completion/system: accomodate multiple versions For Homebrew, switch between v1 and v2 of bash-completion based on whether the running Bash shell is new enough to use v2. plugins/go: simplify _bash-it-gopath-pathmunge() plugins/man: Add "R" to `$LESS` plugin/history: no need to set a trap Instead of globbally clearing `$HISTTIMEFORMAT` and setting a return trap to re-enable it, just make it local to the function. Also, set the defaults in a way that is happy with read-only parameters. plugin/latex: just call `pathmunge()` as it will check if the directory exists itself plugin/nginx: dont overwrite user-set variable, and quote path just in case plugin/git-subrepo: use `$HOME` instead of `~` If the outer variable is double-quoted, then the default expansion when undefined does not get tilde-expanded. Use `$HOME`. aliases/general: minor fixes - Don't define some aliases if the target isn't installed, use _command_exists to check instead of `type` and `which`. - Use `$EDITOR` for the editor for aliases about editing, excep the `sudo` ones because maybe you want those specifically? - Fix `ls` aliases to match their common definitions (-A instead of -a: don't show '.' and '..' when displaying hidden files). themes/base: use `type -P` instead of `which` Avoid external binary `which`. Use built-in `type -P` instead. Uppercase `-P` forces a path search to avoid hashed matches and functions/aliases and whatnot. plugins/git: use `type -p` completion/grunt: shellcheck completion/subversion: load system completion Load the completion script from the subversion package installed on the system, instead of bundling a copy. This addresses Bash-it/bash-it#1818. NOTE: If `completions/system` is enabled, then it will load this same file anyway automatically. plugins/battery: lint plugins/xterm: not just Xterm completion/system: load earlier than other completions plugin/projects: cleanup plugins/thefuck: lint plugins/todo: lint plugin/man: simplify Don't overwrite variables that the user has already set. completion/git: use `_completion_exists()` plugin/base: SC2144 globs literally don't work. At all. plugin/base: use `_bash-it-component-item-is-enabled()` lib/githelpers: `shfmt` && `shellcheck` My apologies to future `git blame` hunters ♥ lint: add lib and scripts to clean_files.txt and disable `shfmt` for now pending upstream mvdan/sh#721 Let function blocks begin on new lines so that the opennign and closing braces align. lib/helpers: new functions `_bash_it_history_auto_*()` Two new functions `_bash_it_history_auto_save()` and `_bash_it_history_auto_load()`, which append new history to disk and load new history from disk, respectively. See bash-it/bash-it#1595 for discussion. lib/helpers: new function `_find_uncle()` New function to do a search looking for a sibling to a parent of the current directory, for example to find `../../.git` to indicate that `$PWD` is inside a git repository. main: lint false positive style consistency improvements Adjust location of quotation marks in paths for visual consistency. Use double-bracket test evaluation, which has better feature support and avoids possible external tool invocation. Reduce environmental pollution Don’t `export` every single variable… Only variables that need to be seen by child processes need to be `export`ed. lib: avoid duplicate inclusion For lib/log and lib/utilities, add double-inclusion protection as we're so early in startup that these are loaded explicitly rather than through `reloader.sh` or even the early lib load loop. This *slightly* improves performance, but alsö improves debugging by reducing surface area. lint defaults and base No need for `cat` The input redirection can go at the beginning, it doens't need to go at the end. main: add some debugging alsö, clear a loop variable and set BASH_IT_LOG_PREFIX after reloader. main: move Jekyll stuff to plugins/jekyll If the user doesn't load the Jekyll plugin, then don't load any Jeykll stuff. lib/utilities: s/defined/loaded lib/helpers: define `pathmunge()` unconditionally plugins/history: Add `autoshare` to `$HISTCONTROL` lib/helpers: fix `_command_exists()` The weird subshell is weird AF. Just do a normal `if`. Ditto `_binary_exists()`. lib/helpers: set return value of `pathmunge` This allows use as a test condition, but for very simple plugins this sets the return value for the whole plugin lib/log: automate log prefix Automatically set log prefix when sourcing a file, and relinquish it when returning from that file. TODO: move _bash_it_log_section to alias instead of _bash_it_log_prefix_push() Reduce subshells and make reloader only loop Move the global `reloader.sh` invocation inside the loop to simplify control flow: load global, then aliases, plugins, and completions in one structure. Create lib finalize hook Create an array `_bash_it_library_finalize_hook` and loop at the end of the main `bash_it.sh` to run each element in the array. The purpose here is to run some command after everything else has been loaded. For example, the appearance lib checks for executables for SCM commands, but `$PATH` may be altered after appearance has loaded and therefore some available commands may never be discovered. Therefore, create `_bash_it_appearance_scm_init()` and add it to the hook. It will re-check at end of `bash_it.sh` just before prompt is first displayed. Alsö, use this for the log cleanup function, and for the `set +T` for DEBUG inheritance. lib: fix _bash_it_library_finalize_hook It's an array, not a string. Move bash-it reload alias to aliases/bash-it --- .editorconfig | 2 +- aliases/available/bash-it.aliases.bash | 6 ++ bash_it.sh | 36 +++----- lib/log.bash | 113 +++++++++++++++---------- plugins/available/go.plugin.bash | 2 +- plugins/available/ruby.plugin.bash | 1 - scripts/reloader.bash | 12 +-- 7 files changed, 98 insertions(+), 74 deletions(-) diff --git a/.editorconfig b/.editorconfig index eb3256aa29..36c98e6eaa 100755 --- a/.editorconfig +++ b/.editorconfig @@ -25,7 +25,7 @@ binary_next_line = true # like -bn switch_case_indent = true # like -ci space_redirects = true # like -sr keep_padding = false # like -kp -function_next_line = true # like -fn +#function_next_line = true # like -fn end_of_line = lf charset = utf-8 trim_trailing_whitespace = true diff --git a/aliases/available/bash-it.aliases.bash b/aliases/available/bash-it.aliases.bash index 1f16638b0a..1c56348fa6 100644 --- a/aliases/available/bash-it.aliases.bash +++ b/aliases/available/bash-it.aliases.bash @@ -21,3 +21,9 @@ alias bshsch="bash-it search" alias bshenp="bash-it enable plugin" alias bshena="bash-it enable alias" alias bshenc="bash-it enable completion" + +# BASH_IT_RELOAD_LEGACY is set. +if [[ -n "${BASH_IT_RELOAD_LEGACY:-}" ]] && ! _command_exists reload; then + # shellcheck disable=SC2139 + alias reload="builtin source '${BASH_IT_BASHRC?}'" +fi diff --git a/bash_it.sh b/bash_it.sh index d8ba4db057..e0655e0fb8 100755 --- a/bash_it.sh +++ b/bash_it.sh @@ -3,7 +3,6 @@ # shellcheck disable=SC2034 # # Initialize Bash It -BASH_IT_LOG_PREFIX="core: main: " : "${BASH_IT:=${BASH_SOURCE%/*}}" : "${BASH_IT_CUSTOM:=${BASH_IT}/custom}" : "${CUSTOM_THEME_DIR:="${BASH_IT_CUSTOM}/themes"}" @@ -21,41 +20,38 @@ _bash_it_library_finalize_hook=() # We need to load logging module early in order to be able to log source "${BASH_IT}/lib/log.bash" +_bash_it_log_prefix_push "main" # Load libraries _log_debug "Loading libraries..." for _bash_it_main_file_lib in "${BASH_IT}/lib"/*.bash; do - _bash-it-log-prefix-by-path "${_bash_it_main_file_lib}" + _bash_it_log_section="${_bash_it_lib_file}" _log_debug "Loading library file..." # shellcheck disable=SC1090 source "$_bash_it_main_file_lib" - BASH_IT_LOG_PREFIX="core: main: " done # Load the global "enabled" directory, then enabled aliases, completion, plugins # "_bash_it_main_file_type" param is empty so that files get sourced in glob order for _bash_it_main_file_type in "" "aliases" "plugins" "completion"; do - BASH_IT_LOG_PREFIX="core: reloader: " - _log_debug "Loading \"${file_type}\"..." + _bash_it_log_section=reloader + _log_debug "Loading '${file_type}'..." source "${BASH_IT}/scripts/reloader.bash" "${_bash_it_main_file_type:+skip}" "$_bash_it_main_file_type" - _log_debug "Loaded." - BASH_IT_LOG_PREFIX="core: main: " done # Load theme, if a theme was set # shellcheck source-path=SCRIPTDIR/themes if [[ -n "${BASH_IT_THEME:-}" ]]; then _log_debug "Loading theme '${BASH_IT_THEME}'." - BASH_IT_LOG_PREFIX="themes: githelpers: " + _bash_it_log_section="githelpers" source "${BASH_IT}/themes/githelpers.theme.bash" - BASH_IT_LOG_PREFIX="themes: p4helpers: " + _bash_it_log_section="p4helpers" source "${BASH_IT}/themes/p4helpers.theme.bash" - BASH_IT_LOG_PREFIX="themes: command_duration: " + _bash_it_log_section="command_duration" source "${BASH_IT}/themes/command_duration.theme.bash" - BASH_IT_LOG_PREFIX="themes: base: " + _bash_it_log_section="base" source "${BASH_IT}/themes/base.theme.bash" - BASH_IT_LOG_PREFIX="lib: appearance: " # shellcheck disable=SC1090 if [[ -f "${BASH_IT_THEME}" ]]; then source "${BASH_IT_THEME}" @@ -66,33 +62,35 @@ if [[ -n "${BASH_IT_THEME:-}" ]]; then elif [[ -f "$BASH_IT/themes/$BASH_IT_THEME/$BASH_IT_THEME.theme.bash" ]]; then source "$BASH_IT/themes/$BASH_IT_THEME/$BASH_IT_THEME.theme.bash" fi + _bash_it_log_prefix_pop "theme" fi +_bash_it_log_prefix_push "custom" _log_debug "Loading custom aliases, completion, plugins..." for _bash_it_main_file_type in "aliases" "completion" "plugins"; do _bash_it_main_file_custom="${BASH_IT}/${_bash_it_main_file_type}/custom.${_bash_it_main_file_type}.bash" if [[ -s "${_bash_it_main_file_custom}" ]]; then - _bash-it-log-prefix-by-path "${_bash_it_main_file_custom}" + _bash_it_log_section="${file_type}" _log_debug "Loading component..." # shellcheck disable=SC1090 source "${_bash_it_main_file_custom}" fi - BASH_IT_LOG_PREFIX="core: main: " done # Custom _log_debug "Loading general custom files..." for _bash_it_main_file_custom in "${BASH_IT_CUSTOM}"/*.bash "${BASH_IT_CUSTOM}"/*/*.bash; do if [[ -s "${_bash_it_main_file_custom}" ]]; then - _bash-it-log-prefix-by-path "${_bash_it_main_file_custom}" + _bash_it_log_section="${_bash_it_custom_file}" _log_debug "Loading custom file..." # shellcheck disable=SC1090 source "$_bash_it_main_file_custom" fi - BASH_IT_LOG_PREFIX="core: main: " done +_bash_it_log_prefix_pop "custom" if [[ -n "${PROMPT:-}" ]]; then +_log_trace "Setting prompt..." PS1="${PROMPT}" fi @@ -105,12 +103,6 @@ else PREVIEW="less" fi -# BASH_IT_RELOAD_LEGACY is set. -if [[ -n "${BASH_IT_RELOAD_LEGACY:-}" ]] && ! _command_exists reload; then - # shellcheck disable=SC2139 - alias reload="builtin source '${BASH_IT_BASHRC?}'" -fi - for _bash_it_library_finalize_f in "${_bash_it_library_finalize_hook[@]:-}"; do eval "${_bash_it_library_finalize_f?}" # Use `eval` to achieve the same behavior as `$PROMPT_COMMAND`. done diff --git a/lib/log.bash b/lib/log.bash index aaa0848f2c..9518bdae62 100644 --- a/lib/log.bash +++ b/lib/log.bash @@ -3,10 +3,10 @@ # A collection of logging functions. # Avoid duplicate inclusion -if [[ "${__bi_log_imported:-}" == "defined" ]]; then - return 0 +if [[ "${__bi_log_imported:-}" == "loaded" ]]; then + return 0 fi -__bi_log_imported="defined" +__bi_log_imported="loaded" # Declare log severity levels, matching syslog numbering : "${BASH_IT_LOG_LEVEL_FATAL:=1}" @@ -17,8 +17,17 @@ __bi_log_imported="defined" : "${BASH_IT_LOG_LEVEL_TRACE:=7}" readonly "${!BASH_IT_LOG_LEVEL_@}" -function _bash-it-log-prefix-by-path() { - local component_path="${1?${FUNCNAME[0]}: path specification required}" +declare -a __bash_it_log_prefix=("log" "${__bash_it_log_prefix[@]:-core}") + +function _bash_it_log_prefix_pop() { + _log_trace "End${1:+ (}${1:-}${1:+)}" + unset -v '__bash_it_log_prefix[0]' + __bash_it_log_prefix=("${__bash_it_log_prefix[@]:-default}") +} + +function _bash_it_log_prefix_push() { + local component_path="${_bash_it_log_section:-${1:-default}}" + unset _bash_it_log_section local without_extension component_directory local component_filename component_type component_name @@ -45,8 +54,12 @@ function _bash-it-log-prefix-by-path() { fi fi - # shellcheck disable=SC2034 - BASH_IT_LOG_PREFIX="${component_type:-lib}: $component_name" + if [[ -r "$component_path" ]]; then + __bash_it_log_prefix=("${component_type:-default}: $component_name" "${__bash_it_log_prefix[@]}") + elif [[ -n "$component_path" ]]; then + __bash_it_log_prefix=("${component_name}" "${__bash_it_log_prefix[@]}") + fi + _log_trace "Begin" "${component_name}" } function _has_colors() { @@ -54,53 +67,65 @@ function _has_colors() { [[ -t 1 && "${_bash_it_available_colors:=$(tput colors 2> /dev/null)}" -ge 8 ]] } -function _bash-it-log-message() { - : _about 'Internal function used for logging, uses BASH_IT_LOG_PREFIX as a prefix' - : _param '1: color of the message' - : _param '2: log level to print before the prefix' - : _param '3: message to log' - : _group 'log' - - local prefix="${BASH_IT_LOG_PREFIX:-default}" - local color="${1-${echo_cyan:-}}" - local level="${2:-TRACE}" - local message="${level%: }: ${prefix%: }: ${3?}" - if _has_colors; then - printf '%b%s%b\n' "${color}" "${message}" "${echo_normal:-}" - else - printf '%s\n' "${message}" - fi +function _bash_it_log_message() { + about 'Internal function used for logging, uses __bash_it_log_prefix as a prefix' + param '1: color of the message' + param '2: severity of the message' + param '3: message to log' + group 'log' + + message="($SECONDS) $2: ${__bash_it_log_prefix[1]:-}${__bash_it_log_prefix[1]:+: }${__bash_it_log_prefix[0]:-default}: $3" + _has_colors && echo -e "$1${message}${echo_normal:-}" || echo -e "${message}" +} + +function _log_trace() { + [[ "${BASH_IT_LOG_LEVEL:-0}" -ge ${BASH_IT_LOG_LEVEL_TRACE?} ]] || return 0 + + about 'log a message by echoing to the screen. needs BASH_IT_LOG_LEVEL >= BASH_IT_LOG_LEVEL_TRACE' + param '1: message to log' + param '2: message origin' + example '$ _log_trace "Entering theme plugin"' + group 'log' + + _bash_it_log_message "${echo_blue:-}" "TRACE" "$1${2:+ (}${2:-}${2:+)}" } function _log_debug() { - : _about 'log a debug message by echoing to the screen. needs BASH_IT_LOG_LEVEL >= BASH_IT_LOG_LEVEL_INFO' - : _param '1: message to log' - : _example '$ _log_debug "Loading plugin git..."' - : _group 'log' + [[ "${BASH_IT_LOG_LEVEL:-0}" -ge ${BASH_IT_LOG_LEVEL_INFO?} ]] || return 0 - if [[ "${BASH_IT_LOG_LEVEL:-0}" -ge "${BASH_IT_LOG_LEVEL_INFO?}" ]]; then - _bash-it-log-message "${echo_green:-}" "DEBUG: " "$1" - fi + about 'log a debug message by echoing to the screen. needs BASH_IT_LOG_LEVEL >= BASH_IT_LOG_LEVEL_INFO' + param '1: message to log' + example '$ _log_debug "Loading plugin git..."' + group 'log' + + _bash_it_log_message "${echo_green:-}" "DEBUG" "$1" } function _log_warning() { - : _about 'log a message by echoing to the screen. needs BASH_IT_LOG_LEVEL >= BASH_IT_LOG_LEVEL_WARNING' - : _param '1: message to log' - : _example '$ _log_warning "git binary not found, disabling git plugin..."' - : _group 'log' + [[ "${BASH_IT_LOG_LEVEL:-0}" -ge ${BASH_IT_LOG_LEVEL_WARNING?} ]] || return 0 - if [[ "${BASH_IT_LOG_LEVEL:-0}" -ge "${BASH_IT_LOG_LEVEL_WARNING?}" ]]; then - _bash-it-log-message "${echo_yellow:-}" " WARN: " "$1" - fi + about 'log a message by echoing to the screen. needs BASH_IT_LOG_LEVEL >= BASH_IT_LOG_LEVEL_WARNING' + param '1: message to log' + example '$ _log_warning "git binary not found, disabling git plugin..."' + group 'log' + + _bash_it_log_message "${echo_yellow:-}" " WARN" "$1" } function _log_error() { - : _about 'log a message by echoing to the screen. needs BASH_IT_LOG_LEVEL >= BASH_IT_LOG_LEVEL_ERROR' - : _param '1: message to log' - : _example '$ _log_error "Failed to load git plugin..."' - : _group 'log' + [[ "${BASH_IT_LOG_LEVEL:-0}" -ge ${BASH_IT_LOG_LEVEL_ERROR?} ]] || return 0 - if [[ "${BASH_IT_LOG_LEVEL:-0}" -ge "${BASH_IT_LOG_LEVEL_ERROR?}" ]]; then - _bash-it-log-message "${echo_red:-}" "ERROR: " "$1" - fi + about 'log a message by echoing to the screen. needs BASH_IT_LOG_LEVEL >= BASH_IT_LOG_LEVEL_ERROR' + param '1: message to log' + example '$ _log_error "Failed to load git plugin..."' + group 'log' + + _bash_it_log_message "${echo_red:-}" "ERROR" "$1" } + +# Aliases have no scope, so we can manipulate the global environment. +alias _log_clean_aliases_and_trap="trap - RETURN; unalias source . _log_clean_aliases_and_trap; _log_trace 'Log trace unregistered.'" +_bash_it_library_finalize_hook+=('trap - RETURN' 'unalias source . _log_clean_aliases_and_trap' '_log_trace "Log trace unregistered."') +alias source='_bash_it_log_prefix_push "${BASH_SOURCE##*/}" && builtin source' +alias .=source +trap _bash_it_log_prefix_pop RETURN diff --git a/plugins/available/go.plugin.bash b/plugins/available/go.plugin.bash index 9c503319f0..7e1a2d061a 100644 --- a/plugins/available/go.plugin.bash +++ b/plugins/available/go.plugin.bash @@ -29,4 +29,4 @@ _bash-it-gopath-pathmunge() { pathmunge "${apath}/bin" || true done } -_bash-it-gopath-pathmunge +_bash-it-gopath-pathmunge || true diff --git a/plugins/available/ruby.plugin.bash b/plugins/available/ruby.plugin.bash index 37f8ceb529..c52013aeb9 100644 --- a/plugins/available/ruby.plugin.bash +++ b/plugins/available/ruby.plugin.bash @@ -1,5 +1,4 @@ # shellcheck shell=bash -cite about-plugin about-plugin 'ruby and rubygems specific functions and settings' # Make commands installed with 'gem install --user-install' available diff --git a/scripts/reloader.bash b/scripts/reloader.bash index 846bbf75ee..73d1f31563 100644 --- a/scripts/reloader.bash +++ b/scripts/reloader.bash @@ -2,11 +2,12 @@ # # The core component loader. +_log_debug "Loading..." # shellcheck disable=SC2034 -BASH_IT_LOG_PREFIX="core: reloader: " _bash_it_reloader_type="" -if [[ "${1:-}" != "skip" ]] && [[ -d "${BASH_IT?}/enabled" ]]; then +if [[ "${1:-}" != "skip" && -d "${BASH_IT?}/enabled" ]]; then + _log_trace "Loading enabled components..." case $1 in alias | completion | plugin) _bash_it_reloader_type=$1 @@ -19,24 +20,25 @@ if [[ "${1:-}" != "skip" ]] && [[ -d "${BASH_IT?}/enabled" ]]; then for _bash_it_reloader_file in "$BASH_IT/enabled"/*"${_bash_it_reloader_type}.bash"; do if [[ -e "${_bash_it_reloader_file}" ]]; then - _bash-it-log-prefix-by-path "${_bash_it_reloader_file}" + _bash_it_log_section="${_bash_it_config_file}" _log_debug "Loading component..." - # shellcheck source=/dev/null source "$_bash_it_reloader_file" _log_debug "Loaded." else _log_error "Unable to read ${_bash_it_reloader_file}" fi + _log_trace "end: ${_bash_it_config_file##*/}" done fi if [[ -n "${2:-}" ]] && [[ -d "$BASH_IT/${2}/enabled" ]]; then + _log_trace "Loading enabled $2 components..." case $2 in aliases | completion | plugins) _log_warning "Using legacy enabling for $2, please update your bash-it version and migrate" for _bash_it_reloader_file in "$BASH_IT/${2}/enabled"/*.bash; do if [[ -e "$_bash_it_reloader_file" ]]; then - _bash-it-log-prefix-by-path "${_bash_it_reloader_file}" + _bash_it_log_section="${_bash_it_config_file}" _log_debug "Loading component..." # shellcheck source=/dev/null source "$_bash_it_reloader_file"