diff --git a/.editorconfig b/.editorconfig index 14e6228..713e73f 100644 --- a/.editorconfig +++ b/.editorconfig @@ -9,7 +9,7 @@ insert_final_newline = true trim_trailing_whitespace = true [*.fish] -max_line_length = 80 +max_line_length = 120 [*.md] max_line_length = 120 @@ -49,3 +49,6 @@ ignore = true [plan] trim_trailing_whitespace = false max_line_length = off + +[base/hammerspoon/hammerspoon.types.lua] +max_line_length = off diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index cc7d003..0000000 --- a/.eslintrc.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": ["@ivuorinen"] -} diff --git a/.github/tag-changelog-config.js b/.github/tag-changelog-config.js index bec587c..0dea471 100644 --- a/.github/tag-changelog-config.js +++ b/.github/tag-changelog-config.js @@ -16,10 +16,10 @@ module.exports = { excludeTypes: [], - renderTypeSection: function (label, commits) { + renderTypeSection: (label, commits) => { let text = `\n## ${label}\n\n` - commits.forEach(commit => { + commits.forEach((commit) => { const scope = commit.scope ? `**${commit.scope}:** ` : '' text += `- ${scope}${commit.subject}\n` }) @@ -27,10 +27,10 @@ module.exports = { return text }, - renderChangelog: function (release, changes) { + renderChangelog: (release, changes) => { const now = new Date() const d = now.toISOString().substring(0, 10) const header = `# ${release} - ${d}\n` - return header + changes + '\n\n' + return `${header}${changes}\n\n` }, } diff --git a/.markdownlint.json b/.markdownlint.json deleted file mode 100644 index 729aa6c..0000000 --- a/.markdownlint.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "extends": "@ivuorinen/markdownlint-config", - "code-block-style": { - "style": "fenced" - }, - "code-fence-style": { - "style": "backtick" - }, - "heading-style": { - "style": "atx" - }, - "no-duplicate-heading": { - "siblings_only": true - }, - "required-headings": false, - "ul-style": { - "style": "dash" - } -} diff --git a/.mega-linter.yml b/.mega-linter.yml index bb55758..44c5dbf 100644 --- a/.mega-linter.yml +++ b/.mega-linter.yml @@ -16,12 +16,9 @@ SHOW_SKIPPED_LINTERS: false # Show skipped linters in MegaLinter log TYPESCRIPT_DEFAULT_STYLE: prettier # Default style for TypeScript DISABLE_LINTERS: - REPOSITORY_DEVSKIM - - JAVASCRIPT_ES + - JAVASCRIPT_ES # using biome + - JAVASCRIPT_PRETTIER # using biome YAML_YAMLLINT_CONFIG_FILE: .yamllint.yml -MARKDOWN_MARKDOWNLINT_CONFIG_FILE: .markdownlint.json -JAVASCRIPT_ES_CONFIG_FILE: .eslintrc.json -TYPESCRIPT_ES_CONFIG_FILE: .eslintrc.json REPOSITORY_GIT_DIFF_DISABLE_ERRORS: true FILTER_REGEX_EXCLUDE: > (node_modules|tools|config/cheat/cheatsheets/community|config/cheat/cheatsheets/tldr|config/fzf|config/zsh|config/tmux/plugins) - diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bf3fd09..94e549b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -20,22 +20,22 @@ repos: - id: end-of-file-fixer - id: mixed-line-ending args: [--fix=auto] - - id: pretty-format-json - args: [--autofix, --no-sort-keys] - - repo: https://github.com/igorshubovych/markdownlint-cli - rev: v0.47.0 + - repo: local hooks: - - id: markdownlint - args: [-c, .markdownlint.json, --fix] + - id: biome-check + name: Biome Check + entry: yarn biome check --write --files-ignore-unknown=true --no-errors-on-unmatched + language: system + files: \.(js|ts|jsx|tsx|json|md)$ - repo: https://github.com/adrienverge/yamllint rev: v1.37.1 hooks: - id: yamllint - - repo: https://github.com/koalaman/shellcheck-precommit - rev: v0.11.0 + - repo: https://github.com/shellcheck-py/shellcheck-py + rev: v0.11.0.1 hooks: - id: shellcheck @@ -49,15 +49,11 @@ repos: hooks: - id: actionlint - - repo: https://github.com/renovatebot/pre-commit-hooks - rev: 42.52.8 - hooks: - - id: renovate-config-validator - - repo: https://github.com/JohnnyMorganz/StyLua rev: v2.3.1 hooks: - id: stylua # or stylua-system / stylua-github + exclude: hammerspoon\.types\.lua$ - repo: https://github.com/hugoh/pre-commit-fish.git rev: v1.2 diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index 570308b..0000000 --- a/.prettierignore +++ /dev/null @@ -1,16 +0,0 @@ -# vim: ft=gitignore -.mypy_cache/* -Brewfile.lock.json -base/plan -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 -local/bin/antigen.zsh -local/bin/asdf -tools/antidote/* -tools/dotbot* diff --git a/.prettierrc.js b/.prettierrc.js deleted file mode 100644 index cce301e..0000000 --- a/.prettierrc.js +++ /dev/null @@ -1,15 +0,0 @@ -module.exports = { - ...require('@ivuorinen/prettier-config'), - trailingComma: 'all', - // Add custom options below: - overrides: [ - { - files: '*.md', - options: { - printWidth: 120, - proseWrap: 'preserve', - tabWidth: 2, - }, - }, - ], -} diff --git a/.sonarlint/connectedMode.json b/.sonarlint/connectedMode.json new file mode 100644 index 0000000..5a8cdf8 --- /dev/null +++ b/.sonarlint/connectedMode.json @@ -0,0 +1,5 @@ +{ + "sonarCloudOrganization": "ivuorinen", + "projectKey": "ivuorinen_dotfiles", + "region": "EU" +} diff --git a/base/hammerspoon/hammerspoon.types.lua b/base/hammerspoon/hammerspoon.types.lua index ed2f4c8..0fa4b25 100644 --- a/base/hammerspoon/hammerspoon.types.lua +++ b/base/hammerspoon/hammerspoon.types.lua @@ -2673,7 +2673,7 @@ function canvas:delete(fadeOutTime) end --- optionally return false to indicate that you do not wish to accept the item being dragged. --- "exit" - the user has moved the item out of the canvas; if the previous "enter" callback returned false, this --- message will also occur when the user finally releases the items being dragged. ---- "receive" - indicates that the user has released the dragged object while it is still within the canvas frame. +--- "receive" - indicates that the user has released the dragged object while it is still within the canvas frame. --- When your callback receives this message, you can optionally return false to indicate to the sending application --- that you do not want to accept the dragged item -- this may affect the animations provided by the sending --- application. @@ -2810,7 +2810,7 @@ function canvas:minimumTextSize(index, text) end --- element. The message will be "mouseDown". --- trackMouseUp - indicates that a callback should be invoked when a mouse button has been released over the canvas --- element. The message will be "mouseUp". ---- trackMouseEnterExit - indicates that a callback should be invoked when the mouse pointer enters or exits the +--- trackMouseEnterExit - indicates that a callback should be invoked when the mouse pointer enters or exits the --- canvas element. The message will be "mouseEnter" or "mouseExit". --- trackMouseMove - indicates that a callback should be invoked when the mouse pointer moves within the canvas --- element. The message will be "mouseMove". @@ -4197,7 +4197,7 @@ hs.drawing.windowLevels = nil --- hs.drawing --- for text drawing objects. --- ---- Note: This method returns the default font, size, color, and paragraphStyle used by hs.drawing for text objects. +--- Note: This method returns the default font, size, color, and paragraphStyle used by hs.drawing for text objects. --- If you modify a drawing object's defaults with hs.drawing:setColor , hs.drawing:setTextFont , or --- hs.drawing:setTextSize , the changes will not be reflected by this function. ---@return table @@ -4662,7 +4662,7 @@ hs.drawing.color.ansiTerminalColors = nil ---@type table hs.drawing.color.hammerspoon = nil ---- A collection of colors representing the X11 color names as defined at +--- A collection of colors representing the X11 color names as defined at --- https://en.wikipedia.org/wiki/Web_colors#X11_color_names (names in lowercase) ---@type any hs.drawing.color.x11 = nil @@ -7022,7 +7022,7 @@ function hs.http.doAsyncRequest(url, method, data, headers, callback, cachePolic --- use the asynchronous functions. --- If you attempt to connect to a local Hammerspoon server created with hs.httpserver , then Hammerspoon will block --- until the connection times out (60 seconds), return a failed result due to the timeout, and then the hs.httpserver ---- callback function will be invoked (so any side effects of the function will occur, but it's results will be lost). +--- callback function will be invoked (so any side effects of the function will occur, but it's results will be lost). --- Use hs.http.doAsyncRequest to avoid this. --- If the Content-Type response header begins text/ then the response body return value is a UTF8 string. Any other --- content type passes the response body, unaltered, as a stream of bytes. @@ -7054,7 +7054,7 @@ function hs.http.encodeForQuery(string) end --- are encouraged to use the asynchronous functions --- If you attempt to connect to a local Hammerspoon server created with hs.httpserver , then Hammerspoon will block --- until the connection times out (60 seconds), return a failed result due to the timeout, and then the hs.httpserver ---- callback function will be invoked (so any side effects of the function will occur, but it's results will be lost). +--- callback function will be invoked (so any side effects of the function will occur, but it's results will be lost). --- Use hs.http.asyncGet to avoid this. ---@param url string ---@param headers table|nil @@ -7072,7 +7072,7 @@ function hs.http.get(url, headers) end --- are encouraged to use the asynchronous functions --- If you attempt to connect to a local Hammerspoon server created with hs.httpserver , then Hammerspoon will block --- until the connection times out (60 seconds), return a failed result due to the timeout, and then the hs.httpserver ---- callback function will be invoked (so any side effects of the function will occur, but it's results will be lost). +--- callback function will be invoked (so any side effects of the function will occur, but it's results will be lost). --- Use hs.http.asyncPost to avoid this. ---@param url string ---@param data string|nil @@ -7091,7 +7091,7 @@ function hs.http.post(url, data, headers) end --- are encouraged to use the asynchronous functions --- If you attempt to connect to a local Hammerspoon server created with hs.httpserver , then Hammerspoon will block --- until the connection times out (60 seconds), return a failed result due to the timeout, and then the hs.httpserver ---- callback function will be invoked (so any side effects of the function will occur, but it's results will be lost). +--- callback function will be invoked (so any side effects of the function will occur, but it's results will be lost). --- Use hs.http.asyncPost to avoid this. ---@param url string ---@param data string|nil @@ -7374,7 +7374,7 @@ function hs.httpserver.hsminweb.new(documentRoot) end --- Get or set the access-list table for the hsminweb web server --- --- Note: The access-list feature works by comparing the request headers against a list of tests which either accept or ---- reject the request. If no access list is set (i.e. it is assigned a value of nil ), then all requests are served. +--- reject the request. If no access list is set (i.e. it is assigned a value of nil ), then all requests are served. --- If a table is passed into this method, then any request which is not explicitly accepted by one of the tests --- provided is rejected (i.e. there is an implicit "reject" at the end of the list). --- The access-list table is a list of tests which are evaluated in order. The first test which matches a given @@ -7919,7 +7919,7 @@ function hs.httpserver.hsminweb.cgilua.urlcode.insertfield(table, key, value) en --- Parse the query string and store the key-value pairs in the provided table. --- --- Note: The specification allows for the same key to be assigned multiple values in an encoded string, but does not ---- specify the behavior; by convention, web servers assign these multiple values to the same key in an array (table). +--- specify the behavior; by convention, web servers assign these multiple values to the same key in an array (table). --- This function follows that convention. This is most commonly used by forms which allow selecting multiple options --- via check boxes or in a selection list. --- This function uses cgilua.urlcode.insertfield to build the key-value table. @@ -10225,7 +10225,7 @@ function echorequest:seeAllUnexpectedPackets(state) end --- Sends a single ICMP Echo Request packet. --- --- Note: By convention, unless you are trying to test for specific network fragmentation or congestion problems, ICMP ---- Echo Requests are generally 64 bytes in length (this includes the 8 byte header, giving 56 bytes of payload data). +--- Echo Requests are generally 64 bytes in length (this includes the 8 byte header, giving 56 bytes of payload data). --- If you do not specify a payload, a default payload which will result in a packet size of 64 bytes is constructed. ---@param payload string|nil ---@return echoRequestObject|boolean|nil @@ -15169,7 +15169,7 @@ function watcher:stop() end ---@class hs.utf8 hs.utf8 = {} ---- A collection of UTF-8 characters already converted from codepoint and available as convenient key-value pairs. +--- A collection of UTF-8 characters already converted from codepoint and available as convenient key-value pairs. --- UTF-8 printable versions of common Apple and OS X special keys are predefined and others can be added with --- hs.utf8.registerCodepoint(label, codepoint) --- for your own use. @@ -15238,7 +15238,7 @@ function hs.utf8.hexDump(inputString, count) end --- hs.utf8.registeredKeys[label] --- for convenience and readability. --- ---- Note: If a codepoint label was previously registered, this will overwrite the previous value with a new one. +--- Note: If a codepoint label was previously registered, this will overwrite the previous value with a new one. --- Because many of the special keys you may want to register have different variants, this allows you to easily modify --- the existing predefined defaults to suite your preferences. --- The return value is merely syntactic sugar and you do not need to save it locally; it can be safely ignored -- @@ -15585,13 +15585,13 @@ function hs.webview.newBrowser(rect, preferencesTable, userContentController) en ---@return webviewObject function webview:allowGestures(value) end ---- Get or set whether or not the webview will respond to magnification gestures from a trackpad or magic mouse. +--- Get or set whether or not the webview will respond to magnification gestures from a trackpad or magic mouse. --- Default is false. ---@param value any ---@return webviewObject function webview:allowMagnificationGestures(value) end ---- Get or set whether or not the webview will respond to the navigation gestures from a trackpad or magic mouse. +--- Get or set whether or not the webview will respond to the navigation gestures from a trackpad or magic mouse. --- Default is false. ---@param value any ---@return webviewObject @@ -16455,7 +16455,7 @@ function usercontent:removeAllScripts() end --- } catch(err) { --- console.log('The controller does not exist yet'); --- } ---- Where name matches the name specified in the constructor and message-object is the object to post to the function. +--- Where name matches the name specified in the constructor and message-object is the object to post to the function. --- This object can be a number, string, date, array, dictionary(table), or nil. ---@param fn function ---@return usercontentControllerObject @@ -17860,4 +17860,4 @@ hs.window.tiling = {} ---@param preserveRelativeArea? any ---@param animationDuration? hs.window.animationDuration|nil ---@return any -function hs.window.tiling.tileWindows(windows, rect, desiredAspect, processInOrder, preserveRelativeArea, animationDuration) end \ No newline at end of file +function hs.window.tiling.tileWindows(windows, rect, desiredAspect, processInOrder, preserveRelativeArea, animationDuration) end diff --git a/base/hammerspoon/init.lua b/base/hammerspoon/init.lua index 620b767..2453055 100644 --- a/base/hammerspoon/init.lua +++ b/base/hammerspoon/init.lua @@ -193,11 +193,12 @@ end) -- Paste 1Password secret with Meh + P f18:bind({}, 'p', function() - local output, status = hs.execute('op read "op://Svea/3hzhctmvovbwlgulv7mgy25rf4/login-input"', true) + local output, status = + hs.execute('op read "op://Svea/3hzhctmvovbwlgulv7mgy25rf4/login-input"', true) if status then hs.eventtap.keyStrokes(output:gsub('%s+$', '')) -- trim trailing whitespace else - hs.alert.show('1Password CLI error') + hs.alert.show '1Password CLI error' end end) diff --git a/biome.json b/biome.json new file mode 100644 index 0000000..9a5dc5c --- /dev/null +++ b/biome.json @@ -0,0 +1,103 @@ +{ + "$schema": "https://biomejs.dev/schemas/2.3.1/schema.json", + "vcs": { + "enabled": true, + "clientKind": "git", + "useIgnoreFile": true, + "defaultBranch": "main" + }, + "files": { + "ignoreUnknown": true, + "includes": [ + "**", + "!!**/.mypy_cache", + "!!**/Brewfile.lock.json", + "!!**/base/plan", + "!!**/config/cheat/cheatsheets/community", + "!!**/config/cheat/cheatsheets/tldr", + "!!**/config/fzf", + "!!**/config/nvim", + "!!**/config/op/plugins/used_plugins", + "!!**/config/tmux/plugins", + "!!**/config/zsh", + "!!**/config/vim", + "!!**/lazy-lock.json", + "!!**/local/bin/antigen.zsh", + "!!**/local/bin/asdf", + "!!**/tools/antidote", + "!!**/tools/dotbot", + "!!**/node_modules" + ] + }, + "formatter": { + "enabled": true, + "formatWithErrors": false, + "indentStyle": "space", + "indentWidth": 2, + "lineEnding": "lf", + "lineWidth": 80 + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true, + "correctness": { + "noUnusedVariables": "warn", + "noUnusedImports": "warn" + }, + "style": { + "useConst": "warn", + "useTemplate": "warn" + }, + "suspicious": { + "noExplicitAny": "warn", + "noConsole": "off" + } + } + }, + "javascript": { + "formatter": { + "enabled": true, + "quoteStyle": "single", + "jsxQuoteStyle": "double", + "trailingCommas": "all", + "semicolons": "asNeeded", + "arrowParentheses": "always", + "bracketSpacing": true, + "bracketSameLine": false, + "quoteProperties": "asNeeded", + "indentStyle": "space", + "indentWidth": 2 + } + }, + "json": { + "parser": { + "allowComments": true, + "allowTrailingCommas": false + }, + "formatter": { + "enabled": true, + "indentStyle": "space", + "indentWidth": 2, + "lineWidth": 80 + } + }, + "overrides": [ + { + "includes": ["*.md", "*.mdx"], + "formatter": { + "enabled": true, + "lineWidth": 120 + } + }, + { + "includes": ["package.json"], + "json": { + "formatter": { + "enabled": true, + "indentWidth": 2 + } + } + } + ] +} diff --git a/config/amethyst/layouts/almost-maximize.js b/config/amethyst/layouts/almost-maximize.js index dcb3673..00b0d34 100644 --- a/config/amethyst/layouts/almost-maximize.js +++ b/config/amethyst/layouts/almost-maximize.js @@ -6,21 +6,19 @@ * * @param {Object} windows - All windows in the current space. * @param {Object} screenFrame - The frame of the current screen. - * @param {Object} state - The state of the current space. - * @param {Object} extendedFrames - The frames of the windows in the current space. * @return {Object} - The frames for the windows in the current space. */ function layout() { return { name: 'Almost Maximize', - getFrameAssignments: (windows, screenFrame, state, extendedFrames) => { + getFrameAssignments: (windows, screenFrame) => { const width = screenFrame.width * 0.95 const height = screenFrame.height * 0.95 const x = (screenFrame.width - width) / 2 const y = (screenFrame.height - height) / 2 const windowFrames = {} - windows.forEach(window => { + windows.forEach((window) => { windowFrames[window.id] = { Y: screenFrame.y + y, x: screenFrame.x + x, @@ -33,3 +31,5 @@ function layout() { }, } } + +module.exports = layout() diff --git a/config/exports-secret.example b/config/exports-secret.example index 7abaec6..c581576 100644 --- a/config/exports-secret.example +++ b/config/exports-secret.example @@ -1,5 +1,3 @@ -#!/usr/bin/env bash -# # This file is secret and wont be added to the git repo. export GITLAB_API_TOKEN="" diff --git a/config/fish/completions/docker.fish b/config/fish/completions/docker.fish old mode 100755 new mode 100644 diff --git a/config/fish/config.fish b/config/fish/config.fish index c30882b..02e341d 100644 --- a/config/fish/config.fish +++ b/config/fish/config.fish @@ -26,7 +26,7 @@ if status is-interactive # type -q fnm; and fnm env --use-on-cd --shell fish | source type -q load_nvm; and load_nvm >/dev/stderr - # Intialize other tools if available + # Initialize other tools if available type -q zoxide; and zoxide init fish | source # Start tmux if not already running and not in SSH @@ -40,7 +40,7 @@ set -gx PATH $PATH $HOME/.lmstudio/bin # vim: ft=fish ts=4 sw=4 et: # opencode -fish_add_path /Users/ivuorinen/.opencode/bin +fish_add_path $HOME/.opencode/bin # Added by OrbStack: command-line tools and integration # This won't be added again if you remove it. diff --git a/config/fish/exports.fish b/config/fish/exports.fish index ce80e88..40d3c61 100644 --- a/config/fish/exports.fish +++ b/config/fish/exports.fish @@ -1,5 +1,3 @@ -#!/usr/bin/env fish - # XDG Base Directory Specification set -q XDG_CONFIG_HOME; or set -x XDG_CONFIG_HOME "$HOME/.config" set -q XDG_DATA_HOME; or set -x XDG_DATA_HOME "$HOME/.local/share" diff --git a/config/fish/functions/__macos_app_icon.fish b/config/fish/functions/__macos_app_icon.fish index b5c2249..3a5fd19 100644 --- a/config/fish/functions/__macos_app_icon.fish +++ b/config/fish/functions/__macos_app_icon.fish @@ -26,7 +26,6 @@ Options: return 1 end - if set --query _flag_exact set --function apps (__macos_app_find --exact $argv) or return 1 diff --git a/config/fish/functions/__macos_mac_touchid_sudo.fish b/config/fish/functions/__macos_mac_touchid_sudo.fish index e503649..a7c7e06 100644 --- a/config/fish/functions/__macos_mac_touchid_sudo.fish +++ b/config/fish/functions/__macos_mac_touchid_sudo.fish @@ -139,7 +139,6 @@ Options: return 0 end - __macos_mac_touchid_sudo::check_supported or return diff --git a/config/fish/functions/__ssh_agent_is_started.fish b/config/fish/functions/__ssh_agent_is_started.fish index a9da28a..4318c25 100644 --- a/config/fish/functions/__ssh_agent_is_started.fish +++ b/config/fish/functions/__ssh_agent_is_started.fish @@ -1,23 +1,25 @@ function __ssh_agent_is_started -d "check if ssh agent is already started" - if test -n "$SSH_CONNECTION" - # This is an SSH session - ssh-add -l > /dev/null 2>&1 - if test $status -eq 0 -o $status -eq 1 - # An SSH agent was forwarded - return 0 - end - end + if test -n "$SSH_CONNECTION" + # This is an SSH session + ssh-add -l >/dev/null 2>&1 + if test $status -eq 0 -o $status -eq 1 + # An SSH agent was forwarded + return 0 + end + end - if begin; test -f "$SSH_ENV"; and test -z "$SSH_AGENT_PID"; end - source $SSH_ENV > /dev/null - end + if begin + test -f "$SSH_ENV"; and test -z "$SSH_AGENT_PID" + end + source $SSH_ENV >/dev/null + end - if test -z "$SSH_AGENT_PID" - return 1 - end + if test -z "$SSH_AGENT_PID" + return 1 + end - ssh-add -l > /dev/null 2>&1 - if test $status -eq 2 - return 1 - end + ssh-add -l >/dev/null 2>&1 + if test $status -eq 2 + return 1 + end end diff --git a/config/fish/functions/__ssh_agent_start.fish b/config/fish/functions/__ssh_agent_start.fish index 3766fe4..c7ae4b3 100644 --- a/config/fish/functions/__ssh_agent_start.fish +++ b/config/fish/functions/__ssh_agent_start.fish @@ -1,5 +1,5 @@ function __ssh_agent_start -d "start a new ssh agent" - ssh-agent -c | sed 's/^echo/#echo/' > $SSH_ENV - chmod 600 $SSH_ENV - source $SSH_ENV > /dev/null + ssh-agent -c | sed 's/^echo/#echo/' >$SSH_ENV + chmod 600 $SSH_ENV + source $SSH_ENV >/dev/null end diff --git a/config/fish/functions/_fzf_extract_var_info.fish b/config/fish/functions/_fzf_extract_var_info.fish index dd4e952..34a4b44 100644 --- a/config/fish/functions/_fzf_extract_var_info.fish +++ b/config/fish/functions/_fzf_extract_var_info.fish @@ -3,10 +3,8 @@ function _fzf_extract_var_info --argument-names variable_name set_show_output -- # Extract only the lines about the variable, all of which begin with either # $variable_name: ...or... $variable_name[ string match --regex "^\\\$$variable_name(?::|\[).*" <$set_show_output | - # Strip the variable name prefix, including ": " for scope info lines string replace --regex "^\\\$$variable_name(?:: )?" '' | - # Distill the lines of values, replacing... # [1]: |value| # ...with... diff --git a/config/fish/functions/_fzf_search_directory.fish b/config/fish/functions/_fzf_search_directory.fish index 4541eec..b00c34a 100644 --- a/config/fish/functions/_fzf_search_directory.fish +++ b/config/fish/functions/_fzf_search_directory.fish @@ -24,7 +24,6 @@ function _fzf_search_directory --description "Search the current directory. Repl set -f file_paths_selected ($fd_cmd 2>/dev/null | _fzf_wrapper $fzf_arguments) end - if test $status -eq 0 commandline --current-token --replace -- (string escape -- $file_paths_selected | string join ' ') end diff --git a/config/fish/functions/_puffer_fish_expand_bang.fish b/config/fish/functions/_puffer_fish_expand_bang.fish index 6fb9dfb..193beae 100644 --- a/config/fish/functions/_puffer_fish_expand_bang.fish +++ b/config/fish/functions/_puffer_fish_expand_bang.fish @@ -1,8 +1,8 @@ function _puffer_fish_expand_bang switch (commandline -t) - case '!' - commandline -t $history[1] - case '*' - commandline -i '!' + case '!' + commandline -t $history[1] + case '*' + commandline -i '!' end end diff --git a/config/fish/functions/_puffer_fish_expand_lastarg.fish b/config/fish/functions/_puffer_fish_expand_lastarg.fish index a61b892..4f9c87d 100644 --- a/config/fish/functions/_puffer_fish_expand_lastarg.fish +++ b/config/fish/functions/_puffer_fish_expand_lastarg.fish @@ -1,9 +1,9 @@ function _puffer_fish_expand_lastarg switch (commandline -t) - case '!' - commandline -t "" - commandline -f history-token-search-backward - case '*' - commandline -i '$' + case '!' + commandline -t "" + commandline -f history-token-search-backward + case '*' + commandline -i '$' end end diff --git a/config/fish/functions/_sponge_clear_state.fish b/config/fish/functions/_sponge_clear_state.fish index c6a07da..b1f972c 100644 --- a/config/fish/functions/_sponge_clear_state.fish +++ b/config/fish/functions/_sponge_clear_state.fish @@ -1,5 +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 + set --erase --global _sponge_current_command + set --erase --global _sponge_current_command_exit_code + set --erase --global _sponge_current_command_previously_in_history end diff --git a/config/fish/functions/_sponge_on_exit.fish b/config/fish/functions/_sponge_on_exit.fish index 0c6cc19..30237fd 100644 --- a/config/fish/functions/_sponge_on_exit.fish +++ b/config/fish/functions/_sponge_on_exit.fish @@ -1,3 +1,3 @@ function _sponge_on_exit --on-event fish_exit - sponge_delay=0 _sponge_remove_from_history + sponge_delay=0 _sponge_remove_from_history end diff --git a/config/fish/functions/_sponge_on_postexec.fish b/config/fish/functions/_sponge_on_postexec.fish index 1d67935..b208c31 100644 --- a/config/fish/functions/_sponge_on_postexec.fish +++ b/config/fish/functions/_sponge_on_postexec.fish @@ -1,24 +1,24 @@ function _sponge_on_postexec --on-event fish_postexec - set --global _sponge_current_command_exit_code $status + 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 + # 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 - set --prepend --global _sponge_queue $command - end end diff --git a/config/fish/functions/_sponge_on_preexec.fish b/config/fish/functions/_sponge_on_preexec.fish index a866491..8ded904 100644 --- a/config/fish/functions/_sponge_on_preexec.fish +++ b/config/fish/functions/_sponge_on_preexec.fish @@ -1,16 +1,16 @@ function _sponge_on_preexec --on-event fish_preexec \ - --argument-names command - _sponge_clear_state + --argument-names command + _sponge_clear_state - set --global _sponge_current_command $command + set --global _sponge_current_command $command - builtin history search --case-sensitive --exact --max=1 --null $command \ - | read --local --null found_entries + 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 wasn’t 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 + # If a command is in the history and in the queue, ignore it, like if it wasn’t 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 diff --git a/config/fish/functions/_sponge_on_prompt.fish b/config/fish/functions/_sponge_on_prompt.fish index 03e989a..dcc43ee 100644 --- a/config/fish/functions/_sponge_on_prompt.fish +++ b/config/fish/functions/_sponge_on_prompt.fish @@ -1,5 +1,5 @@ function _sponge_on_prompt --on-event fish_prompt - if test $sponge_purge_only_on_exit = false - _sponge_remove_from_history - end + if test $sponge_purge_only_on_exit = false + _sponge_remove_from_history + end end diff --git a/config/fish/functions/_sponge_remove_from_history.fish b/config/fish/functions/_sponge_remove_from_history.fish index 4d4f827..6cce3f8 100644 --- a/config/fish/functions/_sponge_remove_from_history.fish +++ b/config/fish/functions/_sponge_remove_from_history.fish @@ -1,9 +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 + 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 + builtin history save end diff --git a/config/fish/functions/bass.fish b/config/fish/functions/bass.fish index 2b3af16..04c0783 100644 --- a/config/fish/functions/bass.fish +++ b/config/fish/functions/bass.fish @@ -1,29 +1,29 @@ function bass - set -l bash_args $argv - set -l bass_debug - if test "$bash_args[1]_" = '-d_' - set bass_debug true - set -e bash_args[1] - end + set -l bash_args $argv + set -l bass_debug + if test "$bash_args[1]_" = -d_ + set bass_debug true + set -e bash_args[1] + end - set -l script_file (mktemp) - if command -v python3 >/dev/null 2>&1 - command python3 -sS (dirname (status -f))/__bass.py $bash_args 3>$script_file - else - command python -sS (dirname (status -f))/__bass.py $bash_args 3>$script_file - end - set -l bass_status $status - if test $bass_status -ne 0 - return $bass_status - end + set -l script_file (mktemp) + if command -v python3 >/dev/null 2>&1 + command python3 -sS (dirname (status -f))/__bass.py $bash_args 3>$script_file + else + command python -sS (dirname (status -f))/__bass.py $bash_args 3>$script_file + end + set -l bass_status $status + if test $bass_status -ne 0 + return $bass_status + end - if test -n "$bass_debug" - cat $script_file - end - source $script_file - command rm $script_file + if test -n "$bass_debug" + cat $script_file + end + source $script_file + command rm $script_file end function __bass_usage - echo "Usage: bass [-d] " + echo "Usage: bass [-d] " end diff --git a/config/fish/functions/load_nvm.fish b/config/fish/functions/load_nvm.fish index 55ed127..3205b88 100644 --- a/config/fish/functions/load_nvm.fish +++ b/config/fish/functions/load_nvm.fish @@ -1,16 +1,16 @@ function load_nvm --on-variable="PWD" - set -l default_node_version (nvm version default) - set -l node_version (nvm version) - set -l nvmrc_path (nvm_find_nvmrc) - if test -n "$nvmrc_path" - set -l nvmrc_node_version (nvm version (cat $nvmrc_path)) - if test "$nvmrc_node_version" = "N/A" - nvm install (cat $nvmrc_path) - else if test "$nvmrc_node_version" != "$node_version" - nvm use $nvmrc_node_version + set -l default_node_version (nvm version default) + set -l node_version (nvm version) + set -l nvmrc_path (nvm_find_nvmrc) + if test -n "$nvmrc_path" + set -l nvmrc_node_version (nvm version (cat $nvmrc_path)) + if test "$nvmrc_node_version" = N/A + nvm install (cat $nvmrc_path) + else if test "$nvmrc_node_version" != "$node_version" + nvm use $nvmrc_node_version + end + else if test "$node_version" != "$default_node_version" + echo "Reverting to default Node version" + nvm use default end - else if test "$node_version" != "$default_node_version" - echo "Reverting to default Node version" - nvm use default - end end diff --git a/config/fish/functions/nvm_find_nvmrc.fish b/config/fish/functions/nvm_find_nvmrc.fish index 359c1f9..14d616e 100644 --- a/config/fish/functions/nvm_find_nvmrc.fish +++ b/config/fish/functions/nvm_find_nvmrc.fish @@ -1,3 +1,3 @@ function nvm_find_nvmrc - bass source $NVM_DIR/nvm.sh --no-use ';' nvm_find_nvmrc + bass source $NVM_DIR/nvm.sh --no-use ';' nvm_find_nvmrc end diff --git a/config/fish/functions/paths.fish b/config/fish/functions/paths.fish index 9f06b03..01721f6 100644 --- a/config/fish/functions/paths.fish +++ b/config/fish/functions/paths.fish @@ -158,7 +158,7 @@ function paths --description "Reveal the executable matches in shell paths or fi # check set -l built (type --type $input 12&>/dev/null) if test -n "$built" - and test "$built" = 'builtin' + and test "$built" = builtin set $foundStatus 0 if not set -q _flag_c echo -e -n "builtin\n" diff --git a/config/fish/functions/sponge_filter_failed.fish b/config/fish/functions/sponge_filter_failed.fish index be26e5d..7cccaf2 100644 --- a/config/fish/functions/sponge_filter_failed.fish +++ b/config/fish/functions/sponge_filter_failed.fish @@ -1,11 +1,11 @@ function sponge_filter_failed \ - --argument-names command exit_code previously_in_history + --argument-names command exit_code previously_in_history - if test $previously_in_history = true -a $sponge_allow_previously_successful = true - return 1 - end + 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 + if contains $exit_code $sponge_successful_exit_codes + return 1 + end end diff --git a/config/fish/functions/sponge_filter_matched.fish b/config/fish/functions/sponge_filter_matched.fish index c3c7ea2..ce7c26a 100644 --- a/config/fish/functions/sponge_filter_matched.fish +++ b/config/fish/functions/sponge_filter_matched.fish @@ -1,11 +1,11 @@ function sponge_filter_matched \ - --argument-names command + --argument-names command - for pattern in $sponge_regex_patterns - if string match --regex --quiet $pattern -- $command - return + for pattern in $sponge_regex_patterns + if string match --regex --quiet $pattern -- $command + return + end end - end - return 1 + return 1 end diff --git a/config/fzf/completion.bash b/config/fzf/completion.bash old mode 100755 new mode 100644 index 7404f6f..cede3a5 --- a/config/fzf/completion.bash +++ b/config/fzf/completion.bash @@ -1,3 +1,4 @@ +# shellcheck disable=all # ____ ____ # / __/___ / __/ # / /_/_ / / /_ diff --git a/config/fzf/completion.zsh b/config/fzf/completion.zsh old mode 100755 new mode 100644 index bb256d9..6e67b07 --- a/config/fzf/completion.zsh +++ b/config/fzf/completion.zsh @@ -1,3 +1,4 @@ +# shellcheck disable=all # ____ ____ # / __/___ / __/ # / /_/_ / / /_ diff --git a/config/fzf/everforest.sh b/config/fzf/everforest.sh index cffb6c5..eb1f109 100644 --- a/config/fzf/everforest.sh +++ b/config/fzf/everforest.sh @@ -1,3 +1,4 @@ +# shellcheck shell=bash # Everforest theme for fzf # Generated from template - do not edit manually diff --git a/config/fzf/fzf.bash b/config/fzf/fzf.bash old mode 100755 new mode 100644 diff --git a/config/fzf/fzf.zsh b/config/fzf/fzf.zsh index 067b6cd..0026342 100755 --- a/config/fzf/fzf.zsh +++ b/config/fzf/fzf.zsh @@ -1,3 +1,5 @@ +#!/usr/bin/env zsh +# shellcheck disable=SC1071 # Setup fzf # --------- diff --git a/config/fzf/key-bindings.bash b/config/fzf/key-bindings.bash old mode 100755 new mode 100644 index c388d0d..5581694 --- a/config/fzf/key-bindings.bash +++ b/config/fzf/key-bindings.bash @@ -20,8 +20,8 @@ __fzf_select__() { -o -type d -print \ -o -type l -print 2> /dev/null | cut -b3-"}" opts="--height ${FZF_TMUX_HEIGHT:-40%} --bind=ctrl-z:ignore --reverse ${FZF_DEFAULT_OPTS-} ${FZF_CTRL_T_OPTS-} -m" - eval "$cmd" | - FZF_DEFAULT_OPTS="$opts" $(__fzfcmd) "$@" | + # shellcheck disable=SC2091 # Intentionally execute output of __fzfcmd + eval "$cmd" | FZF_DEFAULT_OPTS="$opts" $(__fzfcmd) "$@" | while read -r item; do printf '%q ' "$item" # escape special chars done @@ -35,7 +35,8 @@ if [[ $- =~ i ]]; then } fzf-file-widget() { - local selected="$(__fzf_select__ "$@")" + local selected + selected="$(__fzf_select__ "$@")" READLINE_LINE="${READLINE_LINE:0:$READLINE_POINT}$selected${READLINE_LINE:$READLINE_POINT}" READLINE_POINT=$((READLINE_POINT + ${#selected})) } @@ -45,6 +46,7 @@ if [[ $- =~ i ]]; then cmd="${FZF_ALT_C_COMMAND:-"command find -L . -mindepth 1 \\( -path '*/\\.*' -o -fstype 'sysfs' -o -fstype 'devfs' -o -fstype 'devtmpfs' -o -fstype 'proc' \\) -prune \ -o -type d -print 2> /dev/null | cut -b3-"}" opts="--height ${FZF_TMUX_HEIGHT:-40%} --bind=ctrl-z:ignore --reverse ${FZF_DEFAULT_OPTS-} ${FZF_ALT_C_OPTS-} +m" + # shellcheck disable=SC2091 # Intentionally execute output of __fzfcmd dir=$( set +o pipefail eval "$cmd" | FZF_DEFAULT_OPTS="$opts" $(__fzfcmd) @@ -55,6 +57,7 @@ if [[ $- =~ i ]]; then local output opts script opts="--height ${FZF_TMUX_HEIGHT:-40%} --bind=ctrl-z:ignore ${FZF_DEFAULT_OPTS-} -n2..,.. --scheme=history --bind=ctrl-r:toggle-sort ${FZF_CTRL_R_OPTS-} +m --read0" script='BEGIN { getc; $/ = "\n\t"; $HISTCOUNT = $ENV{last_hist} + 1 } s/^[ *]//; print $HISTCOUNT - $. . "\t$_" if !$seen{$_}++' + # shellcheck disable=SC2091 # Intentionally execute output of __fzfcmd output=$( set +o pipefail builtin fc -lnr -2147483648 | diff --git a/config/fzf/key-bindings.fish b/config/fzf/key-bindings.fish old mode 100755 new mode 100644 index 743c7c1..88fe13c --- a/config/fzf/key-bindings.fish +++ b/config/fzf/key-bindings.fish @@ -15,158 +15,161 @@ # ------------ function fzf_key_bindings - # Store current token in $dir as root for the 'find' command - function fzf-file-widget -d "List files and folders" - set -l commandline (__fzf_parse_commandline) - set -l dir $commandline[1] - set -l fzf_query $commandline[2] - set -l prefix $commandline[3] + # Store current token in $dir as root for the 'find' command + function fzf-file-widget -d "List files and folders" + set -l commandline (__fzf_parse_commandline) + set -l dir $commandline[1] + set -l fzf_query $commandline[2] + set -l prefix $commandline[3] - # "-path \$dir'*/\\.*'" matches hidden files/folders inside $dir but not - # $dir itself, even if hidden. - test -n "$FZF_CTRL_T_COMMAND"; or set -l FZF_CTRL_T_COMMAND " + # "-path \$dir'*/\\.*'" matches hidden files/folders inside $dir but not + # $dir itself, even if hidden. + test -n "$FZF_CTRL_T_COMMAND"; or set -l FZF_CTRL_T_COMMAND " command find -L \$dir -mindepth 1 \\( -path \$dir'*/\\.*' -o -fstype 'sysfs' -o -fstype 'devfs' -o -fstype 'devtmpfs' \\) -prune \ -o -type f -print \ -o -type d -print \ -o -type l -print 2> /dev/null | sed 's@^\./@@'" - test -n "$FZF_TMUX_HEIGHT"; or set FZF_TMUX_HEIGHT 40% - begin - set -lx FZF_DEFAULT_OPTS "--height $FZF_TMUX_HEIGHT --reverse --bind=ctrl-z:ignore $FZF_DEFAULT_OPTS $FZF_CTRL_T_OPTS" - eval "$FZF_CTRL_T_COMMAND | "(__fzfcmd)' -m --query "'$fzf_query'"' | while read -l r; set result $result $r; end + test -n "$FZF_TMUX_HEIGHT"; or set FZF_TMUX_HEIGHT 40% + begin + set -lx FZF_DEFAULT_OPTS "--height $FZF_TMUX_HEIGHT --reverse --bind=ctrl-z:ignore $FZF_DEFAULT_OPTS $FZF_CTRL_T_OPTS" + eval "$FZF_CTRL_T_COMMAND | "(__fzfcmd)' -m --query "'$fzf_query'"' | while read -l r + set result $result $r + end + end + if [ -z "$result" ] + commandline -f repaint + return + else + # Remove last token from commandline. + commandline -t "" + end + for i in $result + commandline -it -- $prefix + commandline -it -- (string escape $i) + commandline -it -- ' ' + end + commandline -f repaint end - if [ -z "$result" ] - commandline -f repaint - return - else - # Remove last token from commandline. - commandline -t "" + + function fzf-history-widget -d "Show command history" + test -n "$FZF_TMUX_HEIGHT"; or set FZF_TMUX_HEIGHT 40% + begin + set -lx FZF_DEFAULT_OPTS "--height $FZF_TMUX_HEIGHT $FZF_DEFAULT_OPTS --scheme=history --bind=ctrl-r:toggle-sort,ctrl-z:ignore $FZF_CTRL_R_OPTS +m" + + set -l FISH_MAJOR (echo $version | cut -f1 -d.) + set -l FISH_MINOR (echo $version | cut -f2 -d.) + + # history's -z flag is needed for multi-line support. + # history's -z flag was added in fish 2.4.0, so don't use it for versions + # before 2.4.0. + if [ "$FISH_MAJOR" -gt 2 -o \( "$FISH_MAJOR" -eq 2 -a "$FISH_MINOR" -ge 4 \) ] + + history -z | eval (__fzfcmd) --read0 --print0 -q '(commandline)' | read -lz result + and commandline -- $result + else + history | eval (__fzfcmd) -q '(commandline)' | read -l result + and commandline -- $result + end + end + commandline -f repaint end - for i in $result - commandline -it -- $prefix - commandline -it -- (string escape $i) - commandline -it -- ' ' - end - commandline -f repaint - end - function fzf-history-widget -d "Show command history" - test -n "$FZF_TMUX_HEIGHT"; or set FZF_TMUX_HEIGHT 40% - begin - set -lx FZF_DEFAULT_OPTS "--height $FZF_TMUX_HEIGHT $FZF_DEFAULT_OPTS --scheme=history --bind=ctrl-r:toggle-sort,ctrl-z:ignore $FZF_CTRL_R_OPTS +m" + function fzf-cd-widget -d "Change directory" + set -l commandline (__fzf_parse_commandline) + set -l dir $commandline[1] + set -l fzf_query $commandline[2] + set -l prefix $commandline[3] - set -l FISH_MAJOR (echo $version | cut -f1 -d.) - set -l FISH_MINOR (echo $version | cut -f2 -d.) - - # history's -z flag is needed for multi-line support. - # history's -z flag was added in fish 2.4.0, so don't use it for versions - # before 2.4.0. - if [ "$FISH_MAJOR" -gt 2 -o \( "$FISH_MAJOR" -eq 2 -a "$FISH_MINOR" -ge 4 \) ]; - history -z | eval (__fzfcmd) --read0 --print0 -q '(commandline)' | read -lz result - and commandline -- $result - else - history | eval (__fzfcmd) -q '(commandline)' | read -l result - and commandline -- $result - end - end - commandline -f repaint - end - - function fzf-cd-widget -d "Change directory" - set -l commandline (__fzf_parse_commandline) - set -l dir $commandline[1] - set -l fzf_query $commandline[2] - set -l prefix $commandline[3] - - test -n "$FZF_ALT_C_COMMAND"; or set -l FZF_ALT_C_COMMAND " + test -n "$FZF_ALT_C_COMMAND"; or set -l FZF_ALT_C_COMMAND " command find -L \$dir -mindepth 1 \\( -path \$dir'*/\\.*' -o -fstype 'sysfs' -o -fstype 'devfs' -o -fstype 'devtmpfs' \\) -prune \ -o -type d -print 2> /dev/null | sed 's@^\./@@'" - test -n "$FZF_TMUX_HEIGHT"; or set FZF_TMUX_HEIGHT 40% - begin - set -lx FZF_DEFAULT_OPTS "--height $FZF_TMUX_HEIGHT --reverse --bind=ctrl-z:ignore $FZF_DEFAULT_OPTS $FZF_ALT_C_OPTS" - eval "$FZF_ALT_C_COMMAND | "(__fzfcmd)' +m --query "'$fzf_query'"' | read -l result + test -n "$FZF_TMUX_HEIGHT"; or set FZF_TMUX_HEIGHT 40% + begin + set -lx FZF_DEFAULT_OPTS "--height $FZF_TMUX_HEIGHT --reverse --bind=ctrl-z:ignore $FZF_DEFAULT_OPTS $FZF_ALT_C_OPTS" + eval "$FZF_ALT_C_COMMAND | "(__fzfcmd)' +m --query "'$fzf_query'"' | read -l result - if [ -n "$result" ] - cd -- $result + if [ -n "$result" ] + cd -- $result - # Remove last token from commandline. - commandline -t "" - commandline -it -- $prefix - end + # Remove last token from commandline. + commandline -t "" + commandline -it -- $prefix + end + end + + commandline -f repaint end - commandline -f repaint - end - - function __fzfcmd - test -n "$FZF_TMUX"; or set FZF_TMUX 0 - test -n "$FZF_TMUX_HEIGHT"; or set FZF_TMUX_HEIGHT 40% - if [ -n "$FZF_TMUX_OPTS" ] - echo "fzf-tmux $FZF_TMUX_OPTS -- " - else if [ $FZF_TMUX -eq 1 ] - echo "fzf-tmux -d$FZF_TMUX_HEIGHT -- " - else - echo "fzf" - end - end - - bind \ct fzf-file-widget - bind \cr fzf-history-widget - bind \ec fzf-cd-widget - - if bind -M insert > /dev/null 2>&1 - bind -M insert \ct fzf-file-widget - bind -M insert \cr fzf-history-widget - bind -M insert \ec fzf-cd-widget - end - - function __fzf_parse_commandline -d 'Parse the current command line token and return split of existing filepath, fzf query, and optional -option= prefix' - set -l commandline (commandline -t) - - # strip -option= from token if present - set -l prefix (string match -r -- '^-[^\s=]+=' $commandline) - set commandline (string replace -- "$prefix" '' $commandline) - - # eval is used to do shell expansion on paths - eval set commandline $commandline - - if [ -z $commandline ] - # Default to current directory with no --query - set dir '.' - set fzf_query '' - else - set dir (__fzf_get_dir $commandline) - - if [ "$dir" = "." -a (string sub -l 1 -- $commandline) != '.' ] - # if $dir is "." but commandline is not a relative path, this means no file path found - set fzf_query $commandline - else - # Also remove trailing slash after dir, to "split" input properly - set fzf_query (string replace -r "^$dir/?" -- '' "$commandline") - end + function __fzfcmd + test -n "$FZF_TMUX"; or set FZF_TMUX 0 + test -n "$FZF_TMUX_HEIGHT"; or set FZF_TMUX_HEIGHT 40% + if [ -n "$FZF_TMUX_OPTS" ] + echo "fzf-tmux $FZF_TMUX_OPTS -- " + else if [ $FZF_TMUX -eq 1 ] + echo "fzf-tmux -d$FZF_TMUX_HEIGHT -- " + else + echo fzf + end end - echo $dir - echo $fzf_query - echo $prefix - end + bind \ct fzf-file-widget + bind \cr fzf-history-widget + bind \ec fzf-cd-widget - function __fzf_get_dir -d 'Find the longest existing filepath from input string' - set dir $argv - - # Strip all trailing slashes. Ignore if $dir is root dir (/) - if [ (string length -- $dir) -gt 1 ] - set dir (string replace -r '/*$' -- '' $dir) + if bind -M insert >/dev/null 2>&1 + bind -M insert \ct fzf-file-widget + bind -M insert \cr fzf-history-widget + bind -M insert \ec fzf-cd-widget end - # Iteratively check if dir exists and strip tail end of path - while [ ! -d "$dir" ] - # If path is absolute, this can keep going until ends up at / - # If path is relative, this can keep going until entire input is consumed, dirname returns "." - set dir (dirname -- "$dir") + function __fzf_parse_commandline -d 'Parse the current command line token and return split of existing filepath, fzf query, and optional -option= prefix' + set -l commandline (commandline -t) + + # strip -option= from token if present + set -l prefix (string match -r -- '^-[^\s=]+=' $commandline) + set commandline (string replace -- "$prefix" '' $commandline) + + # eval is used to do shell expansion on paths + eval set commandline $commandline + + if [ -z $commandline ] + # Default to current directory with no --query + set dir '.' + set fzf_query '' + else + set dir (__fzf_get_dir $commandline) + + if [ "$dir" = "." -a (string sub -l 1 -- $commandline) != '.' ] + # if $dir is "." but commandline is not a relative path, this means no file path found + set fzf_query $commandline + else + # Also remove trailing slash after dir, to "split" input properly + set fzf_query (string replace -r "^$dir/?" -- '' "$commandline") + end + end + + echo $dir + echo $fzf_query + echo $prefix end - echo $dir - end + function __fzf_get_dir -d 'Find the longest existing filepath from input string' + set dir $argv + + # Strip all trailing slashes. Ignore if $dir is root dir (/) + if [ (string length -- $dir) -gt 1 ] + set dir (string replace -r '/*$' -- '' $dir) + end + + # Iteratively check if dir exists and strip tail end of path + while [ ! -d "$dir" ] + # If path is absolute, this can keep going until ends up at / + # If path is relative, this can keep going until entire input is consumed, dirname returns "." + set dir (dirname -- "$dir") + end + + echo $dir + end end diff --git a/config/fzf/key-bindings.zsh b/config/fzf/key-bindings.zsh old mode 100755 new mode 100644 index dfb473c..5c95782 --- a/config/fzf/key-bindings.zsh +++ b/config/fzf/key-bindings.zsh @@ -1,3 +1,4 @@ +# shellcheck disable=all # ____ ____ # / __/___ / __/ # / /_/_ / / /_ diff --git a/config/karabiner/karabiner.json b/config/karabiner/karabiner.json index 2e6943b..fd82513 100644 --- a/config/karabiner/karabiner.json +++ b/config/karabiner/karabiner.json @@ -1,68 +1,68 @@ { - "profiles": [ + "profiles": [ + { + "complex_modifications": { + "rules": [ + { + "description": "Change right_command+hjkl to arrow keys", + "manipulators": [ + { + "from": { + "key_code": "h", + "modifiers": { + "mandatory": ["right_command"], + "optional": ["any"] + } + }, + "to": [{ "key_code": "left_arrow" }], + "type": "basic" + }, + { + "from": { + "key_code": "j", + "modifiers": { + "mandatory": ["right_command"], + "optional": ["any"] + } + }, + "to": [{ "key_code": "down_arrow" }], + "type": "basic" + }, + { + "from": { + "key_code": "k", + "modifiers": { + "mandatory": ["right_command"], + "optional": ["any"] + } + }, + "to": [{ "key_code": "up_arrow" }], + "type": "basic" + }, + { + "from": { + "key_code": "l", + "modifiers": { + "mandatory": ["right_command"], + "optional": ["any"] + } + }, + "to": [{ "key_code": "right_arrow" }], + "type": "basic" + } + ] + } + ] + }, + "name": "Default profile", + "selected": true, + "simple_modifications": [ { - "complex_modifications": { - "rules": [ - { - "description": "Change right_command+hjkl to arrow keys", - "manipulators": [ - { - "from": { - "key_code": "h", - "modifiers": { - "mandatory": ["right_command"], - "optional": ["any"] - } - }, - "to": [{ "key_code": "left_arrow" }], - "type": "basic" - }, - { - "from": { - "key_code": "j", - "modifiers": { - "mandatory": ["right_command"], - "optional": ["any"] - } - }, - "to": [{ "key_code": "down_arrow" }], - "type": "basic" - }, - { - "from": { - "key_code": "k", - "modifiers": { - "mandatory": ["right_command"], - "optional": ["any"] - } - }, - "to": [{ "key_code": "up_arrow" }], - "type": "basic" - }, - { - "from": { - "key_code": "l", - "modifiers": { - "mandatory": ["right_command"], - "optional": ["any"] - } - }, - "to": [{ "key_code": "right_arrow" }], - "type": "basic" - } - ] - } - ] - }, - "name": "Default profile", - "selected": true, - "simple_modifications": [ - { - "from": { "key_code": "caps_lock" }, - "to": [{ "key_code": "f18" }] - } - ], - "virtual_hid_keyboard": { "keyboard_type_v2": "iso" } + "from": { "key_code": "caps_lock" }, + "to": [{ "key_code": "f18" }] } - ] -} \ No newline at end of file + ], + "virtual_hid_keyboard": { "keyboard_type_v2": "iso" } + } + ] +} diff --git a/config/nvim/lua/plugins/neotree.lua b/config/nvim/lua/plugins/neotree.lua index bfb029b..407e1c6 100644 --- a/config/nvim/lua/plugins/neotree.lua +++ b/config/nvim/lua/plugins/neotree.lua @@ -55,7 +55,8 @@ return { { event = 'file_opened', handler = function(_) - require('neo-tree.command').execute { action = 'close' } + local c = require 'neo-tree.command' + c.execute { action = 'close' } end, }, }, diff --git a/config/sesh/sesh.toml b/config/sesh/sesh.toml index b617d2a..2cc11d8 100644 --- a/config/sesh/sesh.toml +++ b/config/sesh/sesh.toml @@ -56,4 +56,3 @@ disable_startup_command = true name = "Downloads" path = "~/Downloads" startup_command = "lsa" - diff --git a/config/tmux/theme-dark.conf b/config/tmux/theme-dark.conf index b392f5e..397f45e 100644 --- a/config/tmux/theme-dark.conf +++ b/config/tmux/theme-dark.conf @@ -1,2 +1 @@ set -g @catppuccin_flavor "mocha" - diff --git a/config/zsh/plugins/nvm-auto-use/nvm-auto-use.plugin.zsh b/config/zsh/plugins/nvm-auto-use/nvm-auto-use.plugin.zsh index 8610962..b0c11d7 100644 --- a/config/zsh/plugins/nvm-auto-use/nvm-auto-use.plugin.zsh +++ b/config/zsh/plugins/nvm-auto-use/nvm-auto-use.plugin.zsh @@ -1,4 +1,4 @@ -# shellcheck shell=zsh +# shellcheck disable=SC1071,SC1103,SC2148 # Source: https://github.com/nvm-sh/nvm#zsh # place this after nvm initialization! autoload -U add-zsh-hook diff --git a/cspell.config.yaml b/cspell.config.yaml new file mode 100644 index 0000000..6314a8b --- /dev/null +++ b/cspell.config.yaml @@ -0,0 +1,52 @@ +version: "0.2" +ignorePaths: [] +dictionaryDefinitions: [] +dictionaries: [] +words: + - aquasec + - cdgr + - cheatsheets + - CODEQUALITY + - DEVSKIM + - dscacheutil + - emptytrash + - flushcache + - getifaddr + - goenv + - irssi + - Ismo + - isodate + - KEYSFILE + - KEYSSOURCE + - killall + - lakka + - libexec + - Licence + - lmstudio + - localip + - locatedb + - LOGFILE + - luarocks + - mvdan + - myip + - onnimonni + - opencode + - optstring + - orbstack + - osascript + - phpenv + - psub + - pyenv + - SARIF + - shellcheck + - shfmt + - shivammathur + - spelllang + - updatedb + - vendordirs + - vimrc + - virtualenv + - Vuorinen + - zedit +ignoreWords: [] +import: [] diff --git a/docs/tmux-keybindings.md b/docs/tmux-keybindings.md index d80ed66..604c773 100644 --- a/docs/tmux-keybindings.md +++ b/docs/tmux-keybindings.md @@ -33,7 +33,7 @@ Leader: `` ? List key bindings D Choose and detach a client from a list E Spread panes out evenly - L last-session (via sesh) + L last-session (via sesh) M Clear the marked pane N sesh ui T tms @@ -87,4 +87,3 @@ Leader: `` S-Left Move the visible part of the window left S-Right Move the visible part of the window right ``` - diff --git a/local/bin/a b/local/bin/a index f46f687..22ab5a4 100755 --- a/local/bin/a +++ b/local/bin/a @@ -103,9 +103,9 @@ fetch_keys_if_missing() if [[ ! -f "$KEYS_FILE" ]]; then log_message "Keys file '$KEYS_FILE' not found. Attempting to fetch from $KEYS_SOURCE..." mkdir -p "$(dirname "$KEYS_FILE")" - curl -s "$KEYS_SOURCE" -o "$KEYS_FILE" - if [[ $? -ne 0 || ! -s "$KEYS_FILE" ]]; then + if ! curl -s "$KEYS_SOURCE" -o "$KEYS_FILE" || [[ ! -s "$KEYS_FILE" ]]; then + rm -f "$KEYS_FILE" 2> /dev/null || true log_message "Error: Failed to fetch keys from $KEYS_SOURCE" exit 1 fi @@ -126,10 +126,12 @@ encrypt_file_or_directory() elif [[ -f "$file" ]]; then fetch_keys_if_missing local output_file="${file}.age" - age -R "$KEYS_FILE" "$file" > "$output_file" - if [[ $? -eq 0 ]]; then + local temp_file + temp_file="$(mktemp -p "$(dirname "$file")")" + if age -R "$KEYS_FILE" "$file" > "$temp_file" && mv "$temp_file" "$output_file"; then log_message "File encrypted successfully: $output_file" else + rm -f "$temp_file" log_message "Error: Failed to encrypt file '$file'." exit 1 fi @@ -147,10 +149,12 @@ decrypt_file_or_directory() elif [[ -f "$file" ]]; then fetch_keys_if_missing local output_file="${file%.age}" - age -d -i "$KEYS_FILE" "$file" > "$output_file" - if [[ $? -eq 0 ]]; then + local temp_file + temp_file="$(mktemp -p "$(dirname "$file")")" + if age -d -i "$KEYS_FILE" "$file" > "$temp_file" && mv "$temp_file" "$output_file"; then log_message "File decrypted successfully: $output_file" else + rm -f "$temp_file" log_message "Error: Failed to decrypt file '$file'." exit 1 fi diff --git a/local/bin/ad b/local/bin/ad index eb81115..f932446 100755 --- a/local/bin/ad +++ b/local/bin/ad @@ -36,9 +36,8 @@ if [[ ! -f "$KEYS_FILE" ]]; then mkdir -p "$(dirname "$KEYS_FILE")" # Fetch the keys and save to the file - curl -s "$KEYS_SOURCE" -o "$KEYS_FILE" - - if [[ $? -ne 0 || ! -s "$KEYS_FILE" ]]; then + if ! curl -s "$KEYS_SOURCE" -o "$KEYS_FILE" || [[ ! -s "$KEYS_FILE" ]]; then + rm -f "$KEYS_FILE" 2> /dev/null || true echo "Error: Failed to fetch keys from $KEYS_SOURCE" exit 1 fi @@ -50,11 +49,11 @@ fi # Decrypt the file OUTPUT_FILE="${FILE%.age}" -age -d -i "$KEYS_FILE" "$FILE" > "$OUTPUT_FILE" - -if [[ $? -eq 0 ]]; then +TEMP_FILE="$(mktemp -p "$(dirname "$OUTPUT_FILE")")" +if age -d -i "$KEYS_FILE" "$FILE" > "$TEMP_FILE" && mv "$TEMP_FILE" "$OUTPUT_FILE"; then echo "File decrypted successfully: $OUTPUT_FILE" else + rm -f "$TEMP_FILE" echo "Error: Failed to decrypt file." exit 1 fi diff --git a/local/bin/ae b/local/bin/ae index 400b109..3ed6593 100755 --- a/local/bin/ae +++ b/local/bin/ae @@ -37,9 +37,7 @@ if [[ ! -f "$KEYS_FILE" ]]; then mkdir -p "$(dirname "$KEYS_FILE")" # Fetch the keys and save to the file - curl -s "$KEYS_SOURCE" -o "$KEYS_FILE" - - if [[ $? -ne 0 || ! -s "$KEYS_FILE" ]]; then + if ! curl -s "$KEYS_SOURCE" -o "$KEYS_FILE" || [[ ! -s "$KEYS_FILE" ]]; then echo "Error: Failed to fetch keys from $KEYS_SOURCE" exit 1 fi @@ -51,9 +49,7 @@ fi # Encrypt the file OUTPUT_FILE="${FILE}.age" -age -R "$KEYS_FILE" "$FILE" > "$OUTPUT_FILE" - -if [[ $? -eq 0 ]]; then +if age -R "$KEYS_FILE" "$FILE" > "$OUTPUT_FILE"; then echo "File encrypted successfully: $OUTPUT_FILE" else echo "Error: Failed to encrypt file." diff --git a/local/bin/dfm b/local/bin/dfm index 9812e2a..f19890a 100755 --- a/local/bin/dfm +++ b/local/bin/dfm @@ -25,6 +25,7 @@ source_file() case "$CURRENT_SHELL" in fish) if [[ -f "$file.fish" ]]; then + # shellcheck disable=SC1090 source "$file.fish" else echo "Fish shell file not found: $file.fish" @@ -32,6 +33,7 @@ source_file() fi ;; sh | bash | zsh) + # shellcheck disable=SC1090 source "$file" ;; *) diff --git a/local/bin/fzf-tmux b/local/bin/fzf-tmux index 8fe75c6..929241f 100755 --- a/local/bin/fzf-tmux +++ b/local/bin/fzf-tmux @@ -142,7 +142,7 @@ if [[ ! "$opt" =~ "-E" ]] && tmux list-panes -F '#F' | grep -q Z; then zoomed_without_popup=1 original_window=$(tmux display-message -p "#{window_id}") tmp_window=$(tmux new-window -d -P -F "#{window_id}" "bash -c 'while :; do for c in \\| / - '\\;' do sleep 0.2; printf \"\\r\$c fzf-tmux is running\\r\"; done; done'") - tmux swap-pane -t $tmp_window \; select-window -t $tmp_window + tmux swap-pane -t "$tmp_window" \; select-window -t "$tmp_window" fi set -e @@ -154,15 +154,16 @@ fifo1="${TMPDIR:-/tmp}/fzf-fifo1-$id" fifo2="${TMPDIR:-/tmp}/fzf-fifo2-$id" fifo3="${TMPDIR:-/tmp}/fzf-fifo3-$id" if tmux_win_opts=$(tmux show-options -p remain-on-exit \; show-options -p synchronize-panes 2> /dev/null); then - tmux_win_opts=($(sed '/ off/d; s/synchronize-panes/set-option -p synchronize-panes/; s/remain-on-exit/set-option -p remain-on-exit/; s/$/ \\;/' <<< "$tmux_win_opts")) + mapfile -t tmux_win_opts < <(sed '/ off/d; s/synchronize-panes/set-option -p synchronize-panes/; s/remain-on-exit/set-option -p remain-on-exit/; s/$/ \\;/' <<< "$tmux_win_opts") tmux_off_opts='; set-option -p synchronize-panes off ; set-option -p remain-on-exit off' else - tmux_win_opts=($(tmux show-window-options remain-on-exit \; show-window-options synchronize-panes | sed '/ off/d; s/^/set-window-option /; s/$/ \\;/')) + mapfile -t tmux_win_opts < <(tmux show-window-options remain-on-exit \; show-window-options synchronize-panes | sed '/ off/d; s/^/set-window-option /; s/$/ \\;/') tmux_off_opts='; set-window-option synchronize-panes off ; set-window-option remain-on-exit off' fi +# shellcheck disable=SC2329 cleanup() { - \rm -f $argsf $fifo1 $fifo2 $fifo3 + \rm -f "$argsf" "$fifo1" "$fifo2" "$fifo3" # Restore tmux window options if [[ "${#tmux_win_opts[@]}" -gt 0 ]]; then @@ -172,9 +173,9 @@ cleanup() # Remove temp window if we were zoomed without popup options if [[ -n "$zoomed_without_popup" ]]; then tmux display-message -p "#{window_id}" > /dev/null - tmux swap-pane -t $original_window \; \ - select-window -t $original_window \; \ - kill-window -t $tmp_window \; \ + tmux swap-pane -t "$original_window" \; \ + select-window -t "$original_window" \; \ + kill-window -t "$tmp_window" \; \ resize-pane -Z fi @@ -209,39 +210,40 @@ echo "$envs;" > "$argsf" opts=$(printf "%q " "${args[@]}") pppid=$$ -echo -n "trap 'kill -SIGUSR1 -$pppid' EXIT SIGINT SIGTERM;" >> $argsf +echo -n "trap 'kill -SIGUSR1 -$pppid' EXIT SIGINT SIGTERM;" >> "$argsf" close="; trap - EXIT SIGINT SIGTERM $close" -export TMUX=$(cut -d , -f 1,2 <<< "$TMUX") -mkfifo -m o+w $fifo2 +export TMUX +TMUX=$(cut -d , -f 1,2 <<< "$TMUX") +mkfifo -m o+w "$fifo2" if [[ "$opt" =~ "-E" ]]; then - cat $fifo2 & + cat "$fifo2" & if [[ -n "$term" ]] || [[ -t 0 ]]; then - cat <<< "\"$fzf\" $opts > $fifo2; out=\$? $close; exit \$out" >> $argsf + cat <<< "\"$fzf\" $opts > $fifo2; out=\$? $close; exit \$out" >> "$argsf" else - mkfifo $fifo1 - cat <<< "\"$fzf\" $opts < $fifo1 > $fifo2; out=\$? $close; exit \$out" >> $argsf - cat <&0 > $fifo1 & + mkfifo "$fifo1" + cat <<< "\"$fzf\" $opts < $fifo1 > $fifo2; out=\$? $close; exit \$out" >> "$argsf" + cat <&0 > "$fifo1" & fi - tmux popup -d "$PWD" $opt "bash $argsf" > /dev/null 2>&1 + tmux popup -d "$PWD" "$opt" "bash $argsf" > /dev/null 2>&1 exit $? fi -mkfifo -m o+w $fifo3 +mkfifo -m o+w "$fifo3" if [[ -n "$term" ]] || [[ -t 0 ]]; then - cat <<< "\"$fzf\" $opts > $fifo2; echo \$? > $fifo3 $close" >> $argsf + cat <<< "\"$fzf\" $opts > $fifo2; echo \$? > $fifo3 $close" >> "$argsf" else - mkfifo $fifo1 - cat <<< "\"$fzf\" $opts < $fifo1 > $fifo2; echo \$? > $fifo3 $close" >> $argsf - cat <&0 > $fifo1 & + mkfifo "$fifo1" + cat <<< "\"$fzf\" $opts < $fifo1 > $fifo2; echo \$? > $fifo3 $close" >> "$argsf" + cat <&0 > "$fifo1" & fi tmux \ - split-window -c "$PWD" $opt "bash -c 'exec -a fzf bash $argsf'" $swap \ - $tmux_off_opts \ + split-window -c "$PWD" "$opt" "bash -c 'exec -a fzf bash $argsf'" "$swap" \ + "$tmux_off_opts" \ > /dev/null 2>&1 || { "$fzf" "${args[@]}" exit $? } -cat $fifo2 -exit "$(cat $fifo3)" +cat "$fifo2" +exit "$(cat "$fifo3")" diff --git a/local/bin/git-attributes b/local/bin/git-attributes index d0ffbd9..84e378d 100755 --- a/local/bin/git-attributes +++ b/local/bin/git-attributes @@ -25,27 +25,27 @@ fi # Output functions msg_err() { - echo -e "\e[31m$@\e[0m" >&2 + echo -e "\e[31m$*\e[0m" >&2 } msg_success() { - echo -e "\e[32m$@\e[0m" + echo -e "\e[32m$*\e[0m" } msg_warn() { - echo -e "\e[33m$@\e[0m" >&2 + echo -e "\e[33m$*\e[0m" >&2 } msg_info() { - echo -e "\e[36m$@\e[0m" + echo -e "\e[36m$*\e[0m" } msg_debug() { - [[ $VERBOSE -eq 1 ]] && echo -e "\e[35m$@\e[0m" + [[ $VERBOSE -eq 1 ]] && echo -e "\e[35m$*\e[0m" } show_help() @@ -180,7 +180,8 @@ format_rule() get_file_extension() { local file="$1" - local basename=$(basename "$file") + local basename + basename=$(basename "$file") local extension="" # Check if file has no extension or is a dotfile @@ -231,8 +232,8 @@ suggest_rule() # If file path contains .d/ pattern, we need special handling if [[ "$file" =~ \.d/ ]]; then # Extract the pattern part that includes the .d/ directory - local dir_part=$(dirname "$file") - local base_name=$(basename "$file") + local dir_part + dir_part=$(dirname "$file") # Check if it's a config directory pattern worth capturing if [[ "$dir_part" =~ /(\.d|[^/]+\.d)$ ]]; then @@ -430,7 +431,8 @@ detect_shell_scripts() fi # Skip if file extension already covered - local extension=$(get_file_extension "$rel_path") + local extension + extension=$(get_file_extension "$rel_path") if [[ "$extension" != "$rel_path" ]] && grep -q "^\*\.$extension " <<< "$existing_rules"; then msg_debug "Script covered by extension rule: $rel_path (*.$extension)" continue @@ -458,7 +460,8 @@ detect_shell_scripts() fi # Group by directory - local dir=$(dirname "$rel_path") + local dir + dir=$(dirname "$rel_path") if [[ "$dir" == "." ]]; then dir="root" fi @@ -480,7 +483,8 @@ detect_shell_scripts() # Check if we can use directory-based rules instead of individual files for dir in "${!scripts_by_dir[@]}"; do - local files_in_dir=$(echo -e "${scripts_by_dir[$dir]}" | wc -l) + local files_in_dir + files_in_dir=$(echo -e "${scripts_by_dir[$dir]}" | wc -l) local dir_path="$dir" if [[ "$dir" == "root" ]]; then @@ -575,7 +579,8 @@ suggest_gitattributes() declare -A seen_patterns=() while IFS= read -r file; do - local suggestion=$(suggest_rule "$file") + local suggestion + suggestion=$(suggest_rule "$file") if [[ -n "$suggestion" ]]; then IFS=':' read -r pattern attributes <<< "$suggestion" @@ -639,7 +644,8 @@ suggest_gitattributes() formatted_suggestions+="$pattern\n" echo "$pattern" else - local formatted_rule=$(printf "%-${format_width}s %s\n" "$pattern" "$attributes") + local formatted_rule + formatted_rule=$(printf "%-${format_width}s %s\n" "$pattern" "$attributes") formatted_suggestions+="$formatted_rule\n" echo "$formatted_rule" fi diff --git a/local/bin/iterm2_shell_integration.zsh b/local/bin/iterm2_shell_integration.zsh old mode 100755 new mode 100644 index b290510..64c8a73 --- a/local/bin/iterm2_shell_integration.zsh +++ b/local/bin/iterm2_shell_integration.zsh @@ -1,3 +1,4 @@ +# shellcheck disable=all # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 diff --git a/local/bin/pushover b/local/bin/pushover index 7c081ca..ddab8b9 100755 --- a/local/bin/pushover +++ b/local/bin/pushover @@ -142,7 +142,7 @@ if [ ! -x "${CURL}" ]; then exit 1 fi -devices="$(printf "${devices}" | xargs -n1 | sort -u | uniq)\n" +devices="$(printf "%s" "${devices}" | xargs -n1 | sort -u)" if [ -z "${devices}" ]; then __pushover_send_message diff --git a/local/bin/x-env-list b/local/bin/x-env-list index 082bfe2..0c6a30e 100755 --- a/local/bin/x-env-list +++ b/local/bin/x-env-list @@ -126,11 +126,11 @@ if [[ -f "$CONFIG_FILE" ]]; then PROTECTED_KEYS+=("$key") done <<< "$CUSTOM_KEYS" - SKIPPED+=("$(yq '.skipped_keys[]' "$CONFIG_FILE")") - while IFS= read -r key; do + mapfile -t SKIPPED < <(yq '.skipped_keys[]' "$CONFIG_FILE") + for key in "${SKIPPED[@]}"; do # Add to default_skipped_keys SKIPPED_KEYS+=("$key") - done <<< "$SKIPPED" + done CUSTOM_GROUPS=$(yq '.custom_grouping[]' "$CONFIG_FILE") while IFS= read -r group; do @@ -159,6 +159,7 @@ is_protected() return 0 fi # Wildcard match (protected_key contains '*') + # shellcheck disable=SC2053 # Intentional glob matching - protected_key contains wildcard patterns if [[ "$protected_key" == *"*"* ]] && [[ "$key" == $protected_key ]]; then return 0 fi @@ -198,6 +199,7 @@ is_skipped() return 0 fi # Wildcard match (skipped_key contains '*') + # shellcheck disable=SC2053 # Intentional glob matching - skipped_key contains wildcard patterns if [[ "$skipped_key" == *"*"* ]] && [[ "$key" == $skipped_key ]]; then return 0 fi @@ -244,8 +246,15 @@ while IFS='=' read -r key value; do value="[protected value]" fi - # Update group data - if [[ ! " ${all_groups[*]} " =~ " $group " ]]; then + # Update group data - check if group already exists + group_exists=false + for existing_group in "${all_groups[@]}"; do + if [[ "$existing_group" == "$group" ]]; then + group_exists=true + break + fi + done + if [[ "$group_exists" == false ]]; then all_groups+=("$group") fi diff --git a/local/bin/x-load-configs b/local/bin/x-load-configs index e193e67..36e98cb 100755 --- a/local/bin/x-load-configs +++ b/local/bin/x-load-configs @@ -30,10 +30,9 @@ config_msg() { # if $1 is empty, return [ -z "$1" ] && return - [ -z "$2" ] && $2="" local msg_type="$1" - local msg_content="$2" + local msg_content="${2:-}" [[ "$VERBOSE" -eq 1 ]] && printf 'x-load-configs: %s %s\n' "$msg_type" "$msg_content" return 0 } @@ -50,7 +49,8 @@ source_config() { local config_file=$1 if [ -f "$config_file" ]; then - eval "$config_file" + # shellcheck disable=SC1090 + source "$config_file" config_msg "Sourced" "$config_file" else msg "Config file $config_file not found" diff --git a/local/bin/x-pr-comments b/local/bin/x-pr-comments index e9087e7..15e6aa2 100755 --- a/local/bin/x-pr-comments +++ b/local/bin/x-pr-comments @@ -60,7 +60,7 @@ log_debug() filter_coderabbit_addressed_comments() { local input_data="$1" - local is_wrapped="$2" # true for {comments: [...]}, false for [...] + local is_wrapped="$2" # true for {comments: [...]}, false for [...] local jq_filter='select( (.user.login | contains("coderabbit") | not) or @@ -68,9 +68,9 @@ filter_coderabbit_addressed_comments() )' if [[ "$is_wrapped" == "true" ]]; then - echo "$input_data" | jq "{comments: [.comments[] | $jq_filter]}" 2>/dev/null || echo "$input_data" + echo "$input_data" | jq "{comments: [.comments[] | $jq_filter]}" 2> /dev/null || echo "$input_data" else - echo "$input_data" | jq "[.[] | $jq_filter]" 2>/dev/null || echo "$input_data" + echo "$input_data" | jq "[.[] | $jq_filter]" 2> /dev/null || echo "$input_data" fi } @@ -79,13 +79,13 @@ fetch_and_filter_data() { local endpoint="$1" local data_name="$2" - local is_wrapped="$3" # true/false + local is_wrapped="$3" # true/false local data - data=$(gh api "$endpoint" 2>/dev/null || echo "[]") + data=$(gh api "$endpoint" 2> /dev/null || echo "[]") if [[ "$is_wrapped" == "true" ]]; then - data=$(echo "$data" | jq '{comments: .}' 2>/dev/null || echo '{"comments":[]}') + data=$(echo "$data" | jq '{comments: .}' 2> /dev/null || echo '{"comments":[]}') fi data=$(filter_coderabbit_addressed_comments "$data" "$is_wrapped") @@ -94,14 +94,12 @@ fetch_and_filter_data() [[ "$is_wrapped" == "true" ]] && count_field=".comments | length" local count - count=$(echo "$data" | jq -r "$count_field" 2>/dev/null || echo "0") + count=$(echo "$data" | jq -r "$count_field" 2> /dev/null || echo "0") log_debug "$data_name count: $count" echo "$data" } - - # Format file-specific comments grouped by review format_grouped_review_comments() { @@ -110,7 +108,7 @@ format_grouped_review_comments() local repo="$3" local count - count=$(echo "$review_comments" | jq -r 'length' 2>/dev/null || echo "0") + count=$(echo "$review_comments" | jq -r 'length' 2> /dev/null || echo "0") if [[ "$count" -eq 0 ]]; then echo "No file-specific comments found." @@ -143,7 +141,7 @@ Review ID: \($review.id) - API: gh api /repos/'"$repo"'/pulls/1/reviews/\($revie "] | join("")) + " --- " - ' 2>/dev/null || { + ' 2> /dev/null || { log_debug "Error grouping review comments by review ID" echo "Error parsing grouped review comments." } @@ -244,7 +242,7 @@ EOF **URL:** \(.url) **Number:** '"$pr_number"' **Repository:** '"$repo"' -"' 2>/dev/null || { +"' 2> /dev/null || { echo "**Error:** Could not parse PR information" return 1 } diff --git a/local/bin/x-ssh-audit b/local/bin/x-ssh-audit old mode 100644 new mode 100755 index df488a0..5e1a83e --- a/local/bin/x-ssh-audit +++ b/local/bin/x-ssh-audit @@ -350,7 +350,7 @@ ssh_with_retry() log_message "INFO" "Trying SSH agent/default authentication" fi - # shellcheck disable=SC2086 + # shellcheck disable=SC2086,SC2029 if ssh $ssh_opts "${username}@${host}" "$command" 2> /dev/null; then if [ "$try_key" != "NO_KEY" ]; then log_message "SUCCESS" "Connected using SSH key: $try_key" diff --git a/local/bin/x-ssl-expiry-date b/local/bin/x-ssl-expiry-date index 7073922..f4f0b8d 100755 --- a/local/bin/x-ssl-expiry-date +++ b/local/bin/x-ssl-expiry-date @@ -52,17 +52,18 @@ fi for name in "$@"; do # Make a temporary file - # Test if we have BSD or GNU version of mktemp - if (strings "$(which mktemp)" | grep -q GNU); then - # We have the GNU version - tmp=$(mktemp) + # Try GNU syntax first, fall back to BSD + if tmp=$(mktemp 2> /dev/null) && [ -f "$tmp" ]; then + # GNU mktemp succeeded + : else - # We have the BSD version + # Try BSD syntax tmp=$(mktemp -t tmp) fi # Download the certificate if (! echo "" | openssl s_client -connect "$name:$port" > "$tmp" 2> /dev/null); then + rm -f "$tmp" echo "Failed to get cert from https://$name:$port/" exit 3 fi @@ -74,26 +75,26 @@ for name in "$@"; do rm -f "$tmp" # Convert the expiry date + todays date to seconds-past epoch - # Check if we have the BSD or the GNU version of date - if (strings "$(which date)" | grep -q GNU); then - # We have GNU this is easy - then=$(date --date "$date" +%s) + # Try GNU syntax first, fall back to BSD + if then=$(date --date "$date" +%s 2> /dev/null); then + # GNU date succeeded + : else - # We have BSD now it is getting complicated + # BSD date requires manual parsing year=$(echo "$date" | awk '{print $4}') month=$(echo "$date" | awk '{print $1}') day=$(echo "$date" | awk '{print $2}') hour=$(echo "$date" | awk '{print $3}' | awk -F: '{print $1}') minute=$(echo "$date" | awk '{print $3}' | awk -F: '{print $2}') second=$(echo "$date" | awk '{print $3}' | awk -F: '{print $3}') - then=$(date -v${year}y -v${month} -v${day}d -v${hour}H -v${minute}M -v${second}S -u +%s) + then=$(date -v"${year}"y -v"${month}" -v"${day}"d -v"${hour}"H -v"${minute}"M -v"${second}"S -u +%s) fi now=$(date +%s) # Day diff diff=$(("$then" - "$now")) - diff=$($diff / 86400) + diff=$((diff / 86400)) # All done if [ "$days" = "1" ]; then diff --git a/local/bin/x-term-colors b/local/bin/x-term-colors index 9820e3e..507d8c6 100755 --- a/local/bin/x-term-colors +++ b/local/bin/x-term-colors @@ -24,10 +24,10 @@ resetOutput() # ranging between 0 and 255 inclusive rainbowColor() { - let h=$1/43 - let f=$1-43*$h - let t=$f*255/43 - let q=255-t + ((h = $1 / 43)) + ((f = $1 - 43 * h)) + ((t = f * 255 / 43)) + ((q = 255 - t)) if [ $h -eq 0 ]; then echo "255 $t 0" @@ -81,11 +81,13 @@ done resetOutput for i in $(seq 0 127); do + # shellcheck disable=SC2046 # Intentional word splitting to pass 3 RGB values as separate args setBackgroundColor $(rainbowColor "$i") echo -n " " done resetOutput for i in $(seq 255 128); do + # shellcheck disable=SC2046 # Intentional word splitting to pass 3 RGB values as separate args setBackgroundColor $(rainbowColor "$i") echo -n " " done diff --git a/local/bin/x-thumbgen b/local/bin/x-thumbgen index edc5f2a..683b860 100755 --- a/local/bin/x-thumbgen +++ b/local/bin/x-thumbgen @@ -126,8 +126,8 @@ parse_options() # Generate thumbnails recursively using find and filtering by MIME type generate_thumbnails() { - local source_dir=$1 - local output_dir=$2 + local source_dir="$1" + local output_dir="$2" # Ensure the output directory exists (create if necessary) if [ ! -d "$output_dir" ]; then @@ -144,7 +144,7 @@ generate_thumbnails() fi # Determine the relative path with respect to the source directory. - rel_path="${file#$source_dir/}" + rel_path="${file#"$source_dir"/}" dir="$(dirname "$rel_path")" base="$(basename "$rel_path")" filename="${base%.*}" diff --git a/package.json b/package.json index 4bcd96c..c0255f1 100644 --- a/package.json +++ b/package.json @@ -6,14 +6,13 @@ "doc": "docs" }, "scripts": { - "lint:markdown": "markdownlint -d .", - "fix:markdown": "markdownlint -df .", - "lint:prettier": "prettier . --check", - "fix:prettier": "prettier . --write", + "lint:biome": "biome check .", + "fix:biome": "biome check --write .", + "format": "biome format --write .", "test": "bash test-all.sh", "lint:ec": "ec -f gcc", - "lint": "yarn lint:markdown && yarn lint:prettier && yarn lint:ec", - "fix": "yarn fix:markdown && yarn fix:prettier" + "lint": "yarn lint:biome && yarn lint:ec", + "fix": "yarn fix:biome" }, "repository": { "type": "git", @@ -30,13 +29,11 @@ }, "homepage": "https://github.com/ivuorinen/dotfiles#readme", "devDependencies": { - "@ivuorinen/base-configs": "1.0.0", - "@types/node": "^24.10.1", - "bats": "^1.13.0", - "editorconfig-checker": "^6.1.1", - "markdownlint": "^0.40.0", - "prettier": "^3.7.4", - "typescript": "^5.9.3" + "@biomejs/biome": "^2.3.1", + "@types/node": "^24.0.1", + "bats": "^1.12.0", + "editorconfig-checker": "^6.1.0", + "typescript": "^5.8.3" }, "packageManager": "yarn@4.12.0" } diff --git a/yarn.lock b/yarn.lock index 8d1b578..81af95f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5,178 +5,122 @@ __metadata: version: 8 cacheKey: 10c0 -"@ivuorinen/base-configs@npm:1.0.0": - version: 1.0.0 - resolution: "@ivuorinen/base-configs@npm:1.0.0" - checksum: 10c0/399e36bb7352b9e2ad3d91a5632a312670349d7e0976336c6fe113137c6b8c97d92b0b3b05bbe26ea8b533d27406162a5d42889019d27657efe7f08dbb54d820 - languageName: node - linkType: hard - -"@types/debug@npm:^4.0.0": - version: 4.1.12 - resolution: "@types/debug@npm:4.1.12" +"@biomejs/biome@npm:^2.3.1": + version: 2.3.1 + resolution: "@biomejs/biome@npm:2.3.1" dependencies: - "@types/ms": "npm:*" - checksum: 10c0/5dcd465edbb5a7f226e9a5efd1f399c6172407ef5840686b73e3608ce135eeca54ae8037dcd9f16bdb2768ac74925b820a8b9ecc588a58ca09eca6acabe33e2f + "@biomejs/cli-darwin-arm64": "npm:2.3.1" + "@biomejs/cli-darwin-x64": "npm:2.3.1" + "@biomejs/cli-linux-arm64": "npm:2.3.1" + "@biomejs/cli-linux-arm64-musl": "npm:2.3.1" + "@biomejs/cli-linux-x64": "npm:2.3.1" + "@biomejs/cli-linux-x64-musl": "npm:2.3.1" + "@biomejs/cli-win32-arm64": "npm:2.3.1" + "@biomejs/cli-win32-x64": "npm:2.3.1" + dependenciesMeta: + "@biomejs/cli-darwin-arm64": + optional: true + "@biomejs/cli-darwin-x64": + optional: true + "@biomejs/cli-linux-arm64": + optional: true + "@biomejs/cli-linux-arm64-musl": + optional: true + "@biomejs/cli-linux-x64": + optional: true + "@biomejs/cli-linux-x64-musl": + optional: true + "@biomejs/cli-win32-arm64": + optional: true + "@biomejs/cli-win32-x64": + optional: true + bin: + biome: bin/biome + checksum: 10c0/3c644c095b4e9be54b8e93275d8a78bed766a3781b7b4c5c97fd1a736ae6bb3f1f440daa8ceaa1f8f929af711fcffd1cf754f5149315a4695e2b868e29f5d293 languageName: node linkType: hard -"@types/katex@npm:^0.16.0": - version: 0.16.7 - resolution: "@types/katex@npm:0.16.7" - checksum: 10c0/68dcb9f68a90513ec78ca0196a142e15c2a2c270b1520d752bafd47a99207115085a64087b50140359017d7e9c870b3c68e7e4d36668c9e348a9ef0c48919b5a +"@biomejs/cli-darwin-arm64@npm:2.3.1": + version: 2.3.1 + resolution: "@biomejs/cli-darwin-arm64@npm:2.3.1" + conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@types/ms@npm:*": - version: 2.1.0 - resolution: "@types/ms@npm:2.1.0" - checksum: 10c0/5ce692ffe1549e1b827d99ef8ff71187457e0eb44adbae38fdf7b9a74bae8d20642ee963c14516db1d35fa2652e65f47680fdf679dcbde52bbfadd021f497225 +"@biomejs/cli-darwin-x64@npm:2.3.1": + version: 2.3.1 + resolution: "@biomejs/cli-darwin-x64@npm:2.3.1" + conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@types/node@npm:^24.10.1": - version: 24.10.1 - resolution: "@types/node@npm:24.10.1" +"@biomejs/cli-linux-arm64-musl@npm:2.3.1": + version: 2.3.1 + resolution: "@biomejs/cli-linux-arm64-musl@npm:2.3.1" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@biomejs/cli-linux-arm64@npm:2.3.1": + version: 2.3.1 + resolution: "@biomejs/cli-linux-arm64@npm:2.3.1" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@biomejs/cli-linux-x64-musl@npm:2.3.1": + version: 2.3.1 + resolution: "@biomejs/cli-linux-x64-musl@npm:2.3.1" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@biomejs/cli-linux-x64@npm:2.3.1": + version: 2.3.1 + resolution: "@biomejs/cli-linux-x64@npm:2.3.1" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@biomejs/cli-win32-arm64@npm:2.3.1": + version: 2.3.1 + resolution: "@biomejs/cli-win32-arm64@npm:2.3.1" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@biomejs/cli-win32-x64@npm:2.3.1": + version: 2.3.1 + resolution: "@biomejs/cli-win32-x64@npm:2.3.1" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@types/node@npm:^24.0.1": + version: 24.2.1 + resolution: "@types/node@npm:24.2.1" dependencies: - undici-types: "npm:~7.16.0" - checksum: 10c0/d6bca7a78f550fbb376f236f92b405d676003a8a09a1b411f55920ef34286ee3ee51f566203920e835478784df52662b5b2af89159d9d319352e9ea21801c002 + undici-types: "npm:~7.10.0" + checksum: 10c0/439a3c7edf88a298e0c92e46f670234070b892589c3b06e82cc86c47a7e1cf220f4a4b4736ec6ac7e4b9e1c40d7b6d443a1e22f99dd17f13f9dd15de3b32011b languageName: node linkType: hard -"@types/unist@npm:^2.0.0": - version: 2.0.11 - resolution: "@types/unist@npm:2.0.11" - checksum: 10c0/24dcdf25a168f453bb70298145eb043cfdbb82472db0bc0b56d6d51cd2e484b9ed8271d4ac93000a80da568f2402e9339723db262d0869e2bf13bc58e081768d - languageName: node - linkType: hard - -"ansi-regex@npm:^6.0.1": - version: 6.2.2 - resolution: "ansi-regex@npm:6.2.2" - checksum: 10c0/05d4acb1d2f59ab2cf4b794339c7b168890d44dda4bf0ce01152a8da0213aca207802f930442ce8cd22d7a92f44907664aac6508904e75e038fa944d2601b30f - languageName: node - linkType: hard - -"bats@npm:^1.13.0": - version: 1.13.0 - resolution: "bats@npm:1.13.0" +"bats@npm:^1.12.0": + version: 1.12.0 + resolution: "bats@npm:1.12.0" bin: bats: bin/bats - checksum: 10c0/7f697d6305d80d328d620bd58c658f7830fbed57e28a43f18771d89fb6f941a131b440ab18d951fd15fdd23f3c687687d607d7fc03ac4c99f4725e64d2432832 + checksum: 10c0/fa601c7851e0e8bd773987e5b103e48348c63c630432a1d80e0f1849ca0133b22b3eab4f148566dac80b51b42e44db6c54f86a1021b87832a648f38b2501e3a8 languageName: node linkType: hard -"character-entities-legacy@npm:^3.0.0": - version: 3.0.0 - resolution: "character-entities-legacy@npm:3.0.0" - checksum: 10c0/ec4b430af873661aa754a896a2b55af089b4e938d3d010fad5219299a6b6d32ab175142699ee250640678cd64bdecd6db3c9af0b8759ab7b155d970d84c4c7d1 - languageName: node - linkType: hard - -"character-entities@npm:^2.0.0": - version: 2.0.2 - resolution: "character-entities@npm:2.0.2" - checksum: 10c0/b0c645a45bcc90ff24f0e0140f4875a8436b8ef13b6bcd31ec02cfb2ca502b680362aa95386f7815bdc04b6464d48cf191210b3840d7c04241a149ede591a308 - languageName: node - linkType: hard - -"character-reference-invalid@npm:^2.0.0": - version: 2.0.1 - resolution: "character-reference-invalid@npm:2.0.1" - checksum: 10c0/2ae0dec770cd8659d7e8b0ce24392d83b4c2f0eb4a3395c955dce5528edd4cc030a794cfa06600fcdd700b3f2de2f9b8e40e309c0011c4180e3be64a0b42e6a1 - languageName: node - linkType: hard - -"commander@npm:^8.3.0": - version: 8.3.0 - resolution: "commander@npm:8.3.0" - checksum: 10c0/8b043bb8322ea1c39664a1598a95e0495bfe4ca2fad0d84a92d7d1d8d213e2a155b441d2470c8e08de7c4a28cf2bc6e169211c49e1b21d9f7edc6ae4d9356060 - languageName: node - linkType: hard - -"debug@npm:^4.0.0": - version: 4.4.1 - resolution: "debug@npm:4.4.1" - dependencies: - ms: "npm:^2.1.3" - peerDependenciesMeta: - supports-color: - optional: true - checksum: 10c0/d2b44bc1afd912b49bb7ebb0d50a860dc93a4dd7d946e8de94abc957bb63726b7dd5aa48c18c2386c379ec024c46692e15ed3ed97d481729f929201e671fcd55 - languageName: node - linkType: hard - -"decode-named-character-reference@npm:^1.0.0": - version: 1.2.0 - resolution: "decode-named-character-reference@npm:1.2.0" - dependencies: - character-entities: "npm:^2.0.0" - checksum: 10c0/761a89de6b0e0a2d4b21ae99074e4cc3344dd11eb29f112e23cc5909f2e9f33c5ed20cd6b146b27fb78170bce0f3f9b3362a84b75638676a05c938c24a60f5d7 - languageName: node - linkType: hard - -"dequal@npm:^2.0.0": - version: 2.0.3 - resolution: "dequal@npm:2.0.3" - checksum: 10c0/f98860cdf58b64991ae10205137c0e97d384c3a4edc7f807603887b7c4b850af1224a33d88012009f150861cbee4fa2d322c4cc04b9313bee312e47f6ecaa888 - languageName: node - linkType: hard - -"devlop@npm:^1.0.0": - version: 1.1.0 - resolution: "devlop@npm:1.1.0" - dependencies: - dequal: "npm:^2.0.0" - checksum: 10c0/e0928ab8f94c59417a2b8389c45c55ce0a02d9ac7fd74ef62d01ba48060129e1d594501b77de01f3eeafc7cb00773819b0df74d96251cf20b31c5b3071f45c0e - languageName: node - linkType: hard - -"editorconfig-checker@npm:^6.1.1": - version: 6.1.1 - resolution: "editorconfig-checker@npm:6.1.1" +"editorconfig-checker@npm:^6.1.0": + version: 6.1.0 + resolution: "editorconfig-checker@npm:6.1.0" bin: ec: dist/index.js editorconfig-checker: dist/index.js - checksum: 10c0/0a46ce93e2821041c4b4bbf2ab9dc30e1b4eb03d3f20e5b14bbe45767f6f2aafd5e1310ea737c15402d8e193f702a421a814041e072584250e8a7d5e63d83741 - languageName: node - linkType: hard - -"get-east-asian-width@npm:^1.3.0": - version: 1.4.0 - resolution: "get-east-asian-width@npm:1.4.0" - checksum: 10c0/4e481d418e5a32061c36fbb90d1b225a254cc5b2df5f0b25da215dcd335a3c111f0c2023ffda43140727a9cafb62dac41d022da82c08f31083ee89f714ee3b83 - languageName: node - linkType: hard - -"is-alphabetical@npm:^2.0.0": - version: 2.0.1 - resolution: "is-alphabetical@npm:2.0.1" - checksum: 10c0/932367456f17237533fd1fc9fe179df77957271020b83ea31da50e5cc472d35ef6b5fb8147453274ffd251134472ce24eb6f8d8398d96dee98237cdb81a6c9a7 - languageName: node - linkType: hard - -"is-alphanumerical@npm:^2.0.0": - version: 2.0.1 - resolution: "is-alphanumerical@npm:2.0.1" - dependencies: - is-alphabetical: "npm:^2.0.0" - is-decimal: "npm:^2.0.0" - checksum: 10c0/4b35c42b18e40d41378293f82a3ecd9de77049b476f748db5697c297f686e1e05b072a6aaae2d16f54d2a57f85b00cbbe755c75f6d583d1c77d6657bd0feb5a2 - languageName: node - linkType: hard - -"is-decimal@npm:^2.0.0": - version: 2.0.1 - resolution: "is-decimal@npm:2.0.1" - checksum: 10c0/8085dd66f7d82f9de818fba48b9e9c0429cb4291824e6c5f2622e96b9680b54a07a624cfc663b24148b8e853c62a1c987cfe8b0b5a13f5156991afaf6736e334 - languageName: node - linkType: hard - -"is-hexadecimal@npm:^2.0.0": - version: 2.0.1 - resolution: "is-hexadecimal@npm:2.0.1" - checksum: 10c0/3eb60fe2f1e2bbc760b927dcad4d51eaa0c60138cf7fc671803f66353ad90c301605b502c7ea4c6bb0548e1c7e79dfd37b73b632652e3b76030bba603a7e9626 + checksum: 10c0/0876f5adeaf8c40dd179d78449bd3f14cf428f9179714cc49614407a525c185c228173ba849ff81c340af39a7c456cb904598bf3b60407b28b8302f2672ddb91 languageName: node linkType: hard @@ -184,412 +128,37 @@ __metadata: version: 0.0.0-use.local resolution: "ivuorinen-dotfiles@workspace:." dependencies: - "@ivuorinen/base-configs": "npm:1.0.0" - "@types/node": "npm:^24.10.1" - bats: "npm:^1.13.0" - editorconfig-checker: "npm:^6.1.1" - markdownlint: "npm:^0.40.0" - prettier: "npm:^3.7.4" - typescript: "npm:^5.9.3" + "@biomejs/biome": "npm:^2.3.1" + "@types/node": "npm:^24.0.1" + bats: "npm:^1.12.0" + editorconfig-checker: "npm:^6.1.0" + typescript: "npm:^5.8.3" languageName: unknown linkType: soft -"katex@npm:^0.16.0": - version: 0.16.22 - resolution: "katex@npm:0.16.22" - dependencies: - commander: "npm:^8.3.0" - bin: - katex: cli.js - checksum: 10c0/07b8b1f07ae53171b5f1ea0cf6f18841d2055825c8b11cd81cfe039afcd3af2cfc84ad033531ee3875088329105195b039c267e0dd4b0c237807e3c3b2009913 - languageName: node - linkType: hard - -"markdownlint@npm:^0.40.0": - version: 0.40.0 - resolution: "markdownlint@npm:0.40.0" - dependencies: - micromark: "npm:4.0.2" - micromark-core-commonmark: "npm:2.0.3" - micromark-extension-directive: "npm:4.0.0" - micromark-extension-gfm-autolink-literal: "npm:2.1.0" - micromark-extension-gfm-footnote: "npm:2.1.0" - micromark-extension-gfm-table: "npm:2.1.1" - micromark-extension-math: "npm:3.1.0" - micromark-util-types: "npm:2.0.2" - string-width: "npm:8.1.0" - checksum: 10c0/1543fcf4a433bc54e0e565cb1c8111e5e3d0df3742df0cc840d470bced21a1e3b5593e4e380ad0d8d5e490d9b399699d48aeabed33719f3fbdc6d00128138f20 - languageName: node - linkType: hard - -"micromark-core-commonmark@npm:2.0.3, micromark-core-commonmark@npm:^2.0.0": - version: 2.0.3 - resolution: "micromark-core-commonmark@npm:2.0.3" - dependencies: - decode-named-character-reference: "npm:^1.0.0" - devlop: "npm:^1.0.0" - micromark-factory-destination: "npm:^2.0.0" - micromark-factory-label: "npm:^2.0.0" - micromark-factory-space: "npm:^2.0.0" - micromark-factory-title: "npm:^2.0.0" - micromark-factory-whitespace: "npm:^2.0.0" - micromark-util-character: "npm:^2.0.0" - micromark-util-chunked: "npm:^2.0.0" - micromark-util-classify-character: "npm:^2.0.0" - micromark-util-html-tag-name: "npm:^2.0.0" - micromark-util-normalize-identifier: "npm:^2.0.0" - micromark-util-resolve-all: "npm:^2.0.0" - micromark-util-subtokenize: "npm:^2.0.0" - micromark-util-symbol: "npm:^2.0.0" - micromark-util-types: "npm:^2.0.0" - checksum: 10c0/bd4a794fdc9e88dbdf59eaf1c507ddf26e5f7ddf4e52566c72239c0f1b66adbcd219ba2cd42350debbe24471434d5f5e50099d2b3f4e5762ca222ba8e5b549ee - languageName: node - linkType: hard - -"micromark-extension-directive@npm:4.0.0": - version: 4.0.0 - resolution: "micromark-extension-directive@npm:4.0.0" - dependencies: - devlop: "npm:^1.0.0" - micromark-factory-space: "npm:^2.0.0" - micromark-factory-whitespace: "npm:^2.0.0" - micromark-util-character: "npm:^2.0.0" - micromark-util-symbol: "npm:^2.0.0" - micromark-util-types: "npm:^2.0.0" - parse-entities: "npm:^4.0.0" - checksum: 10c0/b4aef0f44339543466ae186130a4514985837b6b12d0c155bd1162e740f631e58f0883a39d0c723206fa0ff53a9b579965c79116f902236f6f123c3340b5fefb - languageName: node - linkType: hard - -"micromark-extension-gfm-autolink-literal@npm:2.1.0": - version: 2.1.0 - resolution: "micromark-extension-gfm-autolink-literal@npm:2.1.0" - dependencies: - micromark-util-character: "npm:^2.0.0" - micromark-util-sanitize-uri: "npm:^2.0.0" - micromark-util-symbol: "npm:^2.0.0" - micromark-util-types: "npm:^2.0.0" - checksum: 10c0/84e6fbb84ea7c161dfa179665dc90d51116de4c28f3e958260c0423e5a745372b7dcbc87d3cde98213b532e6812f847eef5ae561c9397d7f7da1e59872ef3efe - languageName: node - linkType: hard - -"micromark-extension-gfm-footnote@npm:2.1.0": - version: 2.1.0 - resolution: "micromark-extension-gfm-footnote@npm:2.1.0" - dependencies: - devlop: "npm:^1.0.0" - micromark-core-commonmark: "npm:^2.0.0" - micromark-factory-space: "npm:^2.0.0" - micromark-util-character: "npm:^2.0.0" - micromark-util-normalize-identifier: "npm:^2.0.0" - micromark-util-sanitize-uri: "npm:^2.0.0" - micromark-util-symbol: "npm:^2.0.0" - micromark-util-types: "npm:^2.0.0" - checksum: 10c0/d172e4218968b7371b9321af5cde8c77423f73b233b2b0fcf3ff6fd6f61d2e0d52c49123a9b7910612478bf1f0d5e88c75a3990dd68f70f3933fe812b9f77edc - languageName: node - linkType: hard - -"micromark-extension-gfm-table@npm:2.1.1": - version: 2.1.1 - resolution: "micromark-extension-gfm-table@npm:2.1.1" - dependencies: - devlop: "npm:^1.0.0" - micromark-factory-space: "npm:^2.0.0" - micromark-util-character: "npm:^2.0.0" - micromark-util-symbol: "npm:^2.0.0" - micromark-util-types: "npm:^2.0.0" - checksum: 10c0/04bc00e19b435fa0add62cd029d8b7eb6137522f77832186b1d5ef34544a9bd030c9cf85e92ddfcc5c31f6f0a58a43d4b96dba4fc21316037c734630ee12c912 - languageName: node - linkType: hard - -"micromark-extension-math@npm:3.1.0": - version: 3.1.0 - resolution: "micromark-extension-math@npm:3.1.0" - dependencies: - "@types/katex": "npm:^0.16.0" - devlop: "npm:^1.0.0" - katex: "npm:^0.16.0" - micromark-factory-space: "npm:^2.0.0" - micromark-util-character: "npm:^2.0.0" - micromark-util-symbol: "npm:^2.0.0" - micromark-util-types: "npm:^2.0.0" - checksum: 10c0/56e6f2185a4613f9d47e7e98cf8605851c990957d9229c942b005e286c8087b61dc9149448d38b2f8be6d42cc6a64aad7e1f2778ddd86fbbb1a2f48a3ca1872f - languageName: node - linkType: hard - -"micromark-factory-destination@npm:^2.0.0": - version: 2.0.1 - resolution: "micromark-factory-destination@npm:2.0.1" - dependencies: - micromark-util-character: "npm:^2.0.0" - micromark-util-symbol: "npm:^2.0.0" - micromark-util-types: "npm:^2.0.0" - checksum: 10c0/bbafcf869cee5bf511161354cb87d61c142592fbecea051000ff116068dc85216e6d48519d147890b9ea5d7e2864a6341c0c09d9948c203bff624a80a476023c - languageName: node - linkType: hard - -"micromark-factory-label@npm:^2.0.0": - version: 2.0.1 - resolution: "micromark-factory-label@npm:2.0.1" - dependencies: - devlop: "npm:^1.0.0" - micromark-util-character: "npm:^2.0.0" - micromark-util-symbol: "npm:^2.0.0" - micromark-util-types: "npm:^2.0.0" - checksum: 10c0/0137716b4ecb428114165505e94a2f18855c8bbea21b07a8b5ce514b32a595ed789d2b967125718fc44c4197ceaa48f6609d58807a68e778138d2e6b91b824e8 - languageName: node - linkType: hard - -"micromark-factory-space@npm:^2.0.0": - version: 2.0.1 - resolution: "micromark-factory-space@npm:2.0.1" - dependencies: - micromark-util-character: "npm:^2.0.0" - micromark-util-types: "npm:^2.0.0" - checksum: 10c0/f9ed43f1c0652d8d898de0ac2be3f77f776fffe7dd96bdbba1e02d7ce33d3853c6ff5daa52568fc4fa32cdf3a62d86b85ead9b9189f7211e1d69ff2163c450fb - languageName: node - linkType: hard - -"micromark-factory-title@npm:^2.0.0": - version: 2.0.1 - resolution: "micromark-factory-title@npm:2.0.1" - dependencies: - micromark-factory-space: "npm:^2.0.0" - micromark-util-character: "npm:^2.0.0" - micromark-util-symbol: "npm:^2.0.0" - micromark-util-types: "npm:^2.0.0" - checksum: 10c0/e72fad8d6e88823514916890099a5af20b6a9178ccf78e7e5e05f4de99bb8797acb756257d7a3a57a53854cb0086bf8aab15b1a9e9db8982500dd2c9ff5948b6 - languageName: node - linkType: hard - -"micromark-factory-whitespace@npm:^2.0.0": - version: 2.0.1 - resolution: "micromark-factory-whitespace@npm:2.0.1" - dependencies: - micromark-factory-space: "npm:^2.0.0" - micromark-util-character: "npm:^2.0.0" - micromark-util-symbol: "npm:^2.0.0" - micromark-util-types: "npm:^2.0.0" - checksum: 10c0/20a1ec58698f24b766510a309b23a10175034fcf1551eaa9da3adcbed3e00cd53d1ebe5f030cf873f76a1cec3c34eb8c50cc227be3344caa9ed25d56cf611224 - languageName: node - linkType: hard - -"micromark-util-character@npm:^2.0.0": - version: 2.1.1 - resolution: "micromark-util-character@npm:2.1.1" - dependencies: - micromark-util-symbol: "npm:^2.0.0" - micromark-util-types: "npm:^2.0.0" - checksum: 10c0/d3fe7a5e2c4060fc2a076f9ce699c82a2e87190a3946e1e5eea77f563869b504961f5668d9c9c014724db28ac32fa909070ea8b30c3a39bd0483cc6c04cc76a1 - languageName: node - linkType: hard - -"micromark-util-chunked@npm:^2.0.0": - version: 2.0.1 - resolution: "micromark-util-chunked@npm:2.0.1" - dependencies: - micromark-util-symbol: "npm:^2.0.0" - checksum: 10c0/b68c0c16fe8106949537bdcfe1be9cf36c0ccd3bc54c4007003cb0984c3750b6cdd0fd77d03f269a3382b85b0de58bde4f6eedbe7ecdf7244759112289b1ab56 - languageName: node - linkType: hard - -"micromark-util-classify-character@npm:^2.0.0": - version: 2.0.1 - resolution: "micromark-util-classify-character@npm:2.0.1" - dependencies: - micromark-util-character: "npm:^2.0.0" - micromark-util-symbol: "npm:^2.0.0" - micromark-util-types: "npm:^2.0.0" - checksum: 10c0/8a02e59304005c475c332f581697e92e8c585bcd45d5d225a66c1c1b14ab5a8062705188c2ccec33cc998d33502514121478b2091feddbc751887fc9c290ed08 - languageName: node - linkType: hard - -"micromark-util-combine-extensions@npm:^2.0.0": - version: 2.0.1 - resolution: "micromark-util-combine-extensions@npm:2.0.1" - dependencies: - micromark-util-chunked: "npm:^2.0.0" - micromark-util-types: "npm:^2.0.0" - checksum: 10c0/f15e282af24c8372cbb10b9b0b3e2c0aa681fea0ca323a44d6bc537dc1d9382c819c3689f14eaa000118f5a163245358ce6276b2cda9a84439cdb221f5d86ae7 - languageName: node - linkType: hard - -"micromark-util-decode-numeric-character-reference@npm:^2.0.0": - version: 2.0.2 - resolution: "micromark-util-decode-numeric-character-reference@npm:2.0.2" - dependencies: - micromark-util-symbol: "npm:^2.0.0" - checksum: 10c0/9c8a9f2c790e5593ffe513901c3a110e9ec8882a08f466da014112a25e5059b51551ca0aeb7ff494657d86eceb2f02ee556c6558b8d66aadc61eae4a240da0df - languageName: node - linkType: hard - -"micromark-util-encode@npm:^2.0.0": - version: 2.0.1 - resolution: "micromark-util-encode@npm:2.0.1" - checksum: 10c0/b2b29f901093845da8a1bf997ea8b7f5e061ffdba85070dfe14b0197c48fda64ffcf82bfe53c90cf9dc185e69eef8c5d41cae3ba918b96bc279326921b59008a - languageName: node - linkType: hard - -"micromark-util-html-tag-name@npm:^2.0.0": - version: 2.0.1 - resolution: "micromark-util-html-tag-name@npm:2.0.1" - checksum: 10c0/ae80444db786fde908e9295f19a27a4aa304171852c77414516418650097b8afb401961c9edb09d677b06e97e8370cfa65638dde8438ebd41d60c0a8678b85b9 - languageName: node - linkType: hard - -"micromark-util-normalize-identifier@npm:^2.0.0": - version: 2.0.1 - resolution: "micromark-util-normalize-identifier@npm:2.0.1" - dependencies: - micromark-util-symbol: "npm:^2.0.0" - checksum: 10c0/5299265fa360769fc499a89f40142f10a9d4a5c3dd8e6eac8a8ef3c2e4a6570e4c009cf75ea46dce5ee31c01f25587bde2f4a5cc0a935584ae86dd857f2babbd - languageName: node - linkType: hard - -"micromark-util-resolve-all@npm:^2.0.0": - version: 2.0.1 - resolution: "micromark-util-resolve-all@npm:2.0.1" - dependencies: - micromark-util-types: "npm:^2.0.0" - checksum: 10c0/bb6ca28764696bb479dc44a2d5b5fe003e7177aeae1d6b0d43f24cc223bab90234092d9c3ce4a4d2b8df095ccfd820537b10eb96bb7044d635f385d65a4c984a - languageName: node - linkType: hard - -"micromark-util-sanitize-uri@npm:^2.0.0": - version: 2.0.1 - resolution: "micromark-util-sanitize-uri@npm:2.0.1" - dependencies: - micromark-util-character: "npm:^2.0.0" - micromark-util-encode: "npm:^2.0.0" - micromark-util-symbol: "npm:^2.0.0" - checksum: 10c0/60e92166e1870fd4f1961468c2651013ff760617342918e0e0c3c4e872433aa2e60c1e5a672bfe5d89dc98f742d6b33897585cf86ae002cda23e905a3c02527c - languageName: node - linkType: hard - -"micromark-util-subtokenize@npm:^2.0.0": - version: 2.1.0 - resolution: "micromark-util-subtokenize@npm:2.1.0" - dependencies: - devlop: "npm:^1.0.0" - micromark-util-chunked: "npm:^2.0.0" - micromark-util-symbol: "npm:^2.0.0" - micromark-util-types: "npm:^2.0.0" - checksum: 10c0/bee69eece4393308e657c293ba80d92ebcb637e5f55e21dcf9c3fa732b91a8eda8ac248d76ff375e675175bfadeae4712e5158ef97eef1111789da1ce7ab5067 - languageName: node - linkType: hard - -"micromark-util-symbol@npm:^2.0.0": - version: 2.0.1 - resolution: "micromark-util-symbol@npm:2.0.1" - checksum: 10c0/f2d1b207771e573232436618e78c5e46cd4b5c560dd4a6d63863d58018abbf49cb96ec69f7007471e51434c60de3c9268ef2bf46852f26ff4aacd10f9da16fe9 - languageName: node - linkType: hard - -"micromark-util-types@npm:2.0.2, micromark-util-types@npm:^2.0.0": - version: 2.0.2 - resolution: "micromark-util-types@npm:2.0.2" - checksum: 10c0/c8c15b96c858db781c4393f55feec10004bf7df95487636c9a9f7209e51002a5cca6a047c5d2a5dc669ff92da20e57aaa881e81a268d9ccadb647f9dce305298 - languageName: node - linkType: hard - -"micromark@npm:4.0.2": - version: 4.0.2 - resolution: "micromark@npm:4.0.2" - dependencies: - "@types/debug": "npm:^4.0.0" - debug: "npm:^4.0.0" - decode-named-character-reference: "npm:^1.0.0" - devlop: "npm:^1.0.0" - micromark-core-commonmark: "npm:^2.0.0" - micromark-factory-space: "npm:^2.0.0" - micromark-util-character: "npm:^2.0.0" - micromark-util-chunked: "npm:^2.0.0" - micromark-util-combine-extensions: "npm:^2.0.0" - micromark-util-decode-numeric-character-reference: "npm:^2.0.0" - micromark-util-encode: "npm:^2.0.0" - micromark-util-normalize-identifier: "npm:^2.0.0" - micromark-util-resolve-all: "npm:^2.0.0" - micromark-util-sanitize-uri: "npm:^2.0.0" - micromark-util-subtokenize: "npm:^2.0.0" - micromark-util-symbol: "npm:^2.0.0" - micromark-util-types: "npm:^2.0.0" - checksum: 10c0/07462287254219d6eda6eac8a3cebaff2994e0575499e7088027b825105e096e4f51e466b14b2a81b71933a3b6c48ee069049d87bc2c2127eee50d9cc69e8af6 - languageName: node - linkType: hard - -"ms@npm:^2.1.3": - version: 2.1.3 - resolution: "ms@npm:2.1.3" - checksum: 10c0/d924b57e7312b3b63ad21fc5b3dc0af5e78d61a1fc7cfb5457edaf26326bf62be5307cc87ffb6862ef1c2b33b0233cdb5d4f01c4c958cc0d660948b65a287a48 - languageName: node - linkType: hard - -"parse-entities@npm:^4.0.0": - version: 4.0.2 - resolution: "parse-entities@npm:4.0.2" - dependencies: - "@types/unist": "npm:^2.0.0" - character-entities-legacy: "npm:^3.0.0" - character-reference-invalid: "npm:^2.0.0" - decode-named-character-reference: "npm:^1.0.0" - is-alphanumerical: "npm:^2.0.0" - is-decimal: "npm:^2.0.0" - is-hexadecimal: "npm:^2.0.0" - checksum: 10c0/a13906b1151750b78ed83d386294066daf5fb559e08c5af9591b2d98cc209123103016a01df776f65f8219ad26652d6d6b210d0974d452049cddfc53a8916c34 - languageName: node - linkType: hard - -"prettier@npm:^3.7.4": - version: 3.7.4 - resolution: "prettier@npm:3.7.4" - bin: - prettier: bin/prettier.cjs - checksum: 10c0/9675d2cd08eacb1faf1d1a2dbfe24bfab6a912b059fc9defdb380a408893d88213e794a40a2700bd29b140eb3172e0b07c852853f6e22f16f3374659a1a13389 - languageName: node - linkType: hard - -"string-width@npm:8.1.0": - version: 8.1.0 - resolution: "string-width@npm:8.1.0" - dependencies: - get-east-asian-width: "npm:^1.3.0" - strip-ansi: "npm:^7.1.0" - checksum: 10c0/749b5d0dab2532b4b6b801064230f4da850f57b3891287023117ab63a464ad79dd208f42f793458f48f3ad121fe2e1f01dd525ff27ead957ed9f205e27406593 - languageName: node - linkType: hard - -"strip-ansi@npm:^7.1.0": - version: 7.1.2 - resolution: "strip-ansi@npm:7.1.2" - dependencies: - ansi-regex: "npm:^6.0.1" - checksum: 10c0/0d6d7a023de33368fd042aab0bf48f4f4077abdfd60e5393e73c7c411e85e1b3a83507c11af2e656188511475776215df9ca589b4da2295c9455cc399ce1858b - languageName: node - linkType: hard - -"typescript@npm:^5.9.3": - version: 5.9.3 - resolution: "typescript@npm:5.9.3" +"typescript@npm:^5.8.3": + version: 5.9.2 + resolution: "typescript@npm:5.9.2" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10c0/6bd7552ce39f97e711db5aa048f6f9995b53f1c52f7d8667c1abdc1700c68a76a308f579cd309ce6b53646deb4e9a1be7c813a93baaf0a28ccd536a30270e1c5 + checksum: 10c0/cd635d50f02d6cf98ed42de2f76289701c1ec587a363369255f01ed15aaf22be0813226bff3c53e99d971f9b540e0b3cc7583dbe05faded49b1b0bed2f638a18 languageName: node linkType: hard -"typescript@patch:typescript@npm%3A^5.9.3#optional!builtin": - version: 5.9.3 - resolution: "typescript@patch:typescript@npm%3A5.9.3#optional!builtin::version=5.9.3&hash=5786d5" +"typescript@patch:typescript@npm%3A^5.8.3#optional!builtin": + version: 5.9.2 + resolution: "typescript@patch:typescript@npm%3A5.9.2#optional!builtin::version=5.9.2&hash=5786d5" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10c0/ad09fdf7a756814dce65bc60c1657b40d44451346858eea230e10f2e95a289d9183b6e32e5c11e95acc0ccc214b4f36289dcad4bf1886b0adb84d711d336a430 + checksum: 10c0/34d2a8e23eb8e0d1875072064d5e1d9c102e0bdce56a10a25c0b917b8aa9001a9cf5c225df12497e99da107dc379360bc138163c66b55b95f5b105b50578067e languageName: node linkType: hard -"undici-types@npm:~7.16.0": - version: 7.16.0 - resolution: "undici-types@npm:7.16.0" - checksum: 10c0/3033e2f2b5c9f1504bdc5934646cb54e37ecaca0f9249c983f7b1fc2e87c6d18399ebb05dc7fd5419e02b2e915f734d872a65da2e3eeed1813951c427d33cc9a +"undici-types@npm:~7.10.0": + version: 7.10.0 + resolution: "undici-types@npm:7.10.0" + checksum: 10c0/8b00ce50e235fe3cc601307f148b5e8fb427092ee3b23e8118ec0a5d7f68eca8cee468c8fc9f15cbb2cf2a3797945ebceb1cbd9732306a1d00e0a9b6afa0f635 languageName: node linkType: hard