Updates from July, 2017 Toggle Comment Threads | Keyboard Shortcuts

  • ThomasPowell 12:08 pm on July 6, 2017 Permalink
    Tags: go, indentation, , spaces, tabs, whitespace   

    Whitespace is Significant 

    While I was in my first couple years of college, Python was gaining traction as a hot new programming language. I had been programming in C since high school, but was curious about new languages. I took an interest in learning more about Python. A classmate told me that whitespace (at least indentation) was significant in Python. I changed my mind.

    The Holy Wars of Indentation Style


    // From https://en.wikipedia.org/wiki/Indent_style
    // K & R
    while (x == y) {
    something();
    somethingelse();
    }
    // 1TBS
    if (x < 0) {
    puts("Negative");
    } else {
    nonnegative(x);
    }
    // Stroustup
    if (x < 0) {
    puts("Negative");
    negative(x);
    }
    else {
    puts("Non-negative");
    nonnegative(x);
    }
    // Allman
    while (x == y)
    {
    something();
    somethingelse();
    }
    // GNU
    while (x == y)
    {
    something();
    somethingelse();
    }
    // Whitesmiths
    while (x == y)
    {
    something();
    somethingelse();
    }
    // Horstmann
    while (x == y)
    { something();
    somethingelse();
    }
    // Pico
    while (x == y)
    { something();
    somethingelse(); }
    // Ratliff
    while (x == y) {
    something();
    somethingelse();
    }
    // LISP
    while (x == y) {
    something();
    somethingelse(); }

    view raw

    indent.c

    hosted with ❤ by GitHub

    It’s interesting that would’ve been so turned off by a language that placed significance on whitespace and indentation, when I had fantasized about holy wars revolving around C indentation style (Horstmann is the only way!) and tabs vs. spaces (tabs, tab width 4!). I wretched at anything in the GNU C coding style (okay, I still do…), but the funny thing was, I never was able to program in a consistent style: There were other co-workers who had a slightly different preferred style. I was also learning myself, so relative importance of information in code changed, and my opinions on bracing style evolved.

    Non-C Languages that Use Curly Braces for Things

    It was a combination of Java, JavaScript, Perl, and Ruby that altered my perception of “proper” bracing style (BUT NOT SPACES OVER TABS!). A new line after a conditional or function declaration/call before the brace either took up unnecessary amounts of space, or changed the meaning of the code altogether (e.g., blocks in ruby, for which adding a newline = syntax error). And so, I evolved into declaring that 1TBS style was the only proper way to write C (WITH TABS!)

    Ruby

    Ruby has a generally accepted coding style that is enforced by no one except for code reviewers and maybe draconian RuboCop build configurations. I’d link to the coding style, if I had any certainty that the one I grabbed was 99% correct. Even RubyMine doesn’t format code to the same standards as RuboCop.  (Continuation indent and spacing around braces were two settings I had to tweak.)

    Small inconsistencies aside, Ruby code has ended up being the most consistent—visually—to support and add code to. I’ve introduced tighter RuboCop configurations on newer projects to try to adhere more closely to generally accepted coding style for Ruby.

    Ruby also introduced me to an acceptance of significant whitespace. While C code often gets sloppy with spacing around punctuation markers in code, Ruby developers take more care in proper whitespace around the conditionals, braces, etc. Some C/C++ projects like Mozilla do similar standards. However, Ruby is the first language that I’ve seen a community-wide interest in code that presents in the same manner. Of course, most of this code isn’t syntactically significant, but it is of human significance–and humans have their own mental compilers that optimize on standard patterns.

    Still, this isn’t the largest impact Ruby has had on my opinion of significant whitespace. Through Ruby, I’ve been exposed to YAML, HAML, and Slim. (I have dibs on forming a band of Rubyists with that name!) All three languages are unforgiving about inconsistent indentation. They take out explicit expression of boundaries and create visually implicit boundaries via hierarchies of indents. You don’t need to look for an end or closing brace to know that the context has moved up a level. The indentation tells you where that happens.

    (And yes, because of the generally accepted coding style in Ruby, I use 2 spaces instead of tabs now.)

    Golang

    And yet, Ruby coding style is informal. You can code in improper style and still commit your code and/or run it. There’s something about having the freedom to write improper style and being able to be a good “citizen” on your own that is comforting.

    Go does not do this. Writing Go in any editor configured to code in it (I’ve been using the vim-go plugin) automatically formats via gofmt.  It’s pretty unsettling. I longed for the ability to become dictator over coding styles, and then was okay when Ruby dictated one, but gave us the autonomy to do the right thing. This auto-formatting? This is tyranny!

    But, perhaps, it’s time. We can mentally chunk pieces into larger concepts for storage, if code that does the same thing looks the code. Instead of having to remember every brace as an individual piece, we can put “for loop that iterates and prints” as a single chunk.

    A stray brace isn’t going to permanently prevent distillation into larger chunks; it will just take a higher cognitive load to get there. This in turn will require more experience with the language before a programmer can make that leap. Being able to break things into large chunks helps us discover the what instead of dwelling on the how.

     
  • ThomasPowell 7:23 pm on April 3, 2017 Permalink
    Tags: , ,   

    Lua Script to Start, Unhide, and/or Auto-Arrange 

    I’m starting to try using HammerSpoon, which is driven by Lua, for automatically arranging my applications depending on application scenarios.

    I have 3 screens, including a MacBook Pro at Retina native resolution and a Seiki 4K display. I grabbed the names of the monitors from Display Menu‘s menu bar menu.

    I initially made the mistake of looking for “Outlook”, “OneNote”, and “Chrome”, but all three applications require their respective company’s names to be included in the application name.


    https://en.wikipedia.org/wiki/Web_colors#X11_color_names
    hs.streamdeck.init(function(connected, sd)
    device = hs.streamdeck.getDevice(1)
    device.setButtonColor("1", hs.drawing.color.x11.teal)
    end)
    applications = { "Messages", "iTunes", "Skype for Business", "iTerm2", "Microsoft Outlook", "HipChat", "Microsoft OneNote", "MacVim", "RubyMine", "Firefox" }
    hs.hotkey.bind({"cmd", "alt", "ctrl"}, "pageup", function()
    for _k, app_name in pairs(applications) do
    hs.application.launchOrFocus(app_name)
    print(app_name)
    app = hs.application.find(app_name)
    if app then
    hs.application.unhide(app)
    end
    end
    local lgUltra="LG Ultra HD"
    local windowLayout = {
    upper right quadrant
    {"Slack", nil, lgUltra, hs.geometry.rect(0,0,0.5,0.5), nil, nil},
    upper left quadrant
    {"Notes", nil, lgUltra, hs.geometry.rect(0.5,0,0.5,0.5), nil, nil},
    lower right quadrant
    {"Skype for Business", nil, lgUltra, hs.geometry.rect(0.5,0.5,0.5,0.5), nil, nil},
    lower left quadrant
    {"iTerm2", nil, lgUltra, hs.geometry.rect(0,0.5,0.5,0.5), nil, nil}
    }
    hs.layout.apply(windowLayout)
    local laptopScreen="Color LCD"
    local windowLayout = {
    {"Microsoft Outlook", nil, laptopScreen, hs.geometry.rect(0.5,0,0.5,0.5), nil, nil},
    {"HipChat", nil, laptopScreen, hs.geometry.rect(0.5,0.5,0.5,0.5), nil, nil},
    {"Microsoft OneNote", nil, laptopScreen, hs.geometry.rect(0,0.5,0.5,0.5), nil, nil},
    {"Notes", nil, laptopScreen, hs.geometry.rect(0,0,0.5,0.5), nil, nil}
    }
    hs.layout.apply(windowLayout)
    local seiki4KScreen="SE39UY04"
    local windowLayout = {
    {"MacVim", nil, seiki4KScreen, hs.geometry.rect(0,0,0.5,0.5), nil, nil},
    {"Emacs", nil, seiki4KScreen, hs.geometry.rect(0.5,0,0.5,0.5), nil, nil},
    {"RubyMine-EAP", nil, seiki4KScreen, hs.geometry.rect(0,0.5,0.5,0.5), nil, nil},
    {"iTerm2", nil, seiki4KScreen, hs.geometry.rect(0.5,0.5,0.5,0.5), nil, nil}
    }
    hs.layout.apply(windowLayout)
    end)
    Convert a lua table into a lua syntactically correct string
    function table_to_string(tbl)
    local result = "{"
    for k, v in pairs(tbl) do
    Check the key type (ignore any numerical keys – assume its an array)
    if type(k) == "string" then
    result = result.."[\""..k.."\"]".."="
    end
    Check the value type
    if type(v) == "table" then
    result = result..table_to_string(v)
    elseif type(v) == "boolean" then
    result = result..tostring(v)
    else
    result = result.."\""..v.."\""
    end
    result = result..","
    end
    Remove leading commas from the result
    if result ~= "" then
    result = result:sub(1, result:len()1)
    end
    return result.."}"
    end
    hs.hotkey.bind({}, "f13", function()
    hs.location.start()
    locationTable = hs.location.get()
    hs.eventtap.keyStrokes(locationTable["latitude"] .. "," .. locationTable["longitude"])
    print(table_to_string(locationTable))
    end)
    function move_to_third(r,c)
    local win = hs.window.focusedWindow()
    local f = win:frame()
    local screen = win:screen()
    local extents = screen:frame()
    f.x = extents.x + (extents.w / 3) * c
    f.y = extents.y + (extents.h / 3) * r
    f.w = extents.w / 3
    f.h = extents.h / 3
    win:setFrame(f)
    end
    function move_to_two_third_horz(c)
    local win = hs.window.focusedWindow()
    local f = win:frame()
    local screen = win:screen()
    local extents = screen:frame()
    f.x = extents.x + (extents.w / 3) * c
    f.y = extents.y
    f.w = extents.w / 3 * 2
    f.h = extents.h
    win:setFrame(f)
    end
    function move_to_two_third_vert(r)
    local win = hs.window.focusedWindow()
    local f = win:frame()
    local screen = win:screen()
    local extents = screen:frame()
    f.x = extents.x
    f.y = extents.y + (extents.h / 3) * r
    f.w = extents.w
    f.h = extents.h / 3 * 2
    win:setFrame(f)
    end
    function move_to_four_ninths(r,c)
    local win = hs.window.focusedWindow()
    local f = win:frame()
    local screen = win:screen()
    local extents = screen:frame()
    f.x = extents.x + (extents.w / 3) * c
    f.y = extents.y + (extents.h / 3) * r
    f.w = extents.w / 3 * 2
    f.h = extents.h / 3 * 2
    win:setFrame(f)
    end
    function move_to_fourth(r,c)
    local win = hs.window.focusedWindow()
    local f = win:frame()
    local screen = win:screen()
    local extents = screen:frame()
    f.x = extents.x + (extents.w / 4) * c
    f.y = extents.y + (extents.h / 4) * r
    f.w = extents.w / 4
    f.h = extents.h / 4
    win:setFrame(f)
    end
    for i=0,15 do
    hs.hotkey.bind({"cmd", "alt", "ctrl"}, string.format("%x", i), function()
    move_to_fourth(math.floor(i/4),i%4)
    end)
    end
    for i=1,9 do
    hs.hotkey.bind({"cmd", "alt", "ctrl"}, "pad"..tostring(i), function()
    move_to_third(math.floor((9i)/3),(i1)%3)
    end)
    end
    for i=1,9 do
    hs.hotkey.bind({"cmd", "alt", "ctrl", "shift"}, "pad"..tostring(i), function()
    if i == 1 then move_to_four_ninths(1,0)
    elseif i == 3 then move_to_four_ninths(1,1)
    elseif i == 7 then move_to_four_ninths(0,0)
    elseif i == 9 then move_to_four_ninths(0,1)
    elseif i == 2 then move_to_two_third_vert(1)
    elseif i == 4 then move_to_two_third_horz(0)
    elseif i == 6 then move_to_two_third_horz(1)
    elseif i == 8 then move_to_two_third_vert(0)
    end
    end)
    end
    https://www.hammerspoon.org/docs/hs.application.watcher.html
    https://www.lua.org/pil/9.1.html
    https://stackoverflow.com/questions/16984540/how-to-pass-a-function-as-a-parameter-in-lua
    hs.application.watcher.new()
    TODO Plan:
    Create application watcher
    currentApp = ""
    function applicationWatcher(appName, eventType, appObject)
    if(eventType == hs.application.watcher.activated) then
    if (appName == "HipChat") then
    currentApp = "HipChat"
    end
    if (appName == "Google Chrome") then
    currentApp = "Chrome"
    end
    end
    end
    function alertCurrent()
    hs.alert(currentApp)
    end
    hs.timer.doEvery(5, alertCurrent)

    view raw

    init.lua

    hosted with ❤ by GitHub

     
  • ThomasPowell 12:11 am on April 1, 2017 Permalink
    Tags: ,   

    Hammerspoon Lua Script – Split Windows 3×3 

    I’ve been using using Spectacle pretty heavily, but with a larger screen, I always felt like quadrants were a poor use of real estate, so I began to crack open the source code, which was pretty challenging to navigate because it’s a mix of JavaScript and Objective-C reminiscent of user interface programming from ages past. So, I turned next to Hammerspoon.

    Hammerspoon uses Lua as a programming interface. I was able to automate moving windows around a 3×3 grid on the current screen with 18 lines of code.


    function move_to_third(r,c)
    local win = hs.window.focusedWindow()
    local f = win:frame()
    local screen = win:screen()
    local extents = screen:frame()
    f.x = extents.x + (extents.w / 3) * c
    f.y = extents.y + (extents.h / 3) * r
    f.w = extents.w / 3
    f.h = extents.h / 3
    win:setFrame(f)
    end
    for i=1,9 do
    hs.hotkey.bind({"cmd", "alt", "ctrl"}, tostring(i), function()
    move_to_third(math.floor((i1)/3),(i1)%3)
    end)
    end

    view raw

    init.lua

    hosted with ❤ by GitHub

     
c
Compose new post
j
Next post/Next comment
k
Previous post/Previous comment
r
Reply
e
Edit
o
Show/Hide comments
t
Go to top
l
Go to login
h
Show/Hide help
shift + esc
Cancel
%d bloggers like this: