Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I found a short script to enable note-taking on onethingwell, which includes this:

function n { nano ~/n/$1.txt }

I'd like to extend it to do tab completion, so that if I want to edit the pre-existing note 'foobar' (~/n/foobar.txt) I can type foo[TAB] and have it automatically complete to foobar, rather than having to type in 'foobar' every time. The problem is that bash's built-in tab completion seems to be centered around the current directory, so if I'm in a folder that isn't ~/n, then my tab completion fails -- or, worse, completes to the wrong thing, since perhaps I have a file named 'footastic' in ~/snafu/ (meaning I type $ n foo[TAB], and instead of seeing $ n foobar, I look at my input and see: $ n footastic.

So, after all that preamble, here's the question: if it's possible, how can I tell bash that after I type 'n', for just this once I want it to assume that we're completing using the files in ~/n for completion, rather than using the files in the current directory?

If you understood all that e-mumbling, congratulations, and if you can answer that, thank you very much!

share|improve this question
add comment

2 Answers

up vote 4 down vote accepted

This might get you there...

  1. Enable custom tab completion in your .bashrc

    shopt -s progcomp

  2. Create a compgen function and add it to .bashrc after your notes functions.

    _notes() {
    local cur
        cur=${COMP_WORDS[COMP_CWORD]}
        COMPREPLY=( $(compgen -f $HOME/n/$cur | cut -d"/" -f5 ) )
        }
       complete -o filenames -F _notes n

This works for me - at the basic level. I still haven't solved it for nested directories...

References:

  1. most of it from here: http://sixohthree.com/867/bash-completion

  2. Completion builtin details here: http://www.gnu.org/software/bash/manual/html_node/Programmable-Completion-Builtins.html

share|improve this answer
add comment

To follow up on jasonwryan's answer, I use cut to trim the start of the known path target:

_c ()
{
    local cur
    COMPREPLY=()
    cur=${COMP_WORDS[COMP_CWORD]}
    case "$cur" in
        *)
            COMPREPLY=( $(compgen -f /src/$cur | cut -c 6-) )
            ;;
    esac

    return 0
} &&
complete -o filenames -F _c c

This allows me to operate directly on any directory, subdirectory, or filename under /src/

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.