From b47dda9aeaa489bb6fbec83e271d4889b2af9010 Mon Sep 17 00:00:00 2001
From: Giovanni Bussi <giovanni.bussi@gmail.com>
Date: Thu, 22 Mar 2018 09:27:38 +0100
Subject: [PATCH] Install bash completion if possible

---
 Makefile.conf.in         |  1 +
 configure                | 90 ++++++++++++++++++++++++++++++++++++++++
 configure.ac             | 33 +++++++++++++++
 macports/Portfile.in     |  3 +-
 src/lib/Makefile         |  7 ++++
 src/lib/bash.completion  |  7 ++++
 user-doc/Miscelaneous.md | 15 +++++--
 7 files changed, 152 insertions(+), 4 deletions(-)
 create mode 100644 src/lib/bash.completion

diff --git a/Makefile.conf.in b/Makefile.conf.in
index 93e2e5511..5ebe1397a 100644
--- a/Makefile.conf.in
+++ b/Makefile.conf.in
@@ -38,3 +38,4 @@ htmldir=@htmldir@
 python_bin=@PYTHON_BIN@
 mpiexec=@MPIEXEC@
 make_static_archive=@make_static_archive@
+BASH_COMPLETION_DIR=@BASH_COMPLETION_DIR@
diff --git a/configure b/configure
index bf8b34efd..0cf7b0087 100755
--- a/configure
+++ b/configure
@@ -622,6 +622,7 @@ ac_subst_vars='LTLIBOBJS
 LIBOBJS
 build_dir
 program_name
+pkgconfig_bin
 make_static_archive
 AR_CR
 LD_RO
@@ -653,6 +654,7 @@ LDFLAGS
 CXXFLAGS
 CXX
 MPIEXEC
+BASH_COMPLETION_DIR
 PYTHON_BIN
 LDSHARED
 STATIC_LIBS
@@ -739,6 +741,7 @@ SOEXT
 STATIC_LIBS
 LDSHARED
 PYTHON_BIN
+BASH_COMPLETION_DIR
 MPIEXEC
 CXX
 CXXFLAGS
@@ -1417,6 +1420,9 @@ Some influential environment variables:
               the proper flags
   PYTHON_BIN  python executable (e.g. python2.7 or /opt/local/bin/python2.7) -
               default: search for a python executable
+  BASH_COMPLETION_DIR
+              path where bash completion will be installed - default: search
+              with pkg-config
   MPIEXEC     command to run mpi programs in tests - default not specified,
               which means use PLUMED_MPIRUN env var at runtime for backward
               compatibility
@@ -3022,6 +3028,7 @@ fi
 
 
 
+
 # by default use -O flag
 # we override the autoconf default (-g) because in release build we do not want to
 # include symbol information (obj files are huge)
@@ -8957,6 +8964,80 @@ then
   prefix=/usr/local
 fi
 
+pkgconfig_bin=""
+
+for ac_prog in pkg-config
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_pkgconfig_bin+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $pkgconfig_bin in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_pkgconfig_bin="$pkgconfig_bin" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_pkgconfig_bin="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+pkgconfig_bin=$ac_cv_path_pkgconfig_bin
+if test -n "$pkgconfig_bin"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $pkgconfig_bin" >&5
+$as_echo "$pkgconfig_bin" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$pkgconfig_bin" && break
+done
+
+
+if test -z "$BASH_COMPLETION_DIR" && test -n "$pkgconfig_bin"; then
+  if test "$prefix" == "$(pkg-config --variable=prefix bash-completion 2>/dev/null)"
+  then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: bash-completion is installed on the same prefix where plumed will be installed" >&5
+$as_echo "$as_me: bash-completion is installed on the same prefix where plumed will be installed" >&6;}
+    if pkg-config --variable=completionsdir bash-completion 2>/dev/null >/dev/null ; then
+      BASH_COMPLETION_DIR="$(pkg-config --variable=completionsdir  bash-completion 2>/dev/null)"
+    fi
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: bash-completion is not installed or it is installed on a different prefix" >&5
+$as_echo "$as_me: bash-completion is not installed or it is installed on a different prefix" >&6;}
+    pkgconfig_bin=""
+  fi
+fi
+
+if test -n "$BASH_COMPLETION_DIR"
+then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: bash completion for plumed will be installed in $BASH_COMPLETION_DIR" >&5
+$as_echo "$as_me: bash completion for plumed will be installed in $BASH_COMPLETION_DIR" >&6;}
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: bash completion for plumed will not be installed" >&5
+$as_echo "$as_me: bash completion for plumed will not be installed" >&6;}
+fi
+
+
+
 test "$program_prefix" != NONE &&
   program_transform_name="s&^&$program_prefix&;$program_transform_name"
 # Use a double $ so make ignores it.
