Skip to content

sisoe24/hammerspoon-vscode

Repository files navigation

Codacy Badge

vscode-marketplace vscode-version vscode-installs vscode-ratings vscode-last-update

openvsx-marketplace openvsx-version openvsx-downloads openvsx-rating

1. Hammerspoon-vscode README

Unofficial Hammerspoon extension for Visual Studio Code.

1.1. Features

  • IntelliSense for Hammerspoon API (requires Lua Language Server).
  • Evaluate Hammerspoon code from vscode without reloading the configuration. (thanks to @velios).
  • Execute vscode commands from Hammerspoon via socket connection.
  • Reload Hammerspoon configuration command. (Requires hs.ipc. See Requirements)
  • Hammerspoon console output to Visual Studio Code output window. (Requires hs.ipc. See Requirements)
  • Spoon utilities:
    • Create Spoon template.
    • Generate Spoon documentation. (Requires hs.ipc. See Requirements)

1.2. Requirements

  • Lua Language Server extension (it is included with the extension pack by default).
  • hs.ipc module installed. Some commands depend on the hs.ipc module. To install it, execute hs.ipc.cliInstall() in your Hammerspoon environment and call it at the beginning of your init.lua with require('hs.ipc') (more on module documentation). If you are on an Apple silicon Mac, you might need to follow those instructions to properly install the module.

1.3. Stubs

The extension now uses the Lua Language Server to provide IntelliSense. In order to provide the Hammerspoon API, the extension uses the EmmyLua.spoon stubs from the official Hammerspoon Spoons repository. The extensions offers a quick utility command to download and generate the stubs. The command Hammerspoon: Add Stubs will:

  1. Download the EmmyLua stubs.
  2. Place them in the Hammerspoon spoons directory (default: ~/.hammerspoon/Spoons).
  3. Import them in the init.lua file.
  4. Add them to the Lua.workspace.library user setting.
  5. Reload the Hammerspoon configuration.

Once the stubs are added, you might need to reload VSCode for the changes to take effect.

1.3.1. Notes:

  • Some stubs might fail to load especially when constructors are involved. In that case, you can always add the type annotation manually:

    ---@type hs.application
    local app = hs.application("Safari")
  • The EmmyLua.spoon will try to compile the stubs also for your custom spoons. This can cause an error if there is something wrong with your spoon docs.json.

  • The extension still supports the old way of providing the API, but it is highly recommended to use the new method. The old method can be enabled/disabled via the hammerspoon.enableLegacyProviders setting.

1.4. Evaluate Hammerspoon code

You can evaluate Hammerspoon code from vscode without reloading the configuration. To do so, you need to have the hs.ipc module installed. See Requirements for more information.

To evaluate code, you can use one of the following commands:

  • Hammerspoon: Evaluate Line: Evaluate the current line.
  • Hammerspoon: Evaluate File: Evaluate the entire file.
  • Hammerspoon: Evaluate Selection: Evaluate the selected code.

The commands are also available in the editor right-click context menu.

1.5. Socket connection

You can execute vscode commands from Hammerspoon by sending data via the socket module.

socket = hs.socket.new()
socket:connect('localhost', 54321)
socket:send('workbench.action.toggleZenMode')

-- calling socket:disconnect() immediately, will fail to register the message
hs.timer.doAfter(1, function() socket:disconnect() end)

You can also write arguments inside curly brackets and delimit them by a comma: {arg1, arg2}

socket:send('workbench.action.tasks.runTask {My Task}')

For the extension to accept incoming data, you need to start the server via the command: Hammerspoon: Toggle server connection or via the button in lower the status bar and specify the port in the extension settings (default: 54321).

1.6. Available Commands

All commands are available by opening the Command Palette Command+Shift+P and typing in one of the following Command Name:

