Skip to content

Instantly share code, notes, and snippets.

@luzfcb
Forked from jamesbraza/black_selection.sh
Last active March 9, 2020 15:45
Show Gist options
  • Save luzfcb/912d553ad937aa702677a7a7c30d657b to your computer and use it in GitHub Desktop.
Save luzfcb/912d553ad937aa702677a7a7c30d657b to your computer and use it in GitHub Desktop.
Black on selection
#!/usr/bin/env bash
# Original Source: https://blog.godatadriven.com/black-formatting-selection
# This is a modified version of
# https://gist.github.com/JDusub83/ba2848d71644f4c3496def4c1a1d9fc8
#
# changes:
# - Added debugging prints, permissioning/cleanup, and also a bugfix for
# selecting whole file.
# - Now the original file can only be modified from black to run without errors.
# - Added support to black pyproject.toml - https://black.readthedocs.io/en/stable/pyproject_toml.html
# - Fixed sed syntax
#
# This script will:
# 1 - extract the contents of the indicated lines from the indicated file
# 2 - put the extracted content in a temporary file
# 3 - try to use black to format the temporary file
# 3.1 - if it is not possible to reformat the temporary file,
# then it will end execution without modifying the original file.
# 4 - delete the indicated lines from the original file.
# 5 - inject the formatted code in the original file
#
#
# Note:
# for this to work, you must select a valid code snippet that
# can be valid python code alone, that is, without depending on other codes
set -x
# Inputs
black=${1?param missing to an absolute path to black executable} # absolute path to black
config_path=${2?param missing to an absolute path that contains the pyproject.toml file with black configurations} # absolute path to pyproject.toml with black configurations
input_file=${3?param missing to an absolute path to a file to extract lines}
start_line=${4?param missing to the first line number}
end_line=${5?param missing to the first line number}
black_config_file="$config_path//pyproject.toml"
if [ ! -f "$black_config_file" ]
then
echo "The directory $config_path does not exists or not contains pyproject.toml file";
exit 1;
fi
# Read selected lines and write to tmpfile
selection=$(sed -n "$start_line, $end_line p; $((end_line+1)) q" < "$input_file")
tmpfile=$(mktemp)
chmod 700 "$tmpfile" # Only user can read/write (not execute), for security
# Write to tmpfile and apply Black formatting
echo "$selection" > "$tmpfile"
# Print tmpfile for debugging
echo -e "Before formatting code:\n---------------\n$(cat "$tmpfile")\n---------------"
# run black and if it's successful, update the original file
if $black --config "$black_config_file" "$tmpfile";
then
# Print tmpfile for debugging
echo -e "Reformatted code:\n---------------\n$(cat "$tmpfile")\n---------------"
# Delete original lines from input file
sed -i "$start_line,$end_line d" "$input_file"
# sed doesn't work on empty file, just assume if start line is 1, that the
# whole file was selected.
if [ "$start_line" == 1 ]
then
# sponge wasn't originally installed on my Mac... brew install moreutils
cat "$tmpfile" "$input_file" | sponge "$input_file" # prepend
else
sed -i "$((start_line-1)) r $tmpfile" "$input_file"
fi
# Cleanup tmpfile
rm -f "$tmpfile"
fi
@luzfcb
Copy link
Author

luzfcb commented Mar 9, 2020

Pycharm External Tools configuration:

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment