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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
|
#!/bin/bash
# Created By: srdusr
# Created On: Sat 12 Aug 2023 13:11:39 CAT
# Project: Install/update/downgrade/change version/uninstall Neovim script, primarily for Linux but may work in other platforms
# Color definitions
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color
BOLD=$(tput bold)
NORMAL=$(tput sgr0)
# Define the variable for the date difference command
DATEDIFF_COMMAND="datediff"
# Check if necessary dependencies are installed
check_dependencies() {
missing_dependencies=()
for cmd in wget curl xmllint; do
if ! [ -x "$(command -v "$cmd")" ]; then
missing_dependencies+=("$cmd")
fi
done
if [ -x "$(command -v datediff)" ]; then
DATEDIFF_COMMAND="datediff"
elif [ -x "$(command -v dateutils.ddiff)" ]; then
DATEDIFF_COMMAND="dateutils.ddiff"
else
missing_dependencies+=("datediff")
fi
if [ ${#missing_dependencies[@]} -gt 0 ]; then
printf "\n${RED}Missing dependencies: ${missing_dependencies[*]}. Please install them to continue!${NC}\n"
exit 1
fi
}
# Check for privilege escalation tools
check_privilege_tools() {
if [ -x "$(command -v sudo)" ]; then
PRIVILEGE_TOOL="sudo"
elif [ -x "$(command -v doas)" ]; then
PRIVILEGE_TOOL="doas"
elif [ -x "$(command -v pkexec)" ]; then
PRIVILEGE_TOOL="pkexec"
elif [ -x "$(command -v dzdo)" ]; then
PRIVILEGE_TOOL="dzdo"
elif [ "$(id -u)" -eq 0 ]; then
PRIVILEGE_TOOL="" # root
else
PRIVILEGE_TOOL="" # No privilege escalation mechanism found
printf "\n${RED}Error: No privilege escalation tool (sudo, doas, pkexec, dzdo, or root privileges) found. You may not have sufficient permissions to run this script.${NC}\n"
printf "\nAttempt to continue Installation (might fail without a privilege escalation tool)? [yes/no] "
read continue_choice
case $continue_choice in
[Yy] | [Yy][Ee][Ss]) ;;
[Nn] | [Nn][Oo]) exit ;;
*) echo "Invalid choice. Exiting..." && exit ;;
esac
fi
}
check_privilege_tools
# Install Neovim
install_neovim() {
printf "${GREEN}Installing Neovim...${NC}\n"
# Detect the operating system to determine the appropriate installation method
case "$(uname -s)" in
Linux)
printf "Detected Linux OS.\n"
# Check if FUSE is available
if [ -x "$(command -v fusermount)" ]; then
printf "FUSE is available. Downloading and running the AppImage...\n"
wget https://github.com/neovim/neovim/releases/download/nightly/nvim.appimage -q -O nvim.appimage
chmod u+x nvim.appimage
"$PRIVILEGE_TOOL" cp nvim.appimage /usr/local/bin/nvim
"$PRIVILEGE_TOOL" mv nvim.appimage /usr/bin/nvim
nvim
else
printf "FUSE is not available. Downloading and extracting the AppImage...\n"
wget https://github.com/neovim/neovim/releases/download/nightly/nvim.appimage -q -O nvim.appimage
chmod u+x nvim.appimage
./nvim.appimage --appimage-extract
"$PRIVILEGE_TOOL" cp squashfs-root/usr/bin/nvim /usr/local/bin
"$PRIVILEGE_TOOL" mv squashfs-root/usr/bin/nvim /usr/bin
nvim
fi
;;
Darwin)
printf "Detected macOS.\n"
wget https://github.com/neovim/neovim/releases/download/nightly/nvim-macos.tar.gz -q -O nvim-macos.tar.gz
xattr -c ./nvim-macos.tar.gz
tar xzvf nvim-macos.tar.gz
"$PRIVILEGE_TOOL" cp nvim-macos/bin/nvim /usr/local/bin
"$PRIVILEGE_TOOL" mv nvim-macos/bin/nvim /usr/bin
nvim
;;
MINGW*)
printf "Detected Windows.\n"
if [ "$PRIVILEGE_TOOL" = "sudo" ]; then
curl -LO https://github.com/neovim/neovim/releases/download/nightly/nvim.appimage && chmod +x nvim.appimage
"$PRIVILEGE_TOOL" cp nvim.appimage /usr/local/bin/nvim
"$PRIVILEGE_TOOL" mv /usr/local/bin/nvim /usr/bin
nvim
elif [ "$PRIVILEGE_TOOL" = "" ]; then
curl -LO https://github.com/neovim/neovim/releases/download/nightly/nvim.appimage && chmod +x nvim.appimage
cp nvim.appimage /usr/local/bin/nvim
mv /usr/local/bin/nvim /usr/bin
nvim
else
printf "No privilege escalation tool found. Cannot install Neovim on Windows.\n"
fi
;;
*)
printf "Unsupported operating system.\n"
;;
esac
printf "${GREEN}Neovim has been installed successfully!${NC}\n"
}
# Uninstall Neovim
uninstall_neovim() {
printf "${RED}Uninstalling Neovim...${NC}\n"
# Detect the operating system to determine the appropriate uninstallation method
case "$(uname -s)" in
Linux)
printf "Detected Linux OS.\n"
"$PRIVILEGE_TOOL" rm /usr/local/bin/nvim
"$PRIVILEGE_TOOL" rm /usr/bin/nvim
;;
Darwin)
printf "Detected macOS.\n"
"$PRIVILEGE_TOOL" rm /usr/local/bin/nvim
"$PRIVILEGE_TOOL" rm /usr/bin/nvim
;;
MINGW*)
printf "Detected Windows.\n"
if [ "$PRIVILEGE_TOOL" = "sudo" ]; then
"$PRIVILEGE_TOOL" rm /usr/local/bin/nvim
"$PRIVILEGE_TOOL" rm /usr/bin/nvim
else
[ "$PRIVILEGE_TOOL" = "" ]
rm /usr/local/bin/nvim
rm /usr/bin/nvim
fi
;;
*)
printf "Unsupported operating system.\n"
;;
esac
printf "${GREEN}Neovim has been uninstalled successfully!${NC}\n"
}
# Check if Neovim is already installed
check_neovim_installed() {
if [ -x "$(command -v nvim)" ]; then
return 0 # Neovim is installed
else
return 1 # Neovim is not installed
fi
}
# Define the variable to control the prompt
SHOW_PROMPT=1
# Check if necessary dependencies are installed
check_dependencies
# Check if Neovim is already installed
if check_neovim_installed; then
printf "${GREEN}Neovim is already installed!${NC}\n"
else
# Prompt user for initial installation
read -p "Neovim is not installed. Do you want to install it? [yes/no] " install_choice
case $install_choice in
[Yy]*) install_neovim ;;
[Nn]*) ;;
*) echo "Please answer yes or no." ;;
esac
fi
# Fetch the latest Neovim Nightly release information from GitHub
wget https://github.com/neovim/neovim/releases/tag/nightly -q -O - >/tmp/nvim_release_info
RESPONSE=$(wget https://github.com/neovim/neovim/releases/tag/nightly --save-headers -O - 2>&1)
# Check if the release exists
if [[ "$RESPONSE" =~ 404\ Not\ Found ]]; then
printf "${RED}Unable to fetch latest Neovim Nightly info. Exiting...${NC}\n"
exit
fi
# Initialize variables
should_prompt=0
current_version=$(nvim --version | head -n 1)
new_version=$(xmllint --html --xpath "//pre//code/node()" /tmp/nvim_release_info 2>/dev/null | grep NVIM)
current_datetime_iso=$(date --iso-8601=ns)
new_release_datetime_iso=$(xmllint --html --xpath "string(//relative-time/@datetime)" /tmp/nvim_release_info 2>/dev/null)
time_since_release=$("DATEDIFF_COMMAND" "$new_release_datetime_iso" "$current_datetime_iso" -f "%H hours %M minutes ago")
# Check if the new Neovim version is available
if [[ "$new_version" == "" ]]; then
printf "\n${RED}Failed to retrieve latest Neovim Nightly version from the repository. Aborting...${NC}\n"
exit
fi
# Check if the current version is already the latest
if [[ "$current_version" == "$new_version" ]]; then
printf "\n${RED}No new ${BOLD}Neovim Nightly${NORMAL}${RED} version found!\n${NC}Last release: ${time_since_release}\nExiting...\n"
exit
fi
# If a newer version is found, prompt the user
if [[ "$current_version" != "$new_version" ]]; then
printf "\n${GREEN}New ${BOLD}Neovim Nightly${NORMAL}${GREEN} version available!${NC}\n${current_version} -> ${BOLD}${new_version}${NORMAL}\nReleased: ${time_since_release}\n\n"
should_prompt=1
fi
# Function to update Neovim Nightly
update_neovim() {
printf "${RED}Updating Neovim Nightly...${NC}\n"
download_url="https://github.com/neovim/neovim/releases/download/nightly/nvim.appimage"
curl_command="curl -L -w http_code=%{http_code}"
curl_output=$("$curl_command" "$download_url" -o /tmp/nvim)
http_code=$(echo "$curl_output" | sed -e 's/.*\http_code=//')
error_message=$(echo "$curl_output" | sed -e 's/http_code.*//')
if [[ $http_code == 200 ]]; then
chmod +x /tmp/nvim
"$PRIVILEGE_TOOL" cp /tmp/nvim /usr/local/bin
"$PRIVILEGE_TOOL" mv /tmp/nvim /usr/bin
printf "${GREEN}Neovim Nightly updated successfully!${NC}\n"
else
printf "${RED}Failed to update Neovim Nightly! ERROR: ${error_message}${NC}\n"
fi
}
rm /tmp/nvim_release_info
downgrade_neovim() {
# Fetch all the release tags from GitHub
ALL_TAGS=$(curl -s "https://api.github.com/repos/neovim/neovim/tags" | grep '"name":' | cut -d '"' -f 4)
# Filter out major version tags (assumes version tag format is "vx.y.z")
MAJOR_VERSIONS=$(echo "$ALL_TAGS" | grep -E "^v[0-9]+\.[0-9]+\.0$")
# Show available major versions to the user
echo "Available major versions:"
echo "$MAJOR_VERSIONS"
# Ask user to choose a version
read -p "Enter the major version to downgrade to (e.g., v0.1, v0.2, ...): " DESIRED_MAJOR_VERSION
# Construct the desired version tag
DESIRED_VERSION=$(echo "$MAJOR_VERSIONS" | grep "$DESIRED_MAJOR_VERSION")
if [ "$DESIRED_VERSION" = "" ]; then
echo "Invalid major version. Exiting..."
exit 1
fi
printf "${RED}Downgrading Neovim to version $DESIRED_VERSION...${NC}\n"
# Construct the URL for the desired version's release page on GitHub
RELEASE_URL="https://github.com/neovim/neovim/releases/tag/$DESIRED_VERSION"
# Download the release page HTML
wget "$RELEASE_URL" -q -O /tmp/neovim_release.html
# Find the download URL for the desired version's binary
DOWNLOAD_URL=$(grep -o "https://github.com/neovim/neovim/releases/download/$DESIRED_VERSION/nvim.appimage" /tmp/neovim_release.html)
# Download the desired version of Neovim
wget "$DOWNLOAD_URL" -q -O /tmp/nvim
# Make the downloaded binary executable
chmod +x /tmp/nvim
# Install the downloaded binary to appropriate locations
"$PRIVILEGE_TOOL" cp /tmp/nvim /usr/local/bin
"$PRIVILEGE_TOOL" mv /tmp/nvim /usr/bin
# Clean up temporary files
rm /tmp/neovim_release.html
printf "${GREEN}Neovim has been downgraded to version $DESIRED_VERSION successfully!${NC}\n"
}
use_stable_neovim() {
# Fetch the latest stable version tag from GitHub releases
STABLE_NVIM_VERSION=$(curl -s "https://api.github.com/repos/neovim/neovim/releases/latest" | grep '"tag_name":' | cut -d '"' -f 4)
printf "${RED}Using Latest Stable Neovim version $STABLE_NVIM_VERSION...${NC}\n"
# Construct the URL for the latest stable version's release page on GitHub
RELEASE_URL="https://github.com/neovim/neovim/releases/tag/$STABLE_NVIM_VERSION"
# Download the release page HTML
wget "$RELEASE_URL" -q -O /tmp/neovim_release.html
# Find the download URL for the latest stable version's binary
DOWNLOAD_URL=$(grep -o "https://github.com/neovim/neovim/releases/download/$STABLE_NVIM_VERSION/nvim.appimage" /tmp/neovim_release.html)
# Download the latest stable version of Neovim
wget "$DOWNLOAD_URL" -q -O /tmp/nvim
# Make the downloaded binary executable
chmod +x /tmp/nvim
# Install the downloaded binary to appropriate locations
"$PRIVILEGE_TOOL" cp /tmp/nvim /usr/local/bin
"$PRIVILEGE_TOOL" mv /tmp/nvim /usr/bin
# Clean up temporary files
rm /tmp/neovim_release.html
printf "${GREEN}Latest Stable Neovim version $STABLE_NVIM_VERSION has been set up successfully!${NC}\n"
}
while [ "$SHOW_PROMPT" -gt 0 ]; do
read -p "Do you wish to update, downgrade, or use stable Neovim? [update/downgrade/stable/no] " choice
case $choice in
[Uu]*)
update_neovim
break
;;
[Dd]*)
downgrade_neovim
break
;;
[Ss]*)
use_stable_neovim
break
;;
[Nn]*) exit ;;
*) echo "Please choose update, downgrade, stable, or no." ;;
esac
done
|