# -*-eselect-*- # Copyright 2005-2014 Gentoo Authors # Distributed under the terms of the GNU GPL version 2 or later # # DOCUMENTATION # Following actions possible # * show do_show() # * list do_list() # * set do_set() # * update do_update() # # Behaviour: # do_show(): # Checks if /usr/bin/emacs is a link and if the target exists, # if yes, it outputs the currently linked Emacs version. # If it is no symlink, the user is told so, the same if there is # no /usr/bin/emacs or the target does not exist. # do_list(): List all available versions of GNU Emacs # do_set(): Set a version to be target of the symlink. # do_update(): Set the target to the highest version available # (optionally: only if not set) DESCRIPTION="Manage /usr/bin/emacs version" MAINTAINER="emacs@gentoo.org" VERSION="1.18" # ctags and etags are handled in their own module BINARYLIST="emacsclient b2m ebrowse rcs-checkin grep-changelog" MANPAGELIST="${BINARYLIST}" HEADERLIST="emacs-module.h" find_targets() { # Return the list of available Emacs binaries local j for j in "${EROOT}"/usr/bin/emacs-[0-9]*; do [[ -f ${j} ]] && basename ${j} done } remove_infopath() { # When cleaning symlinks this takes care of the info documentation settings rm -f "${EROOT}/etc/env.d/50emacs" } # Define INFOPATH environment variable in env file set_infopath() { [[ -d ${EROOT}/usr/share/info/$1 ]] || return 1 echo "INFOPATH=${EPREFIX}/usr/share/info/$1" >"${EROOT}/etc/env.d/50emacs" } remove_symlinks() { # Remove existing symlinks to binaries, man pages, # and the env file (own function) local f for f in emacs ${BINARYLIST}; do rm -f "${EROOT}/usr/bin/${f}" done for f in emacs ${MANPAGELIST}; do rm -f "${EROOT}/usr/share/man/man1/${f}.1"* done for f in ${HEADERLIST}; do rm -f "${EROOT}/usr/include/${f}" done remove_infopath } set_bin_symlinks() { # Set symlinks to binaries in /usr/bin/ local target=$1 f for f in ${BINARYLIST}; do # set symlink only if target binary actually exists if [[ -f ${EROOT}/usr/bin/${f}-${target} ]]; then ln -s "${f}-${target}" "${EROOT}/usr/bin/${f}" || die \ "Couldn't set ${f}-${target} ${EROOT}/usr/bin/${f} symlink" fi done } set_man_symlinks() { # Set symlinks to man pages local target=$1 suffix f i for f in ${MANPAGELIST}; do for i in "${EROOT}/usr/share/man/man1/${f}-${target}.1"*; do if [[ -f ${i} ]]; then # target file exists; determine compression suffix suffix=${i##*/"${f}-${target}.1"} ln -s "${f}-${target}.1${suffix}" \ "${EROOT}/usr/share/man/man1/${f}.1${suffix}" fi done done } set_header_symlinks() { # Set symlinks to header files in /usr/include/ local target=$1 f for f in ${HEADERLIST}; do if [[ -f ${EROOT}/usr/include/${target}/${f} ]]; then ln -s "${target}/${f}" "${EROOT}/usr/include/${f}" \ || die "Couldn't set ${EROOT}/usr/include/${f} symlink" fi done } set_symlinks() { # Set symlinks to binaries and man pages, update info path local target=$1 nomain=$2 targets suffix i # target may be specified by its name or its index if is_number "${target}"; then # numeric index, find the target's name targets=( $(find_targets) ) [[ ${target} -ge 1 && ${target} -le ${#targets[@]} ]] \ || die -q "Number out of range: $1" target=${targets[target-1]} fi # is the target valid, i.e. does an Emacs binary with this name exist? [[ -f ${EROOT}/usr/bin/${target} ]] \ || die -q "Target \"$1\" doesn't appear to be valid!" echo "Switching emacs to ${target} ..." remove_symlinks || die -q "Couldn't remove existing symlink" # the main /usr/bin/emacs symlink is only set for Emacs binaries # (but not for other providers of auxiliary programs, e.g., XEmacs) if [[ -z ${nomain} ]]; then ln -s "${target}" "${EROOT}/usr/bin/emacs" \ || die "Couldn't set ${target} ${EROOT}/usr/bin/emacs symlink" for i in "${EROOT}/usr/share/man/man1/${target}.1"*; do if [[ -f ${i} ]]; then suffix=${i##*/"${target}.1"} ln -s "${target}.1${suffix}" \ "${EROOT}/usr/share/man/man1/emacs.1${suffix}" fi done fi set_bin_symlinks "${target}" set_man_symlinks "${target}" set_header_symlinks "${target}" set_infopath "${target}" # update /etc/profile.env from /etc/env.d files do_action env update noldconfig return 0 } xemacs_info() { # This is just informational to tell that XEmacs has been found, # a wish from graaff if [[ -e ${EROOT}/usr/bin/xemacs ]]; then echo write_list_start "XEmacs is also installed" fi } vim_info() { # Don't take this too serious if [[ -e ${EROOT}/usr/bin/vi ]]; then echo write_list_start "Vi found, your system is in real trouble now! ;)" fi } test_for_root() { # checks if the user has rights to modify /usr/bin/ [[ -w ${EROOT}/usr/bin ]] || die -q "You need root privileges!" } ### show action ### describe_show() { echo "Show the current target of the Emacs symlink" } do_show() { [[ $# -gt 0 ]] && die -q "Too many parameters" write_list_start "Current target of Emacs symlink:" if [[ -L ${EROOT}/usr/bin/emacs && -e ${EROOT}/usr/bin/emacs ]]; then write_kv_list_entry \ "$(basename "$(readlink "${EROOT}/usr/bin/emacs")")" "" elif [[ -e ${EROOT}/usr/bin/emacs ]]; then write_kv_list_entry \ "(not a symlink or target of symlink does not exist)" "" else write_kv_list_entry "(unset)" "" fi if ! is_output_mode brief; then xemacs_info #vim_info fi } ### list action ### describe_list() { echo "List available Emacs symlink targets" } do_list() { [[ $# -gt 0 ]] && die -q "Too many parameters" local i targets targets=( $(find_targets) ) for (( i = 0; i < ${#targets[@]}; i++ )); do # Highlight the currently chosen version [[ ${targets[i]} = \ "$(basename "$(readlink "${EROOT}/usr/bin/emacs")")" ]] \ && targets[i]=$(highlight_marker "${targets[i]}") done write_list_start "Available Emacs symlink targets:" write_numbered_list -m "(none found)" "${targets[@]}" if ! is_output_mode brief; then xemacs_info #vim_info fi } ### set action ### describe_set() { echo "Set a new Emacs symlink" } describe_set_options() { echo "target : Target name or number (from 'list' action)" } describe_set_parameters() { echo "" } do_set() { [[ -z $1 ]] && die -q "You didn't tell me what to set the symlink to" [[ $# -gt 1 ]] && die -q "Too many parameters" test_for_root if [[ -e ${EROOT}/usr/bin/emacs && ! -L ${EROOT}/usr/bin/emacs ]]; then die -q "${EROOT}/usr/bin/emacs exists but is not a symlink" fi set_symlinks "$1" || die -q "Couldn't set a new symlink" # ctags symlinks are handled in an own module now do_action ctags update } ### update action ### describe_update() { echo "Automatically update the Emacs symlink" } describe_update_options() { echo "ifunset : Do not override currently set version" } do_update() { [[ -z $1 || $1 = ifunset || $1 = --if-unset ]] || die -q "Usage error" [[ $# -gt 1 ]] && die -q "Too many parameters" test_for_root if [[ -L ${EROOT}/usr/bin/emacs ]]; then if [[ $1 = *if*unset && -e ${EROOT}/usr/bin/emacs ]]; then do_action ctags update ifunset return fi # this is not redundant: "update" is called in pkg_postrm() of emacs # and should clean up any dead symlinks if no valid target exists remove_symlinks || die -q "Couldn't remove existing symlink" elif [[ -e ${EROOT}/usr/bin/emacs ]]; then die -q "${EROOT}/usr/bin/emacs exists but is not a symlink" fi local targets=( $(find_targets) ) if [[ ${#targets[@]} -gt 0 ]]; then set_symlinks "${targets[${#targets[@]}-1]}" \ || die -q "Couldn't set a new symlink" elif [[ -f ${EROOT}/usr/bin/xemacs ]]; then # no Emacs target found - link to XEmacs versions set_symlinks xemacs nomain fi # ctags and etags symlinks are handled in an own module do_action ctags update }