I am using tab completion in a standard Debian install with Bash and I have some files being ignored. For example, if I have the files:
index.php
index.php.a
If I type vim i then tab it immediately selects "index.php " (see space after file name). Normally, it would just complete up to "index.php" and give me the option to type something else after.
Why is it behaving differently in this situation?
Update
Some commands such as "cp" seem to handle the tab completion just fine, so maybe it is vim looking for specific file extensions?
The bash-completion package uses the function _filedir_xspec to complete vim. That function in general completes filenames, but excludes certain patterns depending on which command it is completing.
For vim, the exclusion pattern starts like this:
_install_xspec '*.#([ao]|so|so.!(conf|*/*) ...
I.e., among other things, files ending in .a should be ignored. The thinking behind that is probably that these are often created as backup copies and you probably don't want to edit them.
If you want to override this behaviour, you can add your own completions into ~/.bash_completion; for example, to get vim to complete on all filenames, use this:
complete -f vim
which will make vim tab completion default to the built-in file completion bevahiour.
Related
I am adding commands into my bash profile and am trying to make my code simpler and want to delete the extraneous duplicated code. I have export statements and I have the commands running correctly but I am trying to simplify my code. I am using the same exact code for my commands and want to make it into one file. I am running the commands on a Mac terminal. I have installed npm, atom, atom shell commands and am on Mac OS version 10.14.5.
I tried changing the code structure around but I cannot figure out how to simplify and reuse the commands and make them into a function. The commands are duplicates of each other except that they are pointing to different file paths. I do not want to keep on reusing the same code and I am hoping to make it simpler but not sure how.
export snippet_project="/Users/kevinpleong/Desktop/my-programming-projects/snippet-creator-electronjs"
export programmingprojects="/Users/kevinpleong/Desktop/my-programming-projects"
export personal_website="/Users/kevinpleong/Desktop/my-programming-projects/personal-webiste"
edit-snippet-creator() {
cd /Users/kevinpleong/Desktop/my-programming-projects/snippet-creator-electronjs
atom .
}
edit-personal-website(){
cd /Users/kevinpleong/Desktop/my-programming-projects/personal-website/
atom .
}
edit-programming-projects(){
cd /Users/kevinpleong/Desktop/my-programming-projects/
atom .
}
I am hoping that it outputs the same thing as the bottom 3 blocks of code but I can simplify the code.
The code can be simplified to this:
projects_directory="${HOME}/Desktop/my-programming-projects"
edit-snippet-creator() {
atom "${projects_directory}/snippet-creator-electronjs"
}
edit-personal-website(){
atom "${projects_directory}/personal-website"
}
edit-programming-projects(){
atom "$projects_directory"
}
The exports are redundant
The variables are redundant since they would only each be used once. Only the projects directory is reused.
Trailing slashes are unnecessary.
Use More Quotes™.
That said, as you get used to the shell I expect you'll want to move away from patterns like this, because they are a premature abstraction and they hinder you from learning all the powerful built-in features of the shell, such as Tab completion. For example, if you've already edited a project you can press Ctrl-r to search the command history for the name of that project. Also, I expect atom, like every sane shell command, can take a directory different from the current one as the target, so you can simply type atom ~/Desktop/my, press Tab to complete atom ~/Desktop/my-programming-projects/, and press Tab again to see which projects are available.
I have a project with a deeply nested folder structure. Most of the time I know the name of the file I want to work with, but the folder path is too long/complicated to type when I want to edit it, like:
vim folder/is/deep/down/there/myfile.js
Is there a way to make the shell auto populate the path for me if the filename is unique, with something like:
vim *myfile.js
press TAB -->
vim folder/is/deep/down/there/myfile.js
I mostly use bash, but I'm fine with zsh if it can solve the problem.
I think this is what you're looking for, vim will open all instances of myfile.js in the directory. Fish shell will allow me to tab through the different matching files but I'm not sure it that works with bash.
vim **/myfile.js
What could be a good idea would be to use locate utility in a bash script.
Calling your bash script passing filename as argument would be a smart move, and then using the previously named utility to find it.
Having done that you could simply find if there was 1 or more matches, and if there's just a match you can just use vim [match].
And obviously, the script could be called like ./openinvim.sh myfile.js
Whenever I want to start editing my LaTeX sources by launching, e.g., the command vim pdeOptAff.tex, I find that bash the (tab)-autocompletion is still tedious because the folder typically contains a bunch of files with the same name but different endings:
$ ls
pdaeOptAff.aux pdaeOptAff.out pdaeOptAff.tex.latexmain
pdaeOptAff.bbl pdaeOptAff.pdf pdaeOptAff.toc
pdaeOptAff.blg pdaeOptAff.synctex.gz
pdaeOptAff.log pdaeOptAff.tex
Since I always want to open the the ~.tex file, I would love to have a filter that makes autocomplete expand only the ~.tex files.
In addition, I have an alias defined: alias g='gvim --remote-silent'. So this filter, in particular, should work for the alias.
Try:
complete -f -X '!*.tex' g
Then, you can type:
g <TAB>
And get the completions. Note: this doesn't complete directories. Someone else may have a better solution using compgen.
There's a helpful autocomplete guide on The Linux Documentation Project too.
I am working on a script called to that bookmarks file system locations in bash (with limited support for zsh). You can find the source here: https://github.com/resultsreturned/to
The script supports tab completion for all operations.
Say you have "bookmarked" the location of a folder:
mara#andromeda:~/bin/android-sdk-linux$ to -b android
The script then allows you to access subfolders of the bookmark, like so:
mara#andromeda:~$ to android/docs/
mara#andromeda:~/bin/android-sdk-linux/docs$
Pressing tab twice will give suggestions:
mara#andromeda:~$ to android/s<TAB><TAB>
android/samples/ android/sd-card/ android/sources/ android/system-images/
However, I would rather that the suggestions print only the portion of the path that is not currently input into the buffer. For example, the cd command:
mara#andromeda:~/bin$ cd android-sdk-linux/s<TAB><TAB>
samples/ sd-card/ sources/ system-images/
Note how the suggestions only contain the directory level that is currently being input.
So the question is, how do you control the way bash prints suggestions? Is it possible to do this independently of the completion wordlist (for compgen/complete)? Is there some way to define a regex that would process the completion wordlist for printing as suggestions?
Since feature requests to mark a comment as an answer remain declined, I copy the above solution here.
So the solution turns out to be using -o filenames when invoking complete. Showing only the substrings of COMPREPLY bash completion options to the user – resultsreturned
I would like to make tab completion in bash a bit more intelligent.
Let's say I have a folder with a src file .lisp, and a compiled version of that file .fasl. I would like to type vi filename [tab tab], and the .lisp autocompletes as the only option. That is, it's not likely that I want vim to open a compiled binary, so don't have it in the list of autocomplete options to cycle through.
Is there a way that I can keep a flat list of extensions that autocomplete ignores, or somehow customize it for vim, so that autocomplete ignores only particular file extensions when a bash command starts with vi ...
Any ideas are appreciated.
Thanks!
From man bash:
FIGNORE
A colon-separated list of suffixes to ignore when performing
filename completion. A filename whose suffix matches one of the entries in FIGNORE is excluded from the
list of matched filenames. A sample value is ".o:~" (Quoting is
needed when assigning a value to this variable, which contains
tildes).
So, for your example this can be set in your .bashrc file with
FIGNORE=".o:~:.fasl"
or, if you want to keep any other site-wide settings:
FIGNORE=".o:~:.fasl:$FIGNORE"
The bash complete command seems to be what you want.
Here is a Linux Journal link to 'complete' command video. and here is the follow-up page More on Using the Bash Complete Command
The links explain it quite well, and here is a related SO Question/Answer: Bash autocompletion across a symbolic link