zsh zstyle: autocomplete extensions and directories - autocomplete

How do I write a zstyle rule that matches specific file extensions and directories? For instance, I want the pylint tool to match only *.py files, but also all directories (in case I need to search for a nested file); the following doesn't seem to include them.
zstyle ":completion:*:*:pylint:*" file-patterns "*.py"

The *(-/) glob will match directories, so simply add it to "*.py", like so:
zstyle ":completion:*:*:pylint:*" file-patterns "*.py *(-/)"

Related

How do I diff only certain files?

I have a list of files (a subset of the files in a directory) and I want to generate a patch that includes only the differences in those files.
From the diff manual, it looks like I can exclude (-x), but would need to specify that for every file that I don't want to include, which seems cumbersome and difficult to script cleanly.
Is there a way to just give diff a list of files? I've already isolated the files with the changes into a separate directory, and I also have a file with the list of filenames, so I can present it to diff in whichever way works best.
What I've tried:
cd filestodiff/
for i in `*`; do diff /fileswithchanges/$i /fileswithoutchanges/$i >> mypatch.diff; done
However patch doesn't see this as valid input because there's no filename header included.
patchutils provides filterdiff that can do this:
diff -ur old/ new/ | filterdiff -I filelist > patchfile
It is packaged for several linux distributions

Associate extensionless files to Bash

My Bash scripts do not have any extensions nor shebang line. How can I avoid having to select the syntax highlighter when I open every file for this project?
The files.associations setting allows matching against arbitrary glob patterns, not just file extensions. For instance, for a Bash script named start, you could have the following in your workspace's settings.json:
"files.associations": {
"start": "shellscript"
}
You can also have a comma-separated list of file names between {}:
"files.associations": {
"{start,stop}": "shellscript"
}

rename command doesn't rename

This should work on my CentOS 6.6 but somehow the file name is not changed. What am I missing here?
rename -f 's/silly//' sillytest.zi
This should rename sillytest.zi to test.zi but the name is not changed. Of course I can use mv command but I want to apply to many files and patterns.
There are two different rename utilities commonly used on GNU/Linux systems.
util-linux version
On Red Hat-based systems (such as CentOS), rename is a compiled executable provided by the util-linux package. It’s a simple program with very simple usage (from the relevant man page):
rename from to file...
rename will rename the specified files by replacing the first occurrence of from in their name by to.
Newer versions also support a useful -v, --verbose option.
NB: If a file already exists whose name coincides with the new name of the file being renamed, then this rename command will silently (without warning) over-write the pre-existing file.
Example
Fix the extension of HTML files so that all .htm files have a four-letter .html suffix:
rename .htm .html *.htm
Example from question
To rename sillytest.zi to test.zi, replace silly with an empty string:
rename silly '' sillytest.zi
Perl version
On Debian-based systems ,rename is a Perl script which is much more capable
as you get the benefit of Perl’s rich set of regular expressions.
Its usage is (from its man page):
rename [ -v ] [ -n ] [ -f ] perlexpr [ files ]
rename renames the filenames supplied according to the rule specified as the first argument.
This rename command also includes a -v, --verbose option. Equally useful is its -n, --no-act which can be used as a dry-run to see which files would be renamed. Also, it won’t over-write pre-existing files unless the -f, --force option is used.
Example
Fix the extension of HTML files:
rename s/\.htm$/.html/ *.htm

Ignore all files and files in subdirectories except one file

Imagine the following structure:
/a/1.txt
/a/2.txt
/a/.keep
/a/b/1.txt
/a/b/2.txt
/a/b/3.txt
/a/b/.keep
/a/b/c/1.txt
/a/b/c/2.txt
/a/b/c/3.txt
/a/b/c/4.txt
/a/b/c/.keep
/d/test.txt
/d/work.txt
I want to ignore all files in a directory except .keep files to obtain the following results:
/a/.keep
/a/b/.keep
/a/b/c/.keep
/d/test.txt
/d/work.txt
My .gitignore file that doesn't work:
/a/*
!.keep
Unfortunatelly, you cannot reinclude files at directories ignored by previous rules, according to the gitignore Documentation:
It is not possible to re-include a file if a parent directory of that file is excluded. Git doesn’t list excluded directories for performance reasons, so any patterns on contained files have no effect, no matter where they are defined.
So this
/a/*
!/a/**/.keep
will only reinclude /a/.keep but not the others.
You'll have to exclude each file pattern under /a explictly.
/a/**/*.txt
/a/**/.ignore
/a/**/.alsoignore
UPDATE: Or a better solution is to create the following .gitgnore at your /a subdirectory:
*.*
!.keep
(the only drawback is that this solution will also keep files with no extension)
In your case, you should use:
/a/*
!**/.keep
From the gitignore documentation:
A leading "**" followed by a slash means match in all directories. For
example, "**/foo" matches file or directory "foo" anywhere, the same
as pattern "foo". "**/foo/bar" matches file or directory "bar"
anywhere that is directly under directory "foo".

How can I ignore everything under a folder in Mercurial

I am looking for an expression for the .hgignore file, to ignore all files beneath a specified folder.
eg: I would like to ignore all files and folders beneath bin
Actually any advice on how the expressions are formed would be great
Alternately:
syntax: glob
bin/**
I did some experiments and I found that the regex syntax on Windows applies to the path starting with the current repository, with backslashes transformed to slashes.
So if your repository is in E:\Dev for example, hg status will apply the patterns against foo/bar/file1.c and such. Anchors apply to this path.
So:
Glob applies to path elements and is rooted to element parts
foo matches any folder (or file) named foo (not to "foobar" nor "barfoo")
*foo* matches any folder or file with "foo" in the name
foo/bar* matches all files in "foo" folder starting with "bar"
Regex is case sensitive, not anchored
Of course, backslash regex special characters like . (dot)
/ matches \ path separator on Windows. \ doesn't match this separator...
foo matches all files and folders with "foo" inside
foo/ matches only folders ending with "foo"
/foo/ matches the folder "foo" somewhere in the path
/foo/bar/ matches the folder "bar" in the folder "foo" somewhere in the path
^foo matches file or folder starting by foo at the root of the repository
foo$ matches file ending with foo
I hope this will help, I found the HGIGNORE(5) page a bit succinct.
Both of those will also filter out a directory called cabin, which might not be what you want. If you're filtering top-level, you can use:
^/bin/
For bin directories below your root, you can omit the ^. There is no need to specify syntax, regexp is the default.
syntax: glob
bin/**
This answer is shown above, however I'd also like to add that * and ** are handled differently. ** is recursive, * is not.
See Hg Patterns
Nevermind, I got it
syntax: regexp
bin\\*
expressions follow standard perl regular expression syntax.
to ignore .class files
syntax: regexp
?\.class