-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexcc
More file actions
executable file
·171 lines (121 loc) · 4.09 KB
/
Copy pathexcc
File metadata and controls
executable file
·171 lines (121 loc) · 4.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.8"
# dependencies = []
# ///
#
# This script is self-contained (pure Python) and can be executed
# directly. The `uv` she-bang at the top will create an isolated
# environment on first run and take care of any future dependencies.
"""
excc - Echo to your clipboard !
excc = echo + xcc = echo + 'xclip -sel clipboard'
Copy last used command to clipboard with ease!
A tiny helper that copies its arguments to the system clipboard.
Usage: excc [-sel <selection>] <text to copy>
## Background: Inspired by xcc alias
xcc alias in shell , that can be in `~/.bashrc` :
```
alias xcc='xclip -sel clipboard'
```
Is very useful. I highly recommented it!
Mnemonics comes from fact that ctrl+x and ctrl+c are usual shortcuts to copy into clipboard, so from x and c one gets ergonomic to type `xcc`.
Usage of `xcc`:
```
$ # Copy output of program (here with code of scripts) into clipboard:
$ head -n -0 *.py | xcc
$ # Copy file into clipboard
$ xcc < file
```
## copy to clipboard prevously used command in terminal:
And here need for `excc` arised, as I found myself doing very often, in terminal
* typing: `[arrow up]+[home]+[echo ']+[end]+[' | xcc']+[enter]` (ofc instead of `[arrow up]` can be `[ctrl+R]` for reversed search, etc.).
To achieve sth like:
```
$ echo 'cmd param param... basically long command I want to copy into cliboard' | xcc
```
I come up with idea that it would be more ergonomic to type:
* `[home]+[excc ]+[enter]` instead !
```
$ excc cmd para param...
```
and it's easy mnemonic "echo + xcc" = "xcc" !
## Tip for Power Users / Alternative:
For power users using vim in bash,
can do :
* `[ctrl+X][ctrl+e]` to open current command in `$EDITOR`
* assuming `$EDITOR` is set to `vim`, then
* `:%y+` to copy entire buffer to clipboard
"""
import os
import shutil
import subprocess
import sys
from typing import Callable, List
def _detect_backend() -> Callable[[str], List[str]]:
"""
Detect an available clipboard backend and return a builder that
receives the desired selection and returns the command list.
Preference order:
1. command given in the EXCC_CLIP_CMD environment variable
2. xclip
3. wl-copy
4. xsel
"""
env_cmd = os.getenv("EXCC_CLIP_CMD")
if env_cmd and shutil.which(env_cmd):
return lambda sel: [env_cmd]
if shutil.which("xclip"):
return lambda sel: ["xclip", "-selection", sel]
if shutil.which("wl-copy"):
return lambda sel: ["wl-copy", "-p"] if sel == "primary" else ["wl-copy"]
if shutil.which("xsel"):
return lambda sel: ["xsel", "--" + sel]
raise RuntimeError(
"No clipboard utility found (tried xclip, wl-copy, xsel) and "
"EXCC_CLIP_CMD is not set."
)
_BACKEND = _detect_backend()
def copy_to_clipboard(text: str, selection: str = "clipboard") -> None:
"""
Copy *text* to the clipboard/selection chosen.
"""
cmd = _BACKEND(selection)
subprocess.run(cmd, input=text.encode(), check=True)
def _print_help() -> None:
print(
"""\
excc – echo to your clipboard
Usage:
excc [-sel <selection>] <text …>
excc (-h | --help)
Arguments are copied verbatim to the clipboard.
The optional “-sel” switch lets you choose the selection
(e.g. clipboard, primary). All remaining tokens are treated
as text to copy.
""",
file=sys.stderr,
)
def main(argv: List[str] | None = None) -> None:
argv = sys.argv[1:] if argv is None else argv
if not argv or argv[0] in ("-h", "--help"):
_print_help()
return
selection = "clipboard"
if argv[0] == "-sel":
if len(argv) < 2:
print("excc: -sel requires an argument", file=sys.stderr)
sys.exit(1)
selection = argv[1]
argv = argv[2:]
if not argv:
print("excc: nothing to copy", file=sys.stderr)
sys.exit(1)
text = " ".join(argv)
try:
copy_to_clipboard(text, selection)
except RuntimeError as exc:
print(f"excc: {exc}", file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
main()