196 lines
7.6 KiB
Lua
196 lines
7.6 KiB
Lua
--- === BrewInfo ===
|
|
---
|
|
--- Display pop-up with Homebrew Formula info, or open their URL
|
|
---
|
|
--- Download: [https://github.com/Hammerspoon/Spoons/raw/master/Spoons/BrewInfo.spoon.zip](https://github.com/Hammerspoon/Spoons/raw/master/Spoons/BrewInfo.spoon.zip)
|
|
---
|
|
--- You can bind keys to automatically display the output of `brew
|
|
--- info` of the currently-selected package name, or to open its
|
|
--- homepage. I use it to quickly explore new packages from the output
|
|
--- of `brew update`.
|
|
|
|
local mod={}
|
|
mod.__index = mod
|
|
|
|
-- Conformance hack, our Travis linter expects the object to be called "obj"
|
|
local obj=mod
|
|
|
|
-- Metadata
|
|
mod.name = "BrewInfo"
|
|
obj.version = "1.1"
|
|
mod.author = "Diego Zamboni <diego@zzamboni.org>"
|
|
mod.homepage = "https://github.com/Hammerspoon/Spoons"
|
|
mod.license = "MIT - https://opensource.org/licenses/MIT"
|
|
|
|
--- BrewInfo.brew_path
|
|
--- Variable
|
|
--- A string specifying the path to the `brew` executable. Defaults to `/usr/local/bin/brew`
|
|
mod.brew_path = "/usr/local/bin/brew"
|
|
|
|
--- BrewInfo.brew_info_delay_sec
|
|
--- Variable
|
|
--- An integer specifying how long the alerts generated by BrewInfo will stay onscreen
|
|
mod.brew_info_delay_sec = 3
|
|
|
|
--- BrewInfo.brew_info_style
|
|
--- Variable
|
|
--- A table in conformance with the [hs.alert.defaultStyle](http://www.hammerspoon.org/docs/hs.alert.html#defaultStyle[]) format that specifies the style used by the alerts. Default value: `{ textFont = "Courier New", textSize = 14, radius = 10 }`
|
|
mod.brew_info_style = {
|
|
textFont = "Courier New",
|
|
textSize = 14,
|
|
radius = 10
|
|
}
|
|
|
|
--- BrewInfo.select_text_if_needed
|
|
--- Variable
|
|
--- If `true`, and no text is currently selected in the terminal, issue a double-click to select the text below the cursor, and use that as the input to `brew info`. See also `BrewInfo.select_text_modifiers`. Defaults to `true`.
|
|
mod.select_text_if_needed = true
|
|
|
|
--- BrewInfo.select_text_modifiers
|
|
--- Variable
|
|
--- Table containing the modifiers to be used together with a double-click when `BrewInfo.select_text_if_needed` is true. Defaults to `{cmd = true, shift = true}` to issue a Cmd-Shift-double-click, which will select a continuous non-space string in Terminal and iTerm2.
|
|
mod.select_text_modifiers = {cmd = true, shift = true}
|
|
|
|
-- Internal function to issue a double click with given modifiers
|
|
function leftDoubleClick(modifiers)
|
|
local pos=hs.mouse.absolutePosition()
|
|
hs.eventtap.event.newMouseEvent(hs.eventtap.event.types.leftMouseDown, pos, modifiers)
|
|
:setProperty(hs.eventtap.event.properties.mouseEventClickState, 2)
|
|
:post()
|
|
hs.eventtap.event.newMouseEvent(hs.eventtap.event.types.leftMouseUp, pos, modifiers)
|
|
:post()
|
|
end
|
|
|
|
-- Internal method to get the currently selected text
|
|
-- If `select_text_if_needed` is true and no text is selected, issue
|
|
-- a double-click to select, then use that
|
|
function mod:current_selection()
|
|
local elem=hs.uielement.focusedElement()
|
|
if elem then
|
|
local sel = elem:selectedText()
|
|
if (sel == nil or sel == "") and self.select_text_if_needed then
|
|
-- Simulate a double click to select the text under the cursor
|
|
leftDoubleClick(self.select_text_modifiers)
|
|
hs.timer.usleep(20000)
|
|
sel = elem:selectedText()
|
|
end
|
|
return sel
|
|
else
|
|
return nil
|
|
end
|
|
end
|
|
|
|
-- Internal method to show an alert in the configured style
|
|
function mod:show(text)
|
|
hs.alert.show(text, self.brew_info_style, self.brew_info_delay_sec)
|
|
return self
|
|
end
|
|
|
|
--- BrewInfo:showBrewInfo(pkg, subcommand)
|
|
--- Method
|
|
--- Displays an alert with the output of `brew <subcommand> info <pkg>`
|
|
---
|
|
--- Parameters:
|
|
--- * pkg - name of the package to query
|
|
--- * subcommand - brew subcommand to use for the `info` command. Defaults to an empty string, which results in "brew info <pkg>" being run. For example, if `subcommand` is "cask", the `brew cask info <pkg>` command will be used.
|
|
---
|
|
--- Returns:
|
|
--- * The Spoon object
|
|
function mod:showBrewInfo(pkg, subcommand)
|
|
local info = "No package selected"
|
|
local st = nil
|
|
if pkg and pkg ~= "" then
|
|
local cmd=string.format("%s %s info %s", self.brew_path, subcommand or "", pkg)
|
|
info, st=hs.execute(cmd)
|
|
if st == nil then
|
|
info = "No information found about formula '" .. pkg .. "'!"
|
|
end
|
|
end
|
|
self:show(info)
|
|
return self
|
|
end
|
|
|
|
--- BrewInfo:showBrewInfoCurSel(subcommand)
|
|
--- Method
|
|
--- Display `brew <subcommand> info` using the selected text as the package name
|
|
---
|
|
--- Parameters:
|
|
--- * subcommand - brew subcommand to use for the `info` command. Defaults to an empty string, which results in "brew info" being run. For example, if `subcommand` is "cask", the `brew cask info` command will be used.
|
|
---
|
|
--- Returns:
|
|
--- * The Spoon object
|
|
function mod:showBrewInfoCurSel(subcommand)
|
|
return self:showBrewInfo(self:current_selection(), subcommand)
|
|
end
|
|
|
|
--- BrewInfo:openBrewURL(pkg, subcommand)
|
|
--- Method
|
|
--- Opens the homepage for package `pkg`, as obtained from the `homepage` field in `brew <subcommand> cat <pkg>`
|
|
---
|
|
--- Parameters:
|
|
--- * pkg - name of the package to query
|
|
--- * subcommand - brew subcommand to use for the `cat` command. Defaults to an empty string, which results in "brew cat <pkg>" being run. For example, if `subcommand` is "cask", the `brew cask cat <pkg>` command will be used.
|
|
---
|
|
--- Returns:
|
|
--- * The Spoon object
|
|
function mod:openBrewURL(pkg, subcommand)
|
|
local msg = "No package selected"
|
|
if pkg and pkg ~= "" then
|
|
local j, st, t, rc=hs.execute(string.format("%s %s cat %s", self.brew_path, (subcommand or ""), pkg ))
|
|
if st ~= nil then
|
|
local url=string.match(j, "\n%s*homepage%s+['\"](.-)['\"]%s*\n")
|
|
if url and url ~= "" then
|
|
hs.urlevent.openURLWithBundle(url, hs.urlevent.getDefaultHandler("http"))
|
|
return self
|
|
end
|
|
end
|
|
msg = "An error occurred obtaining information about '" .. pkg .. "'"
|
|
end
|
|
self:show(msg)
|
|
return self
|
|
end
|
|
|
|
--- BrewInfo:openBrewURLCurSel(subcommand)
|
|
--- Method
|
|
--- Opens the homepage for the currently-selected package, as obtained from the `homepage` field in `brew <subcommand> cat <pkg>`
|
|
---
|
|
--- Parameters:
|
|
--- * subcommand - brew subcommand to use for the `cat` command. Defaults to an empty string, which results in "brew cat <pkg>" being run. For example, if `subcommand` is "cask", the `brew cask cat <pkg>` command will be used.
|
|
---
|
|
--- Returns:
|
|
--- * The Spoon object
|
|
function mod:openBrewURLCurSel(subcommand)
|
|
return self:openBrewURL(self:current_selection(), subcommand)
|
|
end
|
|
|
|
--- BrewInfo:bindHotkeys(mapping)
|
|
--- Method
|
|
--- Binds hotkeys for BrewInfo
|
|
---
|
|
--- Parameters:
|
|
--- * mapping - A table containing hotkey modifier/key details for the following items:
|
|
--- * show_brew_info - Show output of `brew info` using the selected text as package name
|
|
--- * open_brew_url - Open the homepage of the formula whose name is currently selected
|
|
--- * show_brew_cask_info - Show output of `brew cask info` using the selected text as package name
|
|
--- * open_brew_cask_url - Open the homepage of the Cask whose name is currently selected
|
|
function mod:bindHotkeys(mapping)
|
|
local def = {
|
|
show_brew_info = function() self:showBrewInfoCurSel() end,
|
|
open_brew_url = function() self:openBrewURLCurSel() end,
|
|
}
|
|
for action, key in pairs(mapping) do
|
|
local subcommand_show = action:match("show_brew_(.*)_info")
|
|
if subcommand_show and subcommand_show ~= "" then
|
|
def[action] = function() self:showBrewInfoCurSel(subcommand_show) end
|
|
end
|
|
|
|
local subcommand_open = action:match("open_brew_(.*)_url")
|
|
if subcommand_open and subcommand_open ~= "" then
|
|
def[action] = function() self:openBrewURLCurSel(subcommand_open) end
|
|
end
|
|
end
|
|
hs.spoons.bindHotkeysToSpec(def, mapping)
|
|
end
|
|
|
|
return mod
|