Swift TIL 3

Posted on 2020-06-24 16:38 +0100 in TIL • Tagged with Swift, Apple • 1 min read

Today's little "Swift TIL" is observers. While reading up on the language I was delighted to find that it has observer support baked right into the language, for any sort of variable. So code like this:

var name  = "David" {

    willSet( new ) {
        print( "About to change name from \(name) to \(new)" )
    }

    didSet( old ) {
        print( "Name changed from \(old) to \(name)" )
    }
}

name = "davep"

Does what you'd imagine:

About to change name from David to davep
Name changed from David to davep

Not only can I see how that'd be useful for the main sorts of purposes that Swift is put to, I can think of many times when I'd have benefitted from that in my general day-to-day work. Of course, you can create an observer approach in any language really, but having an idiom that's part of the language feels nice and tidy.


Swift TIL 2

Posted on 2020-06-23 14:21 +0100 in TIL • Tagged with Swift, Apple • 1 min read

Following on with writing little notes to myself so I remember some key things as I learn about Swift...

I sort of feel like this will make reading code a little harder, so it's one I want to keep in mind. When calling an instance method, if it's not ambiguous, you can omit self. from the call. For example:

class Foo {
    private func inner() -> String { "Foo" }
    func outer() -> String { inner() + self.inner() }
}

print( Foo().outer() )

This makes me feel a little uneasy, and I strongly suspect I'll always use self. when writing such code: I'm a big fan of the idea that we write code for people, not for compilers.


Swift TIL 1

Posted on 2020-06-22 13:18 +0100 in TIL • Tagged with Swift, Apple • 1 min read

As I mentioned yesterday, I'm going to make a small series of posts where I write down things that I've stumbled on while getting to know Swift that are, for me personally, worthy of note, different, unusual, cool, or just simply "WTF!?!".

Because learning new stuff is fun.

My first one is that you can use keywords as identifiers if you "escape" them with backticks. Kind of like this:

let `let` = "let"

print( `let` )

I'm struggling to imagine a situation where I'd ever want to do this. I'm still unsure if my reaction is "that's cool" or "WTF?!?".


A second attempt to learn Swift

Posted on 2020-06-21 14:48 +0100 in Coding • Tagged with Swift, Apple, coding • 4 min read

It's five years ago this month that I bought myself my first macOS (then OS X) device. After many years of having a Windows machine as my daily driver, which was also my work machine (I worked from home), I decided it was high time that I returned to having a Unix-a-like system on my desk too. For a decade or so, starting in the later-90s, I'd had a GNU/Linux desktop. I still had a Windows desktop (until a couple of years ago most of my work was on DOS and Windows), but thanks to the wonders of a KVM, and later an X server that ran on Windows, my personal hacking was done on a GNU/Linux desktop.

But as things moved around, priorities changed, as life moved on, the GNU/Linux boxes got retired and never quite replaced. Eventually, in 2015, I found myself with the means and desire to recover that sort of setup. Long story short, after a lot of reading up and weighing up options I decided that the best option for a desktop Unix was... an iMac!

I loved it. Sure, there were lots of little things on the surface that were different or annoying or just plain not as cool as the Mac fans would tell you, but under the hood I found what I needed: a Unix CLI with all the things I knew well. And, of course, it ran GNU Emacs just fine; that was the really important thing for me.

Pretty much right away I decided that it might be fun to learn the tools necessary to develop native Mac apps, and perhaps even iOS apps. I downloaded XCode, bought a book, and started working through it. Having got that book, I decided it might be interesting to own an iOS device too. So, sort of needing an MP3 player, and having no wish to get an iPhone, I got myself an iPod Touch. So I was all set to devour the Swift book, write some stuff for OS X, create an iOS app or two, and... life happened. Stuff cropped up that distracted me from taking that further and I never really returned to working through the book.

Fast forward to now and that initial iMac and iPod purchase spiralled a wee bit. Next after the iPod was an iPad Mini, when my Nexus 7 was starting to show its age and it was obvious that Google wasn't going to produce any more good Android tablets. Then, when I needed a very portable Unix-a-like machine for trips between where I was living and Edinburgh, I got myself a MacBook Air. Since then the iPod Touch has been replaced once, as has the iPad Mini. I now also own an iPad and a MacBook Pro. Unless Apple screw up and turn Macs into something unusable for developers (there are rumours), I imagine I'll be using Apple devices for some time to come now.

And then, last month, having finally got frustrated with where Google were going with Android and the Pixel series, I jumped ship to the iPhone 11.

