marketplace/text

Clean Paste

v0.1.0

@rebindfree

Paste without formatting in every app, with smart quotes straightened and extra spaces removed.

Gallery

Clean Paste preview

Readme

Press Ctrl+Shift+V (Cmd+Shift+V on macOS) to paste only the text, with no fonts or colors. Smart quotes are straightened and runs of spaces collapse to one. Plain Ctrl+V or Cmd+V still pastes as usual.

Needs Rebind 3.5.0 or newer on Windows or macOS. No extra permissions.

Settings

  • Key and Held with the key: the shortcut. Defaults V with Ctrl+Shift on Windows and Cmd/Win+Shift on macOS.
  • Straighten smart quotes: turns “ ” ‘ ’ into " and '.
  • Collapse extra spaces: turns runs of spaces and tabs into one space and drops spaces at line ends.

Key changes apply while the package runs on Rebind 3.9 or newer. On older versions, restart the package.

Limits

  • When the clipboard has no text, a notice appears in Rebind. To see notices on the desktop, turn on Desktop notifications in Rebind's settings.
  • The cleaned text replaces what was on the clipboard, so the formatted copy is gone afterwards.
  • Apps that already use Ctrl+Shift+V (some terminals, Chrome's own plain paste) get this package's paste instead while it runs.
  • Live use remains unverified on Windows and macOS.

Stop

Stop the package from the editor toolbar, or press Left Ctrl + Left Alt + K to stop all scripts.

Reviews

No reviews yet. Be the first, from the app.

Source

Version 0.1.0 (current)

main.luau

-- Clean Paste: paste the clipboard as plain text, with smart quotes
-- straightened and runs of spaces collapsed. Plain paste is untouched.

local IS_MAC = _REBIND.platform == "macos"

local MODS = {
  ["Ctrl+Shift"] = { ctrl = true, shift = true },
  ["Cmd/Win+Shift"] = { win = true, shift = true },
  ["Ctrl+Alt"] = { ctrl = true, alt = true },
  ["Alt+Shift"] = { alt = true, shift = true },
}

local cfg = UI.Schema({
  key = UI.Keybind("V", { label = "Key" }),
  modifier = UI.Select(
    if IS_MAC then "Cmd/Win+Shift" else "Ctrl+Shift",
    { "Ctrl+Shift", "Cmd/Win+Shift", "Ctrl+Alt", "Alt+Shift" },
    { label = "Held with the key" }
  ),
  quotes = UI.Toggle(true, { label = "Straighten smart quotes" }),
  spaces = UI.Toggle(true, { label = "Collapse extra spaces" }),
})

local function chordHeld()
  local want = MODS[cfg.modifier] or {}
  local have = Input.GetModifiers()
  for _, m in { "ctrl", "alt", "shift", "win" } do
    if (want[m] == true) ~= have[m] then
      return false
    end
  end
  return true
end

local function clean(text)
  if cfg.quotes then
    text = text:gsub("“", '"'):gsub("”", '"'):gsub("‘", "'"):gsub("’", "'")
  end
  if cfg.spaces then
    text = text:gsub("[ \t]+", " "):gsub(" +\n", "\n")
  end
  return text
end

Bind(cfg.key, {
  when = chordHeld,
  action = Async(function()
    local ok, text = pcall(Clipboard.Get)
    if not ok or not text then
      UI.Notify("The clipboard has no text", "warning")
      return
    end
    Clipboard.Set(clean(text))
    -- let go of the chord first, or the paste becomes another chord
    while Input.GetModifiers().shift or Input.GetModifiers().alt do
      Sleep(10)
    end
    HID.Press(if IS_MAC then "LWin+V" else "LCtrl+V")
  end),
})