There’s now an official build of Emacs that runs natively on Android phones – I came across a brief post about this on one of the Emacs blogs last month, and tried it out yesterday. It’s working pretty well; there are some weirdnesses and limitations, but it certainly displays my org-agenda in a passable way, which is realistically going to be my main use-case. Going to meetings at work and needing to agree on dates and times for subsequent meetings is always a bit of a feat of guesswork when my agenda is only available at a computer, so this will definitely help with that.
The setup process was actually smoother than I expected; the trickiest bit was wrangling file permissions on my phone to get the right stuff to sync properly, but it all seems to be working well for the moment. Here are a few notes I wanted to make on how this works:
One of the first things I had to do was install a second onscreen keyboard; I normally use GBoard, which I appreciate for its autocorrect and swipe mode, but it doesn’t show any modifier keys so I’d have no way of running any commands inside Emacs. I installed Hacker’s Keyboard to take care of this stuff, so now my workflow is “switch keyboard to run an Emacs command, switch keyboard to do literally anything else”, which is slightly laborious, but seems to be the only solution that allows me to actually do things in Emacs while being able to use autocorrect and the clipboard the rest of the time.
It took me a while to figure out how the storage inside Emacs intersects with the rest of the files on the phone. The folder Emacs recognises as ~
is actually specific to the program itself (I guess I should call it an app? Bizarre), and can’t be accessed by anything else that I’m aware of, even the Android file browser. Enabling global file access for Emacs in the phone settings allows Emacs to read from/write to other directories, as long as they’re inside /storage/emulated/0/
. This is done, confusingly, not in the settings for Emacs within the usual app settings, but in another setting called something like “special access”.
I wanted to sync my agenda files from Google Drive, so went back to an app called Autosync for Google Drive that I’d tried before when I was attempting to sync the same files so they could be viewed in various other apps that all ended up not really being fit for purpose. This also had to be given global file access, but at least I knew how to do this by this point. I paid £4.99 to unlock a couple of features including the ability to sync more than one pair of folders – I have some custom Emacs functions stored elsewhere in my Google Drive so now those are on my phone as well.
My .emacs.d
doesn’t live in Google Drive, but is “synced” among my systems using Git, and and I didn’t want to start fiddling with things by putting a copy on GDrive or anything like that. I found another app called MGit that actually has many more features than I need (really all I want is pull
), but was sufficient for getting my config onto the phone, or at least into the specific folder /storage/emulated/0/Documents/
, the only one that MGit is allowed to access; I then had to go into Emacs and open each relevant file in turn, and then use M-x write-file
to copy each of them into the phone’s .emacs.d
, which was definitely the most time-consuming part of the process, and will obviously need to be repeated whenever I make changes to my config in the future (so, like, tomorrow then).
I also had to make a few edits to my setup to ensure my config would load properly on Android without errors. More on this below, but most of it was just wrapping a lot of computer-only stuff in (unless (string-equal system-type "android"))
. I updated everything on my computer, somewhat speculatively, and was pleasantly surprised the only thing I hadn’t taken into account before transferring the config over was the fact that Android doesn’t seem to believe in scrollbars, which makes sense, I suppose.
Very non-FOSS-ly of me, I’m too scared to post on a mailing list full of venerable techbros and engage in earnest discourse about whether this really is a bug, but certain attempts to use (add-to-list)
refused to work properly, so I ended up having to just redefine the list entirely as a quoted value (i.e. (setq org-agenda-files '("/storage/emulated/0/Documents/org/calendar/music.org" "/storage/emulated/0/Documents/org/calendar/admin.org"))
instead of (add-to-list 'org-agenda-files "~/Documents/drive/org/calendar/music.org")
… (add-to-list 'org-agenda-files "~/Documents/drive/org/calendar/admin.org")
. Confusingly, another use of (add-to-list)
worked fine, so I don’t know what’s going on here.
The Android version of Emacs doesn’t include GNUTLS, so it can’t connect to servers and therefore can’t download packages with (use-package)
. I guess if I was extremely hardcore I could just copy the package files into .emacs.d
myself (and byte-compile them?? not that I know what this means), but none of the third-party packages I’m using elsewhere are absolutely essential on my phone, so I’ve just wrapped them in that (unless)
function. To be fair, this probably improves the load time.
Even with Hacker’s Keyboard, the worst thing about this implementation of Emacs is the way it responds to keyboard commands. More often than not (but not always, which is odd), if I try entering a command that ends with a non-modified key (e.g. C-x 1
), it interprets the modified key correctly and then just writes the next bit of the command into the buffer and tells me (e.g.) C-x <text-conversion> is undefined
. Googling this seems to return nothing, so I’m guessing it’s an issue that only happens on Android versions. The consequence is that I’ve had to unlearn a lot of keybindings, because commands that end by pressing enter always work fine, so M-x …
is a safe bet. For the same reason, I’ve redefined y-or-n-p
to yes-or-no-p
, which is hilarious, because all the Emacs chads love to do the opposite.
The other keyboard issue is that the keyboard can’t be used in read-only buffers – and obviously you’d think “why would the keyboard need to be used in read-only buffers”, but technically the agenda dispatcher comes into this category, so I can’t use any of the single-keyboard-press commands that I’d normally use to navigate it. I guess this means that if I ever need to view a date that isn’t within the next week, I’ll need to type it as an org timestamp in the scratch buffer first, and then tap that to bring the date up … that’s fine. It also makes it quite hard to exit the agenda, so I end up just closing Emacs with it still open, which feels very Wrong to me, but I suppose it’s not really a problem.