Vim: highlight word wrap column in insert mode
Code:
No comments

I like vim’s colorcolumn for highlighting where word wrap will occur, but I consider it a distraction when I’m not in insert mode. After some tinkering, I wrote this in my .vimrc:


" highlight textwidth column in insert mode
highlight ColorColumn ctermbg=0*
function! HighlightOn()
if &textwidth > 0
" the +1 feature in the 'colorcolumn' docs doesn't work for me
let &colorcolumn=&textwidth + 1
else
let &colorcolumn=""
endif
endfunction
autocmd InsertEnter * :call HighlightOn()
autocmd InsertLeave * let &colorcolumn=""

That note about +1 is me working around a bug. I should be able to just write:


" highlight textwidth column in insert mode
highlight ColorColumn ctermbg=0*
autocmd InsertEnter * let &colorcolumn=+1
autocmd InsertLeave * let &colorcolumn=""

Unfortunately, some tweak or plugin breaks this feature for me. I wrote this workaround rather than diagnose and fix it properly because the process just seemed too tedious.

Replacing Ack with Ag
Code: , , ,
No comments

I used grep to search code for a bit over a decade. I switched to ack to get more quicker searches without the distractions of svn/git metadata and other non-code files. After a very nice five years of ack, I’ve switched to ag. I’ve been recommending it to other devs for a year or two (it’s faster than ack with a couple really nice features like obeying .gitignore configs), but only took the time to switch this week.

On Arch, installing was as simple as:

pacman -S the_silver_searcher
pacman -Rns ack

Updating my vimrc’s section for ack.vim was supposed to be straightforward but turned into a pain in the ass. In my vimrc I had:

" Use Ack instead of Grep when available
if executable("ack")
  set grepprg=ack\-H\--nogroup\--nocolor
endif
command! -nargs=* -complete=file Ack call Ack(<q-args>)
nmap <leader>a :Ack 
nmap <leader>A :Ack <cword><CR>

I added the following after the ‘endif’, so my config falls back to ack on systems without ack:

if executable("ag")
  let g:ackprg="ag --nogroup --nocolor --column"
  set grepprg=ag\ --vimgrep\ $*
  set grepformat=%f:%l%c%m
endif

Unfortunately, ack.vim got loaded by pathogen after .vimrc, so the let g:ackprg default at the top was overriding my config. This drove me insane for a few minutes, and maybe there’s some clever way to say that my setting should not be replaceable, but I just commented out the line in ~/.vim/bundle/ack.vim/plugin/ack.vim and moved on with my life.

Then I edited my `a` alias, and aliased “ack”, knowing that I’ll make that mistake for a few months:

alias a='ag'
alias ack='ag'

Last, I added a ~/.agignore to ignore rcov output:

coverage
rcov

Not much config to update, but ag is sharply faster drop-in replacement for ack.

Craftsmanship Tour: Jim Ray
Code: , , , ,
No comments

Last Tuesday I spent the afternoon with Jim Ray at the excellent Hooked coffeeshop in Denver, CO (and then I spent the next several days sick from a bad meal and recovering, so this post got delayed).

We worked on FindAPair, a small web app he’s developing with Jeff Powell. Developers can list their city and link to their Twitter and GitHub profiles to find other devs to pair with. (Yeah, this basic idea felt pretty familiar.)

First, Jim and I added some acceptance tests using Steak to test profile editing. Steak is a DSL for acceptance in BDD, but closer to Ruby code than the popular Cucumber. Jim explained he chose Steak because this project does not have a non-technical customer who’d read, verify, and help write specs. Cucumber’s translation between text files and method calls would be unnecessary complexity.

FindAPair uses the wonderful Devise library, so we followed the steps on the wiki to allow people to log in by username as well as email address. It went pretty well, but we needed to do a little tweaking for Rails 3. Of course, we contributed back to the docs. One of the nice things about GitHub is how frictionless it is to share these small improvements.

Another interesting bit of coding was planning the URL structure of the site. The two major resources are users and the cities they live in. Jim wanted to have really simple URLs like findapair.me/jimiray or findapair.me/denver. He didn’t want to overlap the namespaces, but he couldn’t decide between them. As he was explaining the problem I thought back to the early days of the web and suggested putting cities at the root and users at findapair.me/~jimiray. Jim laughed, decided the audience was nerdy enough to remember it, so we committed it.

I’m not going to recount all the little things we did, but it was a fun afternoon building what could be a great resource.

While I was programming with Jim, I was reminded of the importance of studying. I knew a lot more vim commands than Jim, but it’s not because I’m any smarter. When I started learning vim I quickly realized it was a far bigger topic than I could absorb at once, so I only learned enough to take care of my daily routine. After I was comfortable with that, I started reading the vim manual, but I read at most one chapter a week. Read a little, experiment, give it time to settle, refresh my reading in a few days, and then move on to something else. In the decade since then, I still watch for new information about vim, reading the vim subreddit and Twitter accounts like learnvim and dotvimrc. It’s easy to skip over the stuff I already know. It’s easier to earn in small amounts over years than read one book and hope to retain everything.

