Skip to content

Commit 4b71895

Browse files
authored
Improve GNU sed fallback while allowing use of -i.bak
On most Linux distributions (e.g. Ubuntu), there's no gsed command; the default "sed" is GNU sed with in-place editing capabilities. For those systems, we don't want the redirect + file move workaround applied. However, detecting the sed capabilities is error-prone and just as inefficient as the separate "mv" it would avoid. Instead, add a configuration that users can uncomment. Add a new TODOTXT_SED_COMMAND config variable to allow (Linux and Cygwin) users who have GNU sed to skip the less efficient emulation; "make install" auto-detects sed in-place editing capability. Merge pull request #447 from inkarkat/fix-inplace-sed
2 parents d1e2775 + 3232901 commit 4b71895

3 files changed

Lines changed: 38 additions & 2 deletions

File tree

Makefile

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,15 @@ clean: test-pre-clean VERSION-FILE ## remove dist directory and all release fi
100100
install: build installdirs ## local package install
101101
$(INSTALL_PROGRAM) $(DISTNAME)/todo.sh $(DEST_COMMAND)
102102
$(INSTALL_DATA) $(DISTNAME)/todo_completion $(DEST_COMPLETION)
103-
[ -e $(DEST_CONFIG) ] || \
104-
sed "s/^\(export[ \t]*TODO_DIR=\).*/\1~\/.todo/" $(DISTNAME)/todo.cfg > $(DEST_CONFIG)
103+
if [ ! -e $(DEST_CONFIG) ]; then \
104+
sed 's@^\(export TODO_DIR=\).*@\1~/.todo@' $(DISTNAME)/todo.cfg > $(DEST_CONFIG); \
105+
if sed -i.bak 's@^# \(export TODOTXT_SED_COMMAND=sed\)$$@\1@' $(DEST_CONFIG) 2>/dev/null; then \
106+
rm -f $(DEST_CONFIG).bak; \
107+
echo 'This sed supports in-place editing.'; \
108+
else \
109+
echo 'Need sed in-place emulation here.'; \
110+
fi; \
111+
fi
105112

106113
.PHONY: uninstall
107114
uninstall: ## uninstall package

todo.cfg

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,13 @@ export TODO_FILE DONE_FILE REPORT_FILE
103103
# Set a default action for calling todo.sh without arguments.
104104
# Also allows for parameters for the action.
105105
# export TODOTXT_DEFAULT_ACTION=''
106+
107+
## sed capabilities
108+
# If you have GNU sed or another sed that supports in-place editing
109+
# via -i[SUFFIX], uncomment this for a minuscule performance gain.
110+
# export TODOTXT_SED_COMMAND=sed
111+
112+
# Uncomment this if you have add-ons that also do in-place editing
113+
# via sed, pass the -i.bak as the first argument like todo.sh itself,
114+
# and your system needs the in-place emulation.
115+
# export TODOTXT_SED_EXPORT_FOR_ADDONS=1

todo.sh

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,25 @@ export TODO_SH TODO_FULL_SH
2727

2828
oneline_usage="$TODO_SH [-fhpantvV] [-d todo_config] action [task_number] [task_description]"
2929

30+
# Assumption: The in-place argument is the first
31+
# Assumption: Only a single file is processed with sed
32+
sed() {
33+
if [ -n "$TODOTXT_SED_COMMAND" ]; then
34+
command "$TODOTXT_SED_COMMAND" "$@"
35+
elif command -v gsed &>/dev/null; then
36+
gsed "$@"
37+
elif [ "$1" = '-i.bak' ]; then
38+
shift
39+
filepath=${!#}
40+
filepath_temp=${TMPDIR-/tmp}/todo.sh-sed.$RANDOM.$$
41+
command sed "$@" > "$filepath_temp" && mv "$filepath_temp" "$filepath"
42+
else
43+
command sed "$@"
44+
fi
45+
}
46+
[ "$TODOTXT_SED_EXPORT_FOR_ADDONS" = 1 ] \
47+
&& export -f sed
48+
3049
usage()
3150
{
3251
cat <<-EndUsage

0 commit comments

Comments
 (0)