summaryrefslogtreecommitdiff
path: root/scripts/Scripts/vimv
blob: 83518ad74761c2337a17953ea96d3468be7fb218 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#!/usr/bin/env bash
set -eu

# Lists the current directory's files in Vim, so you can edit it and save to rename them
# USAGE: vimv [file1 file2]
# https://github.com/thameera/vimv

declare -r FILENAMES_FILE=$(mktemp "${TMPDIR:-/tmp}/vimv.XXXXXX")

trap '{ rm -f "${FILENAMES_FILE}" ; }' EXIT

safeMove() {
    local src="$1"
    local dest="$2"
    mkdir -p "$(dirname "$dest")"
    if [ -e "$dest" ]; then
        echo "WARN: Can't rename '$src' -> '$dest', destination exists!" >&2
        return 1
    fi
    if git ls-files --error-unmatch "$src" > /dev/null 2>&1; then
        git mv -- "$src" "$dest"
    else
        mv -n -- "$src" "$dest"
    fi
}

if [ $# -ne 0 ]; then
    src=( "$@" )
else
    IFS=$'\r\n' GLOBIGNORE='*' command eval 'src=($(ls -1A))'
fi

for ((i=0;i<${#src[@]};++i)); do
    echo "${src[i]}" >> "${FILENAMES_FILE}"
done

${EDITOR:-vi} "${FILENAMES_FILE}"

IFS=$'\r\n' GLOBIGNORE='*' command eval 'dest=($(cat "${FILENAMES_FILE}"))'
IFS=$'\r\n' GLOBIGNORE='*' command eval 'dest_unique=($(cat "${FILENAMES_FILE}" | sort -u))'

if (( ${#src[@]} != ${#dest[@]} )); then
    echo "WARN: Number of files changed. Did you delete a line by accident? Aborting.." >&2
    exit 1
fi

if (( ${#dest[@]} != ${#dest_unique[@]} )); then
    echo "WARN: Destination filenames are not unique! Aborting.." >&2
    exit 1
fi

declare -i count=0
EXT="vimv-tmp-$(date +%s)-${RANDOM}"
for ((i=0;i<${#src[@]};++i)); do
    if [ "${src[i]}" != "${dest[i]}" ]; then
        safeMove "${src[i]}" "${dest[i]}.${EXT}" && ((++count))
    fi
done

for ((i=0;i<${#src[@]};++i)); do
    if [ "${src[i]}" != "${dest[i]}" ]; then
        safeMove "${dest[i]}.${EXT}" "${dest[i]}" || : resume on error
    fi
done

echo "$count" files renamed.