https://uhnomoli.com/uh.nom.o.lithe ramblings of a programmer2020-06-08T13:44:53ZAndrew Frickeandrew@uhnomoli.comhttps://uhnomoli.com/https://uhnomoli.com/2014/03/19/A-couple-of-new-TextMate-themes/A couple of new TextMate themes2014-03-19T13:44:00ZAbout every six months or so I get bored with my setup and go poking around in an attempt to spice things up. One of the first things I start messing around with is my text editor theme. The last two however, I never got around to releasing and now seems like as good a time as any.<p>About every six months or so I get bored with my setup and go poking around in an attempt to spice things up. One of the first things I start messing around with is my text editor theme. The last two however, I never got around to releasing and now seems like as good a time as any.</p>
<div class="scrots">
<figure class="scrots-scrot">
<a href="/assets/images/words/mint.png"><img src="/assets/images/words/mint-thumb.png" width="348" height="185" alt="Mint"></a>
<figcaption>Mint</figcaption>
</figure>
<figure class="scrots-scrot">
<a href="/assets/images/words/ash.png"><img src="/assets/images/words/ash-thumb.png" width="348" height="185" alt="Ash"></a>
<figcaption>Ash</figcaption>
</figure>
</div>
<p>The older of the two is mint. It was mostly an attempt at overcoming my everlasting struggle with brown. I love the idea of brown, but I can just never seem to pull it off. I feel I made it halfway there. I was going for more of a foresty vibe, but in the end the only image that comes to mind is that of a carrot.</p>
<p>Ash was more or less a happy accident. I just started messing around and ended up knocking it out in a day. I really like how it came together. At the start a volcano came to mind and I just ran with it. I like the bit of green, it really adds some variety without looking out of place.</p>
<p>Both are available on <a href="https://github.com/Anomareh/TextMate-Themes">GitHub</a> along with my two other themes: Erebus and Monokai Dark.</p>
https://uhnomoli.com/2014/01/14/Is-it-time-for-the-80-character-line-limit-to-go/Is it time for the 80 character line limit to go?2014-01-14T13:44:00ZAh the 80 character line limit. It’s the first thing in nearly any styleguide and <a href="https://programmers.stackexchange.com/questions/148677/why-is-80-characters-the-standard-limit-for-code-width">it came to be</a> largely because of the width of the IBM punched card from the ‘20s. Nearly a century later and it’s as common as ever. Is it time for a change?<p>Ah the 80 character line limit. It’s the first thing in nearly any styleguide and <a href="https://programmers.stackexchange.com/questions/148677/why-is-80-characters-the-standard-limit-for-code-width">it came to be</a> largely because of the width of the IBM punched card from the ‘20s. Nearly a century later and it’s as common as ever. Is it time for a change?</p>
<p>I think one of the main reasons the limit is still so prevalent is because people feel it somehow helps deter less experienced programmers from writing poor code. Long lines <em>can</em> indicate a handful of different problems with the two biggest offenders being overly complex code and indentation hell.</p>
<p>However, my issue with this thought process is someone who isn’t aware of these issues isn’t going to magically start writing better code because of a line limit. In the end all that will change is formatting and the programmer will have learned nothing in the process. They’ll just shrug it off as tradition.</p>
<p>Rather than asking contributors to check if a line is too long, they should rather be checking if a line is detrimental to the maintainability or readability of the codebase. Common sense, no? As a bonus, you might even catch those short lines that aren’t so hot instead of giving them a free pass.</p>
<h2>But the split windows! Won’t somebody please think of the split windows?</h2>
<p>One of the big differences between a standard aspect ratio and a widescreen aspect ratio is that vertical screen real estate becomes much more valuable than horizontal screen real estate. Poor code aside, as poor code hurts the codebase no matter how long the lines are, lines are often identifiable by their first 80 characters. The only time you need to scroll horizontally is when you’re working with a specific long line.</p>
<p>But, when you start chopping at lines that happen to be over some arbitrary limit, what you’re trading is vertical real estate for horizontal real estate. You’re trading gold for copper. Regardless of the line limit, you’re spending the majority of your time traversing files vertically, not horizontally.</p>
<p>Anecdotal evidence being anecdotal, the most common desktop resolution I’ve encountered in my programmer centric web presence is by far 1920 by 1080. Nearly every programmer I’ve worked with or talked to has more than one monitor. I even know one that is experimenting with a portrait dual screen setup.</p>
<p>In short, an 80 character line limit is in no way necessary to ensure effective window splitting when you’re dealing with a workspace that’s 3840 pixels wide. A workspace that’s 1920 pixels wide can still be comfortably split in half.</p>
<h2>So where does that leave us?</h2>
<p>At this point I really don’t feel the character line limit serves a purpose. To a certain degree I feel it’s more harmful than beneficial. I’d really like to see projects start taking a common sense approach when it comes to line length.</p>
<p>Lastly, please stop using this convention when writing emails. On a desktop they’ll take up a quarter of the screen and they’re an absolute mess on phones. My eyes and sanity thanks you.</p>
https://uhnomoli.com/2014/01/10/Rolling-your-own-PJAX-implementation-with-History.js/Rolling your own PJAX implementation with History.js2014-01-10T13:44:00ZIf you were like me, at some point you read somewhere about this cool new thing called <a href="https://pjax.herokuapp.com/">PJAX</a>. Essentially, instead of issuing normal HTTP requests when navigating a site, links are fetched and loaded via AJAX to avoid full page refreshes. The site feels much more responsive. This isn’t without it’s quirks however.<p>If you were like me, at some point you read somewhere about this cool new thing called <a href="https://pjax.herokuapp.com/">PJAX</a>. Essentially, instead of issuing normal HTTP requests when navigating a site, links are fetched and loaded via AJAX to avoid full page refreshes. The site feels much more responsive. This isn’t without it’s quirks however.</p>
<p>My issue with PJAX largely revolved around the inability to implement animations. First and foremost, the provided hooks weren’t sufficient. It was possible to rig something up with CSS and class swapping, but not only did that feel gross it often broke down as soon as the back button entered the picture. Although PJAX felt slightly faster, without animations it was just as jarring as a full page refresh and so I didn’t see a point.</p>
<p>As I was working on the redesign of this site, I decided to take another look to see what had changed. Unfortunately I discovered not much had. However, instead of moving on this time I decided to take a quick look for any alternative solutions. I pleasantly discovered <a href="https://github.com/browserstate/history.js/">History.js</a>.</p>
<p>After a little bit of fiddling, I had quickly rolled my own PJAX implementation powered by History.js. Thinking there may be a few people out there that are in the same spot I was, I figured I’d post a quick write up.</p>
<p>First we start off with your usual boilerplate.</p>
<pre><code data-lang="javascript">(function ($) {
var $document = $(document);
// our code ...
})(jQuery);
</code></pre>
<p>The next thing we need to do, and I wish more JavaScript developers kept graceful degradation in mind, is check whether or not the browser supports the HTML5 history API. History.js makes this easy for us.</p>
<pre><code data-lang="javascript">if (!History.enabled) {
return false;
}
</code></pre>
<p>Now if we run into an unsupported browser our site doesn’t cease to function. As an added bonus, there will be one less site out there that’s shoving some snarky message in the user’s face about how they need to upgrade to a <em>real</em> browser so they can experience the greatness that is four different versions of jQuery being used to style some text.</p>
<p>Moving on, before we get to implementing anything, we have a bit more setup to do.</p>
<pre><code data-lang="javascript">var root = History.getRootUrl();
$.expr.filters.internal = function (elem) {
return (elem.hostname == window.location.hostname && /(\/|\.html)$/i.test(elem.pathname)) || false;
};
function find_all($html, selector) {
return $html.filter(selector).add($html.find(selector));
}
function parse_html(html) {
return $($.parseHTML(html, document, true));
}
function parse_response(html) {
var
head = /<head[^>]*>([\s\S]+)<\/head>/.exec(html),
body = /<body[^>]*>([\s\S]+)<\/body>/.exec(html),
$head = head ? parse_html(head[1]) : $(),
$body = body ? parse_html(body[1]) : $(),
title = $.trim(find_all($head, 'title').last().html()),
$content = $.trim(find_all($body, '#content').first().contents());
return {
'title': title,
'$content': $content
}
}
</code></pre>
<p>The first thing we’re doing here is caching a value that we’ll be using later. After that we’re defining a custom jQuery pseudo selector so we can avoid littering our markup with <code>data-*</code> attributes. Lastly, we’re defining a few helper functions to make our code easier to work with.</p>
<p>Although these helper functions are fairly straightforward, I’ll quickly run through them. The first, <code>find_all</code>, simply grabs all occurrences of <code>selector</code> in the supplied chunk of HTML. Next, <code>parse_all</code> abstracts the process of turning a chunk of HTML into a jQuery object.</p>
<p>The last helper function is <code>parse_response</code> and it’s a bit more significant compared to the rest. This is where we’re parsing the AJAX response for the title and the chunk of the page that we’re trying to load. Line 24 is worth singling out as you’re likely going to want to change it to work with your site.</p>
<p>Now we’re ready to start implementing PJAX.</p>
<pre><code data-lang="javascript">$document.ready(function () {
$document.on('click', 'a:internal', function (event) {
if (event.which == 2 || event.ctrlKey || event.metaKey) {
return true;
}
History.pushState(null, null, $(this).attr('href'));
event.preventDefault();
return false;
});
});
</code></pre>
<p>Depending on your use case you may wish to alter the above, but for basic usage it’s likely sufficient. All we’re doing here is changing our internal links to use the HTML5 history API.</p>
<p>The key thing here is actually the selector where we’re using our custom pseudo selector from earlier. A link is considered internal if it’s on the same domain and ends with either <code>/</code> or <code>.html</code>. Again, depending on your use case, you may want to change that.</p>
<p>All that’s left now is the handling of our state changes.</p>
<pre><code data-lang="javascript">// This is the event that's triggered by the HTML5 history API.
$(window).on('statechange', function () {
var
url = History.getState().url,
rel = url.replace(root, '/');
// Here we're making our AJAX call.
$.get(rel).done(function (date) {
var response = parse_response(date);
// First we need to check if the chunk we were looking for was found
// in the response. If it wasn't we reject the link.
if (!response.$content.length) {
document.location.href = url;
return false;
}
// This is our target container.
var $content = $('#content');
// Here we're updating the page title if one was found in the response.
if (response.title.length) {
$('title').last().html(response.title);
}
// Now we're loading the response.
$content
.slideUp(500)
.promise()
.done(function () {
$content
.html(response.$content)
.slideDown(500);
});
// If the AJAX request failed, we're again rejecting the link.
}).fail(function () {
document.location.href = url;
return false;
});
});
</code></pre>
<p>I’ve gone ahead and annotated most of what’s going on in the comments. The only things I’ll bring up specifically are lines 20 and 28 to 35. As before, you’re likely going to want to change the selector on line 20. You’re also likely going to want to change how the response is loaded which would be lines 28 to 35.</p>
<p>The only thing left is to put it all together.</p>
<pre><code data-lang="javascript">(function ($) {
var $document = $(document);
if (!History.enabled) {
return false;
}
var root = History.getRootUrl();
$.expr.filters.internal = function (elem) {
return (elem.hostname == window.location.hostname && /(\/|\.html)$/i.test(elem.pathname)) || false;
};
function find_all($html, selector) {
return $html.filter(selector).add($html.find(selector));
}
function parse_html(html) {
return $($.parseHTML(html, document, true));
}
function parse_response(html) {
var
head = /<head[^>]*>([\s\S]+)<\/head>/.exec(html),
body = /<body[^>]*>([\s\S]+)<\/body>/.exec(html),
$head = head ? parse_html(head[1]) : $(),
$body = body ? parse_html(body[1]) : $(),
title = $.trim(find_all($head, 'title').last().html()),
$content = $.trim(find_all($body, '#content').first().html());
return {
'title': title,
'$content': $content
}
}
$document.ready(function () {
$document.on('click', 'a:internal', function (event) {
if (event.which == 2 || event.ctrlKey || event.metaKey) {
return true;
}
History.pushState(null, null, $(this).attr('href'));
event.preventDefault();
return false;
});
});
$(window).on('statechange', function () {
var
url = History.getState().url,
rel = url.replace(root, '/');
$.get(rel).done(function (date) {
var response = parse_response(date);
if (!response.$content.length) {
document.location.href = url;
return false;
}
var $content = $('#content');
if (response.title.length) {
$('title').last().html(response.title);
}
$content
.slideUp(500)
.promise()
.done(function () {
$content
.html(response.$content)
.slideDown(500);
});
}).fail(function () {
document.location.href = url;
return false;
});
});
})(jQuery);
</code></pre>
<p>And there we have it. A simple, straightforward PJAX implementation that doesn’t restrict us when it comes to how we want to handle loading our PJAX responses. It’s by no means perfect or without flaws, but it’s solid enough for basic usage and easily extensible for more complicated use cases.</p>