8000 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

Conversation

ernstki
Copy link
@ernstki ernstki commented Mar 3, 2022

Use case: I want to quickly copy-paste some statements from the history of a recent IPython session into another source file.

Previously, I may have had some hacky shell function that involved running sqlite3, but I'd always have to hunt for where the SQLite database was, and that was irritating. What I was looking for was something comparable to history in the Unix shell; easy to pipe into grep, pbcopy or xclip, et cetera.

This PR includes:

  • a -l / --limit option which defaults to the last 1000 entries from the SQLite history database
  • a -P / --pretty option which pretty-prints the output with IPython.util.PyColorize
  • flags to specify a custom delimiter (defaults to tab) and add a header row (corresponding to the SQLite column names)
  • flags which control --pretty's colorized output, defaulting to color only when standard output is a terminal

Things I would appreciate feedback on

  • show? display? print? tail? aliases for all four?
  • how to handle querying the history from a non-default profile
  • how to warn on conflicting/nonsensical options, e.g., --color=always when --pretty wasn't given
    • pretty sure it's not just logging.warning
  • how to read the profile config to get the same color scheme setting that the user might have specified there
  • if -p is OK as an alias for --pretty, or if that's likely to conflict with some other option
  • how to run the existing tests for historyapp.py
    • when I run pytest in the top-level repository directory, I just get
      ImportError: Error importing plugin "IPython.testing.plugin.pytest_ipdoctest": No module named 'IPython.testing.plugin.pytest_ipdoctest'
      
  • whether Bash/Zsh completion for IPython is a thing, and where to add support for this subcommand if so
    • I do see examples/IPython Kernel/ipython-completion.bash, but that can't be the "real" completion script if it's in examples, can it?

To-do

  • tests
  • warn on conflicting/nonsensical options
  • add documentation of new feature(s) to the pr directory

ernstki added 2 commits March 3, 2022 15:58
Includes:

* a `-l` / `--limit` option which defaults to the last 1000 entries from
  the SQLite history database

* a `-P` / `--pretty` option which pretty-prints the output with
  IPython.util.PyColorize

* flags to specify a custom delimiter (defaults to tab) and add a header
  row (corresponding to the SQLite column names)

* flags which control `--pretty`'s colorized output, defaulting to color
  only when stdout is a terminal
@Carreau
Copy link
Member
Carreau commented Feb 23, 2025

Closing old stale PRs, sorry if this was not addressed, but this has been a few years, so there are few chances of someone actually pushing this through.

Feel free to resubmit if you feel this has a chance to be revived.

@Carreau Carreau closed this Feb 23, 2025
@ernstki
Copy link
Author
ernstki commented Feb 27, 2025

Feel free to resubmit if you feel this has a chance to be revived.

@Carreau Do you think it has more of a chance of being merged if I am simply more confident with the changes and the PR writeup (i.e., don't ask any questions, or ask for feedback)?

I can see how that might be psychologically off-putting / burdensome to an already-spread-thin open source maintainer.

If it is a desirable feature, I will rebase the changes against some recent branch, no problem. Otherwise I can simply maintain it as a local patchset that I apply to each new IPython installation manually.

@Carreau Carreau reopened this Feb 27, 2025
@Carreau
Copy link
Member
Carreau commented Feb 27, 2025

I mostly need time to review. I can try.

one thing: I think you can use 'with conn' instead of manual closing .

Comment on lines +16 to +21
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.
"""

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.

Comment on lines +53 to +57
colors = CaselessStrEnum(
("Neutral", "NoColor", "LightBG", "Linux"),
default_value="Neutral",
help="Set the color scheme (NoColor, Neutral, Linux, or LightBG).",
).tag(config=True)
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.

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.

Comment on lines +125 to +126
import sys
from IPython.utils import PyColorize
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.

Comment on lines +147 to +151
# 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]))
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.

@ernstki
Copy link
Author
ernstki commented Mar 30, 2025

@Carreau thanks for the thoughtful feedback! This is on my radar, and I'll be sure to note what behavior has changed in recent releases before I update the PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants
0