Prevent vim :make from changing the current working directory? - perl

Synopsis:
When calling vim's make command, it changes the current working directory (cwd) to the directory of the current file. It then runs the makeprg from there. I want to prevent the make command from changing the cwd, and instead call the makeprg from the directory of the parent vim instance
Example:
I have the following standard perl project hierarchy
project/
lib/
My/
Module/
Foo.pm
My PERL5LIB is set to
PERL5LIB=':lib'
In my .vimrc I have
compiler perl
set makeprg=perl\ -c\ %
I edit my module using vim from the root project level:
/path/to/project$ vim lib/My/Module/Foo.pm
In vim :pwd works as expected:
:pwd
"/path/to/project"
Also calling !perl -c works as expected, finds my project lib, and displays the result in a shell window:
:!perl-c %
OUTPUT:
perl -c lib/My/Module/Foo.pm
lib/My/Module/Foo.pm Syntax ok
However :make returns an error
:make
"Can't open perl script lib/My/Module/Foo.pm : No such file or directory"
Setting makeprg to pwd shows the problem
:set makeprg=pwd
:make
"/path/to/project/lib/My/Module"
So before make runs makeprg it is changing to the directory of the current file, which is why perl can't find 'lib/.../Foo.pm' there.
Is there any way to prevent make from doing this?

If Vim's :make command is changing the current working directory, and autochdir is not set, a plugin may have added an autocommand to the QuickFixCmdPre set. One plugin that does this is eclim, which calls the QuickFixLocalChangeDirectory() function if g:EclimMakeLCD is set to 1.
Use :au to find all the autocommands in your current configuration, paying particular attention to entries for QuickFixCmdPre and make.

Related

Windows Powershell Basic Questions - new user

When trying to open a file with text editor VIM, I am unable to open the file unless VIM (shortcut) is in my current working directory. As an example, I am able to write start firefox to open a firefox window. However, start vim C:\filepath\filename.txt does not work unless a vim shortcut is in my current directory. How do I get around this?
Also, is there a way to have a program execute a file in the current working directory without having to reference the entire file path? For example instead of Start-Process vim C:\Users\User\Desktop\File\file.txt is there an available path shortcut like Start-Process vim ~\file.txt with ~ representing the current working directory?
The OS need to determine the full path of the exe, no matter what.
There's 2 ways that it will happen.
You're calling the executable from it's working directory
The executable location is in the Windows environment variable.
You can view the PATH variable content through this simple statement
$env:Path -split ';' | sort
You sill see that the Firefox path is listed there, but not the one from VIM.
That's why the former can be started by it's executable name and the latter require the full path.
You need to add VIM directory to your PATH variable if you want to be able to call it just by typing vim
Otherwise, if you have restricted access or don't want to edit that variable, you can also set a $vim variable, then invoke it whenever you want to call the executable.
Regarding the second part of your question
Powershell use the dot as a reference to the current directory .\file.txt.
You can also just specify the filename without anything else file.txt.
Both backslash \ & slash / work for filepath so .\file.txt and ./file.txt are both valid ways to reference the file.
Use ..\ to reference the parent directory (e.g. ..\file.txt)
$Vim = "c:\Path\To\Vim.exe"
& $vim "file.txt"
& $vim ".\file.txt"
#Forward slash also work for paths
& $vim "./file.txt"

why doesn't make -C change $PWD as seen through a scripting language such as Perl?

Here is temp/Makefile:
all:
echo $$PWD
echo $(CURDIR)
perl -e 'print $$ENV{"PWD"}'
and now
$make -C temp
make: Entering directory `/home/mgaleck/temp'
/home/mgaleck/temp
/home/mgaleck/temp
/home/mgaleck
make: Leaving directory `/home/mgaleck/temp'
Why is the third value without temp?
According to Make manual, -C option causes to "change the directory" (working directory?) first.
Same thing happens with Python.
Because the PWD environment variable doesn't hold the current working directory; it holds whatever the current working directory was the last time sh set it. Anything other than a shell starting up, or a shell executing the cd builtin (or a similar builtin like pushd, in shells that have it), has no effect on PWD, and relying on PWD anywhere except in the shell is probably a silly idea. Use getcwd (C), Cwd::getcwd (Perl), os.getcwd (Python), etc. instead.

colorgcc perl script with output to non-tty enabled writing to C dependency files

Ok, so here's my issue. I have written a build script in bash that pipes output to tee and sorts different output to different log files (so I can summarize errors/warnings at the end and get some statistics on files built). I wanted to use the colorgcc perl script (colorgcc.1.3.2) to colorize the output from gcc and had found in other places that this won't work piping to tee, since the script checks if it is writing to something that is not a tty. Having disabled this check everything was working until I did a full build and discovered some of the code we receive from another group builds C dependency files (we don't control this code, changing it or the build process for these isn't really an option).
The problem is that these .d files have the form as follows:
filename.o filename.d : filename.c \
dependant_file1.h \
dependant_file2.h (and so on for however many dependencies there are)
This output from GCC gets written into the .d file, but, since it is close enough to a warning/error message colorgcc outputs color codes (believe it's the check for filename:lineno:message but not 100% sure, could be filename:message check in the GCCOUT while loop). I've tried editing the regex to attempt to not match this but my perl-fu is admittedly pretty weak. So what I end up with is a color code on each line for these dependency files, which obviously causes the build to fail.
I ended up just replacing the check for ! -t STDOUT with a check for a NO_COLOR envar I set and unset in the build script for these directories (emulates the previous behavior of no color for non-tty). This works great if I run the full script, but doesn't if I cd into the directory and just run make (obviously setting and unsetting manually would work but this is a pain to do every time). Anyone have any ideas how to prevent this script from writing color codes into dependency files?
Here's how I worked around this. I added the following to colorgcc to search the gcc input for the flag to generate the .d files and just directly called the compiler in that case. This was inserted in place of the original TTY check.
for each $argnum (0 .. $#ARGV)
{
if ($ARGV[$argnum] =~ m/-M{1,2}/)
{
exec $compiler, #ARGV
or die("Couldn't exec");
}
}
I don't know if this is the proper 'perl' way of doing this sort of operation but it seems to work. Compiling inside directories that build .d files no longer inserts color codes and the source file builds do (both to terminal and my log files like I wanted). I guess sometimes the answer is more hacks instead of "hey, did you try giving up?".

Can't exec No such file or directory

Merry Christmas to everybody. I'm having a dilemma with a perl script. In my script, I call another program with a system call, but I got this error:
Can't exec "./Classificador/svm_classify": No such file or directory at Analise_de_Sentimentos_mudanca.pl line 463.
I don't know if there is a problem in having my program in a different directory than the called program.
Another curious thing is that this script used to run normally in Ubuntu 10.10. But now I've changed to Mint 14. Is it missing some library?
Best wishes,
Thiago
The relative pathname ./Classificador/svm_classify is interpreted relative to the user's current directory, not the directory containing the perl script. You need to do one of the following:
The user must cd to the directory containing the perl script before running it.
The perl script should call chdir() to set the current directory to the directory where it's stored.
Put the absolute pathname in the script, instead of ./.
Does this "./Classificador/svm_classify" exists ?
Check the following :
1) to go the directory where this file lays - Analise_de_Sentimentos_mudanca.pl
2) run :
ll Classificador/svm_classify
3) show us the results

VIM: FileType specific mapping not working when defined in ftplugin

I am trying to set a mapping for FileType perl. The mapping is for the case when I forgot to use semicolon at the end of the line.
So first I tried adding in my .vimrc autocmd! FileType perl nnoremap <leader>; $a;<esc> and it worked fine but than I thought of using ftlugin/perl.vim .
So I added the below line in my corresponding ~/.vim/after/ftplugin/perl.vim
nnoremap <buffer> <leader>; $a;<esc>
but it didn't work.
Any idea why it is not working ?
My perl version is perl 5, version 14.
Try putting the file in ~/.vim/ftplugin/perl.vim instead of ~/.vim/after/ftplugin/perl.vim. From :help after-directory:
*after-directory*
4. In the "after" directory in the system-wide Vim directory. This is
for the system administrator to overrule or add to the distributed
defaults (rarely needed)
5. In the "after" directory in your home directory. This is for
personal preferences to overrule or add to the distributed defaults
or system-wide settings (rarely needed).
From :help ftplugin:
If you do want to use the default plugin, but overrule one of the settings,
you can write the different setting in a script: >
setlocal textwidth=70
Now write this in the "after" directory, so that it gets sourced after the
distributed "vim.vim" ftplugin |after-directory|. For Unix this would be
"~/.vim/after/ftplugin/vim.vim". Note that the default plugin will have set
"b:did_ftplugin", but it is ignored here.
One thing I just noticed that was driving me crazy: <buffer> must be lowercase! Out of habit, I uppercase all of my <BRACKET> prefixes... and I had done the same for <BUFFER>. None of my ftplugin mappings worked and I couldn't figure it out... until I wasted hours trying different things, only to find that it must be lowercase <buffer>.