33

Being productive with your tools

 4 years ago
source link: https://www.tuicool.com/articles/InqY7rV
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Trig­gered by an (ad­mit­ted­ly very harsh) re­cent ar­ti­cle by @cliff­s­ki , a re­cent need to re­boot in­to Win­dows 10 in or­der to fix MSVC 2019 sup­port in Mag­num (to be hor­ri­fied from the UX of Win­dows 10), and a re­sult­ing dis­cus­sion on our Git­ter chat , I de­cid­ed to share what I think is use­ful for be­ing a pro­duc­tive de­vel­op­er. In this case with Lin­ux and the KDE Plas­ma 5 desk­top be­ing my sys­tem of choice.

Git is a friend, not a de­spised en­e­my

Think of Git not as of the an­noy­ing ob­scure last-mile tool to “push your code to cus­tomers”, but a tool that can ac­tive­ly keep you fo­cused, or­ga­nized, help you re­view your changes, have your ed­it his­to­ry safe and let you eas­i­ly pick up in­ter­rupt­ed work from yes­ter­day.

I’m reg­u­lar­ly us­ing git status and git diff as a “scope guard” — to avoid the set of changes in my work­ing copy grow­ing too large. Then I’m us­ing the in­ter­ac­tive git add -i to pick rel­e­vant changes and com­mit them in­to as many sep­a­rate com­mits as de­sir­able, of­ten us­ing git re­base -i to back-in­te­grate fix­up patch­es to ex­ist­ing com­mits.

There’s noth­ing eas­i­er than do­ing a quick git stash to see if your lat­est mod­i­fi­ca­tions are to blame for bro­ken tests or if it’s some­thing else.

Some peo­ple ar­gue that “[their] job is cod­ing, not mak­ing beau­ti­ful com­mit logs” , but from my ex­pe­ri­ence scop­ing up a task in­to a se­quence of clean com­mits helps a lot — if the diff is self-con­tained, makes sense and doesn’t con­tain un­re­lat­ed changes, you can re­view your work much eas­i­er and be sure you didn’t mess any­thing up. It pays off lat­er when in­ves­ti­gat­ing bugs as well, git blame to­geth­er with git bisect are pow­er­ful tools for pin­ning down is­sues in large or un­fa­mil­iar code­bas­es. But they need a clean his­to­ry to work prop­er­ly.

Get to know your ed­i­tor, shell and key­board lay­out

While ev­ery ed­i­tor is dif­fer­ent, there are a few fea­tures I ab­so­lute­ly de­mand to con­sid­er it us­able. If the ed­i­tor starts slow, has a typ­ing lag, can’t ap­ply a con­sis­tent in­den­ta­tion and white­space pol­i­cy, doesn’t know block edit­ing or com­ment­ing/un­com­ment­ing code isn’t a key short­cut, then it’s use­less for me. Kate from KDE (and ev­ery­thing based on it — KWrite, KDe­vel­op) is my ed­i­tor of choice. I have to ad­mit I nev­er both­ered to learn Vim — most­ly be­cause the cur­rent way I ed­it files is fast enough, the bot­tle­neck be­ing my brain and not “how fast I can type”.

Know­ing how to nav­i­gate with key­board is es­sen­tial as well — far too of­ten I see se­nior pro­gram­mers with 20+ years of ex­pe­ri­ence mov­ing across words or lines on­ly by re­peat­ed­ly press­ing ar­row keys like if there was no oth­er way. Ctrl Ar­row skips whole words and there’s Home / End , use them! On Mac, how­ev­er, I was nev­er able to have those work con­sis­tent­ly across apps and it’s one of rea­sons why I’d rather SSH in­to a Mac than use its key­board di­rect­ly.

Pick a shell where you can work fast — 90% of what you do there is re­peat­ed­ly ex­e­cut­ing short com­mands, so it’s es­sen­tial to have this op­ti­mized. The plain Win­dows cmd.exe is ab­so­lute­ly ter­ri­ble at that, but most oth­er shells can be made a joy to work with if you con­fig­ure their his­to­ry han­dling.

"\e[A":history-search-backward
"\e[B":history-search-forward

Paste this in­to your /etc/inputrc , open a new ter­mi­nal, type a com­mand pre­fix and pres Up to au­to­com­plete it from typed his­to­ry. Sim­ple and in­tu­itive. You can thank me lat­er.

Have your desk­top work for you

I have a sin­gle ex­ter­nal 27” 4K screen. It prac­ti­cal­ly cov­ers my field of view and fits ev­ery­thing I can fo­cus on in a sin­gle mo­ment, but not more . By choice — I cur­rent­ly don’t have any de­sire to use more than one screen. What I usu­al­ly see else­where is peo­ple hav­ing one screen with an IDE and the oth­er with a sin­gle Slack win­dow, an e-mail or a brows­er, with all the mes­sages, an­i­mat­ed ads and no­ti­fi­ca­tions con­stant­ly beg­ging for at­ten­tion, on­ly mak­ing fo­cused work mis­er­able.

