-
-
Save jemshid/2f00c8d0812f3fd7440ced673705a74b to your computer and use it in GitHub Desktop.
copy to clipboard ipython magic
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
The functionality requires installation of xsel package | |
sudo apt-get install xsel | |
1. clip: Add copy to clipboard from IPython! | |
2. ch : Copy history to clipboard. Just one line. | |
To install, just copy it to your profile/startup directory, typically: | |
~/.ipython/profile_default/startup/ | |
Example usage: | |
%clip hello world | |
# will store "hello world" | |
a = [1, 2, 3] | |
%clip a | |
# will store "[1, 2, 3]" | |
You can also use it with cell magic | |
In [1]: %%clip | |
...: Even multi | |
...: lines | |
...: work! | |
...: | |
If you don't have a variable named 'clip' you can rely on automagic: | |
clip hey man | |
a = [1, 2, 3] | |
clip a | |
""" | |
from cStringIO import StringIO | |
import sys | |
if sys.platform == 'darwin': | |
from AppKit import NSPasteboard, NSArray | |
elif sys.platform.startswith('linux'): | |
from subprocess import Popen, PIPE | |
else: | |
raise ImportError("Clip magic only works on osx or linux!") | |
from IPython.core.magic import register_line_cell_magic | |
def _copy_to_clipboard(arg): | |
arg = str(globals().get(arg) or arg) | |
if sys.platform == 'darwin': | |
pb = NSPasteboard.generalPasteboard() | |
pb.clearContents() | |
a = NSArray.arrayWithObject_(arg) | |
pb.writeObjects_(a) | |
elif sys.platform.startswith('linux'): | |
p = Popen(['xsel', '--clipboard'], stdin=PIPE) | |
p.communicate(input=arg) | |
print 'Copied to clipboard!' | |
@register_line_cell_magic | |
def clip(line, cell=None): | |
if line and cell: | |
cell = '\n'.join((line, cell)) | |
_copy_to_clipboard(cell or line) | |
# def cliph(line, cell=None) | |
# %his% | |
# We delete it to avoid name conflicts for automagic to work | |
del clip | |
@register_line_cell_magic | |
def ch(line, cell=None): | |
if line and cell: | |
cell = '\n'.join((line, cell)) | |
oldStdout = sys.stdout | |
myStdout = StringIO() | |
sys.stdout = myStdout | |
argMagicSting = 'history' + ' ' + str(line) | |
get_ipython().magic(argMagicSting) | |
sys.stdout = oldStdout | |
resString = myStdout.getvalue() | |
print resString | |
_copy_to_clipboard(resString) | |
# get_ipython().magic('clip ' + resString) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""This function is modified by Jemshid on line 28 and line 151.to make the ch (copy history) function work. | |
The changes are | |
import sys on line 28 | |
sys.stdout on line 151 | |
Implementation of magic functions related to History. | |
""" | |
#----------------------------------------------------------------------------- | |
# Copyright (c) 2012, IPython Development Team. | |
# | |
# Distributed under the terms of the Modified BSD License. | |
# | |
# The full license is in the file COPYING.txt, distributed with this software. | |
#----------------------------------------------------------------------------- | |
#----------------------------------------------------------------------------- | |
# Imports | |
#----------------------------------------------------------------------------- | |
from __future__ import print_function | |
# Stdlib | |
import os | |
from io import open as io_open | |
# Our own packages | |
from IPython.core.error import StdinNotImplementedError | |
from IPython.core.magic import Magics, magics_class, line_magic | |
from IPython.core.magic_arguments import (argument, magic_arguments, | |
parse_argstring) | |
from IPython.testing.skipdoctest import skip_doctest | |
from IPython.utils import io | |
from IPython.utils.py3compat import cast_unicode_py2 | |
import sys | |
#----------------------------------------------------------------------------- | |
# Magics class implementation | |
#----------------------------------------------------------------------------- | |
_unspecified = object() | |
@magics_class | |
class HistoryMagics(Magics): | |
@magic_arguments() | |
@argument( | |
'-n', dest='print_nums', action='store_true', default=False, | |
help=""" | |
print line numbers for each input. | |
This feature is only available if numbered prompts are in use. | |
""") | |
@argument( | |
'-o', dest='get_output', action='store_true', default=False, | |
help="also print outputs for each input.") | |
@argument( | |
'-p', dest='pyprompts', action='store_true', default=False, | |
help=""" | |
print classic '>>>' python prompts before each input. | |
This is useful for making documentation, and in conjunction | |
with -o, for producing doctest-ready output. | |
""") | |
@argument( | |
'-t', dest='raw', action='store_false', default=True, | |
help=""" | |
print the 'translated' history, as IPython understands it. | |
IPython filters your input and converts it all into valid Python | |
source before executing it (things like magics or aliases are turned | |
into function calls, for example). With this option, you'll see the | |
native history instead of the user-entered version: '%%cd /' will be | |
seen as 'get_ipython().magic("%%cd /")' instead of '%%cd /'. | |
""") | |
@argument( | |
'-f', dest='filename', | |
help=""" | |
FILENAME: instead of printing the output to the screen, redirect | |
it to the given file. The file is always overwritten, though *when | |
it can*, IPython asks for confirmation first. In particular, running | |
the command 'history -f FILENAME' from the IPython Notebook | |
interface will replace FILENAME even if it already exists *without* | |
confirmation. | |
""") | |
@argument( | |
'-g', dest='pattern', nargs='*', default=None, | |
help=""" | |
treat the arg as a glob pattern to search for in (full) history. | |
This includes the saved history (almost all commands ever written). | |
The pattern may contain '?' to match one unknown character and '*' | |
to match any number of unknown characters. Use '%%hist -g' to show | |
full saved history (may be very long). | |
""") | |
@argument( | |
'-l', dest='limit', type=int, nargs='?', default=_unspecified, | |
help=""" | |
get the last n lines from all sessions. Specify n as a single | |
arg, or the default is the last 10 lines. | |
""") | |
@argument( | |
'-u', dest='unique', action='store_true', | |
help=""" | |
when searching history using `-g`, show only unique history. | |
""") | |
@argument('range', nargs='*') | |
@skip_doctest | |
@line_magic | |
def history(self, parameter_s = ''): | |
"""Print input history (_i<n> variables), with most recent last. | |
By default, input history is printed without line numbers so it can be | |
directly pasted into an editor. Use -n to show them. | |
By default, all input history from the current session is displayed. | |
Ranges of history can be indicated using the syntax: | |
``4`` | |
Line 4, current session | |
``4-6`` | |
Lines 4-6, current session | |
``243/1-5`` | |
Lines 1-5, session 243 | |
``~2/7`` | |
Line 7, session 2 before current | |
``~8/1-~6/5`` | |
From the first line of 8 sessions ago, to the fifth line of 6 | |
sessions ago. | |
Multiple ranges can be entered, separated by spaces | |
The same syntax is used by %macro, %save, %edit, %rerun | |
Examples | |
-------- | |
:: | |
In [6]: %history -n 4-6 | |
4:a = 12 | |
5:print a**2 | |
6:%history -n 4-6 | |
""" | |
args = parse_argstring(self.history, parameter_s) | |
# For brevity | |
history_manager = self.shell.history_manager | |
def _format_lineno(session, line): | |
"""Helper function to format line numbers properly.""" | |
if session in (0, history_manager.session_number): | |
return str(line) | |
return "%s/%s" % (session, line) | |
# Check if output to specific file was requested. | |
outfname = args.filename | |
if not outfname: | |
outfile = sys.stdout # default | |
# We don't want to close stdout at the end! | |
close_at_end = False | |
else: | |
if os.path.exists(outfname): | |
try: | |
ans = io.ask_yes_no("File %r exists. Overwrite?" % outfname) | |
except StdinNotImplementedError: | |
ans = True | |
if not ans: | |
print('Aborting.') | |
return | |
print("Overwriting file.") | |
outfile = io_open(outfname, 'w', encoding='utf-8') | |
close_at_end = True | |
print_nums = args.print_nums | |
get_output = args.get_output | |
pyprompts = args.pyprompts | |
raw = args.raw | |
pattern = None | |
limit = None if args.limit is _unspecified else args.limit | |
if args.pattern is not None: | |
if args.pattern: | |
pattern = "*" + " ".join(args.pattern) + "*" | |
else: | |
pattern = "*" | |
hist = history_manager.search(pattern, raw=raw, output=get_output, | |
n=limit, unique=args.unique) | |
print_nums = True | |
elif args.limit is not _unspecified: | |
n = 10 if limit is None else limit | |
hist = history_manager.get_tail(n, raw=raw, output=get_output) | |
else: | |
if args.range: # Get history by ranges | |
hist = history_manager.get_range_by_str(" ".join(args.range), | |
raw, get_output) | |
else: # Just get history for the current session | |
hist = history_manager.get_range(raw=raw, output=get_output) | |
# We could be displaying the entire history, so let's not try to pull | |
# it into a list in memory. Anything that needs more space will just | |
# misalign. | |
width = 4 | |
for session, lineno, inline in hist: | |
# Print user history with tabs expanded to 4 spaces. The GUI | |
# clients use hard tabs for easier usability in auto-indented code, | |
# but we want to produce PEP-8 compliant history for safe pasting | |
# into an editor. | |
if get_output: | |
inline, output = inline | |
inline = inline.expandtabs(4).rstrip() | |
multiline = "\n" in inline | |
line_sep = '\n' if multiline else ' ' | |
if print_nums: | |
print(u'%s:%s' % (_format_lineno(session, lineno).rjust(width), | |
line_sep), file=outfile, end=u'') | |
if pyprompts: | |
print(u">>> ", end=u"", file=outfile) | |
if multiline: | |
inline = "\n... ".join(inline.splitlines()) + "\n..." | |
print(inline, file=outfile) | |
if get_output and output: | |
print(cast_unicode_py2(output), file=outfile) | |
if close_at_end: | |
outfile.close() | |
@line_magic | |
def recall(self, arg): | |
r"""Repeat a command, or get command to input line for editing. | |
%recall and %rep are equivalent. | |
- %recall (no arguments): | |
Place a string version of last computation result (stored in the | |
special '_' variable) to the next input prompt. Allows you to create | |
elaborate command lines without using copy-paste:: | |
In[1]: l = ["hei", "vaan"] | |
In[2]: "".join(l) | |
Out[2]: heivaan | |
In[3]: %recall | |
In[4]: heivaan_ <== cursor blinking | |
%recall 45 | |
Place history line 45 on the next input prompt. Use %hist to find | |
out the number. | |
%recall 1-4 | |
Combine the specified lines into one cell, and place it on the next | |
input prompt. See %history for the slice syntax. | |
%recall foo+bar | |
If foo+bar can be evaluated in the user namespace, the result is | |
placed at the next input prompt. Otherwise, the history is searched | |
for lines which contain that substring, and the most recent one is | |
placed at the next input prompt. | |
""" | |
if not arg: # Last output | |
self.shell.set_next_input(str(self.shell.user_ns["_"])) | |
return | |
# Get history range | |
histlines = self.shell.history_manager.get_range_by_str(arg) | |
cmd = "\n".join(x[2] for x in histlines) | |
if cmd: | |
self.shell.set_next_input(cmd.rstrip()) | |
return | |
try: # Variable in user namespace | |
cmd = str(eval(arg, self.shell.user_ns)) | |
except Exception: # Search for term in history | |
histlines = self.shell.history_manager.search("*"+arg+"*") | |
for h in reversed([x[2] for x in histlines]): | |
if 'recall' in h or 'rep' in h: | |
continue | |
self.shell.set_next_input(h.rstrip()) | |
return | |
else: | |
self.shell.set_next_input(cmd.rstrip()) | |
print("Couldn't evaluate or find in history:", arg) | |
@line_magic | |
def rerun(self, parameter_s=''): | |
"""Re-run previous input | |
By default, you can specify ranges of input history to be repeated | |
(as with %history). With no arguments, it will repeat the last line. | |
Options: | |
-l <n> : Repeat the last n lines of input, not including the | |
current command. | |
-g foo : Repeat the most recent line which contains foo | |
""" | |
opts, args = self.parse_options(parameter_s, 'l:g:', mode='string') | |
if "l" in opts: # Last n lines | |
n = int(opts['l']) | |
hist = self.shell.history_manager.get_tail(n) | |
elif "g" in opts: # Search | |
p = "*"+opts['g']+"*" | |
hist = list(self.shell.history_manager.search(p)) | |
for l in reversed(hist): | |
if "rerun" not in l[2]: | |
hist = [l] # The last match which isn't a %rerun | |
break | |
else: | |
hist = [] # No matches except %rerun | |
elif args: # Specify history ranges | |
hist = self.shell.history_manager.get_range_by_str(args) | |
else: # Last line | |
hist = self.shell.history_manager.get_tail(1) | |
hist = [x[2] for x in hist] | |
if not hist: | |
print("No lines in history match specification") | |
return | |
histlines = "\n".join(hist) | |
print("=== Executing: ===") | |
print(histlines) | |
print("=== Output: ===") | |
self.shell.run_cell("\n".join(hist), store_history=False) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment