aboutsummaryrefslogtreecommitdiffstats
path: root/incdec.bash
diff options
context:
space:
mode:
authorTeddy Wing2021-08-25 00:32:09 +0200
committerTeddy Wing2021-08-25 00:32:09 +0200
commit353315bc5369a078f9ac70e5007db630c7fcb749 (patch)
tree8de4086f16eb818abe9c7bf33006dced242fb9b3 /incdec.bash
parentff00a3c613570c5460a420c5882da41ed2e09142 (diff)
downloadreadline-incdec-353315bc5369a078f9ac70e5007db630c7fcb749.tar.bz2
Rename `incdec` to `incdec.bash`
Add a ".bash" extension to the main include script make explicit the intent for it to be used with Bash.
Diffstat (limited to 'incdec.bash')
-rw-r--r--incdec.bash104
1 files changed, 104 insertions, 0 deletions
diff --git a/incdec.bash b/incdec.bash
new file mode 100644
index 0000000..98ba10b
--- /dev/null
+++ b/incdec.bash
@@ -0,0 +1,104 @@
+# Copyright (c) 2021 Teddy Wing
+#
+# This file is part of Incdec.
+#
+# Incdec 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 3 of the License, or
+# (at your option) any later version.
+#
+# Incdec is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Incdec. If not, see <https://www.gnu.org/licenses/>.
+
+
+# Increment or decrement a number on the current line.
+function __readline_incdec {
+ local increment_by="$1"
+ local backward="$2"
+
+ line=$(perl -s -e '
+sub incdec {
+ my ($line, $increment_by, $point_position, $is_backward) = @_;
+
+ $point_position ||= 0;
+ $is_backward ||= 0;
+
+ my $start_position = 0;
+ my $previous_match_start = 0;
+ while ($line =~ /(-?\d+)/g) {
+ if ($is_backward) {
+ # Set start position to the current match start. This gives us the
+ # correct start position when incrementing the last number in a
+ # line.
+ $start_position = $-[0];
+
+ # If point is not at the end, set start position to the number
+ # closest to the point position.
+ if ($point_position < $-[0]) {
+ $start_position = $previous_match_start;
+
+ last;
+ }
+
+ $previous_match_start = $-[0];
+ }
+ else {
+ if ($point_position < $+[0]) {
+ $start_position = $-[0];
+
+ last;
+ }
+ }
+ }
+
+ pos($line) = $start_position;
+ $line =~ s/\G([^-\d]*)(-?\d+)/$1 . ($2 + $increment_by)/e;
+
+ return $line;
+}
+
+my $output = incdec($line, $increment_by, $point_position, $backward);
+print $output;
+' \
+ -- \
+ -line="$READLINE_LINE" \
+ -increment_by="$increment_by" \
+ -point_position="$READLINE_POINT" \
+ -backward="$backward"
+ )
+
+ READLINE_LINE="$line"
+}
+
+# Increment the nearest number to the left of point by 1.
+function __readline_incdec_increment {
+ local old_line_length="${#READLINE_LINE}"
+
+ __readline_incdec 1 1
+
+ local new_line_length="${#READLINE_LINE}"
+
+ # If a negative sign was removed, keep point where it was.
+ if [ "$old_line_length" -gt "$new_line_length" ]; then
+ READLINE_POINT="$(($READLINE_POINT - 1))"
+ fi
+}
+
+# Decrement the nearest number to the left of point by 1.
+function __readline_incdec_decrement {
+ local old_line_length="${#READLINE_LINE}"
+
+ __readline_incdec -1 1
+
+ local new_line_length="${#READLINE_LINE}"
+
+ # If a negative sign was added, keep point where it was.
+ if [ "$old_line_length" -lt "$new_line_length" ]; then
+ READLINE_POINT="$(($READLINE_POINT + 1))"
+ fi
+}