case insensitive glob listing in zsh - zsh

I have the following code:
$ print -l backgrounds/**/*.((#i)jpg|jpeg|gif|webp|png|svg|xcf|cur|ppm|pcd)
the intention was to list some image file indifernet of the case of file termination.
But my code seems to not be functional because won't list files whit uppercase endings.
Can someone explain my error in the above code example?
Thanks in advance.

You need the #i to apply to everything, not just jpg. You can use:
$ print -l backgrounds/**/*.(#i)(jpg|jpeg|gif|webp|png|svg|xcf|cur|ppm|pcd)
Make sure you have also done:
set -o extended_glob

Note that using #i requires that EXTENDED_GLOB be set in your script/shell:
setopt EXTENDED_GLOB
See the docs, section 1.8.4 Globbing Flags, or type man zshexpn.
And you want: *.(#i)(jpg|gif|etc)

Related

What can I change in order that Compdef can bind my function?

I have created some console commands in PHP. I need to use autocompletion when I launch my tasks.
I used alias otra="php console.php" in my .zshrc file.
The function itself seems to work but when I type my command name 'otra', there is only folders autocompletion...which is completely irrelevant in my case.
#compdef _otra otra
function _otra {
local line
_arguments -C \
"1: :(createAction createBundle)" \
"*::arg:->args"
}
I want to only have the two words createAction and createBundle to appear when I type otra and type .
EDIT
Ok, it is what I was thinking...if I remove my alias, the completion works but I cannot remove it since otra is not a valid command...
I tried to use setopt no_complete_aliases as I see it in another Stackoverflow post but it does not work for me.
In fact, it was related to the alias but I did not have to set setopt no_complete_aliasesin my case but pretty much the contrary...
After I put setopt complete_aliases in my .zshrc file, it works :D

remove a file called -l from command line (Centos)

Someone accidentally created a file name '-l' and I cannot remove it, because rm -l interprets the filename as a flag. I've tried quotes, escaping and nothing is working.
In virtually all Unix commandline utilities you can use a double-dash -- to separate options from arguments. Under the hood, getopt will stop attempting to parse arguments as options when it first encounters a --. From the docs:
getopt has three ways to deal with options that follow non-options argv elements. The special argument ‘--’ forces in all cases the end of option scanning.
In your specific case with rm, use:
$ rm -- -l

compiling a ICC binary [duplicate]

I am getting the following error running make:
Makefile:168: *** missing separator. Stop.
What is causing this?
As indicated in the online manual, the most common cause for that error is that lines are indented with spaces when make expects tab characters.
Correct
target:
\tcmd
where \t is TAB (U+0009)
Wrong
target:
....cmd
where each . represents a SPACE (U+0020).
Just for grins, and in case somebody else runs into a similar error:
I got the infamous "missing separator" error because I had invoked a rule defining a function as
($eval $(call function,args))
rather than
$(eval $(call function,args))
i.e. ($ rather than $(.
This is a syntax error in your Makefile. It's quite hard to be more specific than that, without seeing the file itself, or relevant portion(s) thereof.
For me, the problem was that I had some end-of-line # ... comments embedded within a define ... endef multi-line variable definition. Removing the comments made the problem go away.
My error was on a variable declaration line with a multi-line extension. I have a trailing space after the "\" which made that an invalid line continuation.
MY_VAR = \
val1 \ <-- 0x20 there caused the error.
val2
In my case, I was actually missing a tab in between ifeq and the command on the next line. No spaces were there to begin with.
ifeq ($(wildcard $DIR_FILE), )
cd $FOLDER; cp -f $DIR_FILE.tpl $DIR_FILE.xs;
endif
Should have been:
ifeq ($(wildcard $DIR_FILE), )
<tab>cd $FOLDER; cp -f $DIR_FILE.tpl $DIR_FILE.xs;
endif
Note the <tab> is an actual tab character
In my case error caused next. I've tried to execute commands globally i.e outside of any target.
UPD. To run command globally one must be properly formed. For example command
ln -sf ../../user/curl/$SRC_NAME ./$SRC_NAME
would become:
$(shell ln -sf ../../user/curl/$(SRC_NAME) ./$(SRC_NAME))
In my case, this error was caused by the lack of a mere space. I had this if block in my makefile:
if($(METHOD),opt)
CFLAGS=
endif
which should have been:
if ($(METHOD),opt)
CFLAGS=
endif
with a space after if.
In my case, the same error was caused because colon: was missing at end as in staging.deploy:. So note that it can be easy syntax mistake.
I had the missing separator file in Makefiles generated by qmake. I was porting Qt code to a different platform. I didn't have QMAKESPEC nor MAKE set. Here's the link I found the answer:
https://forum.qt.io/topic/3783/missing-separator-error-in-makefile/5
Just to add yet another reason this can show up:
$(eval VALUE)
is not valid and will produce a "missing separator" error.
$(eval IDENTIFIER=VALUE)
is acceptable. This sort of error showed up for me when I had an macro defined with define and tried to do
define SOME_MACRO
... some expression ...
endef
VAR=$(eval $(call SOME_MACRO,arg))
where the macro did not evaluate to an assignment.
I had this because I had no colon after PHONY
Not this,
.PHONY install
install:
install -m0755 bin/ytdl-clean /usr/local/bin
But this (notice the colon)
.PHONY: install
...
Following Makefile code worked:
obj-m = hello.o
all:
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
So apparently, all I needed was the "build-essential" package, then to run autoconf first, which made the Makefile.pre.in, then the ./configure then the make which works perfectly...

how to properly expand filenames in zsh alias

Wrote a seemingly simple alias to convert mp3 to wav but doesn't expand the files at run time. Changed it to a function after I was unable to get it working.
Was hoping to get an explanation of why it didn't work as written.
alias 2wav="for fn in *.mp3;do echo \"Converting $fn\";avconv -y -i $fn ${$(basename $fn .mp3)}.wav 2>/dev/null;done"
Do any of your filenames contain spaces? e.g. foo bar.mp3 would produce a command line of
avconv -y -i foo bar.mp3 foo bar.wav
^^^---input file, doesn't exist
^^^^^^^--output file, but since there's no input, it's useless
^^^^^^^^^^--- miscellaneous unknown/invalid arguments
You'd need quotes around the arguments:
alias ........ -y -i "$fn" "${$(basename .....}".wav
Solved (at least partially).
alias 2wav='for fn in *.mp3;do echo "Converting ${fn}";avconv -y -i ${fn} ${$(basename ${fn} .mp3)}.wav 2>/dev/null;done'
Not sure why this fixed it but I enclosed the command with single quotes and added braces around the vars and it just worked. True that spaces in file names would still be a potential problem. I'll have to experiment with that.
Solved.
alias 2wav='for fn in *.mp3;do echo "Converting ${fn}";avconv -y -i "${fn}" "${$(basename "${fn}" .mp3)}".wav 2>/dev/null;done'
Now works for filenames containing spaces. I'm guessing that the single quotes prevent the expansion from happening until runtime and that's why this works.
Any clarification is welcome...

How to make zsh search configuration in $XDG_CONFIG_HOME

Looking to make my ~ a cleaner place, I would like to move as much user configuration files into $XDG_CONFIG_HOME, which is ~/.config by default. So I would like to store all my zsh user files in $XDG_CONFIG_HOME/zsh/. So far already have this:
% ls $XDG_CONFIG_HOME/zsh/
histfile zsh_cache zshrc
Easy, you just have to fill your ~/.zshrc. Now the trickiest part seems to make zsh read directly $XDG_CONFIG_HOME/zsh/zshrc without sourcing it from ~/.zshrc. How would you proceed?
One may edit /etc/zsh/zshenv to set $XDG_CONFIG_HOME directories and $ZDOTDIR. This require write privilegies on this files though.
So provided that $HOME is defined when zsh read it (I don't know if it's the case), you may add to your /etc/zsh/zshenv:
if [[ -z "$XDG_CONFIG_HOME" ]]
then
export XDG_CONFIG_HOME="$HOME/.config/"
fi
if [[ -d "$XDG_CONFIG_HOME/zsh" ]]
then
export ZDOTDIR="$XDG_CONFIG_HOME/zsh/"
fi
It is good practice to not put a / at the end of any variable holding a certain path.
For example, $XDG_CONFIG_HOME/zsh translates to "$HOME/.config//zsh" and the / repeats because XDG_CONFIG_HOME ends with a /.
So I think your answer should be -
if [[ -z "$XDG_CONFIG_HOME" ]]
then
export XDG_CONFIG_HOME="$HOME/.config"
fi
if [[ -d "$XDG_CONFIG_HOME/zsh" ]]
then
export ZDOTDIR="$XDG_CONFIG_HOME/zsh"
fi
Variation to psychoslave's answer which uses ${HOME}/.zshenv to initiate the environment. No root access needed.
export XDG_CONFIG_HOME=${XDG_CONFIG_HOME:=${HOME}/.config}
export ZDOTDIR=${ZDOTDIR:=${XDG_CONFIG_HOME}/zsh}
source $ZDOTDIR/.zshenv
This was discussed on this thread on the zsh-users mailing list.
You may want to consider saving history in XDG_DATA_HOME. Specifications can be found at XDG Base Directory Specification.
Write a wrapper for zsh that executes zsh after setting the environment variable ZDOTDIR to where you want zsh to look for the config files.
See: http://zsh.sourceforge.net/Intro/intro_3.html

Resources