As of right now I'm in a situation where I'm all about the Apple ecosystem regarding hardware and operating systems (including for my work machine), all of which is there to support my heavy use of the Google ecosystem (actually, the one bit of Google hardware I still lean on heavily is the Google Home -- I have 3 around my home).

So... given all of that, I thought it was time to look at returning to learning Swift, with a view to writing some native macOS and i(Pad)OS stuff. I soon realised that the book I'd bought back in 2015 was rather out of date. It covers Swift 1.2 -- we're now up to 5.2! Given this, and given I've forgotten pretty much everything I'd read at the time, I decided I should start again from scratch.

This weekend I've started reading my way though iOS Programming Fundamentals with Swift. While this obviously has an emphasis on iOS, I'm already finding that the first part of the book is a really great introduction to the Swift language in general. The pace seems just right, and the way topics are grouped makes it easy enough for me to skip over what's obvious (I don't need to know what objected-oriented programming is, and what the difference between a class and an object is, etc) and read up on the detail of this particular language when it comes to general concepts I know (knowing the differences between a class, struct and enum in the language is important, for example).

I've yet to write a line of code, but I'm fine with that. The book is spending a lot of time introducing the language before encouraging you to fire up XCode, and I'm okay with that. I'm never a fan of being asked to write out code that I can't properly follow -- that just makes stuff look like magic when it's far more educational to know what's going on. What I am finding is I'm making lots of notes that are either "oh, yeah, this is cool, I like this idea!" or "WTF are you kidding me?!?". Which is really nice -- it's always great to learn a new language that's a bit different from what you normally use.

My plan then, over the next few weeks, it to keep at this and hopefully document my journey. I think I'd like to write a short series of TIL-type posts; nothing too long, just some new thing I read or discovered and my reaction to it. So, if you happen to follow this blog, I apologise in advance for any Swift-spam.

You have been warned. ;-)


My journey to the dark side is complete

Posted on 2020-06-14 20:00 +0100 in Emacs • Tagged with Emacs • 4 min read

Ever since the whole business of "light mode" and "dark mode" really kicked off in the mobile OS world, I've been a fan of the dark modes. On both Android and iOS/iPadOS, when apps became available with dark modes, I'd switch to it. When the operating systems themselves adopted the switch, that's what I went for. As well as having a love for all things black (anyone who knows me personally will know that), I think it just looks better on mobile devices. I can't quite say why, but it just works best for me.

So, when macOS got a supported dark mode, I instantly switched it on, obviously. Then, within a day, I switched it back to light mode. Surprisingly it just didn't work for me, and I wasn't sure why. Since then I've tried living with it a few times and it's rarely lasted more than a few hours. There was something, something I couldn't quite put my finger on, that didn't sit right.

Last Monday I decided to give it another go. This time, however, I thought I'd figured it out. The "problem" was Emacs! As mentioned back in January, for as long as I've used it (so since the mid-1990s), my Emacs has always had a light background -- probably because that's how it came "out of the box" (I'm talking Emacs in graphical mode here; I started with it on OS/2 Warp and then moved to a GNU/Linux X-based desktop). I figured that the contrast between the colour scheme of Emacs, and the rest of the machine, was the issue here.

I spend most of my working day either in Emacs, or in iTerm2 -- often rapidly switching between the two. I've always run iTerm2 in the usual dark background mode with light text. So I figured the problem was having a dark OS desktop, dark terminal, and then a light editing environment. Eventually that'd feel wrong.

So I decided that, for the first time in about 25 years, I should give Emacs a go with a dark mode. Taking a quick look at popular dark themes I noticed sanityinc-tomorrow-night looked easy on the eye, so I gave that a go (actually, I gave each of the themes in that set a go, initially starting with sanityinc-tomorrow-eighties, but I finally settled on sanityinc-tomorrow-night).

To start with it didn't look too good; not because of a problem with the theme itself, but because, over time, I'd made changes and tweaks to my setup that assumed I'd be using my usual light theme. After some dabbling and tinkering and trying things out, I got it looking "just so".

Screenshot 2020-06-14 at 19.40.43.png

Having got that working, I then thought it would be nice to be able to have Emacs -- at least on restart -- adapt to me switching between dark and light mode on macOS. It turns out that detecting if macOS is in dark mode is easy enough, the command defaults read -g AppleInterfaceStyle will emit Dark if in dark mode. So, knowing that, I updated my personal package for checking things about the environment that Emacs is in to use that information:

(defconst is-a-macOS-dark-mode-window-p
  (and
   is-a-macOS-window-p
   (string= (shell-command-to-string "defaults read -g AppleInterfaceStyle") "Dark\n"))
  "Are we running in a macOS window in dark mode?")

So, as of now, my Emacs setup is such that, if I'm in graphical mode on macOS and I'm in dark mode, Emacs will use a dark theme, otherwise it'll do what it did before -- with a light background in a graphical mode and a more Borland-a-like blue background when in CHUI mode.

This seems to have made a difference. Almost one week on my work Macbook is still in dark mode, and I've switched both of my personal Macbooks, and my iMac, into dark mode too. I think it's sticking this time. Next up is to give some serious consideration to darkening the web in general. Only now am I noticing just how damn bright most of it is!


As a slight aside to the above, I've also made one other change to Emacs: I've finally dropped the display of scroll bars. In the themes I'm using they didn't look so great, appearing to be distracting. For the past 25 years I've had the scrollbars there, but never actually used them; all they've ever done is serve as a visual aid to where I am in a file. Thing is, I'm not sure I ever really pay that much attention to that either. So, as a test, I've also been running with them turned off and, so far, I'm really not noticing them been gone.

The habits we form that we convince ourselves make sense...


Some more ~/.emacs.d evolution

Posted on 2020-06-07 16:48 +0100 in Emacs • Tagged with Emacs, Lisp, Emacs Lisp • 3 min read

When I started with this version of the blog on Hashnode1, my plan was to try and write something at least once a week. I managed to do that as far as January this year, give or take, but then things got a little busy, the world got trickier, and... Well, you don't need me to tell you about that. Anyway, I'm back to write some more and, hopefully, try and keep up with writing. I feel it'll do me good.

I have been busy since January. Work has, as far as possible, carried on as normal. The only big difference being I'm back working from home. It's an odd turn of events personally given that I'd worked from home for 21 years, then (with some trepidation) went back to working in an office. Having got used to being in an office and being around people, it took some adjusting to working alone again.

So, on to the main point of this post... During that period I've spent a lot more time at my machine than I would normally, and so it was inevitable that I'd end up tinkering with my Emacs configuration. While it's true that there's hardly a week goes by where I don't tinker with some small thing, I try not to make huge changes too often. Huge changes do happen though.

A handful of weeks back was another one of those times where I made a big change.

After I burnt my original ~/.emacs file back in 2016 I've had an approach where I've tried to make things as modular as possible, and as easy to clone down to a new machine as possible. The design I came up with, especially once I moved over to using use-package, has served me well. But there was always one thing that bothered me: the files that handled the loading and configuration of packages were, in effect, still three large monolithic files. While this was better than a single monolithic ~/.emacs, it still didn't feel quite right.

Giving it a bit of thought, I decided that what I really wanted was a single directory in which I could drop lots of small .el files that would handle the loading and configuration of all sorts of packages. While it didn't gain anything concrete, the idea felt tidier. Tidy is good. Feeling like the code smell is good, is good too.

First though I needed a way to load multiple files, ideally within a whole directory hierarchy, without needing to know in advance what files would be there. After a little bit of tinkering I settled on this bit of code that revolves around the use of directory-files-recursively:

(let ((source (expand-file-name "init.d/packages.d/" user-emacs-directory)))
  (when (file-exists-p source)
    (cl-loop for use in (directory-files-recursively source (rx ".el" eol))
             do (load (file-name-sans-extension use)))))

Simply put, this code finds every file in and below ~/.emacs.d/init.d/packages.d/ whose name ends in .el (note the use of a regular expression, using rx to create it), removes the extension from the name, and loads it with load (dropping the extension means load can decide if it wants to load the compiled version of the code, or the source, depending on what's available).

After writing that I could then start to populate ~/.emacs.d/init.d/packages.d/ with lots of smaller files that handled the loading of packages. In some cases there's a file just for one package, in other cases there's a file that handles a logical grouping of packages (where there are obvious direct dependencies, or where one package is designed to extend the other, etc). For now I've decided to break things down into three directories that map to the three monolithic files I had before:

Screenshot 2020-06-07 at 16.36.28.png

However, I'm not totally wedded to this design and I may change this as time goes on.

While I've not spent any time properly testing it out, I've also not really noticed any obvious impact on startup speed. However, this tends not to be a real concern for me. I seldom start Emacs anyway. I always have it running and use emacsclient as my editor in most places so files open instantly in the running version of Emacs.


  1. Note from future me: we're now back over on blog.davep.org of course. 


dnote.el - A wrapper for the dnote CLI

Posted on 2020-01-19 16:35 +0000 in Emacs • Tagged with Emacs, Lisp, Emacs Lisp • 3 min read

Late on last year I stumbled on an article about dnote. Annoyingly, I can't recall now where I saw it, but I made a reminder to look at it over my Christmas break.

Dnote looked like a tool that would fill a hole I had in how I work. When it comes to making notes about things, and keeping things for future reference, I use a few tools, each one being just right (for me) for the job in question. I use Evernote to track documents and other household type things. I use Keep to make notes about stuff I need to remember short-term (say, the size of a space in my bedroom that I want furniture to go in) and also to record notes while in meetings at work. I use Journey to keep a journal about... anything, really. Finally, I use Pinboard to keep hold of URLs I might want to go back to (I also use it to create a to-read list).

Amongst all of this, however, I felt I was missing something for keeping track of things that don't really fall into any of the categories above. Mostly this would be work-based or hacking-based things that are short and sweet but I don't always use enough to easily remember. I wanted just the right tool that would let me ferret away useful one-liners, remind myself of obscure switches that get used once or twice a year, etc.

After reading up on dnote it seemed pretty clear that this was just such a tool.

After getting back to the office at the start of this month I decided to make use of it and see how it went. My idea was simple: I'd record any "TIL" stuff that I might want to remember in the future, as well as recording things I need now and again but can't always remember.

So far it's working quite well. I like that it has a simple CLI. I like that it's got a backend that you can use to sync between different machines. I like that it's got a web interface that's mobile-friendly. I like that it's Free Software and so you can host your own server if you wish.

I found I liked it enough that, of course, I felt the need to start a simple Emacs wrapper for the CLI.

At the moment dnote.el is designed to be a simple capture system. There are commands for capturing a one-liner (entered in the Emacs mini-buffer), for capturing the content of the current buffer, and for capturing freshly-entered multi-line text, entered in a buffer that uses markdown-mode. There's also a command for syncing notes if you have configured dnote to talk to a backend.

What I don't have right now is the ability to navigate and view notes. So far I've not really felt the need for that because the CLI approach works so well. Longer-term though I can see my tweaking this and adding in commands for searching, viewing, editing and deleting notes.

But, for now, if you've not had a look at dnote, I'd highly recommend having a play and seeing if it makes sense for you. And, if it does, and you're an Emacs user, perhaps dnote.el will be useful too?


Where I live and work

Posted on 2020-01-11 14:17 +0000 in Coding • Tagged with Emacs, shell • 2 min read

It's no surprise that I spend a lot of time in Emacs. Especially when I'm developing software, either for work or for personal fun, most of my time is time spent in Emacs. While I do obviously flit over to Chrome, and mostly do my CLI stuff in iTerm2 (I really like eshell but it just can't replace a good terminal for me), I spend a lot of time looking at Emacs.

Here's what my Emacs looks like:

Screenshot 2020-01-11 at 13.49.04.png

Key elements for me are as follows:

Light background

Something I've never really got on with when it comes to code editing is dark themes and dark backgrounds. I find it too much of an eye strain. Oddly, I tend to prefer dark themes everywhere else, but not when it comes to working in Emacs. The theme I use is the built-in adwaita theme.

Less boring mode line

I make use of powerline to make the mode line a bit less boring-looking. While the colour scheme is such that it's kept in line with the light look, the style is nice in that it sort of matches the style of prompt I use in my shell.

Screenshot 2020-01-11 at 14.05.39.png

Full screen

I always run Emacs as a full-screen application, then splitting it into different tiled windows using its own internal window handling. This is something I've done from way back when I got started with my first GNU/Linux desktop machine, and still like to do on macOS.

I also run Emacs as a server and then use a little wrapper around emacsclient to open files (both locally and remotely) from the command line in that Emacs session.

Comfortable eshell when I need it

Although I say above that I generally don't use eshell, preferring to use a full-featured terminal application, in combination with fish, I do sometimes dip into eshell for quick things. So of course I have that configured to feel comfortable too.

Screenshot 2020-01-11 at 14.10.07.png

I do this easily thanks to eshell-git-prompt.


nuke-buffers.el -- Tidy up open buffers in Emacs

Posted on 2019-12-14 13:17 +0000 in Emacs • Tagged with Emacs, Lisp, Emacs Lisp • 2 min read

Both at work and at home I use Emacs by keeping a copy running all the time, and use emacsclient to open files inside it (including on remote machines thanks to a bit of ssh and heavy use of tramp -- I might write this up at some point). This works really well, but does mean I tend to build up a lot of buffers over time.

Having lots of buffers open isn't generally an issue, and if I'm working on lots of different files in a project during the course of a hacking session it's actually a good thing. But, quite often, I want to tidy up the buffer list, clearing it back to near-zero buffers open. Many years ago, when I had a "proper" tower system running 24/7, with Emacs open all the time, I'd use clean-buffer-list as part of midnight. Along the way that fell out of favour with me, likely because I drifted into using machines that had Emacs open all the time but where the machine wasn't awake all the time.

Eventually I decided to have some fun rolling my own solution, and nuke-buffers was born.

Rather than try and do things in an automated way, this was designed to be bound to a key (or two) and then be run when I wanted, being as harsh as possible about cleaning up the buffer list. Since first writing it it's worked well for me.

These days I tend to let the buffer list build up as I work on a new feature, or chase down a bug, etc. Then, once I've made the final commit for that period of focus, I'll hit the nuke-buffer key combo as the final act of confirming that I've done the job. So not only does this help tidy my Emacs session a bit, it also feels like a physical form of punctuation -- back in less sensible days, when I had some terrible habits, it would have been when I'd reach for the celebratory cigarette; buffer-tidying feels far more wholesome. ;)

The way the code works is, of course, mostly directed at how I work -- it's highly likely it wouldn't make sense for many other people. The main aim is to kill as many buffers as possible, but without disturbing anything else. The list of buffers it gathers for nuking avoids buffers that are visiting files but have unsaved content, avoids the minibuffer (obviously), avoids any "special" buffer (one that starts with a space then an asterisk), avoids the current buffer and also avoids any buffer in a list of names to avoid.

I've being using this on a daily basis for around 2.5 years now and it's done the job without ever losing me any work.


git2gantt -- Simple tool to visualise coding runs

Posted on 2019-12-08 13:44 +0000 in Python • Tagged with Python, documentation • 3 min read

At the start of this year, as part of a much bigger process to review the work that had taken place over the previous 12 months, I was asked (at work) to provide some information about how much time I'd spent on various projects. Now, for me, there's really only one project, but there's lots of different tools and libraries that I've written to support the main work I do. All of these are split into different repositories in the company-internal instance of GitLab. This meant that getting a rough idea of what I was working on and when would be easy enough -- it's all there in the commit history.

Given that this information would make up a couple of slides at most during a far bigger presentation, I wanted something that would be snappy and easy for non-developers to follow and understand. I spent a bit of time pondering some options and decided that (ab)using a gantt chart layout would make sense.

That choice was made all the more easier given that GitLab supports the use of mermaid charts within its Markdown. This meant I could quickly write some code that took the git log of each repository, turned it into mermaid code, and then render it (by hand, this was all about getting things done quickly) via GitLab.

This sounded like it could be a fun personal project. The result was some Python code called git2gantt.

As mentioned above, the output isn't anything too clever, it's just code that can be used to create a plot via mermaid. For example, running git2gannt over itself:

gantt
  title git2gantt output
  dateFormat YYYY-MM-DD

  section git2gantt
  Development: devgit2gantt20190208, 2019-02-08, 2019-02-13
  Development: devgit2gantt20190214, 2019-02-14, 2019-02-15
  Development: devgit2gantt20190303, 2019-03-03, 2019-03-04
  Development: devgit2gantt20191203, 2019-12-03, 2019-12-04

Usage is pretty straightforward: Screenshot 2019-12-08 at
13.18.12.png As you can see, it can be run over multiple repos at once, and there's also an option to have it consider every branch within each repository. Another handy option is the ability to limit the output to just one author -- perhaps you just want to document what you've done on a repo, not the contributions of other people.

Also especially handy, if you don't want to bore people with too much detail, is the "fuzz" option. This lets you tell git2gannt how relaxed you want it to be when it tries to decide how long a run of work on a repo lasted. So, perhaps, you're working on and off on a library that supports some other system you're documenting, but you might only be making changes every other day or so. With the correct fuzz value you can make it clear you were working on the library for a couple of weeks, despite there only being a commit every other day.

An example of running the output over a handful of projects would look something like this:

Screenshot 2019-12-08 at 13.34.41.png

This is one of those tools I knocked up quickly to get a job done, and haven't quite got round to finishing off fully. One thing I'd really like to do is add mermaid support directly within it, so that it actually has the option to emit plots, not just mermaid code (or, perhaps, drop the mermaid approach and use something else entirely).

Meanwhile though, if you're looking for something quick and dirty that will help you visualise what you've been working on and when for a good period of time... perhaps this will help.