What I have in­stead is six vir­tu­al desk­tops — one ded­i­cat­ed for the brows­er, an­oth­er three for work, one desk­top sole­ly for file / pack­age man­age­ment and one with a mu­sic play­er. This makes it pos­si­ble to have each vir­tu­al desk­top a sin­gle area of fo­cus, com­pared to a pile of win­dows the IDE won’t dis­tract you when read­ing a PDF and a brows­er win­dow won’t dis­tract from cod­ing. It’s im­por­tant that the taskbar shows on­ly win­dows from the cur­rent desk­top and noth­ing else. Re­cent­ly I even turned off all brows­er push no­ti­fi­ca­tions so ac­tiv­i­ty from one vir­tu­al desk­top doesn’t leak in­to oth­ers in any way.

En22eum.png!web Desk­top switch­er in the taskbar Ctrl F1F6 short­cuts for switch­ing. Ctrl F1 is al­ways the brows­er desk­top.

Im­por­tant for desk­top switch­ing short­cuts is that they’re ab­so­lute (so I don’t have to think about di­rec­tion , just the des­ti­na­tion ) and that there’s no an­i­ma­tion — if the brain is fo­cused on a par­tic­u­lar screen area, quick switch­ing to an­oth­er desk­top and back will not cause it to lose con­text. That’s al­so why I nev­er use Alt Tab , it has an un­pre­dictable or­der and caus­es so much vis­ual noise that los­ing con­text is in­evitable. An­oth­er es­sen­tial fea­ture is an abil­i­ty to make a win­dow stay al­ways on top or be present on all vir­tu­al desk­tops — a float­ing con­sole win­dow with a long-run­ning op­er­a­tion, for ex­am­ple.

vUR3aiJ.png!web Al­ways on top A diff opened in gitk stays on top while edit­ing code in a fullscreen IDE be­low; a “rolled-up” con­sole win­dow with a long-run­ning op­er­a­tion above it.

Your com­put­er can be a pow­er-house

It’s com­mon for me to have a brows­er with 100+ tabs open, two IDEs with ~50 files each, sev­er­al con­sole win­dows each with mul­ti­ple tabs, file man­ag­er with five split tabs, a dozen of PDFs open on top and a spread­sheet for pro­cras­ti­nat­ing on my tax­es. When I fin­ish my work, I put the lap­top to sleep and when I re­sume work the next day, it’s all there, ex­act­ly how I left it. Up­time of 90 days isn’t any­thing ex­tra­or­di­nary ei­ther.

A lap­top with 16 GB of RAM, of­ten run­ning on­ly at 800 MHz, has no prob­lem keep­ing up with all that. But it’s im­por­tant that I can re­ly on the sys­tem to not do any shady busi­ness in the back­ground — hog­ging the CPU with an an­tivirus check or down­load­ing gi­ga­bytes of sys­tem up­dates un­less I tell it to (and then ran­dom­ly re­boot­ing) would be an ab­so­lute show­stop­per.

On KDE Plas­ma, if I press Alt F2 , KRun­ner , a pop­up search win­dow, ap­pears. It can open apps, search tabs in my brows­er, do sim­ple cal­cu­la­tions but al­so has a plug­in that gives me ac­cess to a data­base of pre-de­fined sym­bols — whether I need an em-dash for a tweet, a trade­mark char­ac­ter or a ¯\_(ツ)_/¯ re­sponse for a chat. A crit­i­cal re­quire­ment is that it has to work pre­dictably and with­out any de­lay; typ­ing a known pre­fix and press­ing En­ter will al­ways give the same re­sult, no mat­ter how fast I type.

ZriUJny.png!web

An­oth­er very handy thing is a glob­al key­board his­to­ry. More of­ten than not, you need to copy sev­er­al things at once, not just one. Or you ac­ci­den­tal­ly copy some­thing and lose the pre­cious clip­board con­tents. Es­pe­cial­ly when you need to switch win­dows or desk­tops to copy mul­ti­ple things, the vis­ual noise will make your brain go out of the zone very quick­ly. With Klip­per I can use Ctrl Alt Up or Down to pick a dif­fer­ent en­try from the clip­board his­to­ry.

Python is the best cal­cu­la­tor, shell and knife

It’s a good idea to have a pen and a piece of pa­per on your desk, es­pe­cial­ly when you are cod­ing vis­ual things. Us­ing it to cal­cu­late a dot prod­uct by hand isn’t . A ter­mi­nal win­dow with an in­ter­ac­tive Python in­stance is a much bet­ter tool. And with Mag­num now get­tingPython bind­in­gs, it has ev­ery­thing need­ed.

>>> from magnum import *
>>> Matrix3.rotation(Deg(45))
Matrix(0.707107, -0.707107, 0,
       0.707107, 0.707107, 0,
       0, 0, 1)

Quick, where are the mi­nus signs in a 2D ro­ta­tion ma­trix?

Python is the go-to choice al­so for all string-pro­cess­ing shell scripts longer than one line — in­stead of try­ing to re­mem­ber how to use awk and cut in­side a while loop in Bash, whip that up in Python. It’ll be eas­i­er to de­bug, ex­tend and you wouldn’t need to learn the ob­scure tools again a week lat­er.

Fast it­er­a­tion times are key

There’s no worse pro­duc­tiv­i­ty killer than a tool that makes me wait un­til an op­er­a­tion is done. That’s a forced in­ter­rup­tion and my brain im­me­di­ate­ly gives up on all con­text. I can it­er­ate or core APIs in Mag­num ba­si­cal­ly with­out in­ter­rup­tion, in­cre­men­tal com­pi­la­tion tak­ing few sec­onds at most. Then, with Util­i­ty::Tweak­able , I can live-ed­it con­stants in a run­ning app for even faster turn­around times.

In con­trast, Mag­num’sPython bind­in­gs are done with py­bind11, which ex­pos­es a very sim­ple API do­ing very com­plex things un­der­neath. How­ev­er I soon got in­to a state where the it­er­a­tion time of a sin­gle com­pile & link got to al­most a minute — the whole en­gine with 800 tar­gets com­piles from scratch faster than that. To stay oc­cu­pied dur­ing this “down­time”, I tem­po­rar­ily switch to an­oth­er task, but the con­text switch over­head slow­ly makes the fo­cus dis­ap­pear.

Have a stack you can trust …

With Mag­num not far from be­ing a decade old, I have the lux­u­ry of re­ly­ing on a ma­ture, sta­ble and well-test­ed code­base. De­vel­op­ing new things on top of a trust­ed stack is a breeze, be­cause com­bin­ing well-test­ed and well-un­der­stood build­ing blocks most of­ten leads to the re­sult be­hav­ing cor­rect­ly as well — with any de­bug­ging hap­pen­ing on­ly on the sur­face lev­el.

This ex­tends to pro­vid­ing sup­port as well — know­ing the in­ter­nals well I can quick­ly nar­row down a re­port­ed prob­lem, re­mote­ly di­ag­nose it by ask­ing just a few ques­tions and pro­vide ei­ther a so­lu­tion or a work­around al­most im­me­di­ate­ly.

… and sev­er­al al­ter­na­tives for the stacks you can’t

Not ev­ery­thing is a “Zen Gar­den”, though — there’s the OS, GPU driv­ers, third par­ty li­braries, com­pil­ers and hard­ware, each at a var­i­ous state of sta­bil­i­ty. For those it’s im­por­tant to al­ways have an al­ter­na­tive im­ple­men­ta­tion to test on — if an im­age fails to load with one plug­in, try with an­oth­er. If a shad­er works flaw­less­ly on one GPU, it might as well crash and burn on an­oth­er.

Try to pri­mar­i­ly de­vel­op against the most con­form­ing im­ple­men­ta­tion (of a com­pil­er, stan­dard li­brary, GPU driv­er, file for­mat load­er) and reg­u­lar­ly test on at least one oth­er, to ver­i­fy your as­sump­tions. In­vest­ing a week (or even a month) of your time in­to set­ting up a CI test ma­trix that does au­to­mat­ic test­ing for you on sev­er­al dif­fer­ent plat­forms, ide­al­ly in­clud­ing GPU code, will pay back mul­ti­ple times.

NBRryun.png!web Build Ma­trix And that’sjust the top half.

Web is un­for­tu­nate­ly just too damn slow

Ev­er since I made the light­weight Mag­num web­site and docs, the rest of the In­ter­net com­par­a­tive­ly start­ed to feel much slow­er . While I can jump to a doc­u­men­ta­tion of Mesh­Tools::gen­er­ateS­mooth­Nor­mals() in a frac­tion of a sec­ond, nav­i­gat­ing to a par­tic­u­lar is­sue of a par­tic­u­lar project through the GitHub UI to write a re­ply is so slow that it’s faster for me to just re­call its num­ber and type the whole ad­dress out .

For ex­ter­nal li­braries I’m us­ing, I of­ten end up re­gen­er­at­ing the docs my­self us­ing m.css . The search func­tion­al­i­ty of any Sphinx-gen­er­at­ed docs is a bad joke and Googling the ac­tu­al be­hav­ior of Python’s splitlines() isn’t near­ly as straight­for­ward as it should be ei­ther. I end­ed up build­ing my own search­able copy of Eigen doc­u­men­ta­tion , did a sim­i­lar thing for An­droid NDK and I’m plan­ning to do that for Python stan­dard li­brary as well.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK