Stupid Vim tricks - putting the time on the status line

The other week I realized that I was often moving my mouse for no reason while coding.  Well, not no reason - I wanted to see what time it was.  You see, I have Windows set to hide the taskbar because I use 13" laptops and want to maximize my vertical screen space.  But that means that I have to hit the Windows key or move the mouse down to bring up the clock.

I don't have this problem when browsing the web, because Vivaldi has a setting to put a clock in the lower-right corner of the window.  So I thought to myself, "Self, do you think Vim can do that same thing?"

Well, it turns out it can!  In fact, there's even an article on it.  Of course, that's for putting it in the plain-old status line.  I'm using the airline plugin, so I had to tweak it a little.  Still, I was able to get the passable looking image above by putting the following in my .vimrc:

" Put the current date and time in the status line and keep it updated
let g:airline_section_z='%p%% %#__accent_bold#%{g:airline_symbols.linenr}%l%#__restore__#%#__accent_bold#/%L%{g:airline_symbols.maxlinenr}%#__restore__#:%v %{strftime("%b %d %I:%M:%S%p")}'
let status_update_timer = timer_start(1000, 'UpdateStatusBar',{'repeat':-1})
function! UpdateStatusBar(timer)
  execute 'let &ro = &ro'
endfunction

The timer update the time every second (obviously you can do longer if you want).  That's because, otherwise, the time won't update until you do something in the editor window.  This way it stays current, even if I'm not actively editing.

PHP documentation and sockets

PHP's documentation gets way too much credit.  I often hear people rave about how great it is.  Many of them are newbies, but I hear the same thing from experienced developers who've been writing PHP code for years.

Well, they're wrong.  PHP's documentation sucks.  And if you disagree, you're just plain wrong.

Actually, let me add some nuance to that.  It's not that the documentation sucks per se, it's that it sucks as documentation

You see, a lot of PHP's documentation is written with an eye to beginners.  It has lots of examples and it actually does a very good job of showing you what's available and giving you a general idea of how to use it.  So in terms of a tutorial on how to use the language, the documentation is actually quite good.

The problem is that, sometimes, you don't need a tutorial.  You need actual documentation.  By that, I mean that sometimes you care less about the generalities and more about the particulars.  For instance, you might want to know exactly what a function returns in specific circumstances, or exactly what the behavior is when you pass a particular argument.  Software is about details, and these details matter.  However, PHP frequently elides these details in favor of a more tutorial-like format.  And while that might pass muster for a rookie developer, it's decidedly not OK from the perspective of a seasoned professional.

Case in point: the socket_read() function.  I had to deal with this function the other day.  The documentation page is rather short and I was less than pleased with what I found on it. 

By way of context, I was trying to talk to the OpenVPN management console, which runs on a UNIX domain socket.  We had a small class (lifted from another project) that basically provided a nice facade over the socket communication functions.  I'd noticed that, for some reason, the socket communication was slow.  And I mean really slow.  Like, a couple of seconds per call slow.  Remember, this is not a network call - this is to a domain socket on the same box.  It might not be the fastest way to do IPC, but it should still be reasonably quick.

So I did some experimentation.  Nothing fancy - just injecting some microtime() and var_dump() calls to get a general idea of how long things were taking.  Turns out that's all I needed.  It quickly became obvious that each call to the method to read from the was taking about 1 second, which is completely absurd.

For context, the code in that method was doing something like this (simplified for illustration):

$timeoutTime = time() + 30;
$message = '';
while (time() < $timeoutTime) {
    $character = socket_read($this->socket, 1);
    if ($character === '' || $character === false) {
        break;  // We're done reading
    }
    $message .= $character;
}

Looks reasonable, right?  After all, the documentation says that socket_read() will return the number of characters requested (in this case one), or false on error, or the empty string if there's no more data.  So this seems like it should work just fine. 

Well...not so much.

The problem is with the last read.  It turns out that the documentation is wrong - socket_read() doesn't return the empty string when there's no more data.  In fact, I couldn't get it to return an empty string ever.  What actually happens is that it goes along happily until it exhausts the available data, and then it waits for more data.  So the last call just hangs until it reaches a timeout that's set on the connection (in our case, it was configured to 1 second) and then returns false.

So because we were relying on that "empty string on empty buffer" behavior to detect the end of input, calling that method always resulted in a one-second hang.  This was fairly easily fixed by just reading the data in much larger chunks and checking how much was actually returned to determine if we needed another read call.  But that's not the point.  The point is that we relied on what was in the documentation, and it was just totally wrong!

And it's not like this is the first time I've been bitten by the PHP docs.  Historically, PHP has been very bad about documenting edge cases.  For example, what happens if a particular parameter is null?  What's the exact behavior if the parameters do not match the expected preconditions?  Or what about that "flags" parameter that a bunch of functions take?  Sometimes the available flags are well documented, but sometimes it's just an opaque one-line description that doesn't really tell you what the flag actually does.  It's a crap shoot.

To be fair, the PHP documentation is not the worst I've ever seen.  Not even close.  And it really is very good about providing helpful examples.  It's just that it errs on the side of being light on details, and software is details.

New new office setup

Last year I posted a picture of my work-from-home office setup.  Well, it turns out that working from home is actually a significantly less temporary condition than I thought at the time.  So I moved and re-jiggered my office a little bit.

I moved my desk from the basement upstairs to what was the spare bedroom (it's actually not much of a bedroom anyway - just barely big enough for a queen-sized bed) and moved the spare bed down to the basement.  This was a major improvement over the winter, as the heating situation in the basement is not great.  It also gives me a lot more natural light, which is just makes things more pleasant in general.

In terms of hardware, things are much the same, but with some minor changes.  As you can see, I kept my old monitor setup, with my crappy old monitors.  Not because I'm particularly attached to them, but just because it's convenient and I don't have a lot of desk space to work with.  I also have my trusty Ultimate Hacking Keyboard, which I still love.

I did get an upgraded laptop - still a ThinkPad, so you can't really tell the difference, just a newer model with more RAM.  I also added the tablet I got myself for Christmas (in lieu of exchanging gifts, my wife and I decided to upgrade our tablets), a Samsung Galaxy Tab 6 Lite.  It's actually a fairly nice little tablet, especially for the $250 price tag.  It's also really nice as an additional screen to play videos, podcasts, or music in the background while I work.  That way that stuff doesn't get in the way as it might if I put it on my computer (and it also doesn't have to go over the VPN). 

I've also upgraded my trackball from a Logitech Marble Mouse to a Kensington Expert Mouse.  This was actually necessitated by the fact that my Marble Mouse was really old and the left-click button finally started to die.  I've actually wanted to try an Expert Mouse style trackball for a long time - pretty much ever since I've been using left-handed trackballs.  But until relatively recently, I was too cheap to justify spending $100 on a trackball, so I settled for the Marble Mouse, which is much less expensive, but still good.  However, this time I decided to give the Expert Mouse a shot.  There aren't really that many choices for ambidextrous trackballs anyway, so why not get a nice one?  And so far it is pretty nice.  The large trackball takes a little getting used to, but it controls well enough and is fairly comfortable with the wrist rest.  It's got a scroll wheel that's nicer than the buttons on the Marble Mouse, and the configuration software works pretty well.  The Expert Mouse actually has four physical buttons and the scroll wheel, compared to the four buttons total (including scroll) on the Marble Mouse, and will treat clicking both top or bottom buttons at once as fifth and sixth buttons.  That's nice because it actually gives you a little more slack to do something useful with the extra buttons. So I have the top buttons configured for universal scroll, copy, and paste.  However, I did find that there's not way in the UI to control the concurrent-click detection time, so using the click-both feature on the bottom two buttons (right- and left-click by default) doesn't work well - it's easy for it to confused and do things like swallow double-clicks.  Still, I'm happy with the change.

Right now I'm quite happy with my home office.  The hardware and desk space situation is good; I get plenty of sunlight, but due to the angles the sun never shines straight in the window; and I can even open the windows and get some fresh air!  And this is a good thing, because I'm going to be in it for a while.  My company isn't planning to require anyone to return to the office until at least October.  The offices are currently open with various COVID restrictions in place, but non-essential employees are returning on a purely voluntary basis.  And so far there aren't that many people in the office, so unless working from home is a problem for some reason, we don't really have much of a reason to go back.

I guess we'll see what happens toward the end of the year.  I know a lot of people are rooting for a "part-time office" model where we could go into the office two or three days a week for meetings and work from home the rest of the time.  So far there are no plans for that model, but I find it appealing as well.  My team was already distributed across two offices, so just having everyone work from home wasn't really that disruptive to us.  In fact, it might actually be easier in some expects, since while it does take away the in-person aspect, it also takes away the risks associated with that in a distributed team.  Sure, we can't have spontaneous, ad hoc conversations, but we also are less likely to leave important people out of those spontaneous conversations. I experienced that several times in a previous team where we had one remote person, who we would frequently forget to include in or notify of decisions we made in those spontaneous discussions.  Instead, we just have the conversation in the Slack channel and everybody can see it and join in if they want.  

Rediscovering wrestling

Last year I posted about a cool site that details the deaths of famous pro wrestlers.  Since then, I've gotten back into professional wrestling.  Well, at least a little bit.

To be honest, I'm probably more interested in the meta-commentary than in the shows themselves.  Although I do pull up the occasional match (or even an old special event) on YouTube, I don't follow any of the regular broadcasts or story lines.  It's not necessarily that I'm not interested, it's just that I don't have the time.  Wrestling is a highly visual medium, so it's not the sort of thing you can easily put on in the background while you work (at least not if you want to absorb any of it at all).  I'd rather read a synopsis or watch a summary montage.  

What I have been watching is a lot of behind-the-scenes documentaries and interviews.  It turns out the real stories behind pro wrestling are at least as interesting as the ones on TV, if not more so.  It's a tough business that blurs the lines between fantasy and reality, full of creative people whose job is to get attention.  How could there not be lots of interesting drama?  And, as it turns out, lots of compelling tragedy.

Most recently, I've been watching Vice TV's documentary series The Dark Side of the Ring.  It's very well done.  It covers a range of characters and scandals in the wrestling industry, ranging from the "industry drama" of things like the Montreal screwjob to genuine, out and out tragedies, like the story of Chris Benoit.  They include interview with a variety of wrestling insiders (though there are several frequent contributors, like Jim Cornette) and do a pretty good job of expressing the uncertainty and ambiguity of many of these events.

That's actually what I find compelling about many of these stories - the ambiguity.  Many of the interviewees are, naturally, pro wrestlers, which means they're performers.  That means they can speak engagingly, with passion and conviction, about these events.  But for many of these stories, you see that from people on both sides, which makes it clear that these passionate, straight-forward accounts really aren't the whole story.  While the on-screen world of wrestling is very black-and-white, with designated good guys and bad guys, the off-screen world is much more gray.  For all the larger-than-life personas that they put on, these are actually just regular people who are trying to navigate difficult and sometimes unclear situations.  The messiness of these situations is part of what makes them so impactful. 

I've also been watching a number of the "full shoot" interviews from The Hannibal TV.  These are interviews conducted by Devon Nicholson, a.k.a. Hannibal, with a variety of wrestling personalities about their careers.  They discuss not only their in-ring and on-screen rivalries, but also the kind of things that happened back-stage and what it was like being on the road as a wrestler.  They all have lots of good stories, but it's sometimes hard to tell exactly how factual they are.  Joe Rogan has also had some good episodes featuring interviews with pro wrestlers.  In particular, I enjoyed his interviews with Jake "The Snake" Roberts, Diamond Dallas Page, and Mark "The Undertaker" Calloway.

If you're interested in a feature-length documentary, both Andre the Giant and The Ressurection of Jake The Snake Roberts were quite good.  Both men are interesting case studies on the life of a successful professional wrestler.  These documentaries detail the struggles these men went through and how wrestling contributed to them.  The latter also describes Jake's eventual recovery with the help of Diamond Dallas Page.

For me, this real-life stuff does a lot to enhance the wrestling performances that I do watch.  Between the COVID lock-downs and the crazy political situations of the past year, I find wrestling to be a welcoming break.  The on-screen performances, while hardly Shakespeare, can be entertaining and offer a familiar and somewhat comforting "good vs. bad" narrative.  And if nothing else, they certainly are impressive athletic displays.  (Yes, the results are predetermined, so it might not be a "sport", but that doesn't mean the participants aren't athletes.)  Meanwhile, the peeks back-stage are a good reminder than nothing is clear-cut and that while people can be complicated and sometimes contradictory, they all still have value and people who care about them.  That's something that's worth remembering and holding onto amidst the toxic stew that is our current media and online discourse.

Stupid Git tricks: Undoing a stash pop

Here's a handy little Git nugget I learned the other day: if you get conflicts trying to apply a popped stash, it doesn't get removed from the stack.  I didn't actually know this, but it's a very handy piece of information.

In this case, I was trying to stash my changes so I could switch to a different branch.  Normally this is as easy as git stash ; git co develop ; git stash pop, but I failed to account for conflicts.  And this time it wasn't the "nice" kind of conflict, where you just fix it and move on with your life.  Noooooo.  This time, I realized that I actually needed to base my changes on the branch I was originally on.  (That branch was due to be merged into develop, but it just hadn't happened yet.)  So fixing the conflicts would have been a waste of time because I'd just have the same conflicts in reverse when I switched back.

But it turns out you can just do a git reset --hard whatever and because of the conflicts, the stashed changes will still be on the top of the stack.  Very handy!  This little nugget saved me a bunch of time.