Last active
September 19, 2024 01:37
-
-
Save pmarreck/522d68be93e97606ffeef776cd0d4488 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# OK, why tabs? Why resurrect this age-old nerd debate again? | |
# Very simple: It's an accessibility issue: | |
# https://adamtuttle.codes/blog/2021/tabs-vs-spaces-its-an-accessibility-issue/ | |
# To set the default tab width on your terminal (which unfortunately defaults to 8), | |
# run: `tabs -2` (or whatever width you want), possibly in your dotfiles. | |
# is AWK set to anything? If not, prefer frawk, then gawk, then awk | |
[ -z "${AWK}" ] && export AWK=$(command -v frawk || command -v gawk || command -v awk) | |
reformat_spaces_to_tabs() { | |
local file="$1" | |
function determine_tab_size_in_spaces() { | |
$AWK ' | |
{ | |
# Match the leading spaces and count the occurrences | |
match($0, /^ */); | |
indents[RLENGTH]++; | |
} | |
END { | |
# Find the 3 most common indentation levels | |
max_count = 0; | |
max_indent = 0; | |
second_max_indent = 0; | |
third_max_indent = 0; | |
for (indent in indents) { | |
if (indents[indent] > max_count && indent > 0) { | |
third_max_indent = second_max_indent; | |
second_max_indent = max_indent; | |
max_indent = indent; | |
max_count = indents[indent]; | |
} | |
} | |
# Determine what the greatest common divisor is for the most common indentation levels, | |
# handling up to 8 spaces (which is what my terminal outputs, which is ridiculous) | |
# There is undoubtedly a less janky way to do this | |
if (max_indent % 8 == 0 && second_max_indent % 8 == 0 && third_max_indent % 8 == 0) { | |
print 8; | |
} else if (max_indent % 7 == 0 && second_max_indent % 7 == 0 && third_max_indent % 7 == 0) { | |
print 7; | |
} else if (max_indent % 6 == 0 && second_max_indent % 6 == 0 && third_max_indent % 6 == 0) { | |
print 6; | |
} else if (max_indent % 5 == 0 && second_max_indent % 5 == 0 && third_max_indent % 5 == 0) { | |
print 5; | |
} else if (max_indent % 4 == 0 && second_max_indent % 4 == 0 && third_max_indent % 4 == 0) { | |
print 4; | |
} else if (max_indent % 3 == 0 && second_max_indent % 3 == 0 && third_max_indent % 3 == 0) { | |
print 3; | |
} else if (max_indent % 2 == 0 && second_max_indent % 2 == 0 && third_max_indent % 2 == 0) { | |
print 2; | |
} else if (max_indent == 0) { | |
print 0; | |
} else { | |
print 1; | |
} | |
} | |
' "$1" | |
} | |
local indent=$(determine_tab_size_in_spaces "$file") | |
if (( indent > 0 )); then | |
# >&2 echo "Indent size: $indent" | |
indent_spaces=$(printf "%${indent}s") | |
$AWK -v indent="$indent_spaces" ' | |
{ | |
while (match($0, "^\t*"indent)) { | |
$0 = gensub("^(\t*)"indent, "\\1\t", "g"); | |
} | |
print; | |
}' "$file" #> "$file.tmp" && mv "$file.tmp" "$file" | |
else | |
# >&2 echo "Indent size: 0" | |
cat "$file" | |
fi | |
} | |
# Export the function so it can be used by find -exec | |
export -f reformat_spaces_to_tabs | |
# Run the function, passing along any args, if this file was run directly (such as via sudo) instead of as an include | |
# Sometimes, $0 contains a leading dash to indicate an interactive (or is it login?) shell, | |
# which is apparently an old convention (which also broke the basename call on OS X) | |
_me=$(basename "${0##\-}") | |
if [ "$_me" = "reformat_spaces_to_tabs" ]; then | |
$_me "$@" | |
fi | |
unset _me |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment