ZSH: How to disable default completion for `make`? - zsh

I wrote my auto-completion function for make command, and placed it in ~/.zsh:
function __comp_make {
# ... function body ....
}
compctl -K __comp_make make
Unfortunately, it will not work because completion for make is already defined in
/usr/share/zsh/functions/Completion/Unix/_make
and apparently it takes precedence over my rule.
I had to rename _make to unused_make so it is not loaded at zsh initialization. It works, but it is rather ugly solution.
My question is: how should I set my completion rule so it takes precedence over the loaded defaults?
Related:
How does one override an existing zsh keyboard completion?
Edit:
zsh 4.3.17

You need to set your fpath. See here.
In your ~/.zshrc, something like:
fpath=( ~/.zshfunctions $fpath )
where ~/.zshfunctions contains your custom completion files, should solve this for you. Note that your functions are loaded before the system ones. This will not work:
fpath=( $fpath ~/.zshfunctions )
As an aside, you're using compctl. It's old. I'd recommend using compsys instead, although a decent link explaining why escapes me at the moment.
These go into some detail about writing completion functions, including the fpath. You might find them useful for reference.
Z-shell completion functions: introduction
Writing z-shell completion functions

Related

shell function doesn't work in subfolder?

I have the following code that should open the Recode.xlsx inside the subf folder but doesn't
write_xlsx(mtcars, "subf/Recode.xlsx")
shell("subf/Recode.xlsx", wait=FALSE)
The following code works, so if anyone has an idea on why it doesn't work it would help me
write_xlsx(mtcars, "Recode.xlsx")
shell("Recode.xlsx", wait=FALSE)
Here’s what the documentation of the shell function says (emphasis mine):
shell is a more user-friendly wrapper for system. To make use of Windows file associations, use shell.exec.
And here is another bit of relevant information from the shell.exec documentation:
To be interpreted as relative, the path also needs to use backslashes as separators (at least in Windows 10).
So the following is the correct usage:
shell.exec("subf\\Recode.xlsx")

How to combine two Vim commands into one (command not keybinding)

I've found few Stack Overflow questions talking about this, but they are all regarding only the :nmap or :noremap commands.
I want a command, not just a keybinding. Is there any way to accomplish this?
Use-case:
When I run :make, I doesn't saves automatically. So I'd like to combine :make and :w. I'd like to create a command :Compile/:C or :Wmake to achieve this.
The general information about concatenating Ex command via | can be found at :help cmdline-lines.
You can apply this for interactive commands, in mappings, and in custom commands as well.
Note that you only need to use the special <bar> in mappings (to avoid to prematurely conclude the mapping definition and execute the remainder immediately, a frequent beginner's mistake: :nnoremap <F1> :write | echo "This causes an error during Vim startup!"<CR>). For custom commands, you can just write |, but keep in mind which commands see this as their argument themselves.
:help line-continuation will help with overly long command definitions. Moving multiple commands into a separate :help :function can help, too (but note that this subtly changes the error handling).
arguments
If you want to pass custom command-line arguments, you can add -nargs=* to your :command definition and then specify the insertion point on the right-hand side via <args>. For example, to allow commands to your :write command, you could use
:command -nargs=* C w <args> | silent make | redraw!
You can combine commands with |, see help for :bar:
command! C update | silent make | redraw!
However, there is a cleaner way to achieve what you want.
Just enable the 'autowrite' option to automatically write
modified files before a :make:
'autowrite' 'aw' 'noautowrite' 'noaw'
'autowrite' 'aw' boolean (default off)
global
Write the contents of the file, if it has been modified, on each
:next, :rewind, :last, :first, :previous, :stop, :suspend, :tag, :!,
:make, CTRL-] and CTRL-^ command; and when a :buffer, CTRL-O, CTRL-I,
'{A-Z0-9}, or `{A-Z0-9} command takes one to another file.
Note that for some commands the 'autowrite' option is not used, see
'autowriteall' for that.
This option is mentioned in the help for :make.
I have found a solution after a bit of trial and error.
Solution for my usecase
command C w <bar> silent make <bar> redraw!
This is for compiling using make and it prints output only if there is nonzero output.
General solution
command COMMAND_NAME COMMAND_TO_RUN
Where COMMAND_TO_RUN can be constructed using more than one command using the following construct.
COMMAND_1_THAN_2 = COMMAND_1 <bar> COMMAND_2
You can use this multiple times and It is very similar to pipes in shell.

HISTIGNORE not working in zsh

I have added
export HISTIGNORE="ls:cd:pwd:exit:cd .."
to my .zshrc file.
Deleted .zsh_history and restarted terminal but it still wont ignore those commands.
The zsh shell doesn't use the HISTIGNORE environment variable. Instead, it has a HISTORY_IGNORE environment variable.
From the zshparam manual:
HISTORY_IGNORE
If set, is treated as a pattern at the time history files are
written. Any potential history entry that matches the pattern is skipped. For example, if the value is fc * then
commands that invoke the interactive history editor are never
written to the history file.
Note that HISTORY_IGNORE defines a single pattern: to specify
alternatives use the (first|second|...) syntax.
So in your case, you would want to do
HISTORY_IGNORE="(ls|cd|pwd|exit|cd ..)"
or something similar.
Notice that this affects only history written to the history file, not the history in the currently active shell session, as far as I can see.

Fail a grunt build when debug prints exist in source

I am working on a PHP/Javascript project where I've nicely set up a build workflow. It involves testing, minifying, compressing into the final zip deliverable, and a whole lot of other nice stuff.
I want to build a task that fails when there are certain patterns in the source code. I would like to look for any print_r(), error_log(), var_dump(), etc functions, and halt the build process if there are any. Perhaps later I would like to check for things in Javascript or CSS so this is not only a PHP question.
I know it can be done with grunt-shell and grep but I'd like to know the following:
Are there any grunt plugins specific to this task? Ideally I would like to be able to specify a list of regexes per file type, and to set whether to continue or fail the build on pattern match.
How do others tackle the problem of double-checking the packaged source for the most common debug statements or other patterns?
Not a complete answer to my question, but I've recently come across this grunt plugin which is somewhat related. It removes console.log statements from JavaScript. Haven't tried it yet. Looks good. I still would like to know if there's something similar for PHP though.
http://grunt-tasks.com/grunt-remove-logging-calls/
Edit: Seeing as there's only tumbleweeds rolling in the wind here, I'm posting my workaround that's based on grunt-shell. However this is not what I was looking for. It's not perfect because it doesn't do proper syntax parsing:
shell: {
check_debug_prints: {
command: '(! (egrep -r "var_dump|print_r|error_log" --include=*.php src || egrep -r "console\.\w+|debugger;" --include=*.js src) ) || (echo "Debug prints in source - build aborted" && false )'
}
},
and
grunt.loadNpmTasks( 'grunt-shell' );
Edit 2: I finally found the exact grunt plugin I was looking for. It is grunt-search. There is a failOnMatch boolean option that lets you indicate if a particular regex pattern should cause the build to fail when found.

zsh: using "less -R" as READNULLCMD

Now, I'm pretty sure of the limitation here. But let's step back.
The simple statement
READNULLCMD="less -R"
doesn't work, generating the following error:
$ <basic.tex
zsh: command not found: less -R
OK. Pretty sure this is because, by default, zsh doesn't split string variables at every space. Wherever zsh is using this variable, it's using $READNULLCMD where it should be using ${=READNULLCMD}, to ensure the option argument is properly separated from the command by a normal space. See this discussion from way back in 1996(!):
http://www.zsh.org/mla/users/1996/msg00299.html
So, what's the best way around this, without setting SH_WORD_SPLIT (which I don't want 99% of the time)?
So far, my best idea is assigning READNULLCMD to a simple zsh script which just calls "less -R" on STDIN. e.g.
#!/opt/local/bin/zsh
less -R /dev/stdin
Unfortunately this seems to be a non-starter as less used in this fashion for some reason misses the first few lines on input from /dev/stdin.
Anybody have any better ideas?
The problem is not that less doesn't read its environment variables (LESS or LESSOPEN). The problem is that the READNULLCMD is not invoked as you might think.
<foo
does not translate into
less $LESS foo
but rather to something like
cat foo | less $LESS
or, perhaps
cat foo $LESSOPEN | less $LESS
I guess that you (like me) want to use -R to obtain syntax coloring (by using src-hilite-lesspipe.sh in LESSOPEN, which in turn uses the "source-highlight" utility). The problem with the latter two styles of invocation is that src-hilite-lesspipe.sh (embedded in $LESSOPEN) will not receive a filename, and hence it will not be able to deduce the file type (via the --infer-lang option to "source-highligt"). Without a filename suffix, "source-highlight" will revert to "no highlighting".
You can obtain syntax coloring in READNULLCMD, but in a rather useless way. This by specifying the language explicitly via the --lang-def option. However, you'll have as little clue as "source-higlight", since the there's no file name when the data is passed anonymously through the pipe. Maybe there's a way to do a on-the-fly heuristic parser and deduce it by contents, but then you've for sure left this little exercise.
export LESS=… may be a good solution exclusively for less and if you want such behavior the default in all cases, but if you want more generic one then you can use functions:
function _-readnullcmd()
{
less -R
}
READNULLCMD=_-readnullcmd
(_- or readnullcmd have no special meaning just the former never appears in any distributed zsh script and the latter indicates the purpose of the function).
Set the $LESS env var to the options you always want to have in less.
So don't touch READNULLCMD and use export LESS="R" (and other options you want) in your zshrc.

Resources