Skip to content

Instantly share code, notes, and snippets.

@thequux
Last active May 31, 2016 22:35
Show Gist options
  • Save thequux/388004f2a29523e8f55db119df41950b to your computer and use it in GitHub Desktop.
Save thequux/388004f2a29523e8f55db119df41950b to your computer and use it in GitHub Desktop.
Multirust-compatible racer wrapper

This wrapper automatically sets the RUST_SRC_DIRECTORY environment variable for whatever rust compiler is currently active, automatically creating a new checkout whenever necessary. This should be compatible with all of the multirust-alike tools, but it has only been tested with rustup.rs

Installation

Simply place this somewhere on your path before the main racer binary and set the execute bit.

Uninstallation

See rm(1).

Bugs

If you keep up to date with nightly, this will likely result in your disk slowly filling with copies of the rust source tree. While there are far worse uses for the disk space, you also likely have better. You may simply delete all directories beginning with rust- in $RUST_SOURCE_ROOT (${RUSTUP_HOME}/src or ${HOME}/.multirust/src, whichever is defined) to reclaim the disk space. (Strictly speaking, you can also remove the git directory, but it will automatically be redownloaded the next time the wrapper is run so this usually doens't make sense.)

#!/bin/bash
# Set a default for RUSTUP_HOME
: ${RUSTUP_HOME:=${HOME}/.multirust}
: ${RUST_SOURCE_ROOT:=${RUSTUP_HOME}/src}
[[ -d ${RUST_SOURCE_ROOT} ]] || mkdir -p "${RUST_SOURCE_ROOT}"
SELF_FOUND=0
# TODO: This doesn't deal well with path entries that contain spaces
for cmd in $(which -a "$(basename "$0")"); do
if (( $SELF_FOUND == 1 )); then
NEXT_RACER="${cmd}"
elif [[ "${cmd}" -ef "$0" ]]; then
SELF_FOUND=1
fi
done
if ! (( $SELF_FOUND )); then
: ${NEXT_RACER:=racer}
fi
function vivify() {
HASH=$1
export GIT_DIR="$RUSTUP_HOME/src/git"
if ! [[ -d "${GIT_DIR}" ]]; then
git clone --bare --quiet https://github.com/rust-lang/rust "${GIT_DIR}"
fi
if (( $(date +%s) - 3600*12 > $(stat -c %Y "${GIT_DIR}") )); then
git fetch --all
fi
TREE="$(git rev-parse --verify --quiet "${HASH}^{tree}")"
if [[ $? -ne 0 ]]; then
echo "Inable to resolve ${HASH}" >/dev/stderr
exit 1
fi
if ! [[ -d "${RUST_SOURCE_ROOT}/rust-${TREE}" ]]; then
git archive --prefix=rust-"${TREE}/" ${HASH} | tar xC "${RUST_SOURCE_ROOT}"
fi
readlink -f "${RUST_SOURCE_ROOT}/rust-${TREE}"
}
function rust_version() {
# Get the current rust compiler version
local RUST_COMMIT="$(rustc -vV 2>/dev/null |awk '($1 == "commit-hash:") { print $2 }')"
if (( $? )); then
echo "Rust isn't installed!" >/dev/stderr
exit 2
fi
echo $RUST_COMMIT
}
exec env RUST_SRC_PATH="$(vivify "$(rust_version)")/src" "${NEXT_RACER}" "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment