Vortex Race 3 TKL LED Programming for Mac

I decided to switch to my Vortex Race 3 TKL for a more programming-centric job from the Vortex Tab 90M that felt a little better for email and spreadsheets. The Race 3 has Cherry MX Silent Reds vs. the Vortex Tab 90M’s Cherry MX Silent Blacks.

A couple of things that were a little bit difficult to follow were:

  1. How to set up the Race 3 for Mac (it had been used on a Windows PC most recently and never really used on a Mac). This Reddit thread gives some suggestions on how to optimize that.
  2. How to program the LEDs (for just basic effects):

The LED programming was fairly simple once I understood it (see here for a copy of the manual). The cool LED effects when you type are accessible by pressing the Pn key + one of the ‘1’ through ‘5’ keys. ‘4’ and ‘5’ have multiple effects:

Pn + ‘4’ cycles different “display single color LED mode”s which means that the interactive LED effects appear in context with your

  • [no effect?]
  • Interactive mode – keys light up as you type.
  • Flash vortex mode – keys pulse around the keyboard originating from your keystrokes
  • Aurora mode – keys pulse in color around the keyboard originating from your keystrokes

Pn + ‘5’ cycles different “Display full color LED mode”s which means “display on all the keys regardless of context”:

  • [no effect]
  • Full key light mode – just 100% on
  • Breath mode – keyboard pulses
  • Vortex mode – RGBs cycle in different phases with each other.
  • Rain drop mode – random drops of “color” appear on the keys

Pn + X – brightness down for the above effects

Pn + V – brightness up for the above effects

Pn + [< key] and Pn + [> key] are LED speed up and down.


Reviews of M1 Macs for Development

So far, the key interest for me have been the potential drastic improvement in battery life. I’m almost willing to sacrifice a bit of short term productivity to get there. I don’t know that the experiences sound any worse that trying to get my favorite development environments productive on Windows or a non-Debian flavor of Linux:

JetBrains and Xcode-centric perspective (11/23/2020):
https://medium.com/before-semicolon/is-m1-mac-worthy-or-good-for-developers-developer-review-3ed832f4105e

Rubyist perspective (11/25/2020):

https://www.driftingruby.com/episodes/a-rubyist-s-apple-m1-review

macOS 11 Big Sur compatibility on Apple Silicon · Issue #7857 · Homebrew/brew · GitHub (closed as of 12/26/2020):

https://github.com/Homebrew/brew/issues/7857

TypeScript/JavaScript/Rust (12/3/2020):

https://dev.to/redhoodjt1988/how-to-setup-development-environment-on-new-macbook-pro-m1-3kh

Rails’ DHH’s own experience (12/28/2020):

DriftingRuby tweet:


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.

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
{"Firefox", nil, lgUltra, hs.geometry.rect(0,0,0.5,0.5), nil, nil},
upper left quadrant
{"Microsoft Teams", 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
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
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)
appWatcher = hs.application.watcher.new(applicationWatcher)
appWatcher:start()
Dispatch application coroutine on activate
Pause coroutine on deactivate
Application-specific coroutine tracks exactly the important info for that app.
{"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}
}
hs.layout.apply(windowLayout)
local seiki4KScreen="SE39UY04"
local windowLayout = {
{"MacVim", nil, seiki4KScreen, hs.geometry.rect(0,0,0.5,0.5), nil, nil},
{"RubyMine", nil, seiki4KScreen, hs.geometry.rect(0.5,0,0.5,1.0), nil, nil},
{"Google Chrome", nil, seiki4KScreen, hs.geometry.rect(0,0.5,0.5,0.5), nil, nil}
}
hs.layout.apply(windowLayout)
end)

view raw
init.lua
hosted with ❤ by GitHub


Excel for Mac Breaks Up Spreadsheets Into Pages

Excel for Mac seems to use “Page Layout” view by default. This can be switched to the more sane Normal view by selecting View -> Normal from the menu.

You can change the default view in Excel -> Preferences -> View -> Preferred view for new sheets.

Still trying to figure out if there is a way to force all document openings to this setting as well.


Trying to Dig a Little More In-Depth With Maven

I’ve been reading Maven: The Definitive Guide (affiliate link) as a Kindle eBook and finally got to the point of trying the first example project. The book had mentioned that maven might be installed on Mac OS X already (due to usage with some versions of XCode). Magically, it’s there:

So far, I like the book’s approach to Maven.  It evangelizes maven as a tool, but puts the purpose of Maven in context, and explains, “Why Maven?” as well as explaining that “Maven or Ant?” is the wrong question.

If you’re looking to download the files to complete the example Maven projects, they’ve moved from the URLs in the Kindle version of the book because Maven: The Definitive Guide has been split into two books, Maven by Example and Maven: The Complete Reference.

All the project examples can still be downloaded from a single zip file from the Maven by Example book. However, the chapter numbers are not the same in the Maven by Example book, and the folders in the examples are named by a chap-{title} convention.

Within the zip file:

  • Chapter 4’s project (Simple Weather Application) (originally at http://www.sonatype.com/book/mvn-examples-1.0.zip or http://www.sonatype.com/book/mvn-examples-1.0.tar.gz) is now available in the zip file under:
    • ch-custom/simple-weather
  • Chapter 5’s project (Simple Web Application)
    • ch-simple-web/simple-webapp

 

 


MacBook Pro setup list.

Some things that I’ve set up on my MBP:

  • Terminal Settings
    • ~/.profile
      • Changed prompt
      • Default is ‘h:W u$ ‘ [ Computer-Name: current-directory username$ ]
      • Changed to ‘[w] ‘
      • man bash, find “PROMPTING” for escape codes
  • Editors
    • TextEdit – for simple text files, quick code tweaks
    • XCode [default code editor] – for longer code edit sessions and code viewing
    • macvim – for text file batch editing, power code substitution
  • Programming
  • XCode
  • git for Mac
  • Twitter
  • TweetDeck for Social Media Monitoring
  • Nambu for compact Twitter monitoring with lists
  • Tweetie for Twitter as a stream only
  • Mail
  • Mac Mail 4.2 connected to Exchange server is more useful than Outlook on Windows with Desktop Search or Xobni