Craftsmanship Tour: 8th Light
Code: , , , , , , , ,
No comments

The second stop on my craftsmanship tour was last Friday at 8th Light. They’re a local Chicago consultancy that’s active in the software craftsmanship community, especially in building the new Chicago SC group.

I started out pairing with Colin Jones, which was a bit lucky because he’s also a vim user. After I shared the joy of matchit.vim we got down to the task at hand.

8th Light is one of a few companies that do work for Groupon, the local wunderkind. Our task was to write a small script to sync data between services for a small percentage of subscribers, but when a site has over 40 million subscribers, you can’t just hack out something fast and hope for the best.

The work needed was very similar to an existing script, but Colin’s first instinct wasn’t a quick copy and paste and tweak. We analyzed the script to find the points of commonality and extracted them to a superclass, and we grew the existing tests (yes, the one-off script already had tests) to cover the new functionality.

I get the feeling that by the time I finish this tour I’m going to be pretty familiar with every combination of testing and mocking library out there. Last Monday it was Cucumber, this time I dropped into learning rspec and its built-in mocking. I’m glad I experimented with writing my own mocking library a few years ago, I earned a deeper understanding of mocking than one library’s API and was able to explain what I was trying to do and find the right bit of rspec docs quickly.

Every Friday lunch is “8th Light University” and a developer presents on an interesting topic. Colin gave a presentation on Clojure, walking through the basics of functional programming style like map, filter, and the importance of understanding when Clojure will or won’t walk an entire sequence to produce its result (as demonstrated by using (range 10000000000000)). It ended with a little exercise to add up all the numbers between 1 and 1000 that are evenly divisible by 3 and 5, my solution wasn’t too bad, though I should’ve used reduce in place of filter/apply:

(defn evenly_divisible? [x] (or (= 0 (rem x 3)) (= 0 (rem x 5))))
(print (apply + (filter evenly_divisible? (drop 1 (range 1000)))))

That refresher of Lisp syntax and FP came in handy immediately after lunch, when I paired with Micah Martin. He was working on adding a Clojure interface to the GUI toolkit Limelight.

We refactored some Java and Clojure to remove some code duplicated logic for locating and loading GUI elements (“players”). I don’t really have any experience in Java, but it only took me about five minutes of removing duplication before I ran into hassles with the type system.

As soon I was distracted by the interesting problem of structuring code in an unfamiliar language, my hands reverted to use vim commands. We were using IntelliJ IDEA on OS X, so I flailed a bit, at one point griping “I feel like I’m wearing mittens”. It’s disorienting to lose tools I’ve tweaked and practiced with almost daily for a dozen years.

The Java started like this:

public void recruit(PropPanel panel, String playerName, CastingDirector castingDirector)
{
  final Scene scene = panel.getRoot();
  final String scenePlayersPath = scene.getResourceLoader().pathTo("players");
 
  final boolean couldRecruitFromPScene = recruitFrom(panel, playerName, castingDirector, scenePlayersPath);
  if(!couldRecruitFromPScene)
  {
    final String productionPlayersPath = scene.getProduction().getResourceLoader().pathTo("players");
    final boolean couldRecruitFromProduction = recruitFrom(panel, playerName, castingDirector, productionPlayersPath);
    if(!couldRecruitFromProduction)
    {
      boolean couldRecruitDefaultPlayer = recruitFrom(panel, playerName, builtinCastingDirector, BuiltinBeacon.getBuiltinPlayersPath());
    }
  }
}

I found this code really hard to read, in part because there were nested conditionals when it’s really doing the sequential work of trying different paths. It’s a bad application of single exit point because Java is a garbage collected language. It’s OK to have multiple return points from a function because you don’t have to worry you’re leaking memory. So I rewrote it as:

public void recruit(PropPanel panel, String playerName, CastingDirector castingDirector)
{
  final Scene scene = panel.getRoot();
  final String scenePlayersPath = scene.getResourceLoader().pathTo("players");
  final String productionPlayersPath = scene.getProduction().getResourceLoader().pathTo("players");
 
  if (recruitFrom(panel, playerName, castingDirector, scenePlayersPath))
    return;
 
  if (recruitFrom(panel, playerName, castingDirector, productionPlayersPath))
    return;
 
  recruitFrom(panel, playerName, builtinCastingDirector, BuiltinBeacon.getBuiltinPlayersPath());
}

There are fewer variables and I moved their initialization together, so your eye picks up the parallel structure and just focuses on the differences.

Of course, that’s not just parallel structure but repeated code in the conditionals and call to recruitFrom(). I fell into Ruby syntax trying to explain what I wanted to do as the next step of refactoring:

public void recruit(PropPanel panel, String playerName, CastingDirector castingDirector)
{
  final Scene scene = panel.getRoot();
  [
    [scene.getResourceLoader().pathTo("players"),                 castingDirector],
    [scene.getProduction().getResourceLoader().pathTo("players"), castingDirector],
    [BuiltinBeacon.getBuiltinPlayersPath(),                       builtinCastingDirector],
  ].each { |path, director|
    if (recruitFrom(panel, playerName, director, path))
      return;
  }
}

Now the code doesn’t have any extra variables or repeated method calls. If the recruitFrom signature changed, there’d be exactly one place to change it.

Alas, it was not to be. I couldn’t simply bundle a player and a canvas in an array of tuples because they were of different types. Micah started typing a simple inner class to gather them together, but I vetoed it. Even though it would removtge duplication, I didn’t think it worth the tradeoff of added complexity of a new, data-only class. We left it at the previous revision.

Refactoring isn’t a blind set of tools to apply while (code.has_refactoring_possible?) because they’re about managing complexity by moving it to explicit places without duplication. You can spend hours smoothing things out only to be left with a stubborn bit of complexity that you can leave a warning on rather than spend a disproportionate amount of time trying to get that last bit. I find that when I do this, a future change will often expose what the real trouble is and I can advance the refactoring then.

All in all, a great day at 8th Light. I’m still looking for places to visit in Chicago before the end of the year, so please check out my calendar and suggest places here or on Twitter.

256-Color XTerms in Ubuntu
Code: , , , , , ,
10 comments

It’s not commonly used, but most Linux terminals can support 256 colors. It’s also a bit of a pain in the ass to set up if it doesn’t Just Work out of the box. Having spent a while today tinkering and searching and cursing and testing and trading mail/IM with folks who understand the eldritch depths of terminals better than I, I thought I’d write up my findings for anyone else who’d like spiffy colors.

Ncurses and other terminal programming libraries need to know what capabilities your terminal supports, like highlighting, underlining, blinking, and colors. This used to be done with termcap but now everyone uses terminfo, which hold the specifications in a set of files. The first thing to do is make sure you have a 256-color terminfo file for your terminal:

$ find /lib/terminfo /usr/share/terminfo -name "*256*"

What you need is to see a filed named terminal-256color. For example, mine is xterm-256color. My first hassle was that Ubuntu doesn’t install this by default. I can’t guess what it will be named in your distribution (look for packages with ‘ncurses’ or ‘term’ in their names), but in Ubuntu it’s just a quick:

$ sudo aptitude install ncurses-term

Xterm needs a little more configuration, edit ~/.Xdefaults to add:

*customization: -color
XTerm*termName:  xterm-256color

To make this apply to new terminals (so you don’t have to log out and back in), run:

$ xrdb -merge ~/.Xdefaults
# you'll also want to add this to your ~/.xsession so it happens every time you log in:
if [ -f $HOME/.Xdefaults ]; then
  xrdb -merge $HOME/.Xdefaults
fi

One tricky thing about xterm is that is supports 256 colors via ANSI escape sequences, but they won’t be available to programs without the right terminfo file. So popular test scripts will work while ncurses-based programs will fail. I spent a lot of time catching on to this one. This config file will tell xterm to enable 256 colors and set the TERM environment variable to ‘xterm-256color’ so the right terminfo file is used. You can test this with:

$ tput colors
256
$ echo $TERM
xterm-256color

Xterm color test

At this point, you’re all set. Individual applications may need some configuring to use 256-color schemes. In vim, :set t_Co should now report that you have 256 colors available. Run locate vim | grep 256 to find the color schemes available, and :colo desert256 to use one. If none of those suit you, there are plenty more available. I put a little code in my ~/.vimrc to only load it when I have colors available, because sometimes I use different terminals.

colorscheme desert
if &t_Co > 2 || has("gui_running")
  syntax on
endif
if &t_Co == 256
  colorscheme inkpot
endif

Vim in 256 colors with colorscheme 'inkpot'

GNU screen needs a hint to use 256 colors. You can add the following to your ~/.screenrc, or just wait for Ubuntu Intrepid Ibex later this month to include it by default:

# terminfo and termcap for nice 256 color terminal
# allow bold colors - necessary for some reason
attrcolor b ".I"
# tell screen how to set colors. AB = background, AF=foreground
termcapinfo xterm 'Co#256:AB=\E[48;5;%dm:AF=\E[38;5;%dm'
# erase background with current bg color
defbce "on" 
# set TERM
term screen-256color-bce

This was all (of course) an hours-long session of yak shaving because I’m playing around with a secret project I’m not yet ready to announce.


Fatal error: Call to undefined function twentyseventeen_get_svg() in /home/malaprop/push.cx/wp-content/themes/pushcx/archive.php on line 45