How to 'set path' automatically when opening Vim from a directory? - ruby-on-rails

I'm trying to get :A (e.g. switch between controller and spec) working in vim-rails. If I navigate to my rails project, run vim ., open a controller file and run :A, I get the error:
E345: Can't find file "app/controllers/widgets_controller.rb" in path
If I then set the path explicitly:
:set path=/Users/me/Documents/Code/my-project
then :A works as expected. How can I set the path initially when I open a directory with Vim?

Not exactly when opening a directory: since you seem to be working with projects, give the project plugin a try.
Using that, you could execute arbitrary commands when entering or leaving a project.
From the plugin description:
You can use this plugin's basic functionality to set up a list of
frequently-accessed files for easy navigation. The list of files
will be displayed in a window on the left side of the Vim
window, and you can press or double-click on
filenames in the list to open the files. This is similar to how
some IDEs I've used work. I find this easier to use than
having to navigate a directory hierarchy with the file-explorer.
It also obviates the need for a buffer explorer because you
have your list of files on the left of the Vim Window.

This is what I do to have a local .vimrc file per project:
In my ~/.vimrc file I define the following:
let s:project_root = finddir('.git/..', expand('%:p:h').';')
let s:local_vimrc = join([s:project_root, '.vimrc'], '/')
if filereadable(s:local_vimrc)
exec "source " . s:local_vimrc
endif
In the project root (which usually has a .git dir) I do the following:
touch /path/to/project/.vimrc
In the .vimrc file, I prepend the path variable (notice the ^path). Using :set path^= instead of :set path+= prepends the new directory to the beginning of the path instead of appending it to the end. This makes it faster for the find command to search for your files.
let s:project_root = finddir('.git/..', expand('%:p:h').';')
exec 'setlocal path^='.s:project_root
setlocal wildmode=longest,list,full
setlocal wildmenu
setlocal tags=/path/to/project/root/tags
Now the :find command should only display files and directories relative to the project root.

Related

Pyinstaller adding data files