@@ -9019,6 +9100,15 @@ $as_echo "$as_me: **** As of PLUMED 2.5, you cannot change paths anymore during
 { $as_echo "$as_me:${as_lineno-$LINENO}: **** Please configure and make clean to change the prefix" >&5
 $as_echo "$as_me: **** Please configure and make clean to change the prefix" >&6;}
 
+if test -z "$BASH_COMPLETION_DIR" ; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: **** Bash completion for plumed will not be installed, please add the following two lines to your bashrc" >&5
+$as_echo "$as_me: WARNING: **** Bash completion for plumed will not be installed, please add the following two lines to your bashrc" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: **** _$program_name() { eval \"\$($program_name --no-mpi completion 2>/dev/null)\";}" >&5
+$as_echo "$as_me: WARNING: **** _$program_name() { eval \"\$($program_name --no-mpi completion 2>/dev/null)\";}" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: **** complete -F _$program_name -o default $program_name" >&5
+$as_echo "$as_me: WARNING: **** complete -F _$program_name -o default $program_name" >&2;}
+fi
+
 if test $mpi == true; then
   if test $mpi_found == ok; then
     { $as_echo "$as_me:${as_lineno-$LINENO}: **** PLUMED will be compiled using MPI" >&5
diff --git a/configure.ac b/configure.ac
index fcfa917bb..e74a67ff2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -261,6 +261,7 @@ AC_ARG_VAR(SOEXT,[extension of dynamic libraries (so/dylib)])
 AC_ARG_VAR(STATIC_LIBS,[variables that should be linked statically directly to MD code - configure will add here -ldl if necessary ])
 AC_ARG_VAR(LDSHARED,[command for linking shared library - configure will use CXX plus the proper flags ])
 AC_ARG_VAR(PYTHON_BIN,[python executable (e.g. python2.7 or /opt/local/bin/python2.7) - default: search for a python executable])
+AC_ARG_VAR(BASH_COMPLETION_DIR,[path where bash completion will be installed - default: search with pkg-config])
 AC_ARG_VAR(MPIEXEC,[command to run mpi programs in tests - default not specified, which means use PLUMED_MPIRUN env var at runtime for backward compatibility])
 
 
@@ -1096,6 +1097,32 @@ then
   prefix=/usr/local
 fi
 
+pkgconfig_bin=""
+
+AC_PATH_PROGS(pkgconfig_bin,pkg-config)
+
+if test -z "$BASH_COMPLETION_DIR" && test -n "$pkgconfig_bin"; then
+  if test "$prefix" == "$(pkg-config --variable=prefix bash-completion 2>/dev/null)"
+  then
+    AC_MSG_NOTICE([bash-completion is installed on the same prefix where plumed will be installed])
+    if pkg-config --variable=completionsdir bash-completion 2>/dev/null >/dev/null ; then
+      BASH_COMPLETION_DIR="$(pkg-config --variable=completionsdir  bash-completion 2>/dev/null)"
+    fi
+  else
+    AC_MSG_NOTICE([bash-completion is not installed or it is installed on a different prefix])
+    pkgconfig_bin=""
+  fi
+fi
+
+if test -n "$BASH_COMPLETION_DIR"
+then
+  AC_MSG_NOTICE([bash completion for plumed will be installed in $BASH_COMPLETION_DIR])
+else
+  AC_MSG_NOTICE([bash completion for plumed will not be installed])
+fi
+
+AC_SUBST(BASH_COMPLETION_DIR)
+
 AC_ARG_PROGRAM
 
 
@@ -1136,6 +1163,12 @@ AC_MSG_NOTICE([**** Executable will be named $program_name])
 AC_MSG_NOTICE([**** As of PLUMED 2.5, you cannot change paths anymore during "make install"])
 AC_MSG_NOTICE([**** Please configure and make clean to change the prefix])
 
+if test -z "$BASH_COMPLETION_DIR" ; then
+  AC_MSG_WARN([**** Bash completion for plumed will not be installed, please add the following two lines to your bashrc])
+  AC_MSG_WARN([**** _$program_name() { eval "\$($program_name --no-mpi completion 2>/dev/null)";}])
+  AC_MSG_WARN([**** complete -F _$program_name -o default $program_name])
+fi
+
 if test $mpi == true; then
   if test $mpi_found == ok; then
     AC_MSG_NOTICE([**** PLUMED will be compiled using MPI])
diff --git a/macports/Portfile.in b/macports/Portfile.in
index a923394d3..3b3e4de3c 100644
--- a/macports/Portfile.in
+++ b/macports/Portfile.in
@@ -51,7 +51,8 @@ configure.args-append \
                --disable-libsearch \
                --disable-static-patch \
                --disable-mpi \
-               --disable-python
+               --disable-python \
+               BASH_COMPLETION_DIR=${prefix}/share/bash-completion/completions
 
 # Hardcode path for libplumedKernel.dylib.
 # This allows to patch MD codes using the --runtime option but using as
diff --git a/src/lib/Makefile b/src/lib/Makefile
index 993ea2216..6492f9c27 100644
--- a/src/lib/Makefile
+++ b/src/lib/Makefile
@@ -300,6 +300,10 @@ ifdef python_bin
           $(python_bin) buildPythonInterface.py build_ext -i
 	cp -pr install/python "$(DESTDIR)$(libdir)/$(program_name)/" 
 endif
+ifdef BASH_COMPLETION_DIR
+	mkdir -p "$(DESTDIR)$(BASH_COMPLETION_DIR)"
+	cp bash.completion "$(DESTDIR)$(BASH_COMPLETION_DIR)/$(program_name)"
+endif
 # making everything visible:
 	chmod -R go+rX,go-w "$(DESTDIR)$(libdir)/$(program_name)"
 	chmod -R go+rX,go-w "$(DESTDIR)$(includedir)/$(program_name)"
@@ -338,6 +342,9 @@ endif
 ifdef SOEXT
 	@echo $(libdir)/lib$(program_name).$(SOEXT)
 	@echo $(libdir)/lib$(program_name)Kernel.$(SOEXT)
+endif
+ifdef BASH_COMPLETION_DIR
+	@echo $(BASH_COMPLETION_DIR)/$(program_name)
 endif
 	@if test -d ../../vim/help ; then echo "A vim plugin can be found here: $(libdir)/$(program_name)/vim/" ; fi
 	@if test -d ../../vim/help ; then echo "Copy it to $(HOME)/.vim/ directory" ; fi
diff --git a/src/lib/bash.completion b/src/lib/bash.completion
new file mode 100644
index 000000000..8caeb5c87
--- /dev/null
+++ b/src/lib/bash.completion
@@ -0,0 +1,7 @@
+# generic bash completion for plumed
+# actual function is generated with current plumed version
+
+_plumed() { eval "$(plumed --no-mpi completion 2>/dev/null)";}
+
+complete -F _plumed -o default plumed
+
diff --git a/user-doc/Miscelaneous.md b/user-doc/Miscelaneous.md
index 476adb46e..08f9794c5 100644
--- a/user-doc/Miscelaneous.md
+++ b/user-doc/Miscelaneous.md
@@ -96,12 +96,14 @@ dist: DISTANCES ...
 
 \page BashAutocompletion Using bash autocompletion
 
-For the impatients, just add the following to your .bashrc file:
+When possible, PLUMED tries to install bash autocompletion so that
+you do not have to do anything. Just use the `<TAB>` key to complete
+plumed commands (e.g. `plumed dr<TAB>`) or even options (e.g. `plumed driver --i<TAB>`).
+In case this does not work, you might have to add the following lines to your .bashrc file:
 \verbatim
 _plumed() { eval "$(plumed --no-mpi completion 2>/dev/null)";}
 complete -F _plumed -o default plumed
 \endverbatim
-and enjoy bash autocompletion.
 
 \par Effect
 
@@ -136,12 +138,19 @@ in this specific case.
 
 \par Technicalities
 
-The command `plumed completion` just writes on its standard output the body of a bash function.
+At configure time if the variable `BASH_COMPLETION_DIR` is defined it will be used to decide where PLUMED
+autocompletion should be installed. Otherwise, configure will look for the presence of the `bash-completion` package
+and, in case it is installed on the same prefix as PLUMED, also PLUMED autocompletion will be installed.
+Finally, if none of these two conditions are satisfied, autocompletion will not be enabled. You will
+have to change your bashrc file once adding the following lines:
 Now look at these lines:
 \verbatim
 _plumed() { eval "$(plumed --no-mpi completion 2>/dev/null)";}
 complete -F _plumed -o default plumed
 \endverbatim
+This is what you are expected to do if for instance you have multiple versions of PLUMED installed
+concurrently using separate env modules.
+The command `plumed completion` just writes on its standard output the body of a bash function.
 The `-o default` options will make sure that if `plumed --no-mpi completion` returns an error the default bash completion
 will be used. This is what will happen if you load an older PLUMED version for which the `completion` command is not available yet.
 In future PLUMED versions the `plumed completion` command might return more sophisticated functions. You should
-- 
GitLab