Command Name Command ID Description
Hammerspoon: Add Stubs hammerspoon.addStubs Add EmmyLua stubs to the Hammerspoon Spoons directory
Hammerspoon: Evaluate Line hammerspoon.evaluateCurrentLineText Evaluate the current line
Hammerspoon: Evaluate File hammerspoon.evaluateCurrentFileText Evaluate the entire file
Hammerspoon: Evaluate Selection hammerspoon.evaluateSelectedText Evaluate the selected code
Hammerspoon: Add Stubs hammerspoon.addStubs Add EmmyLua stubs
Hammerspoon: Reload Hammerspoon configuration hammerspoon.reloadConfiguration Reload Hammerspoon configuration
Hammerspoon: Show Hammerspoon Console hammerspoon.showConsole Show Hammerspoon console
Hammerspoon: Toggle server connection hammerspoon.createSpoon Toggle connection that allows incoming data to be executed as vscode commands
Hammerspoon: Create Spoon hammerspoon.createSpoon Quick Spoon startup template
Hammerspoon: Generate Spoon Documentation hammerspoon.generateSpoonDoc Generate docs.json for current spoon

1.6.1. Notes

  • Hammerspoon: Reload Hammerspoon configuration command can be executed via a button in the Editor Toolbar.

    HsReload

  • The Spoon template will get created in the Hammerspoon: Spoons: Path configuration value which defaults to .hammerspoon/Spoons.

  • When generating documentation for the Spoon, the editor's current active file must be a init.lua.

  • By default, the extension does not provide any shortcut. But you can assign each command to one. (see Key Bindings for Visual Studio Code for more information).

    {
      "key": "cmd+shift+e",
      "command": "hammerspoon.evaluateCurrentLineText",
      "when": "editorTextFocus && resourceLangId == lua"
    }

1.7. Extension settings

  • Enable Legacy Providers - hammerspoon.enableLegacyProviders

    Enable the legacy providers. Defaults to true.

    Note: The legacy providers are incomplete and might not work as expected. It is highly recommended to use the stubs instead.

  • Console: Focus Output Window - hammerspoon.console.focusOutputWindow

    Focus the output window when a message is received from Hammerspoon. Defaults to true.

    Tip: I always have hs.console.clearConsole() at the top of the init.lua since it gets pretty messy understanding where starts what.

  • Console: Filter Output -hammerspoon.console.filterOutput

    An array of regex patterns. Useful to filter out the Hammerspoon console output inside VScode.

    Example:

    {
      "hammerspoon.console.filterOutput": [
        "➡.+",
        "ERROR:.+"
      ]
    }

    Tip: I use the extension Python EasyPrint (which also works on Lua) to quickly print debug statements. The print statement always starts with a Unicode char , which I can use in the regex filter.

  • Network: Port - hammerspoon.network.port: number

    A port to use for incoming connection when sending message from Hammerspoon. Defaults to 54321.

  • Spoons: Extra Documentation - hammerspoon.spoon.extraDocumentation

    To generate the extra documentation (HTML/Markdown), you need to have access to the Hammerspoon source code repository with its python dependency.

    From Hammerspoon official documentation:

    With that done, the setting takes two options:

    • repository-path: The Hammerspoon source code repository path.
    • interpreter-path: The Python interpreter path of the Hammerspoon source code repository.

    Example:

    "hammerspoon.spoons.extraDocumentation": {
        "repository-path": "/Users/virgil/Developer/SourceCode/hammerspoon",
        "interpreter-path": "/Users/virgil/Developer/SourceCode/hammerspoon/.venv/bin/python"
    }
  • Spoons: Path - hammerspoon.spoons.path

    The path where to create the Spoons. Defaults to ~/.hammerspoon/Spoons. If a custom path is specified, remember to add it to your init.lua.

    From Hammerspoon official documentation:

    Note that hs.loadSpoon() uses package.path to find Spoons. Hence you can have it look for Spoons in other paths by adding those paths to package.path as follows:

    -- Look for Spoons in ~/.hammerspoon/MySpoons as well
    package.path = package.path .. ";" ..  hs.configdir .. "/MySpoons/?.spoon/init.lua"

1.9. Acknowledgment

luaparse for generating the symbol table. EmmyLua for the stubs.