-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathemacs_install.sh
executable file
·302 lines (266 loc) · 8.74 KB
/
emacs_install.sh
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
#!/bin/bash
set -o pipefail
APTITUDE=0
YUM=0
PACMAN=0
AURPAC=""
if command -v aptitude >/dev/null ; then
APTITUDE=1
APTGET=aptitude
APTMARK=aptitude
APTCACHE=aptitude
elif command -v apt-get >/dev/null ; then
APTITUDE=1
APTGET=apt-get
APTMARK=apt-mark
APTCACHE=apt-cache
elif command -v yum >/dev/null ; then
YUM=1
elif command -v pacman >/dev/null ; then
PACMAN=1
if command -v pacaur > /dev/null ; then
AURPAC=pacaur
elif command -v yaourt > /dev/null ; then
AURPAC=yaourt
elif command -v yay > /dev/null ; then
AURPAC=yay
else
echo "An AUR capable package manager is required: e.g. pacaur, yaourt, or yay"
exit 1
fi
else
echo "Unrecognized Linux distribution" >&2
exit 1
fi
NEW_EMACS_EXECUTABLE_NAME=
if [ $APTITUDE -eq 1 ] ; then
# Ubuntu has a snapshot repo we can just add to get the latest
echo "Adding Ubuntu repo for latest Emacs snapshot..."
# check if it's already added
if [ -z "$(find /etc/apt -name '*.list' -exec grep -E '^[^#]+ubuntu-elisp/ppa' {} \;)" ] ; then
if command -v apt-add-repository ; then
sudo apt-add-repository ppa:ubuntu-elisp/ppa
if [ $? -ne 0 ] ; then
echo ""
echo ""
echo "Unable to add repository"
exit 1
fi
else
echo "Tool apt-add-repository not available!" >&2
exit 1
fi
sudo ${APTGET} update
if [ $? -ne 0 ] ; then
echo ""
echo ""
echo "Unable to update ${APTGET} database"
exit 1
fi
fi
echo ""
echo ""
echo "Getting latest Emacs snapshot..."
#check if it's already installed
if ! dpkg -l emacs-snapshot 2>/dev/null | grep -qE '.i.[ ]+emacs-snapshot[ ]+' &>/dev/null ; then
sudo ${APTGET} install -y emacs-snapshot
if [ $? -ne 0 ] ; then
echo ""
echo ""
echo "Unable to install emacs-snapshot"
exit 1
fi
echo ""
echo ""
echo "Setting emacs-snapshot to remain unchanged..."
sudo ${APTMARK} hold emacs-snapshot
if [ $? -ne 0 ] ; then
echo ""
echo ""
echo "Unable to mark emacs-snapshot to hold against updates"
exit 1
fi
fi
# the installed executable to set as the "emacs" version
NEW_EMACS_EXECUTABLE_NAME=$(which emacs-snapshot)
elif [ $YUM -eq 1 ] ; then
# Fedora, CentOS, etc don't have a snapshot repo, so we have to build from source
# get the list of deps for the emacs package, but exclude any sub-packages named emacs
DEPS=$(yum deplist emacs | awk '/provider:/ {print $2}' | sort -u | grep -v emacs | sed -e "s@[.]$(uname -i)@@g" -e "s@[.]noarch@@g" )
# we need the development versions of these packages too so we can build against them
DEVEL_DEPS=autoconf automake
for D in $DEPS ; do
DEVEL_DEPS="${DEVEL_DEPS} ${D}-devel"
done
if [ $? -ne 0 ] ; then
echo ""
echo ""
echo "Unable to determine dependencies for a generic emacs install"
exit 1
fi
# install emacs so we get all the dependencies
sudo yum install -y $(DEPS) ${DEVEL_DEPS}
if [ $? -ne 0 ] ; then
echo ""
echo ""
echo "Unable to install emacs dependencies"
exit 1
fi
EMACS_GIT_REPO=https://git.savannah.gnu.org/git/emacs.git
# clone the source for the emacs repo
git clone --recursive --depth=1 ${EMACS_GIT_REPO} emacs-src
if [ $? -ne 0 ] ; then
echo ""
echo ""
echo "Unable to clone emacs repo from ${EMACS_GIT_REPO}"
exit 1
fi
# go into the cloned directory
cd emacs-src
# fetch all available tags so we can parse them
git fetch --tags
# Parse the tags, and determine the latest non-RC release
# release tags are like "emacs-25.2.34" or "emacs-25.2" or "emacs-25.2-rc3"
VERSION=$(git tag -l | grep -E 'emacs-[0-9]+([.][0-9]+)+$' | sort | tail -n1)
if [ $? -ne 0 ] ; then
echo ""
echo ""
echo "Unable to determine latest tagged release version"
exit 1
fi
git checkout $VERSION
if [ $? -ne 0 ] ; then
echo ""
echo ""
echo "Cannot checkout git tag ${VERSION} in the emacs repo clone"
exit 1
fi
# run autogen to setup for the build
./autogen.sh
if [ $? -ne 0 ] ; then
echo ""
echo ""
echo "Error running autogen for ${VERSION}, see errors above"
exit 1
fi
# make sure the emacs version of ctags doesn't overwrite any sintall ctags version
./configure --without-makeinfo --program-transform-name='s/^ctags$/ctags.emacs/'
if [ $? -ne 0 ] ; then
echo ""
echo ""
echo "Error configuring ${VERSION}, see errors above"
exit 1
fi
make -j $(nproc)
if [ $? -ne 0 ] ; then
echo ""
echo ""
echo "Error builiding ${VERSION}, see errors above"
exit 1
fi
sudo make install
if [ $? -ne 0 ] ; then
echo ""
echo ""
echo "Error installing ${VERSION}, see errors above"
exit 1
fi
#parse down to only the part of the version that would be on the executable
EXE_VERSION=$(echo $VERSION | grep -Eo "emacs-[0-9]{2}[.][0-9]+")
# add the newly installed version to the alternatives list
sudo update-alternatives --install /usr/bin/emacs emacs /usr/local/bin/${EXE_VERSION} 10
if [ $? -ne 0 ] ; then
echo ""
echo ""
echo "Error adding ${EXE_VERSION} as an alternative"
exit 1
fi
# the installed executable to set as the "emacs" version
NEW_EMACS_EXECUTABLE_NAME=/usr/local/bin/${EXE_VERSION}
# cleanup by deleting the source repo
cd ..
rm -rf emacs-src
elif [ $PACMAN -eq 1 ] ; then
if ! pacman -Q emacs > /dev/null ; then
echo "Installing emacs from pacman, sudo access required"
sudo ${AURPAC} -Sy emacs
if [ $? -ne 0 ] ; then
echo ""
echo ""
echo "Unable to install emacs from ${AURPAC}"
exit 1
fi
fi
NEW_EMACS_EXECUTABLE_NAME=$(which emacs)
fi
if [ $PACMAN -ne 1 ] ; then
echo ""
echo ""
echo "Updating alternatives to use emacs-snapshot..."
sudo update-alternatives --set emacs ${NEW_EMACS_EXECUTABLE_NAME}
if [ $? -ne 0 ] ; then
echo ""
echo ""
echo "Unable to update emacs alternative to ${NEW_EMACS_EXECUTABLE_NAME}"
exit 1
fi
fi
echo ""
echo ""
echo "Creating link for .emacs config"
cd ~ && ln -sf .emacs.d/config/emacs .emacs
if [ $? -ne 0 ] ; then
echo ""
echo ""
echo "Couldn't create symlink from ~/.emacs to ~/.emacs.d/config/emacs"
exit 1
fi
if [ $PACMAN -eq 1 ] ; then
if ! pacman -Q ripgrep > /dev/null ; then
sudo ${AURPAC} -Sy ripgrep
if [ $? -ne 0 ] ; then
echo ""
echo ""
echo "Couldn't install ripgrep from ${AURPAC}"
exit 1
fi
fi
else
echo ""
echo ""
echo "Installing ripgrep"
if ! command -v rg &>/dev/null ; then
if command -v dpkg &>/dev/null ; then
RIPGREP_VERSION=0.10.0
if ! wget https://github.com/BurntSushi/ripgrep/releases/download/${RIPGREP_VERSION}/ripgrep_${RIPGREP_VERSION}_amd64.deb ; then
echo "ERROR: unable to get the ripgrep deb file"
exit 1
fi
#install it
sudo dpkg -i ripgrep_${RIPGREP_VERSION}_amd64.deb
#clean it up
rm ripgrep_${RIPGREP_VERSION}_amd64.deb
else
echo " Manual install required: https://github.com/BurntSushi/ripgrep/releases"
echo ""
fi
fi
fi
echo ""
echo ""
echo "Completed successfully!"
echo "Opening emacs for the first time to allow it to download missing packages."
echo "Note that this may result in warnings. Once completed, simply exit emacs and the additional"
echo "packages will be downloaded with a second invocation."
echo "This may take some time ..."
# Force it to re-initialize the packages immediately, otherwise
# it won't have the new elpa and melpa repos.
# We have to do this on the first time opening/running it or use-package won't find the
# missing package dependencies it needs to download and install.
# Compiling these packages frequently produces warnings though, so we can't do --debug-init.
# We do it twice with the refresh because it's pretty common to get an erroneous missing dependency
# compile error on some of the packages during the first run, that are resolved by simply exiting
# and re-running the same thing.
emacs --execute='(package-refresh-contents)'
emacs --execute='(package-refresh-contents)'
emacs --debug-init