I'm struggling with pyinstaller. Whenever I build this specific script with a kivy GUI and a .kv file, and run the .exe after the build, I get a fatal error:
IOError: [Errno 2] No such file or directory: 'main.kv'
I've tried adding the .kv file, as well as a mdb and dsn file (for pypyodbc) using --add-data, but I get an error: unrecognized arguments: --add-data'main.kv'. (There were more --add-data arguments for the other files mentioned.)
Are there any solutions for this or maybe alternative methods?
As others (#Anson Chan, #schlimmchen) have said:
If you want to add some extra files, you should use Adding Data Files.
Two ways to implement
Command Line: add parameter to --add-data
Spec file: add parameter to datas=
Generated when running pyinstaller the first time.
Then later you can edit your *.spec file.
Then running pyinstaller will directly use your *.spec file.
Parameter Logic
Parameter in --add-data or datas=:
--add-data:
format: {source}{os_separator}{destination}
os_separator:
Windows: ;
Mac/Linux/Unix: :
source and destination
Logic:
source: path to single or multiple files, supporting glob syntax. Tells PyInstaller where to find the file(s).
destination
file or files: destination folder which will contain your source files at run time.
* NOTE: NOT the destination file name.
folder: destination folder path, which is RELATIVE to the destination root, NOT an absolute path.
Examples:
Single file: 'src/README.txt:.'
multiple files: '/mygame/sfx/*.mp3:sfx'
folder: '/mygame/data:data'
datas=
Format: list or tuple.
Examples: see the following.
added_files = [
( 'src/README.txt', '.' ),
( '/mygame/data', 'data' ),
( '/mygame/sfx/*.mp3', 'sfx' )
]
a = Analysis(...
datas = added_files,
...
)
Your case
For your (Windows OS) here is:
--add-data in command line
pyinstaller -F --add-data "main.kv;." yourtarget.py
OR:
datas= in yourtarget.spec file, see following:
a = Analysis(...
datas = ["main.kv", "."],
...
)
If you check pyinstaller -h for help, you can find --add-data option works like this [--add-data <SRC;DEST or SRC:DEST>]. So in your case try
pyinstaller -F --add-data "main.kv;main.kv" yourtarget.py
The solution is to run: pyi-makespec yourscript.py
Then edit the yourscript.spec script and add the files under datas in a= Analysis.
datas=[ ( '/pathToYourFile/main.kv', '.' )]
then run pyinstaller yourscript.spec
should be good after that.
Next -F or --onefile option is assumed when running pyinstaller.
Note that (MacOS Monterey, 12.2 here) the expected folder hierarchy w/in you .app file will be similar to this,
pyinstaller does not add files nor create necessary folders into any of the folders of this folder structure; at least not in any apparent way. You won't find them.
However, when the application runs, a temporary folder is used under /var/folders which is very different from the folder structure in point 1. above. print(os.path.dirname(__file__)) while running the application will reveal which exact temporary folder is used each time it runs. For convenience, let's call it my_app_tmp_folder i.e. your app runs under the folder /var/folder/my_app_tmp_folder
Then, pyinstaller adds data files or creates necessary directories w/in this temporary folder. In other words, when the application runs, all added files will be there and according to the specified folder structure (through --add-data option). print(os.listdir(os.path.dirname(__file__))) will show system and application needed files and folders.
Bottom line: Files specified w/ --add-data option will be visible w/in /var/folder/my_app_tmp_folder when running and not w/in the *.app folder.
Some useful links from documentation:
https://pyinstaller.readthedocs.io/en/stable/runtime-information.html#using-file
https://pyinstaller.readthedocs.io/en/stable/spec-files.html#adding-files-to-the-bundle
https://pyinstaller.readthedocs.io/en/stable/operating-mode.html#bundling-to-one-file
My application had this issue and a subsequent issue that is likely, if not inevitable.
1. --add-data for a kv file
Use --add-data as in the answer by crifan.
2. Kivy still can't find the file
Once PyInstaller has the kv file in the correct directory, Kivy still can't find the file.
Possible Symptoms:
GUI launches, but screen is black and empty.
An AttributeError error that depends on the application code.
AttributeError Examples:
This question
My own case:
AttributeError: 'NoneType' object has no attribute 'ids'
Fortunately, this answer solves the problem.

How do I name the .bowerrc file?

This MEAN-stack tutorial describes using Bower to install AngularJS in your public folder. One of the steps describes creating a file called ".bowerrc" in your test-app folder. However, Windows won't let you create a file without a name. How do I accomplish this on a Windows system?
on the command line (make sure to cd into your working directory), issue this command:
touch .bowerrc
This will also work for other files common to webdev like .htaccess and .gitignore
Note: If you haven't installed git bash for windows, you may not have support for the touch command. In that case (as mentioned in one of the comments here), the easiest way to accomplish this is via the cli with:
echo "" > .bowerrc
To create a file that starts with a "." in Windows, you just need to add a trailing ".".
So, simply name your file ".bowerrc." instead of ".bowerrc".
See https://superuser.com/questions/64471/create-rename-a-file-folder-that-begins-with-a-dot-in-windows for more information and more detailed solution if this doesn't work for you.
Another way to accomplish this is through Notepad++.
Create the file in Notepad++
Set the encoding to "Encoding in ANSI" (click "Encoding" in the menu bar)
Save the file as .bowerrc (change the "Save as type:" to . which is one list item up from *.txt)
Simply rename the file you created:
C:\project> ren bowerrc .bowerrc

Adding a new build rule to parse all rtf files

Xcode includes a flexible build rules system. The documentation is all but non-existant however.
A project I am working on for iOS 5 and iOS 6 includes an rtf help file. For iOS 6, I can convert the rtf file into an archived NSAttributedString object, then load that at runtimeand display it directly to a UITextView. For iOS 5, I can't (without a lot of work in Core Text...) so I want just the text without the style info.
I wrote a command line tool, RTFToData that takes an RTF file as input and generates a .txt file and a .data file (where the .data file contains a version of the styled text that my project knows how to use.)
Here is the syntax of my command line tool:
RTFToData [-o] source_path [destination_path]
-o (optional) overwite existing files
source_path (required) path to source RTF file (must have extension "rtf" or "RTF"
destination_directory (optional.) writes output files to source file directory if no destination specified
destination_directory must exist if specified.
I want to set up my project so that I can add .rtf files as sources (with the "add to target" checkbox NOT checked.) I want Xcode to run my RTFToData command on each file specifying that the output files should be copied into a directory and then added to the target.
Ideally, I'd like the build process to know about the dependencies between my source .rtf files and the processed .data and .txt files. If I touch a .rtf file, I'd like the build process to re-run the rtftodata command.
I am a makefile and unix scripting neophyte. I THINK I can use a run script build rule that will do this, but I am unclear on how. I guess I need to write a script that finds all files of type ".rtf", pipes that list of files into an invocation of my RTFToData.
Can somebody outline the steps I need to take in the Xcode IDE to make my project handle this smoothly?
As a side-note, is there some directory where you can put command line tools so they are available to the current version of Xcode? So far I've been installing the RTFToData command in /Library/usr/bin, but I'd really like the build tool to be included in the project, or at the very least, not have to use sudo to set up every development machine that is used to build this project.
Create a custom build phase
Add the .rtf files to your project and make sure they are added to your target.
Go to your target settings and select the "Build Rules" tab:
Click the "Add Build Rule" button at the bottom.
You want to configure your rule based on something like this:
Enter a standard wildcard glob for the files you want to match (*.rtf).
Inside the script section you can make use of a number of environment variables. Assuming your glob has matched the input file Test.rtf you have access to these vars:
INPUT_FILE_PATH = /path/to/your/project/source/Test.rtf
INPUT_FILE_NAME = Test.rtf
INPUT_FILE_BASE = Test
INPUT_FILE_SUFFIX = .rtf
INPUT_FILE_DIR = /path/to/your/project/source/
You want to process your file and send it to the ${DERIVED_FILES_DIR} directory with whatever new filename or extension you need. In this case we take the base filename from the input and give it a new extension.
Fill out the "Output Files" section with the same output file you used in the script. This will ensure the dependency system works and that the file will be copied to your .app. The script will only be run if the input has changed or the output file is missing from the .app.
Note that the "Output Files" should not have double quotes. The paths will be quoted for you by Xcode.
If your script generates multiple output files, add extra entries for those as well.
Once this is all set up, .rtf files added to your target will be converted to whatever output files your script generates. The original .rtf files will not exist in the final .app.
Where to put scripts/programs
As a side-note, is there some directory where you can put command line
tools so they are available to the current version of Xcode?
Put your tools somewhere below the directory that contains your .xcproject. Then from your build phase/rules use the ${SRCROOT} environment variable, which is the directory containing your project:
Assuming this file system layout:
/path/to/project/project.xcodeproj
/path/to/project/Tools/CommandLineTool
Use this in your build phase/rules:
"${SRCROOT}/Tools/CommandLineTool" "${INPUT_FILE_PATH}" ...
Remember to use double-quotes everywhere you can!

Opening a db/migrate/* file more effectively? Wildcard to complete the beginning of the name of the file?

Working from a bash shell and utilizing vim, I generally have a pretty effective workflow. However, when I attempt to access files in the db/migrate directory of a rails project, it becomes very tedious to access the files as the each contain a long integer at the being of their file names. I've tried vim db/migrate/*name_of_migration.rb but to no avail.
Is there a way to access files via wildcard of in this manor?
If you're using vim-7.3, then you can do this from inside vim:
:set path=/path/to/your/project/root/**
:find migrate/*cr<tab>
and vim will show you the possible candidates for completion.
If you're typing the name of the migration correctly, I assure you that the * will match the leading digits.
For example, from the root of your project,
$ vim db/migrate/*create_users.rb
will open 20111123142812_create_users.rb.
Otherwise, my preferred method is to use
$ vim db/migrate
to "open" the directory in vim, and use the in-vim navigator to select the migration you're interested in from the list of files.

vimrc - current working directory

I would like to be able to access the current working directory in my vimrc.
For example, I can access the current file by using %.
Specifically,
I have the following line in my vimrc:
map ,l :!latex %
When it runs everything works fine, except the resulting dvi and other files are stored in my home directory instead of my current working directory.
Any suggestions?
See :help autochdir. Vim can automatically change the current working directory to the directory where the file you are editing lives.
Otherwise, if you want to do this manually, see :help cd and :help lcd.
see :he filename-modifiers
:!latex % -output-directory %:h
Most likely, you're running vim from your home directory, so it is the current for him. The latex command, being invoked from vim, also therefore has the home directory as current.
You probably know this, and want just to extract path from the filename and supply it as an argument to -o option of the latex command. Just use the shell capabilities:
:!latex % -output-directory `dirname "%"`
I am not sure that it's -output-directory option, but you get what you asked for--a directory name of the file you're editing.

Resources