How do I add a newline to hs.eventtap.keyStrokes in Hammerspoon?
Asked Answered
M

3

6

I just started using Hammerspoon. I'm trying to output multiple lines of text by pressing Cmd+Shift+l .

Here is what I have tried so far :

hs.hotkey.bind({"cmd", "shift"}, "l", function()
  hs.eventtap.keyStrokes('from sklearn import metrics')
  hs.eventtap.keyStroke("return")
  hs.eventtap.keyStrokes('from sklearn.cross_validation import train_test_split')
end)

I also tried with inline "\n" and "%\n"

How can I bind a key combination to output multiple lines of text? Or, How can I send a newline character?

Malignancy answered 29/3, 2018 at 13:58 Comment(0)
R
7

I ran into the same problem. I tried what you tried above and although it worked in many applications, it still didn't work in Chrome. I used the pasteboard (clipboard) as a workaround.

jira_text = [[a 
long 
multi-line
string]]

-- Hotkey JIRA text
hs.hotkey.bind({"cmd", "alt", "ctrl"}, "J", function ()
  hs.alert.show("Remove this message after debugging!")
  --hs.eventtap.keyStrokes(jira_text)#don't do this!
  hs.pasteboard.writeObjects(jira_text)
  hs.eventtap.keyStroke("cmd", "v")
  end)
--

You could improve it further by using a custom named pasteboard so it doesn't overwrite your clipboard contents (if you want that).

Rockyrococo answered 1/5, 2018 at 18:37 Comment(1)
Any idea how to Cmd+V a custom pasteboard?Cense
G
1

I also ran into this problem and improved Josh Fox's answer by saving the contents of the system pasteboard into a temporary pasteboard before loading and pasting the multi-line string.

MULTILINE_STRING = [[multi
line
string]]

-- Paste Multi-line String
hs.hotkey.bind({'ctrl', 'cmd'}, 'F1', function()
    -- save clipboard data to temp
    tempClipboard = hs.pasteboard.uniquePasteboard()
    hs.pasteboard.writeAllData(tempClipboard, hs.pasteboard.readAllData(nil))
    
    -- load string into clipboard and paste
    hs.pasteboard.writeObjects(MULTILINE_STRING)
    hs.eventtap.keyStroke({'cmd'}, 'v')

    -- recall clipboard data
    hs.pasteboard.writeAllData(nil, hs.pasteboard.readAllData(tempClipboard))
    hs.pasteboard.deletePasteboard(tempClipboard)
end)
Gramophone answered 6/7, 2021 at 17:11 Comment(0)
B
0

I wasn't loving all this clipboard manipulation (too many side effects, probably unnecessarily heavy performance-wise), so I just solved this with the use of a helper function and some string splitting. Keep in mind that lua doesn't have a native string splitting function, I'm using the one from stringy here, but any custom or library-supplied string splitting function will work.

--- prevents hs.eventtap.keyStrokes from chewing up `\n`
--- @param str string
--- @return nil
function pasteMultilineString(str)
  local lines = stringy.split(str, "\n")
  local is_first_line = true
  for _, line in ipairs(lines) do
    if is_first_line then
      is_first_line = false
    else
      hs.eventtap.keyStroke({}, "return")
    end
    hs.eventtap.keyStrokes(line)
  end
end
Benzedrine answered 28/12, 2022 at 5:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.