10000 WIP: Implement 'ipython history show [opts]' by ernstki · Pull Request #13568 · ipython/ipython · GitHub
[go: up one dir, main page]

Skip to content

WIP: Implement 'ipython history show [opts]' #13568

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 131 additions & 5 deletions IPython/core/historyapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,15 @@

from traitlets.config.application import Application
from .application import BaseIPythonApplication
from traitlets import Bool, Int, Dict
from traitlets import Bool, Int, Dict, Unicode, CaselessStrEnum
from ..utils.io import ask_yes_no

show_hist_help = """Show recent entries from the IPython history database.

Limited to the last 1000 unless `--limit=N` is supplied; `--limit=0` or `-1`
prints all entries in the database.
"""

Comment on lines +16 to +21
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can inline this directly if you wish, you don't have to rely on a seperate variable. Up to you.

trim_hist_help = """Trim the IPython history database to the last 1000 entries.

This actually copies the last 1000 entries to a new database, and then replaces
Expand All @@ -30,6 +36,123 @@
"""


class HistoryShow(BaseIPythonApplication):
description = show_hist_help
limit = Int(1000, help="Number of recent history entries to show.").tag(config=True)

delimiter = Unicode(
"\t", help="Delimiter for separating the columns of history output."
).tag(config=True)

header = Bool(False, help="Include a header row in the output.").tag(config=True)

pretty = Bool(
False, help="Pretty-print the output using IPython.utils.PyColorize."
).tag(config=True)

colors = CaselessStrEnum(
("Neutral", "NoColor", "LightBG", "Linux"),
default_value="Neutral",
help="Set the color scheme (NoColor, Neutral, Linux, or LightBG).",
).tag(config=True)
Comment on lines +53 to +57
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This have changed in 9.0, now we have themes, that are arbitrary strings, the Neutral, CoColor, LightBG, and Linux still exists but are lower case.


color = CaselessStrEnum(
("Never", "Always", "Auto"),
default_value="Auto",
help="Choose when to display color; requires `--pretty`.",
).tag(config=True)

flags = Dict(
{
"L": (
{"HistoryShow": {"limit": -1}},
"No limit; show all history entries.",
),
"pretty": ({"HistoryShow": {"pretty": True}}, pretty.help),
"P": ({"HistoryShow": {"pretty": True}}, "An alias for `--pretty`."),
"header": ({"HistoryShow": {"header": True}}, header.help),
"headers": ({"HistoryShow": {"header": True}}, "An alias for `--header`."),
"H": ({"HistoryShow": {"header": True}}, "An alias for `--header`."),
"color-always": (
{"HistoryShow": {"color": "Always"}},
"Always output in color (e.g., when piping into `less -R`).",
),
"C": (
{"HistoryShow": {"color": "Always"}},
"An alias for `--color-always`.",
),
"color-never": (
{"HistoryShow": {"color": "Never"}},
"Never show color, even if the output is a terminal.",
),
}
)

aliases = Dict(
dict(
l="HistoryShow.limit",
limit="HistoryShow.limit",
d="HistoryShow.delimiter",
delimiter="HistoryShow.delimiter",
header="HistoryShow.header",
pretty="HistoryShow.pretty",
colors="HistoryShow.colors",
color="HistoryShow.color",
)
)

def start(self):
profile_dir = Path(self.profile_dir.location)
hist_file = profile_dir / "history.sqlite"
con = sqlite3.connect(hist_file)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It hink we can do a with sqlite3.connect(hist_file) as con here.


if not self.limit:
self.limit = -1

# Grab the recent history from the current database.
entries = list(
con.execute(
"""SELECT session, line, source, source_raw FROM
history ORDER BY session DESC, line DESC LIMIT ?""",
(self.limit,),
)
)

# Emulate shell `history` command; newest at bottom
entries.reverse()

if self.pretty:
import sys
from IPython.utils import PyColorize
Comment on lines +125 to +126
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can import those unconditionally at top of file.


pyformat = PyColorize.Parser(style=self.colors, parent=self).format

for entry in entries:
header = f">>> # session {entry[0]}, line {entry[1]}\n"
entry = header + str(entry[3])

if (
sys.stdout.isatty() or self.color == "Always"
) and self.color != "Never":
print(pyformat(entry, out="str"))
else:
# could set self.colors='NoColor' and just use pyformat
# here, too, but this is probably marginally faster
print(entry, "\n")

else:
if self.header:
print(self.delimiter.join(["session", "line", "source", "source_raw"]))
for entry in entries:
# FIXME: even if you specify `-d,` this is not very
# CSV-friendly, since the outer quote character (single or
# double) depends on whether the history entry itself has
# embedded strings
print(self.delimiter.join([repr(x) for x in entry]))
Comment on lines +147 to +151
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that's fine as is for now.


con.close()


class HistoryTrim(BaseIPythonApplication):
description = trim_hist_help

Expand Down Expand Up @@ -144,10 +267,13 @@ class HistoryApp(Application):
name = u'ipython-history'
description = "Manage the IPython history database."

subcommands = Dict(dict(
trim = (HistoryTrim, HistoryTrim.description.splitlines()[0]),
clear = (HistoryClear, HistoryClear.description.splitlines()[0]),
))
subcommands = Dict(
dict(
show=(HistoryShow, HistoryShow.description.splitlines()[0]),
trim=(HistoryTrim, HistoryTrim.description.splitlines()[0]),
clear=(HistoryClear, HistoryClear.description.splitlines()[0]),
)
)

def start(self):
if self.subapp is None:
Expand Down
0