You are not logged in.
That should work in version 14 (in the post I called it ./ regression)
I'm now trying to clean the source code. Maybe we can put it on AUR then. Or do you have any more feature suggestions? I have never actually used other completions like bash-completions. But I got the idea for how to do 'recommendations' after seeing its source code.
I also found a way to remove the blink, and that is by immediately writing bash's $PS1 variable. This can be done in the calling bash function too. Unless there's a bash built-in or something this could be quite tricky to interpret: see what I mean
Offline
Isn't 100% clear to me, i tried version 14 and i've had that error; is the ./ regression supposed to be fixed or expected in v.14?
Help me to improve ssh-rdp !
Retroarch User? Try my koko-aio shader !
Offline
You're right, I fixed it now, not sure what happened earlier.
version 15: outdated
This one also fixes path escaping e.g. "cat $downloads/file.<TAB>" turned into "cat \$downloads/file.txt" instead of "cat $downloads/file.txt"
Last edited by Procyon (2010-07-30 10:07:39)
Offline
I appologise in advance for the newb question but could you tell me what i need to do to get this working, (what files to source/unsource, what to add to where etc.) i cant seem to get this working at all.
Thanks in advance
() Registered Linux user #500376
/\ www.asciiribbon.org - against html e-mail
Offline
Save the file, chmod +x file, and move it to a directory in $PATH
I recommend
mkdir ~/bin
And adding this to .bashrc:
export PATH=~/bin:$PATH
Or else as root move it to /usr/bin
Because bind -x only listens to variable changes in bash scripts and not changing the environment in Python for instance, you need an intermediary function:
The code blocks above will do, here is error message from v14:
$ kingbash.py
Usage:
function kingbash.fn() { echo -n "KingBash> $READLINE_LINE"; OUTPUT=`kingbash.py`; READLINE_POINT=`echo "$OUTPUT" | tail -n 1`; READLINE_LINE=`echo "$OUTPUT" | head -n -1`; echo -ne "\r\e[2K"; }
bind -x '"\t":kingbash.fn'
You can add those two lines to your .bashrc
About the function:
The first echo is a place holder, because the line is cleared by readline automatically (see blink above). The closer it resembles your PS1 the better, but I'm not sure if it's a good idea to code a PS1 interpreter in.
The last echo clears the line.
READLINE_POINT is expected as the last output line from kingbash.py (or whatever you called the script) and READLINE_LINE the first.
Offline
Thanks Procyon , got it working fine, still not sure what i was doing wrong probably something stupid.
Thanks for a great script. Saves a lot of typing!
+1 from me for putting it in the AUR btw.
() Registered Linux user #500376
/\ www.asciiribbon.org - against html e-mail
Offline
version 16: outdated
It will now try to complete a command after sudo, type, whatis and whereis.
Insert will now move the selector to the next item in the next run instance.
About new features, there are two situations that can be used:
1. User pressed <TAB> on empty line
2. User pressed <TAB> in the first word and it can't complete to a command but can to a file.
The first one sometimes happens when you paste text or accidentally hit <TAB>, so maybe just printing a tab is good. The stdin can be peeked to see if there is a large paste.
The second could complete the file. If . isn't in your PATH, then a directory + executable is a good idea to check for. If the first word has a / then this already happens (e.g. "./configu<TAB>" works) so just checking to see if it can complete to a directory would be enough.
Besides that I think it might be nice to have it go into a file manager mode, with a session file with things like where you were in each directory, and what program to use for what extension.
Good idea? Or going a bit too far for tab-completion?
Maybe having to press <TAB> before entering the file manager is annoying with a lot of usage, and it's better to use a real file manager after all though.
Last edited by Procyon (2010-08-01 11:49:08)
Offline
Hi Procyon, I can't get Ver.16 to work, i've left things set up as with V15 and just replaced it with the new script but everytime i try it i get
KingBash> bash: /usr/bin/KingBash: /usr/bin/python^M: bad interpreter: No such file or directory
I've tried different shabangs (#!/usr/bin/env python & #! /usr/bin/python)but no luck.
() Registered Linux user #500376
/\ www.asciiribbon.org - against html e-mail
Offline
The ^M means that the file was saved with DOS's "\r\n" newline style.
Try to convert it with sed -i 's/\r$//' /usr/bin/KingBash
Offline
Thanks again Procyon, dont know how it got saved like that.
Besides that I think it might be nice to have it go into a file manager mode, with a session file with things like where you were in each directory, and what program to use for what extension.
Good idea? Or going a bit too far for tab-completion?
I think it might be going a bit overboard, this is good the way it is. One thing i would like to add though is for it to show your aliass' the way 'normal' bash completion does. Is there a way to do that?
() Registered Linux user #500376
/\ www.asciiribbon.org - against html e-mail
Offline
version 17: outdated
This version has a small hack for trying to complete a special character that needs a backslash, e.g. [ or (, so that when the last character before <TAB> is a backslash, it tries to complete on those special characters. It gets complicated when you have a file list like: "[group]_video.mkv", "(C78)_comic.zip", "file.txt". When you then type backslash, it won't be shown on the prompt, but "file.txt" will be removed from the file list. Of course like the previous versions, you can just type [ or ( even like this: "mplayer [<TAB>" (which by the way does not work with bash's completion)
I also added the aliases and functions. If someone knows how to get a list of all builtins I will add that too.
You need to change the calling function to give the list as a parameter. It works without too.
The example I added in the error message to get all functions and aliases should work on zsh too (does zsh even have bind -x though?)
Which is: declare -f | sed -n 's/ () {\?$//p'; alias | sed 's/alias //;s/=.*//'
The entire error/usage message is: (where kingbash.py is what you saved the file as)
function kingbash.fn() {
echo -n "KingBash> $READLINE_LINE" #Where "KingBash> " looks best if it resembles your PS1, at least in length.
OUTPUT=`kingbash.py "$(declare -f | sed -n 's/ () {\?$//p'; alias | sed 's/alias //;s/=.*//')"`
READLINE_POINT=`echo "$OUTPUT" | tail -n 1`
READLINE_LINE=`echo "$OUTPUT" | head -n -1`
echo -ne "\r\e[2K"; }
bind -x '"\t":kingbash.fn'
EDIT:
@sausageandeggs: I think you're right about it being too much. I have trouble imagining how to implement my regular file manager usage with this.
And because the user could use a different key, there shouldn't be a fail-safe I mentioned earlier like "the user pasted a lot of text, print a tab character instead of running the application"
Maybe just something like:
$ file.<TAB>
$ [] file.txt
Last edited by Procyon (2010-08-05 11:31:57)
Offline
I don't know how to get a list of the builtins locally on demand, but this is what i've found so far. I don't know how complete it is though, or if its of any use to you!
alias, bg, bind, break, builtin, cd, command, compgen, complete, continue, declare,
dirs, disown, echo,enable, eval, exec, exit, export, fc, fg, getopts, hash, help, history,
jobs, kill, let, local, logout, popd,printf, pushd, pwd, read, readonly, return, set, shift,
shopt, source, suspend, test, times, trap, type,typeset, ulimit, umask, unalias, unset, wait
() Registered Linux user #500376
/\ www.asciiribbon.org - against html e-mail
Offline
That's a bit clunky, it will work though. I found out that `help` lists builtins (in bash, not in zsh). It's very hard to get a clean list, after trying some things I came up with (the not much better):
help -s a b c d e f g h i j k l m n o p q r s t u v w x y z | sed 's/[ :].*//'
So you get the following calling function:
function kingbash.fn() {
echo -n "KingBash> $READLINE_LINE" #Where "KingBash> " looks best if it resembles your PS1, at least in length.
OUTPUT=`kingbash.py "$(declare -f | sed -n 's/ () {\?$//p'; alias | sed 's/alias //;s/=.*//'; help -s a b c d e f g h i j k l m n o p q r s t u v w x y z | sed 's/[ :].*//')"`
READLINE_POINT=`echo "$OUTPUT" | tail -n 1`
READLINE_LINE=`echo "$OUTPUT" | head -n -1`
echo -ne "\r\e[2K"; }
bind -x '"\t":kingbash.fn'
Offline
Instead of "help -s a b c d e f g h i j k l m n o p q r s t u v w x y z | sed 's/[ :].*//' "
"compgen -A builtin" does it less chunkily, you just need a bit of sed magic to get rid of "." ".." "[" from the top of the list
"compgen -A builtin | grep [a-z]" works (slows things down tough) Trying get it into the function now.
Last edited by sausageandeggs (2010-08-01 17:23:37)
() Registered Linux user #500376
/\ www.asciiribbon.org - against html e-mail
Offline
Nice job! It seems to work with multiple -A parameters too. So:
OUTPUT=$(kingbash.py "$(compgen -A builtin -A function -A alias | grep [a-z])")
Offline
Yup, infact i've since found out that compgen -A builtin can be written as compgen -b and compgen -c will generate all your commands, aliases and functions in one go. and i've left the grep out of it all together as i dont really see the need for it [ . and .. are cmds after all! So i've just
`OUTPUT=`KingBash "$(compgen -c)"`
Last edited by sausageandeggs (2010-08-01 18:11:17)
() Registered Linux user #500376
/\ www.asciiribbon.org - against html e-mail
Offline
After testing, I actually don't recommend using compgen -c, because it stats all files inside your $PATH, unlike the python code.
You can see the difference like this:
strace bash -c 'compgen -c &>/dev/null' 2>&1 | less
And a non-stat'ing ls:
strace bash -c '/bin/ls $(echo $PATH | tr : \ ) &>/dev/null' 2>&1 | less
Offline
cool. I didn't know about the readline bind trick and the READLINE_* variables. for me it's only useful if it doesn't spawn a new X window though
< Daenyth> and he works prolifically
4 8 15 16 23 42
Offline
Hmm... I see what you mean, -c does go all round the houses doesn't it, Still compgen -ab -A function does the job well enough.
() Registered Linux user #500376
/\ www.asciiribbon.org - against html e-mail
Offline
Version 18: http://aur.pastebin.com/wrcePEhp
You can now press F2 and it will work like Enter, but also remove the command and put the cursor there. Kind of like mc/pcfm's F2 for entering a custom command.
I uploaded it to AUR as kingbash: http://aur.archlinux.org/packages.php?ID=39429
Offline
cool stuff. Almost the "dmenu for a shell" I've been looking for
Would be great if the following:
cd<tab>ecl work
would propose:
cd workspaces/eclipse/
(Check if any of the files/dirs in the current dir match any of the strings, then descend as you keep finding matches)
< Daenyth> and he works prolifically
4 8 15 16 23 42
Offline
@Dieter@be: that's a bit too weird. When would you form a command in such a way? It's also incompatible with commands that don't take just filenames, making it limited in usage to what commands it is hacked in for. Maybe you should consider adding something like e=~/workspaces/eclipse/; alias e="cd $e" to .bashrc
About dmenu, right now the first argument is added to a listing of everything in $PATH. For a custom list you could try:
export READLINE_LINE="*"
export READLINE_POINT=1
command=$(KingBash "a b c" | head -n 1)
Since the command list is pretty static, it's possible to move the listing of everything in PATH to the calling function (with /bin/ls), and make it split on newline only so you can give it arguments that contain spaces.
Some dmenu features would need extra code, like space.
Offline
@Dieter@be: that's a bit too weird. When would you form a command in such a way? It's also incompatible with commands that don't take just filenames, making it limited in usage to what commands it is hacked in for. Maybe you should consider adding something like e=~/workspaces/eclipse/; alias e="cd $e" to .bashrc
About dmenu, right now the first argument is added to a listing of everything in $PATH. For a custom list you could try:
export READLINE_LINE="*"
export READLINE_POINT=1
command=$(KingBash "a b c" | head -n 1)Since the command list is pretty static, it's possible to move the listing of everything in PATH to the calling function (with /bin/ls), and make it split on newline only so you can give it arguments that contain spaces.
Some dmenu features would need extra code, like space.
I think I would mostly use this completion style when searching in my history. When I want to find a command and i only know some specific parts that occur "all over" that command.
Or to put it differently: ^R's matching style is not advanced enough for me
< Daenyth> and he works prolifically
4 8 15 16 23 42
Offline
I guess a history mode in kingbash might also function like dmenu.
Something along the lines of
function kingbash_history.fn() {
"prompt stuff"
history -a
/usr/bin/KingBash -r ~/.bash_history
"setting readline vars"; }
bind -x '"\r": kingbash_history.fn'
Where a dmenu implementation would use READLINE_LINE='*'; READLINE_POINT=1; KingBash -r ~/.dmenu_list
And a special history mode would only have to split the "readline" line up and look them up in the file, and add some special bindings like starting a new item to look for with Space and moving the cursor with Left/Right.
Offline
version 19: outdated
I added the dmenu-like things. It works with KingBash -r filename.txt. My bash_history is 4MB and it's not bad speed-wise.
function kingbash.hs() {
history -a
echo -n "KingBash> $READLINE_LINE"
OUTPUT=`KingBash -r <(tac ~/.bash_history)`
READLINE_POINT=`echo "$OUTPUT" | tail -n 1`
READLINE_LINE=`echo "$OUTPUT" | head -n -1`
echo -ne "\r\e[2K"; }
bind -x '"%": kingbash.hs'
Where % is a ^R (C-v, C-r). If you know how to do that using only ascii please let me know.
To replace GUI dmenu:
#! /bin/bash
rm /tmp/menu
cat > /tmp/inmenu
urxvtc -e bash -c 'export READLINE_POINT=0; answ=$(KingBash -r /tmp/inmenu | head -n 1); echo -n "$answ" > /tmp/menu'
while sleep 0.1; do [ -f /tmp/menu ] && break; done
cat /tmp/menu
rm /tmp/menu
rm /tmp/inmenu
Tricky...
File mode specific keys:
Insert replaces the entire line with the currently selected item
Tab does nothing
Backspace / Left / Right: delete/move around the line
Delete: I'll add it in the next version (along with help text)
Alt+ Backspace: remove word
Escape: clear the line and quit (as dmenu) ^C should also work like this, but right now it will return the current line.
Alt+U: clear line
Other movement keys are the same of course.
Last edited by Procyon (2010-08-06 18:44:40)
Offline