How to change the project used by Indexer during a Vim session? - vim

I'm trying to use Indexer (vimscript #3221) to index the files of a specific project created with project.vim (vimscript #69). As the plugin's documentation says, if I don't set the g:indexer_projectsSettngsFilename variable in ~/.vimrc, it uses ~/.vimprojects file by default. But I want to be able to specify the project without setting that variable in ~/.vimrc (i.e., I want to do it in a more local way).
I tried to set g:indexer_projectsSettngsFilename in _vimrc_local.vim, setting it manually after Vim is started, re-source the plugin (by running :so) once the variable has been set, run :IndexerRebuild afterwards. In either case the plugin does not create the index file for the project.
So how can I make Indexer to change its project during a Vim session?

The Indexer plugin has a dependency: Vimprj, which manages options for different projects: exactly what you need.
The Indexer repository has some examples under doc/examples directory. Check, for example, doc/examples/vimprj_indexer_files.
In short, in the root directory of your project, you need to create the .vimprj directory, and after this, when you open some file under your project directory, all .vimprj/*.vim files will be sourced, and $INDEXER_PROJECT_ROOT variable will be set to the path of your project (which is one level above the .vimprj dir).
I usually put my .indexer_files in .vimprj directory too, and refer to it from .vimprj/my.vim file like this:
" get path to ".vimprj" folder
let s:sPath = expand('<sfile>:p:h')
" specify our ".vimprj/.indexer_files"
let g:indexer_indexerListFilename = s:sPath.'/.indexer_files'
And I can refer from .indexer_files to $INDEXER_PROJECT_ROOT like this:
[my_project]
option:ctags_params = "--langmap=c:.c.h --languages=c"
$INDEXER_PROJECT_ROOT
For more information, see the article: Vim: convenient code navigation for your projects, which explains the usage of Indexer + Vimprj thoroughly.

Related

How do I use one .env as the source of truth

I am creating a build system for development purposes for the FreeCAD application. Repo is here if you want to get a better scope of what I'm talking about.
Essentially the folder structure is:
(Main)
(Linux)
(Ubuntu)
ubuntu.sh
ubuntu.Dockerfile
(Fedora)
fedora.sh
fedora.Dockerfile
(Windows)
(Mac)
.env
What I want to do is use the env variables in .env as a central source of truth for all the build scripts in the tree. But I don't want to have to explicitly define the path of the .env inside the files, absolute or relative paths, as I'm still iterating and I don't want to update all the files if I rearrange the tree. Alternatively, I don't want to put independent .env's in all the child dirs for the same reason (unless they auto update somehow)
My question is as follows:
How do I just explicitly define the "local" path of .env in each script, Dockerfile, etc but only have to modify one top level .env file to auto-update an evolving tree. In a cross platform way
Some things I thought through:
Windows uses "hard links" which are equivalent but non compatible with POSIX hardlinks. I thought about creating windows.env and posix.env in each child dir that point to the same main .env. But most config files can only take one .env path argument.
I thought about writing a script that will update all the .env's when run (would rather not have to), or alternatively, I will accept an answer that uses some dotenv tooling to accomplish the same goal as long as it's cross-platform, and runs locally. I'm just not super familiar with those toolings. I would prefer the tooling or script run as a service and not have to be run everytime in order to update the files.
IF I'm using Git AND only referring to shell scripts, then a command at the top of the script such as . /$(git rev-parse --show-toplevel)/.env works well but has major limitations for use with dockerfiles and other yml based file types.
I currently use a run.sh file at the top level dir that sources the .env and then calls the other files within it. This seems to be the most used pattern I see in other repos. But this means I need to have two files run.sh and run.pwsh which just seems extranuous and hacky to add extras files that are basically one liners.

PTC Integrity batch update member revision

Is there a way to update the member revision of a big list of files via command line?
I can't use :working or :head but have to specify a different revision for each file.
As far as I know --selectionFile only takes paths as input, but not the revision numbers.
edit: I wanted to set member a very big list of files and I wanted to avoid writing the command si updaterevision ... for every file, as it takes ages to complete for that many files. Instead I wanted to know if there is a more advanced method to specify a list of files and their revisions to be able to run the updaterevision only once (like it is with :working) for the whole list of files.
But as it is said in the comment there is no such possibility.
edit2: I use MKS for a couple of years now and as I now know, there is no such possibility (at least up to MKS 11.6) to update many files to different revisions with one single command line call. But using one call per member, as was proposed, made the whole operation take up to several hours as I had many thousands of members in the sandbox and MKS needs some time to complete each sicommand.
Some time already passed since you asked for this question, here is my comment in case it could still be useful for you in the future.
First, It is not completely clear what you want to achieve. Please be more descriptive and if possible provide example.
What I understand as of now is you need to set bunch of files listed as member revision thru the command line. This is fairly simple, the most complicated is actually to have the list of files to be updated to member and the revision that you want to set as member.
I recommend you to create a batch file with the commands to make each file member. You can use Regex to do it very quick and without much trouble.
Here is an example for updating one file member revision:
si updaterevision --hostname=servername --port=portnumber --user=username --changepackageid=5873763:2 --revision=:working myfile_a1.c
where
servername = the name of the server where your sandbox is located
portnumber = the port that provides access to the server for your sandbox
username = your login user id
changepackageid = here you change the number to use your defined TASK:ChangePackage for this changes
revision = if you have a working revision that you want now to become member, just use "working" as revision, otherwise you can define specific revision number, e.g. revision=1.2
At the end you define the name of the file you want to update.
Go to you sandbox root folder, open CMD window, and run the batch file. It will execute each line applying your changes.
If you have a list of files with the revision you want as member, you can use REGEX to convert it into a batch file.
Example list of files in text file:
file1.c 1.10
file3.c 1.19
sec_file1.c 1.1.2.1
support.h 1.7
Use notepad++ or other text editor with regex support and run this search:
Once you know which regex apply, you can now use it in the notepad++ to do a simple search and replace:
Search = ([\w].[\D])\s+([\d.]+).*
Replace = si updaterevision --hostname=servername --port=portnum --user=userid --changepackageid=6123933:4 --revision=\2 \1
\1 => FileName
\2 => File revision
See image below as example:
Finally just save doc as batch file and run it.
Just speculating that if you have a large list of members along with the member revision you want to update to, then you also have an sandbox that served you to generate this list.
If so my approach would be
c:\MySandbox> si updaterevision --recurse --revision=:working
If your member/revision list come from a development path you could first have a sandbox targeting that devpath, resync, (close thesandbox if opened in gui), retarget the sandbox to the destination devpath (or mainline) you want and then issue the command above.
For an single member approach I would use 'si rlog' to generate a list of si-commands directly
si rlog -R --noheaderformat --notrailerformat --revision=:working --format="si updaterevision {membername} --revision={revision}\r\n" > updaterevs.bat.txt
Review updaterevs.bat.txt rename it to updaterevs.bat and ecxecute it.
(Be careful if using it on other sandboxes)
Other interesting readings here might be the "snapshot sandbox" feature,
checkpointing in general and variants rsp. devpaths.
Using only these features might be politically more correct in the philosophy of Integrity.

Change .eclipse folder in Linux

How can I change the .eclipse folder in Linux? I tried adding this line:
-Dosgi.configuration.area=/directory/directory1/eclipse/.eclipse
at the top of eclipse.ini but it doesn't work. I've also tried adding it to various other places in the eclipse.ini but still no luck.
Edit
I have added this line:
-Dosgi.configuration.area=file:/directory/directory1/eclipse/.eclipse
immediately below -vmargs. When Eclipse starts, it now reads from the correct .eclipse location and if .eclipse does not exist there, it creates it. Unfortunately, after Eclipse has loaded, another .eclipse folder is created in my home folder and Eclipse then continues to read from that folder. I suspect that my eclipse.ini file is now correct but there is another file I need to change.
The simplest thing to do is probably pass java a different user.home so that all the other myriad of places that derive a location base it off of user.home. So instead of what you have, use this in .ini file:
-Duser.home=/directory/other/here
In addition to .eclipse, you will probably find other directories created in your overridden user.home, such as .p2, .oracle_jre_usage, etc.
Other notes:
-Dosgi.configuration.area is the changes the configuration area for Eclipse, it does not effect user area. You also probably don't want to change that setting away from the default unless you really want multiple configurations (read more below).
Additionally, the normal thing to do would be to use -configuration as an argument to eclipse{.exe} and let eclipse convert it to the appropriate VM argument.
You probably want -user though to override the user area. Have a look at locations in the Eclipse help for more info (quoted below).
However, there are still things that have individual control over their location, such as secure storage, which is controlled by the -eclipse.keyring command line argument.
Locations
The Eclipse runtime defines a number of locations which give
plug-in developers context for reading/storing data and Eclipse users
a control over the scope of data sharing and visibility. Eclipse
defines the following notions of location:
User (-user) {osgi.user.area} [#none, #noDefault, #user.home,
#user.dir, filepath, url]
User locations are specific to, go figure,
users. Typically the user location is based on the value of the Java
user.home system property but this can be overridden. Information such
as user scoped preferences and login information may be found in the
user location.
Install (-install) {osgi.install.area} [#user.home,
#user.dir, filepath, url]
An install location is where Eclipse itself
is installed. In practice this location is the directory (typically
"eclipse") which is the parent of the eclipse.exe being run or the
plugins directory containing the org.eclipse.equinox.launcher bundle.
This location should be considered read-only to normal users as an
install may be shared by many users. It is possible to set the install
location and decouple eclipse.exe from the rest of Eclipse.
Configuration (-configuration) {osgi.configuration.area} [#none,
#noDefault, #user.home, #user.dir, filepath, url]
Configuration
locations contain files which identify and manage the (sub)set of an
install to run. As such, there may be many configurations per install.
Installs may come with a default configuration area but typical
startup scenarios involve the runtime attempting to find a more
writable configuration location.
Instance (-data) {osgi.instance.area}
[#none, #noDefault, #user.home, #user.dir, filepath, url]
Instance
locations contain user-defined data artifacts. For example, the
Resources plug-in uses the instance area as the workspace location and
thus the default home for projects. Other plugins are free to write
whatever files they like in this location.
While users can set any of
these locations, Eclipse will compute reasonable defaults if values
are not given. The most common usecase for setting location is the
instance area or, in the IDE context, the workspace. To run the
default Eclipse configuration on a specific data set you can specify:
eclipse -data c:\mydata
You must put property definitions like this at the end of the eclipse.ini after the -vmargs line. If there is no -vmargs line you must add one.
So:
.... other lines ....
-vmargs
... other arguments
-Dosgi.configuration.area=/directory/directory1/eclipse.eclipse

Qt Installer framework - Copying files to location other than install directory

I know that, whatever data is placed in package/component dir/data, will be copied to the install directory. What I mean is if I have a binary, readme, license.txt inside package/component dir/data/myapp, package/component dir/data/readme, package/component dir/data/license.txt and if I choose my target installation dir to be “/opt/myfirstapp”, then inisde /opt/myfirstapp, I will have 3 files copied, myapp, readme, license.txt.
Having said that, I also have a “/usr” directory with in package/component dir/data/, however this is not the standard “/usr” which will be inside root “/”, it is just a replica. Now inside my replica “/usr” I have some directory hierarchy and some files, like /usr/bin/myapp, /usr/lib/libmyapp.so, /usr/share/icons” and many more, infact a lot. Now I want the replica “/usr” content to be copied to “/usr” (the original usr inside root folder). I should also make sure that I just add new contents to “/usr” (root /usr), but delete any existing content.
Question is clear, some files inside my data directory will have to go to target install dir, but some selected ones (for ex: /usr) will have to be copied to other paths. How do I achieve this.
Currently we have the same problem in my company: we need 2 target directories, one for the exe and one for the libraries (well, it's a bit more complex but in few words...).
After having spoken with Qt support and got the answer that it's actually not possible ("It is possible only after extracting. After extraction, you can use copy or move operation, unfortunately there is currently no other way.") I decided to use the AdminTargetDir as the second target directory. This because there's no other way to pass dynamic variables to the IFW. So after installation I call a "finalizeInstall_patch.bat" file passing the TargetDir and AdminTargetDir and this will move the libraries directory from TargetDir to AdminTargetDir. Why a .bat patch file ? because it's actually not possible to move a directory using the methods provided by the IFW. Qt support just opened a suggestion-ticket for our problem: https://bugreports.qt-project.org/browse/QTIFW-595
I hope that this answer will help others having same similar problems.
NOTE: There is a way to move a directory (on Windows), calling addOperation("Execute", "cmd /C move source dest...") but this brings to other problems out of topic here.
This worked for us (Qt Installer, macOS):
var args = ["cp", "-R", "#TargetDir#/MyApp.app", "/Applications"];
component.addOperation("Execute", args);

Where/How to save a preferences file in a *nix command line utility?

I am writing a small command line utility. It should hopefully be able to run on OSX, UNIX and Linux.
It needs to save a few preferences somewhere, like in a small YAML config file.
Where would one save such a file?
Language: Python 2.7
OS: *nix
Commonly, these files go somewhere like ~/.rc (eg: ~/.hgrc). This could be the path to a file, or to a directory if you need lots of configuration settings.
For a nice description see http://www.linuxtopia.org/online_books/programming_books/art_of_unix_programming/ch10s03.html
I would avoid putting the file in the ~ directory only because it has gotten totally flooded with crap. The recent trend, at least on ubuntu, is to use ~/.config/<appname>/ for whatever dot files you need. I really like that convention.
If your application is named "someapp" you save the configuration in a file such as $HOME/.someapp. You can give the config file an extension if you like. If you think your app may have more than one config file you can use the directory $HOME/.someapp and create regular-named (not hidden) files in there.
Many cross-platform tools use the same path on OS X as on linux (and other POSIX/non-Windows platforms). The main advantage of using the POSIX locations isn't saving a few lines of code, but saving the need for Mac-specific instructions, and allowing Mac users to get help from the linux users in the community (without any need to translate their suggestions).
The other alternative is to put them in the "Mac-friendly" locations under ~/Library instead. The main advantage of using the Mac locations is basically "Apple says so"—unless you plan to sandbox your code, in which case the main advantage is that you can do so.
If you choose to use the Library locations, you should read About the OS X File System and OS X Library Directory Details in the File System Programming Guide, but here's the short version:
Almost everything: Create a subdirectory with your app's name or bundle ID (unless you're going out of your way to set a bundle ID, you'll get org.python.python, which you don't want…) under ~/Library/Application Support. Ideally you should use APIs like -[NSFileManager URLForDirectory:inDomain:appropriateForURL:create:error:] to get the path; if not, you have to deal with things like localization, sandbox containers, etc. manually.
Anything that can be easily re-created (so it doesn't need to be backed up, migrated, etc.): An identically-named subdirectory of ~/Library/Caches.
Preferences: Use the NSUserDefaults or CFPreferences APIs instead. If you use your own format, the "old" way of doing things is to create a subdirectory under ~/Library/Preferences named with your app's name or bundle ID, and put your files in that. Apple no longer recommends that, but doesn't really recommend an alternative (short of "use CFPreferences, damnit!"); many apps (e.g., Aquamacs) still do it the old way, but others instead pretend they're not preferences and store them under Application Support.
In Python, this works as follows (leaving out the error handling, and assuming you're going by name instead of setting a bundle ID for yourself):
from Foundation import *
fm = NSFileManager.defaultManager()
appsupport = (fm.URLForDirectory_inDomain_appropriateForURL_create_error_(
NSApplicationSupportDirectory, NSUserDomainMask, None, True, None)[0].
URLByAppendingPathComponent_isDirectory_(
appname, True))
caches = (fm.URLForDirectory_inDomain_appropriateForURL_create_error_(
NSCachesDirectory, NSUserDomainMask, None, True, None)[0].
URLByAppendingPathComponent_isDirectory_(
appname, True))
prefs = NSUserDefaults.persistentDomainForName_(appname)

Resources