Vim: gf opens directories, not files - windows

I am trying to configure vim's 'path' and 'suffixesadd' so when I use gf over FILE_NAME, and pwd is /some/dir/, it opens /some/dir/FILE_NAME/File_Name.xml
In vimrc I put:
set suffixesadd=.xml
set path=.,dir/**
But, instead of opening File_Name.xml it opens the directory FILE_NAME
What should I do to configure vim so it looks for files before directories?
PS: Im using gvim in Windows and have NERD plugin active

I don't think this is possible with gf as standard, but you could always do:
" Mapping to make it easier to use - <C-R><C-W> inserts the Word under
" the cursor
nmap gx :call CustomGFOpen("<C-R><C-W>")<CR>
" The function that does the work
function! CustomGFOpen(cursor_word)
" The directory name (e.g. FILE_NAME) is passed as the parameter
let dirname = a:cursor_word
" This is a regular expression substitution to convert
" FILE_NAME to File_Name
let filename = substitute(a:cursor_word, '\(^\|_\)\#<=\([A-Z]\)\([A-Z]\+\)', '\=submatch(2) . tolower(submatch(3))', 'g')
" The extension
let extension = '.xml'
" Join the whole lot together to get FILE_NAME/File_Name.xml
let relative_path = dirname . '/' . filename . extension
" Open that file
exe 'e' relative_path
endfunction

Related

How can I force PostgreSQL to put my output in quotation marks?

I have the following code:
$sql = "copy(" . $sql . ") TO STDOUT CSV HEADER" ;
$cmd = "psql -h " . DATABASE_HOST . " -d " . DATABASE_NAME . " -U " . DATABASE_USER . " -c '" . $sql . ";' > " . WEBUSER_DOWNLOAD_PATH . $archivo_csv ;
I want the output to contain values inside quotes, for example "name", "age", ...,"any".
How can I do this?
Oof. Okay, first thing: this is probably a bad pattern. Consider, for example, what happens when $sql is "DELETE FROM users) TO STDOUT; COPY (SELECT * FROM profiles". Or, since you're issuing a bash command, something like "SELECT 1) TO STDOUT;" rm -rf /". Basically, this code pattern is vulnerable to SQL Injection and Shell Injection problems.
That said, the COPY command has a bunch of options nowadays. You could use something like:
COPY (query) TO STDOUT WITH (FORMAT CSV, HEADER, FORCE_QUOTE *);
I'm assuming you're using a relatively current version (9.0 or later) of postgres. If you're using an older version, you might still be okay. Starting with 8.0, there was a FORCE QUOTE option on the older syntax.

how to escape space and ampersand in same time in powershell script that execute CMD

In my Powershell script, I use "rmtshare.exe" to get information about share level permission. The "rmtshare.exe" can run perfectly under CMD environment with following command:
rmtshare.exe \\fs-sw-206\"C&C FQT"
However, when I bring it to powershell environment. I can't figure out how to escape the space and the ampersand. Here is what I have tried so far which it is not working:
$rmtShare = "C:\rmtshare.exe"
$ServerName = "fs-sw-206"
$ShareName = "C&C FQT"
Invoke-Expression ($rmtShare + " " + "\\" + $ServerName + "\" + $ShareName)
The script above will give error message from the CMD, it said "if a sharename or path contains spaces, it should be enclosed in quotes".
If I changed the last line to this:
Invoke-Expression ($rmtShare + " " + "\\" + $ServerName + "\" + "'"+'"'+"'" + $ShareName +"'"+'"'+"'")
The error message was from Powershell itself, it said "The ampersand (&) character is not allowed". NOTE: if there is no ampersand, it works. So, now I am stuck because I need to escape both characters at the same time.
Please offer your solution.
You may need to download the rmtshare.exe to test out yourself. Download site: (https://www.symantec.com/connect/downloads/remove-folder-share-remote-computer)
so, here is the code in Powershell that overcame the problem - escape space and ampersand in same time in powershell script that execute CMD
$s = " "
$q = '"'
$Verbatim = '--%'
$rmtShare = "C:\rmtshare.exe"
$ServerName = "fs-sw-206"
$ShareName = "C&C FQT"
Invoke-Expression ($rmtShare +$s+$Verbatim+$s+"\\"+$ServerName+"\"+$q+$ShareName+$q)
There should be other solutions as well. Please post if you know it.

Looping through folders and renaming all files in each folder sequentially with folder name

I have a series of subfolders, each with images on them.
Structure looks like
/stuff/
IMG_012.JPG
IMG_013.JPG
IMG_014.JPG
/morestuff/
IMG_022.JPG
IMG_023.JPG
IMG_024.JPG
I would like to write a script on my mac terminal to loop through each folder and rename the images sequentially including the folder name. So, the above structure would look like:
/stuff/
stuff_1.JPG
stuff_2.JPG
stuff_3.JPG
/morestuff/
morestuff_1.JPG
morestuff_1.JPG
morestuff_1.JPG
I orignally tried creating a Automator workflow and using variables, but had difficulty assigning the folder name as the variable and getting the loop to work.
I'm hoping there is an elegant solution with the terminal.
Any ideas?
This should work nicely for you. Save it in your HOME directory as "RenameImages", then make it executable like this:
cd
chmod +x RenameImages
Then you can run it (-exec) it on every directory (-type d) like this:
find . -type d -exec ./RenameImages {} \;
Here is the script:
#!/bin/bash
# Ignore case, i.e. process *.JPG and *.jpg
shopt -s nocaseglob
shopt -s nullglob
# Go to where the user says
echo Processing directory $1
cd "$1" || exit 1
# Get last part of directory name
here=$(pwd)
dir=${here/*\//}
i=1
for image in *.JPG
do
echo mv "$image" "${dir}${i}.jpg"
((i++))
done
At the moment it does nothing except show you what it would do. If you like what it is doing, simply remove the word echo from the 3rd to last line and run it again.
I would just like to throw out another way to do this since you mentioned you tried using Automator. This file search and process software: http://www.softpedia.com/get/File-managers/JFileProcessor.shtml https://github.com/stant/jfileprocessor
Will let you search for files with glob or regex, in subfolders to X or all depth, by name, size, date. You can save to a List window or file. Then you can run a groovy (think java) script to do whatever you want to the list of files; zip or tar them, modify the list strings like sed, delete, move, copy files, grep or ls -l them, whatever. In your case you can modify an existing groovy example to do something like:
int numItems = defaultComboBoxModel.getSize();
System.out.println( "defaultComboBoxModel.getSize() num of items =" + numItems + "=" );
String str = "";
for( int i = 0; i < numItems; i++ )
{
str = defaultComboBoxModel.getElementAt( i ).toString();
System.out.println( "file of index =" + i + " str =" + str + "=" );
String cmd = "mv " + str + " " + i + ".jpg"; // or whatever
def list = cmd.execute().text // this stuff just captures output and write to a log file
list.eachLine{
outFile << it;
}
outFile << System.getProperty("line.separator") + "-------------------------------------" + System.getProperty("line.separator");
}
It will also let you massage your list like add to, delete from, subtract one list from another.

Rename all files in directory?

My task:
Write a program to rename files using regular expressions. This
program will take three command line arguments: the directory in which
to rename files, a regular expression that matches files to be
renamed, and a string to replace the regular expression match. The
primary use is to change file extensions, but it should be able to
handle replacing any portion of the file name.It should run as
follows:
./fixname.rb dir 'pattern' replacement
The program I have written is:
puts "Renaming files..."
folder_path = ARGV[0]
reg_exp = ARGV[1].to_regexp
Dir.glob(folder_path + "/*").sort.each do |f|
filename = File.basename(f, File.extname(f))
myString = String.new
myString = filename
filename = myString.gsub(reg_exp, ARGV[2])
#puts myString
File.rename(f, folder_path + "/" + filename + File.extname(f))
end
puts "Renaming complete."
The rename doesn't happen when I am using regexp, otherwise it is working. I'm getting:
error "`gsub': no implicit conversion of nil into String (TypeError)"
What you think is a regex is not, it's a String containing a regex pattern.
You need to convert that to a Regexp object. How to do that is left to you.

vim: execute shell command with variable and redirect output to new buffer

I want to call msbuild from the function below and redirect the output to a new buffer.
My problem is that I need to use a variable, for the filename, and therefore cant use '!' (can I?), and when I use exe or system() read complains that I'm not giving it a proper file.
func! myFunction()
let findstr = "findstr /s /m " . '"' . expand("%:t") . '"' . " *.vcxproj"
for project in split(system(findstr), nr2char(10))
echo "Building '" . project . "'"
let msbuild = "c:\\windows\\Microsoft.NET\\Framework\\v4.0.30319\\msbuild.exe" . " " . project . " " . "/t:rebuild /p:configuration=debug"
:tabnew | r system(msbuild) "<--THIS LINE HERE
endfor
endfunc
The :read command takes a file not a vim expression. However it can read in from standard output via :read !{cmd}. Example :%r!ls. Using the :execute command you can build your new command with your variable.
exe '%r!' . msbuild
Or you can use :put along with the expression register if you want to use an expression like system(). (Probably want to follow this with :0d_ to delete the first empty line)
put=system(msbuild)
Now it looks like you are trying to build your project and get a list of errors. I would recommend you look into :make, the 'makeprg' option, and the quickfix list as this is a more vim way of building a project.
For more help see:
:h :r!
:h :exe
:h :pu
:h #=
:h :make
:h 'makeprg'
:h quickfix
This is a function you can use to execute arbitrary shell commands and present their output in a new window ( you can put this in your _vimrc):
let s:lastcmd = ''
function! s:RunShellCommand(cmdline, bang)
" Support for repeating last cmd with bang:
let _ = a:bang != '' ? s:lastcmd : a:cmdline == '' ? '' : join(map(split(a:cmdline), 'expand(v:val)'))
if _ == ''
return
endif
let s:lastcmd = _
let bufnr = bufnr('%')
let winnr = bufwinnr(_)
" You can position the new window whenever you want, I chose below + right:
silent! execute winnr < 0 ? 'belowright new ' . fnameescape(_) : winnr . 'wincmd w'
" I could set buftype=nofile, but then no switching back and forth buffers.
" The results are presented just for viewing, not editing, modify at will:
setlocal buftype=nowrite bufhidden=wipe nobuflisted noswapfile wrap number
setlocal modifiable
silent! :%d
" Useful for debugging, if you encounter issues with fnameescape():
call setline(1, 'You entered: ' . a:cmdline)
call setline(2, 'Expanded to: ' . _)
call append(line('$'), substitute(getline(2), '.', '=', 'g'))
silent execute '$read !' . _
silent! execute 'autocmd BufUnload <buffer> execute bufwinnr(' . bufnr . ') . ''wincmd w'''
" If resizing is unwanted for commands with too much output, remove this line:
silent! execute 'autocmd BufEnter <buffer> execute ''resize '' . line(''$'')'
" You can use <localleader>r to re-execute the last command:
silent! execute 'nnoremap <silent> <buffer> <localleader>r :call <SID>RunShellCommand(''' . _ . ''', '''')<CR>'
execute 'resize ' . line('$')
setlocal nomodifiable
1
endfunction " RunShellCommand(cmdline)
command! -complete=shellcmd -nargs=* -bang Shell call s:RunShellCommand(<q-args>, '<bang>')
Use like:
:Shell gcc -ggdb -o test test.c && ./test

Resources