ultracrepidarian
ultracrepidarian

Reputation: 1118

get bash history to vi

When I try to read bash history into vim, I get nothing.

:r !history

If I just execute the command, i.e.

:!history

instead of history I get a snapshot of my terminal as it looked before I started vim.

How can I read the output of "history" into vim? Reading the contents of .bash_history won't do as I save history with timestamps:

HISTTIMEFORMAT='%Y.%m.%d %R  '

Upvotes: 23

Views: 9029

Answers (5)

Ildar Shaymurat
Ildar Shaymurat

Reputation: 41

You may pre-write the history of current session:
history -w
Then in editor you can get last, say, 20 commands of history:
:r ! tail -20 ~/.bash_history

Upvotes: 4

theosp
theosp

Reputation: 7549

:r!echo "history" | bash -i 2>/dev/null | sed -e 's/\x1b\[.//g'

Explanation:

The history command only works on interactive shell.

The first part:

echo "history" | bash -i 2>/dev/null

Forces interactive shell (and removes lines which aren't output of history).

The second part:

sed -e 's/\x1b\[.//g'

Removes escape character the shell might output (happened on my system).

Upvotes: 13

Dennis Williamson
Dennis Williamson

Reputation: 359905

Try:

r !set -o history; HISTFILE=~/.bash_history; history -r; history 10

This will include the timestamps and will not include history that hasn't been saved to the history file.

Upvotes: 1

intuited
intuited

Reputation: 24034

The problem is that that history is only known by the bash shell that started vim. When you do :!history from within vim, you're starting a new bash shell that has its own history, which is empty, which is why you just see the screen as it looked when you started vim: it's outputting all the lines in its history, which is a grand total of zero. This actually is an oversimplification, but anyway you can't get a history of the commands that you typed just before starting vim this way.

If you want to get those lines of history without exiting vim, you can suspend vim by pressing CTRL-Z and then write the history to a file using history >history.tmp. Then type fg 1 to resume vim: this will tell bash to transfer focus back to its "job number 1", which will normally be vim. The job number is displayed after you hit CTRL-Z:

[1]+  Stopped                 vim

so if there's a number other than 1 in the brackets, then you should do fg for that number instead. Then (hopefully you know this) when you're back in vim just :tabedit history.tmp, for example, to open the saved history in a new tab.

You'll have timestamps in this output too, but since you're in vim you can easily filter them out with a :substitute command. Alternatively you can cut them out using HISTTIMESTAMP='' history rather than just history when writing to the file; this will still output the index of each entry. I guess you can filter that out on its way into the file too, by piping it through sed or cut or one of their crew. But it's really easy to do this from within vim (assuming you know the basics of regular expressions; if not, start with :help :substitute or maybe look for a regex tutorial).

Note that if you read in the lines from ~/.bash_history, you're only getting the history from bash shells which have completed, ie you typed exit and the terminal window closed. So any commands you typed just before starting vim won't be there. You can change the way this works but then you end up with commands from different sessions all jumbled up together in the history.

Upvotes: 20

Rob Heiser
Rob Heiser

Reputation: 2862

From a shell prompt:

history | vim -

Upvotes: 29

Related Questions