Skip to content

Commit

Permalink
share/: Use <? redirection
Browse files Browse the repository at this point in the history
This is mostly used instead of `test -r foo && string match bar <foo`
or `set bar (cat foo 2>/dev/null)`.

In doing so it can avoid a weird race condition where the file changes
between the check and the use, and it can avoid an external process or
having to open the file twice.

However it can also cause more work to happen - if you do

```fish
if test -r file
   # do a lot of work with file
end
```

it might be prudent to keep doing that. In the cases here it's usually
just a few `string` calls, which would operate on nothing and so be
pretty quick.
  • Loading branch information
faho committed Mar 21, 2024
1 parent df8b9b7 commit de1e9ed
Show file tree
Hide file tree
Showing 8 changed files with 37 additions and 51 deletions.
2 changes: 1 addition & 1 deletion share/functions/__fish_complete_groups.fish
Expand Up @@ -6,6 +6,6 @@ function __fish_complete_groups --description "Print a list of local groups, wit
else
while read -l line
string split -f 1,4 : -- $line | string join \t
end </etc/group
end <?/etc/group
end
end
4 changes: 2 additions & 2 deletions share/functions/__fish_complete_user_ids.fish
@@ -1,7 +1,7 @@
function __fish_complete_user_ids --description "Complete user IDs with user name as description"
if command -sq getent
getent passwd | string replace -f -r '^([[:alpha:]_][^:]*):[^:]*:(\d+).*' '$2\t$1'
else if test -r /etc/passwd
string replace -f -r '^([[:alpha:]_][^:]*):[^:]*:(\d+).*' '$2\t$1' </etc/passwd
else
string replace -f -r '^([[:alpha:]_][^:]*):[^:]*:(\d+).*' '$2\t$1' <?/etc/passwd
end
end
4 changes: 2 additions & 2 deletions share/functions/__fish_complete_users.fish
Expand Up @@ -10,8 +10,8 @@ function __fish_complete_users --description "Print a list of local users, with
else if command -sq dscl
# This is the "Directory Service command line utility" used on macOS in place of getent.
command dscl . -list /Users RealName | string match -r -v '^_' | string replace -r ' {2,}' \t
else if test -r /etc/passwd
string match -v -r '^\s*#' </etc/passwd | while read -l line
else
string match -v -r '^\s*#' <?/etc/passwd | while read -l line
string split -f 1,5 : -- $line | string join \t | string replace -r ',.*' ''
end
end
Expand Down
22 changes: 8 additions & 14 deletions share/functions/__fish_print_hostnames.fish
Expand Up @@ -18,10 +18,8 @@ function __fish_print_hostnames -d "Print a list of known hostnames"
string split ' '

# Print nfs servers from /etc/fstab
if test -r /etc/fstab
string match -r '^\s*[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}:|^[a-zA-Z\.]*:' </etc/fstab |
string replace -r ':.*' ''
end
string match -r '^\s*[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}:|^[a-zA-Z\.]*:' <?/etc/fstab |
string replace -r ':.*' ''

# Check hosts known to ssh.
# Yes, seriously - the default specifies both with and without "2".
Expand Down Expand Up @@ -65,13 +63,11 @@ function __fish_print_hostnames -d "Print a list of known hostnames"
function _recursive --no-scope-shadowing
set -l paths
for config in $argv
if test -r "$config" -a -f "$config"
set paths $paths (
# Keep only Include lines and remove Include syntax
string replace -rfi '^\s*Include\s+' '' <$config \
# Normalize whitespace
| string trim | string replace -r -a '\s+' ' ')
end
set paths $paths (
# Keep only Include lines and remove Include syntax
string replace -rfi '^\s*Include\s+' '' <?$config \
# Normalize whitespace
| string trim | string replace -r -a '\s+' ' ')
end

set -l new_paths
Expand Down Expand Up @@ -117,9 +113,7 @@ function __fish_print_hostnames -d "Print a list of known hostnames"

# Read all files and operate on their combined content
for file in $known_hosts
if test -r $file
read -z <$file
end
read -z <?$file
end |
# Ignore hosts that are hashed, commented or @-marked and strip the key
# Handle multiple comma-separated hostnames sharing a key, too.
Expand Down
36 changes: 16 additions & 20 deletions share/functions/__fish_set_locale.fish
Expand Up @@ -26,15 +26,13 @@ function __fish_set_locale
# but we operate under the assumption that the locale can't include whitespace. Other whitespace
# shouldn't concern us, but a quoted "locale.LANG=SOMETHING" as a value to something else might.
# Here the last definition of a variable takes precedence.
if test -r /proc/cmdline
for var in (string match -ra 'locale.[^=]+=\S+' < /proc/cmdline)
set -l kv (string replace 'locale.' '' -- $var | string split '=')
# Only set locale variables, not other stuff contained in these files - this also
# automatically ignores comments.
if contains -- $kv[1] $LOCALE_VARS
and set -q kv[2]
set -gx $kv[1] (string trim -c '\'"' -- $kv[2])
end
for var in (string match -ra 'locale.[^=]+=\S+' <?/proc/cmdline)
set -l kv (string replace 'locale.' '' -- $var | string split '=')
# Only set locale variables, not other stuff contained in these files - this also
# automatically ignores comments.
if contains -- $kv[1] $LOCALE_VARS
and set -q kv[2]
set -gx $kv[1] (string trim -c '\'"' -- $kv[2])
end
end

Expand All @@ -54,18 +52,16 @@ function __fish_set_locale
# full POSIX-shell script.
set -l user_cfg_dir (set -q XDG_CONFIG_HOME; and echo $XDG_CONFIG_HOME; or echo ~/.config)
for f in $user_cfg_dir/locale.conf /etc/locale.conf /etc/env.d/02locale /etc/sysconfig/i18n /etc/default/locale
if test -r $f
while read -l kv
set kv (string split '=' -- $kv)
if contains -- $kv[1] $LOCALE_VARS
and set -q kv[2]
# Do not set already set variables again - this makes the merging happen.
if not set -q $kv[1]
set -gx $kv[1] (string trim -c '\'"' -- $kv[2])
end
while read -l kv
set kv (string split '=' -- $kv)
if contains -- $kv[1] $LOCALE_VARS
and set -q kv[2]
# Do not set already set variables again - this makes the merging happen.
if not set -q $kv[1]
set -gx $kv[1] (string trim -c '\'"' -- $kv[2])
end
end <$f
end
end
end <?$f
end

# If we really cannot get anything, at least set character encoding to UTF-8.
Expand Down
5 changes: 1 addition & 4 deletions share/functions/fish_command_not_found.fish
Expand Up @@ -5,11 +5,8 @@
# This has a "ID=" line that defines the exact distribution,
# and an "ID_LIKE=" line that defines what it is derived from or otherwise like.
# For our purposes, we use both.
set -l os
if test -r /etc/os-release
set os (string match -r '^ID(?:_LIKE)?\s*=.*' < /etc/os-release | \
set -l os (string match -r '^ID(?:_LIKE)?\s*=.*' <?/etc/os-release | \
string replace -r '^ID(?:_LIKE)?\s*=(.*)' '$1' | string trim -c '\'"' | string split " ")
end

function __fish_default_command_not_found_handler
printf (_ "fish: Unknown command: %s\n") (string escape -- $argv[1]) >&2
Expand Down
12 changes: 6 additions & 6 deletions share/functions/fish_git_prompt.fish
Expand Up @@ -478,20 +478,20 @@ function __fish_git_prompt_operation_branch_bare --description "fish_git_prompt
set -l total

if test -d $git_dir/rebase-merge
set branch (cat $git_dir/rebase-merge/head-name 2>/dev/null)
set step (cat $git_dir/rebase-merge/msgnum 2>/dev/null)
set total (cat $git_dir/rebase-merge/end 2>/dev/null)
read branch <?$git_dir/rebase-merge/head-name
read step <?$git_dir/rebase-merge/msgnum
read total <?$git_dir/rebase-merge/end
if test -f $git_dir/rebase-merge/interactive
set operation "|REBASE-i"
else
set operation "|REBASE-m"
end
else
if test -d $git_dir/rebase-apply
set step (cat $git_dir/rebase-apply/next 2>/dev/null)
set total (cat $git_dir/rebase-apply/last 2>/dev/null)
read step <?$git_dir/rebase-apply/next
read total <?$git_dir/rebase-apply/last
if test -f $git_dir/rebase-apply/rebasing
set branch (cat $git_dir/rebase-apply/head-name 2>/dev/null)
read branch <?$git_dir/rebase-apply/head-name
set operation "|REBASE"
else if test -f $git_dir/rebase-apply/applying
set operation "|AM"
Expand Down
3 changes: 1 addition & 2 deletions share/functions/help.fish
Expand Up @@ -79,8 +79,7 @@ function help --description 'Show help for the fish shell'
#
# We use this instead of xdg-open because that's useless without a backend
# like wsl-open which we'll check in a minute.
if test -f /proc/version
and string match -riq 'Microsoft|WSL|MSYS|MINGW' </proc/version
if string match -riq 'Microsoft|WSL|MSYS|MINGW' <?/proc/version
and set -l cmd (command -s powershell.exe cmd.exe /mnt/c/Windows/System32/cmd.exe)
# Use the first of these.
set fish_browser $cmd[1]
Expand Down

0 comments on commit de1e9ed

Please sign in to comment.