Skip to content
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

In bash, PREV=$(fc -lrn | head -n 1) doesn't retrieve the previous command #72

Open
marcelpaulo opened this issue Feb 10, 2018 · 5 comments

Comments

@marcelpaulo
Copy link

README.md suggests this function to add the last command to pet:

function prev() {
  PREV=$(fc -lrn | head -n 1)
  sh -c "pet new `printf %q "$PREV"`"
}

However, in bash PREV=$(fc -lrn | head -n 1) results in storing PREV=$(fc -lrn | head -n 1) in PREV:

paulo@monk:~$ ls
bash_completion.d  bin  bk  data  default  Desktop  doc  Downloads  foto  gdrive  go  log  Mail  man  PDF  playlist  RCS  src  stage  tmp  watch  xubuntu 17.10.txt
paulo@monk:~$ PREV=$(fc -lrn | head -n 1)
paulo@monk:~$ echo "$PREV"
	 PREV=$(fc -lrn | head -n 1)
paulo@monk:~$ 

To work correctly in bash, that line should be:

PREV=$(fc -ln -1)

as you can see now:

paulo@monk:~$ ls
bash_completion.d  bin  bk  data  default  Desktop  doc  Downloads  foto  gdrive  go  log  Mail  man  PDF  playlist  RCS  src  stage  tmp  watch  xubuntu 17.10.txt
paulo@monk:~$ PREV=$(fc -ln -1)
paulo@monk:~$ echo "$PREV"
	 ls
paulo@monk:~$ 

I'm struggling to get rid of the leading tab, piping the output to sed results in changing the history. If I find out a neat way of doing it, I will document it here.

@marcelpaulo
Copy link
Author

Found out ! If there's a pipeline, bash seems to add the current command to the history BEFORE running fc, so, to retrieve the last command and get rid of the leading tab, this would do it:

PREV=$(fc -ln -2 -2 | sed 's/[ \t]*//')

To show it in action:

paulo@monk:~$ ls
bash_completion.d  bin  bk  data  default  Desktop  doc  Downloads  foto  gdrive  go  log  Mail  man  PDF  playlist  RCS  src  stage  tmp  watch  xubuntu 17.10.txt
paulo@monk:~$ PREV=$(fc -ln -2 -2 | sed 's/[ \t]*//')
paulo@monk:~$ echo $PREV
ls
paulo@monk:~$ 

@marcelpaulo
Copy link
Author

marcelpaulo commented Feb 10, 2018

As a suggestion, I'd replace function prev() with an alias:

alias prev='cmd=$(fc -ln -2 -2 | sed "s/^[ \\t]*//"); eval pet new $(printf %q "$cmd")'

@marcelpaulo
Copy link
Author

This is still not good. When I use tab completion to complete a command, and the add it to pet with prev, with the alias that I suggested, the command comes with a trailing ****:

paulo@monk:~$ ls --all 
.                  .bash_functions  .cddb      .face      go                  .inputrc       man              .pki             .sudo_as_admin_successful  watch
..                 .bash_history    .config    foto       .goobook_auth.json  .kde           .mozilla         playlist         .thumbnails                .Xauthority
.aptitude          .bash_logout     data       .gconf     .goobook_cache      .launchpadlib  .mplayer         .profile         tmp                        .XCompose
.audacity-data     .bashrc          default    gdrive     .goobookrc          .lesshst       .msmtprc         RCS              .vim                       .Xdefaults
.bash_aliases      bin              Desktop    .ghc       .gphoto             .local         .notmuch-config  .sane            .viminfo                   .xscreensaver
.bash_aliases.swp  bk               .dmrc      .gimp-2.8  .gtkrc-2.0          log            .pacplrc         src              .viminfo.tmp               .xsession-errors
.bash_completion   .cabal           doc        .gnome     .gvimrc             Mail           .parallel        stage            .vimrc                     .xsession-errors.old
bash_completion.d  .cache           Downloads  .gnupg     .ICEauthority       .mailcap       PDF              .stremio-server  .w3m                       xubuntu 17.10.txt
paulo@monk:~$ prev
Command>  ls --all\
Description>  

I type ls -al, then TAB to autocomplete, typed another l, TAB again to continue autocompleting.

There's still some tweaking to do with this alias ...

@marcelpaulo
Copy link
Author

This will solve the problem:

alias prev='cmd=$(fc -ln -2 -2 | sed -E "s/^[ \\t]*//; s/[ ]*\$//"); eval pet new $(printf %q "$cmd")'

@marcelpaulo
Copy link
Author

Just discovered now that the problem with the trailing ** has nothing to do with autocompletion: if there are trailing spaces, they'll with be escaped by printf %q, so they have to be removed before, as I did in the last version of the alias.

djtal added a commit to djtal/dotfiles that referenced this issue Mar 8, 2018
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

No branches or pull requests

1 participant