Skip to content

Commit

Permalink
Merge pull request #1 from kaypiff/devel
Browse files Browse the repository at this point in the history
Add the actual sources
  • Loading branch information
kaypiff authored Dec 22, 2022
2 parents 2f34190 + 04e4e9c commit 6b3c699
Show file tree
Hide file tree
Showing 7 changed files with 317 additions and 2 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@ Isn't it neat?
- `genalias2` - interactive mode, generate shell aliases from ALS
- `genalias2 <filename>` - generate shell aliases from an ALS file
- `genalias2 [filename] <pattern>` - generate using a desired pattern; if filename is empty, stdin is used
- `asect` - list all sections (in separate lines), use `echo $(asect)` or similar to join them.
- `asect <section>` - display the current configuration for a given section
- `asect` - list all sections (in separate lines) with their patterns
- `asect -p` - list all sections (in separate lines) **without** patterns
- `asect <section>` - display the current pattern for a given section
- `asect <section> <pattern>` - create a new section or override an existing section, applying the given pattern
- `asect <section> -d` - delete a section and all of its rules
- `asect <section> -c` - remove all rules from a section
Expand Down
26 changes: 26 additions & 0 deletions install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/bin/sh

# Installation directory. By default it's /usr/bin
install_dir="${1:-/usr/bin}"
# The directory containing source files.
source_dir="$(pwd)/$(dirname $0)/src"

# Make the scripts executable for everyone and writable for the owner
chmod 755 "$source_dir"/*

echo -n "Copying into '$install_dir'... "
cp -p "$source_dir"/* "$install_dir" 2>/dev/null
if [ $? = 0 ]
then
echo "done."

echo "Installation done. You might want to enable ALS by running the following command:"
echo ' # Replace .bashrc with your shell file'
echo ' echo "source \"\$HOME/.local/share/als/output.sh\"" >> ~/.bashrc'
echo ' aa !'
echo ''
else
echo "error."
echo "Couldn't copy ALS files. Try again."
echo "This might be a permission error. Try running this script with root permissions."
fi
48 changes: 48 additions & 0 deletions src/aa
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/bin/sh
#
# aa - quickly add aliases using ALS
#

section="$1"
rule="$2"

# Use $ALS_DATA_DIR as the directory. If that's not set, default to ~/.local/share/als
dir="${ALS_DATA_DIR:-$HOME/.local/share/als}"

# Create the directory if it doesn't exist
mkdir -p "$dir"/sections

# The section file
sect_file="$dir/sections/$section.als"

# Default input/output files
inp_file="$dir/main.als"
out_file="$dir/output.sh"

# Create the input file if it doesn't exist
touch "$inp_file"

# If no args provided, print all aliases
# found on the system and exit.
[ $# = 0 ] && genalias2 "$inp_file" '$< -> $$' && exit 0

if [ ! "$section" = '!' ] ; then

# If the section file doesn't exist, exit with an error.
[ ! -f "$sect_file" ] && echo "error: invalid section: '$section'!" && exit 1

# If no rule provided, print all aliases
# belonging to the given section and exit.
[ ! "$rule" ] && genalias2 "$sect_file" '$< -> $$' && exit 0

# Avoid duplicate aliases by unaliasing the rule first.
ua $(echo "$rule" | sed 's/\s*->.*//g') > /dev/null

# Add the rule to the file.
echo "$rule" >> "$sect_file"

echo "Alias added. Restart your shell for the new ruleset to load."
fi

# Regenerate aliases
genalias2 "$inp_file" > "$out_file"
90 changes: 90 additions & 0 deletions src/asect
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#!/bin/sh
#
# asect - easily manage ALS sections
#

section="$1"
pattern="$2"

# Use $ALS_DATA_DIR as the directory. If that's not set, default to ~/.local/share/als
dir="${ALS_DATA_DIR:-$HOME/.local/share/als}"

# Create the directory if it doesn't exist
mkdir -p "$dir"/sections

# The section file
sect_file="$dir/sections/$section.als"

# Default input file
inp_file="$dir/main.als"

# Create the input file if it doesn't exist already
touch "$inp_file"

list_sections() {
# List the sections in the format <name> '<pattern>'
sed -Ene "s/sections\/(.*)\.als\s*-->\s*(.*)\s*\$/\1 '\2'/p" "$1"
}

list_sections_without_patterns() {
# List the sections in the format <name>
sed -Ene "s/sections\/(.*)\.als\s*-->\s*.*\$/\1/p" "$1"
}

view_section_pattern() {
# Get the individual section pattern and print it.
res=$(grep --color=never "sections/$section.als\s" "$inp_file" | sed -Ee "s/sections\/.*.als\s*-->\s*(.*)\s*\$/\1/")
[ ! "$res" ] && echo "error: no such section!" >> /dev/stderr && exit 1
echo "$res"
}

delete_section() {
[ ! -f "$sect_file" ] && echo "error: no such section!" >> /dev/stderr && exit 1
# Delete the section file to get rid of the rules
rm -f "$sect_file"
# Remove it from the main file
sed -i "/sections\/$section\.als.*/d" "$inp_file"
# Rebuild aliases to remove this section from the shell
aa !
}

clear_section() {
[ ! -f "$sect_file" ] && echo "error: no such section!" >> /dev/stderr && exit 1
# Empty the section file - this removes all rules
echo -n '' > "$sect_file"
# Rebuild aliases to remove the rules from the shell
aa !
}

modify_section() {
touch "$sect_file"
# The current line number where this section is registered in the main file
linenumber=$(grep -n --color=never "sections/$section\.als" "$inp_file" | sed "s/:.*//g")

# If the section is already registered, remove it
[ "$linenumber" ] && sed -i "${linenumber}d" "$inp_file"
# Add the section at the end of the file
echo "sections/$section.als --> $pattern" >> "$inp_file"
}

case $# in
0)
list_sections "$inp_file" ;;
1)
case "$section" in
'-p') list_sections_without_patterns "$inp_file" ;;
* ) view_section_pattern ;;
esac
;;
2)
case "$pattern" in
'-d') delete_section ;;
'-c') clear_section ;;
* ) modify_section ;;
esac
;;
*)
echo "error: too many arguments!" >> /dev/stderr
exit 1
;;
esac
86 changes: 86 additions & 0 deletions src/genalias2
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#!/bin/sh

# A sed command used for escaping input
escape_sed='s/[^a-zA-Z0-9,._\+ \-]/\\&/g; 1!s/^/"/; $!s/$/"/'

# A function for generating ALS files
gen_file() {
# The global pattern
local template="$2"
# If no file provided, use stdin
local file=${1:-"-"}
# The current directory
local cwd=`pwd`

# Go to the directory of the affected file.
# This allows you to use relative paths inside ALS files.
cd "$(dirname "$file")"

# Remove comments and empty lines from the input
local input=$(sed "s/\s*#.*//g;/^&/d;" "$(basename "$file")")

# Look for 'long arrows' in the file - transformations
echo "$input" | grep "\s-->\s" |
while read -r line
do
# Filename
local one=$(echo "$line" | sed "s/\s*-->.*//")
# Pattern
local two=$(echo "$line" | sed "s/.*-->\s*//;$escape_sed")
# Apply the current global pattern to the transformation pattern (for recursive patterns)
local pat=$(echo "$template" | sed "s/\\\$\\\$/$two/g")

# Generate the file with the new pattern as the global pattern
gen_file "$one" "$pat"
done

# Look for 'short arrows' - rules
echo "$input" | grep "\s->\s" |
while read -r line
do
# Short name
local one=$(echo "$line" | sed "s/\s*->.*//;$escape_sed")
# Long name
local two=$(echo "$line" | sed "s/.*->\s*//;$escape_sed")

# Format the rule according to the global pattern and print the result.
echo "$template" | sed "s/\\\$\\\$/$two/g;s/\\\$</$one/g"
done

# Return to the previous directory
cd "$cwd"

return 0;
}

# Input file
src="$1"
# The global pattern. If not supplied,
# use 'alias "$<=$$"'
pat="${2:-"alias \"\$<=\$\$\""}"

# If a file is provided but does not exist,
# exit with an error message.
[ "$src" -a ! -f "$src" ] && echo "error: '$src' is not a file!" && exit 1

# If a file is provided but no global pattern is supplied,
# prepend a header to the output.
if [ "$1" -a ! "$2" ] ; then
echo "#!/bin/sh"
echo "#"
echo "# ======================================="
echo "# Generated with genalias "
echo "# (c)2022 kaypiff "
echo "# https://github.com/kaypiff/als "
echo "#"
echo "# Genalias is licensed under the terms "
echo "# of the GNU General Public License 3 "
echo "# or any later version. See LICENSE "
echo "# for details. "
echo "# ======================================="
echo "#"
echo ""
fi

# Generate the file
gen_file "$src" "$pat"
41 changes: 41 additions & 0 deletions src/ua
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/bin/sh
#
# ua - quickly unalias ALS rules
#

# The first argument is the rule name
rule="$1"

# Use $ALS_DATA_DIR as the directory. If that's not set, default to ~/.local/share/als
dir="${ALS_DATA_DIR:-$HOME/.local/share/als}"

# Create the directory if it doesn't exist
mkdir -p "$dir"/sections

# Default input/output files
inp_file="$dir/main.als"
out_file="$dir/output.sh"

# Create the input file if it doesn't exist
touch "$inp_file"

# This generates a sed command like 'sed -e "11d" "file.als"' that deletes the 11th line from the file
# The line number and the filename come from grep which looks for the rule in all sections files and returns the match.
cmd=$(grep -n --color=never "^\s*$rule\s\+->" "$dir"/sections/*.als | sed -E 's/(.*):(.*):.*/echo "\$\(sed -e \"\2d\" \"\1\" || cat \"\1\"\)" > "\1"/')

# If cmd is empty, it means grep wasn't able to find the rule.
[ ! "$cmd" ] && echo "error: no such rule!" && exit 1

# This is safe because the command is strictly controlled.
# Most of $cmd is hardcoded and the rest comes from the output of grep.
# We don't run any user input here - $cmd is only filled
# with a filename and line number from grep.
# It's in the format: 'sed "<line>d" "<file>"'.
echo $cmd | sh

# Regenerate the aliases
genalias2 "$inp_file" > "$out_file"

echo "Alias removed. Restart your shell for the new ruleset to load."

exit 0
23 changes: 23 additions & 0 deletions uninstall.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/bin/sh

# Installation directory. By default it's /usr/bin
install_dir="${1:-/usr/bin}"
# The directory containing source files.
source_dir="$(pwd)/$(dirname $0)/src"
installed_files=$(for file in $(ls --color=never "$source_dir"); do echo "$install_dir/$file"; done)

echo -n "Removing from '$install_dir'... "
rm -f $installed_files 2>/dev/null
if [ $? = 0 ]
then
echo "done."

echo "Uninstallation done. You might want to disable ALS by running the following command:"
echo ' # Replace .bashrc with your shell file'
echo ' sed -i "/source \"\$HOME\/.local\/share\/als\/output.sh\"/d" ~/.bashrc'
echo ''
else
echo "error."
echo "Couldn't remove ALS files. Try again."
echo "This might be a permission error. Try running this script with root permissions."
fi

0 comments on commit 6b3c699

Please sign in to comment.