C++ Application using TCL API to enable package autoloading - c++

I want to have my C++ application to enable package autoloading for all ActiveTcl packages in C:\Tcl\lib. I pass below tcl command to Tcl_Eval() in my C++ code. And expect "package require <package name>" will automatically find the package and load it.
set ::auto_path [file join {C:\Tcl\lib}]
But it didn't work as what it does in TCL shell - TCL shell looks for pkgIndex.tcl in auto_path, so when "package require", it can find the right package or shared libs. Is it possible to make it work in C++ application? Or is there any better way?

OK, I think I know what the problem might be. The auto_path is a Tcl list of directories — the code that uses it iterates over the list with foreach — that are searched for packages (and auto-loaded scripts, an old mechanism that I think is rather more trouble than it's worth). Yet you're using a single element, the output of that file join. This wouldn't usually matter on platforms other than Windows, as the directory separator is / there (and that's just an ordinary non-whitespace character to Tcl) but on Windows the directory separator is \ and that's a list metasyntax character to Tcl.
What does this mean? Well, after:
set ::auto_path [file join {C:\Tcl\lib}]
We can ask what the things of that list are. For example, we can print the first element of the list…
puts [lindex $::auto_path 0]
What does that output? Probably this:
C:Tcllib
OOooops! The backslashes have been taken as quoting characters, leaving an entirely non-functioning path. That won't work.
The fix is to use a different way to construct the auto_path. I think you'll find that this does what you actually want:
set ::auto_path [list {C:\Tcl\lib}]
Though this is an alternative (still using list; it's best for trouble-free list construction in all cases):
set ::auto_path [list [file normalize {C:\Tcl\lib}]]
(My bet is that you're trying to use file join as a ghetto file normalize. Don't do that. It's been poor practice for a long time now, especially now that we have a command that actually does do what you want.)

Related

List only files but not directories using list.files

How can I list only files, but not directories using list.files (not recursively)? It has an include.dirs argument, but this is ignored when not being used recursively.
I had been thinking something like
list.files(path=myDir, pattern="[^/]$")
but that doesn't seem to work, or a few variations on it. Is there a regex that I can plug in here or a function. I know I can do list.dirs and take a setdiff, but this is already slow enough, I want this to be quicker.
PS: currently on linux, but need something that works cross-platform.
PPS: file.info is really slow, so I think that is also not going to work.
PPPS: It doesn't need to be list.files, that is just the function I had thought should do it.
Consider this regex pattern that matches any file containing letters or numbers and contains the dot extension (to leave out subdirectories but unfortunately files without extensions):
# WITH ANCHORING
files <- list.files(path, pattern=("[a-zA-Z0-9]*[.][a-zA-Z0-9]*$"))
# MATCHING LETTER AND/OR NUMBER FILES WITH EXTENSION
files = list.files(myDir, pattern=("[a-zA-Z0-9]*[.]"))
# WILDCARD FILE MATCHING WITH EXTENSION
files = list.files(myDir, pattern=("*[.]"))
Some other regex variations to catch files with periods (note these also get directories with periods and miss files with no extensions)
list.files(pattern="\\..+$")
list.files(pattern="\\.[[:alnum:]]+$")
And using system2 with ls seems to work pretty well (thanks #42- as well from comments),
system2("ls", args=c("-al", "|", "grep", "^-"))
should get only regular files (including ones without extensions), or
system2("ls", args=c("--classify"))
should return files with directories having a "/" appended so they can be determined.
For an alternative open-source solution, consider the Python solution that allows you to condition if item is a directory and using os.path.join() is agnostic to any OS platform.
import os
files = [f for f in os.listdir(myDir) if os.path.isfile(os.path.join(myDir, f))]

How to search files in windows file explorer with specified extension name?

We can search files in windows 7 or higher version using the following tool:
(I don't have image uploading privilage. I mean the top-right area in windows file explorer.)
When I search for MATLAB files using "*.m", it not only returns *.m files, but also returns *.mp3, *.mp4 files. Is there any way to show *.m files exclusively?
Thanks!
I assume you used the quotation marks here to show the text you typed, because ironically the exact way how it should work is to put the search in quotation marks...
so
*.m
finds .mp3 as well as .m but
"*.m"
should only find the .m files. Alternatively you could also write
ext:".m"
which would guarantee that only extensions are searched. (Although I am not sure if this is ever necessary here, because while windows can have a dot in the filename and also can have files without extensions I am not sure if it is possible to have both at the same time.)
using the following
"*.m"
will solve your problem.You can find more information on regex to be used in msdn in the following link .Advanced query syntax
Above that, you can also take advantage of the wildcard character *.
For example, if you want to search for a file with a name ending with 024 or starting with 024 then you can put in the search box like *024.* or 024*.* respectively.
Here the * after . represents files with any extensions, if you want particular then mention extension line 024.png.
Explorer don't have a function of finding with RegEx.
You need to use Power-Shell instead of Win Explorer;
for example: where '(?i)Out' is a regex
Get-ChildItem -Path e:\temp -Recurse -File | Where-Object { $_.Name -match '(?i)Out' }
alternatively you can just simply search for your extension like this:
.extension
eg:
typing .exe will give you all the files with .exe extensions in a folder.
PS: Typing .xml OR .vmcx will give you both type of files. It is useful if you seek to make an archive of different kinds of files stored in different folders or locations.
You can get close to proper regex support from the mostly awesome Cygwin, and as a bonus you get most every linux tool running natively on linux. But it still doesnn't know that .* means "zero or more of anything", ^ means the start of a line (and $ the end), so some things are still weird.
And a startlingly large bunch of weird corner cases that only deranged perl programmers notice fail the test.
So many other things it gets wrong, but it's more workable than anything in any windows OS, plus you get perl, grep, diff, wget, curl, etc. -- the whole GNU lib for free.
If you want a full on bash shell with proper respect for regex, install the super neet-o Bash for Windows 10
Either will do what you want. And they're a billion times faster than that stupid search bar that takes off at 100 mph then crawls to 1 pixel per 10 minutes near the end.

How to get the list of all installed color schemes in Vim?

Is there a way to get a list of all installed color schemes in Vim? That would make very easy to select one without looking at the .vim directory.
Type
:colorscheme then Space followed by TAB.
or as Peter said,
:colorscheme then Space followed by CTRLd
The short version of the command is :colo so you can use it in the two previous commands, instead of using the "long form".
Just for convenient reference as I see that there are a lot of people searching for this topic and are too laz... sorry, busy, to check for themselves (including me). Here is a list of the default set of colour schemes for Vim 7.4:
blue.vim
darkblue.vim,
delek.vim
desert.vim
elflord.vim
evening.vim
industry.vim
koehler.vim
morning.vim
murphy.vim
pablo.vim
peachpuff.vim
ron.vim
shine.vim
slate.vim
torte.vim
zellner.vim
You can see the list of color schemes under /usr/share/vim/vimNN/colors (with NN being the version, e.g. vim74 for vim 7.4).
This is explained here.
On the linux servers I use via ssh, TAB prints ^I and CTRLd prints ^D.
If you are willing to install a plugin, I recommend https://github.com/vim-scripts/CycleColor.
to cycle through all installed colorschemes. Nice way to easily choose a colorscheme.
Looking at my system's menu.vim (look for 'Color Scheme submenu') and #chappar's answer, I came up with the following function:
" Returns the list of available color schemes
function! GetColorSchemes()
return uniq(sort(map(
\ globpath(&runtimepath, "colors/*.vim", 0, 1),
\ 'fnamemodify(v:val, ":t:r")'
\)))
endfunction
It does the following:
Gets the list of available color scheme scripts under all runtime
paths (globpath, runtimepath)
Maps the script paths to their base names (strips parent dirs and
extension) (map, fnamemodify)
Sorts and removes duplicates (uniq, sort)
Then to use the function I do something like this:
let s:schemes = GetColorSchemes()
if index(s:schemes, 'solarized') >= 0
colorscheme solarized
elseif index(s:schemes, 'darkblue') >= 0
colorscheme darkblue
endif
Which means I prefer the 'solarized' and then the 'darkblue' schemes; if none of them is available, do nothing.
Here is a small function I wrote to try all the colorschemes in $VIMRUNTIME/colors directory.
Add the below function to your vimrc, then open your source file and call the function from command.
function! DisplayColorSchemes()
let currDir = getcwd()
exec "cd $VIMRUNTIME/colors"
for myCol in split(glob("*"), '\n')
if myCol =~ '\.vim'
let mycol = substitute(myCol, '\.vim', '', '')
exec "colorscheme " . mycol
exec "redraw!"
echo "colorscheme = ". myCol
sleep 2
endif
endfor
exec "cd " . currDir
endfunction
If you have your vim compiled with +menu, you can follow menus with the :help of console-menu. From there, you can navigate to Edit.Color\ Scheme to get the same list as with in gvim.
Other method is to use a cool script ScrollColors that previews the colorschemes while you scroll the schemes with j/k.
i know i am late for this answer but the correct answer seems to be
See :help getcompletion():
:echo getcompletion('', 'color')
which you can assign to a variable:
:let foo = getcompletion('', 'color')
or use in an expression register:
:put=getcompletion('', 'color')
This is not my answer, this solution is provided by u/romainl in this post on reddit.
A great solution, and my thanks to your contributors. For years I've been struggling with a totally crappy color scheme -- using SSH under Windows Vista to a Redhat system, terminal type xterm.
The editor would come up with a black background and weird colors for various keywords.
Worse -- that weird color scheme sticks in the xterm terminal after leaving Vim.
Really confusing.
Also, Backspace failed during an insert mode, which was nasty to remember -- though Delete did the same thing.
The cure --
In the SSH monitor, select Edit/Settings.
a. Choose Profile Settings/Colors
b. check 'enable ANSI colors'
c. The standard Text colors are probably OK
Add these lines to $HOME/.vimrc:
colorscheme default
if &term == "xterm"
set t_kb=^H
fixdel
endif
NOTE: the ^H MUST be typed as ctrl-V ctrl-H. Seems peculiar, but this seems to work.
Try
set wildmenu
set wildmode=list:full
set wildcharm=<C-z>
let mapleader=','
nnoremap <leader>c :colorscheme <C-z><S-Tab>
in your ~/.vimrc.
The first two lines make possible matches appear as lists. You can use either or both.
The fourth line makes leader , instead of the default \.
The last line allows you to simply type ,c to get a list and a prompt to change your colorscheme.
The third line effectively allows for Tabs to appear in key maps.
(Of course, all of these strategies I've learned from the internet, and mostly SO, very recently.)
Another simpler way is while you are editing a file - tabe ~/.vim/colors/ ENTER
Will open all the themes in a new tab within vim window.
You may come back to the file you were editing using - CTRL + W + W ENTER
Note: Above will work ONLY IF YOU HAVE a .vim/colors directory within your home directory for current $USER
(I have 70+ themes)
[user#host ~]$ ls -l ~/.vim/colors | wc -l
72

Path and string chopping in Powershell

I'm doing some work involving some automated file moving, and these files contain relative paths that must be maintained. Unfortunately, I'm finding the facilities offered by System.IO.Path, System.String, and Powershell's operators to be a little ill-equipped to handle my work gracefully.
One function that would be very useful to me is the notion of a subtraction of paths, that would work in theory like subtracting vectors. Conceptually, A - B gets you a path from B to A. In the application to paths, D:\A\B\C\D - D:\A\B\ = \C\D. Likewise, D:\A\B\ - D:\A\B\C\D = \..\.. in this case. I can accept, for now, that this only makes sense when one path is wholly contained in the other.
This seems to consist of two steps: 1) determine containment of one path in the other. 2) remove the contained path from the containing path. 3) Optionally, replace folder names with the parent .. symbol based on the sidedness of the operation.
As I am concerned with NTFS, I need both containment and replacement operations to be case-insensitive. For containment, I can use select-string since it is case-insensitive, and allows the -simple switch which allows me to use a path without hacking it apart to escape them for regex.
Removing the string from the other is a little more annoying though. System.IO.Path has nothing for this, System.String's pertinent methods are all case-sensitive, and powershell's operators all require massaging so that the regex will match things.
All this seems like more work than it should be--are there any tools I'm missing that would better handle this?
Determine containment - convert your paths to absolute paths (if not already). You can use Resolve-Path for this. Then you can use $path1.StartsWith($path2, 'OrdinalIgnoreCase') to test for containment.
Remove contained path - $path1.Substring($path2.length)
Replace parent folder names with ... - although I don't have the regex off the top of my head, I'm pretty sure you could do this with a regular expression search/replace using PowerShell's -replace operator
filedirectorypath, on CodePlex, may offer what you need
It's not a PowerShell specific API, but that's no reason not to use it from PowerShell.
Benefits of the NDepend.Helpers.FilePathDirectory over the .NET Framework class System.IO.Path include:
Strongly typed File/Directory path.
Relative / absolute path conversion.
Path normalization API
Path validity check API
Path comparison API
Path browsing API.
Path rebasing API
List of path operations (TryGetCommonRootDirectory, GetListOfUniqueDirsAndUniqueFileNames, list equality…)

white space free path to My Documents

In building a C++ project with the GNU tool chain, make tells me ~
src/Adapter_FS5HyDE.d:1: *** multiple target patterns. Stop.
Search, search, search, and I found out that make thinks that it has multiple targets because the path to my included headers has spaces in it. If you've got your headers stored in some sane place like C:\Program Files then you can take care of this by using the old DOS paths (e.g. C:\PROGRA~1). However, when you have your headers in a truly insane place like My Documents you can get around the problem with MY DOC~1 because there's still a space.
Any idea how to tell my compiler to look in My Documents for headers without make confusing the path as two objects?
(Note: Feel free to throw tomatoes at me for putting header files in My Documents if you'd like, but there is a little rationale for doing that which I don't feel like explaining. If the solution to this question is easy, I'd rather keep it the way it is.)
You can figure out what the old path is by doing a DIR /X in your command prompt.
Or, most of the time you can fake it with the first 6 characters - spaces + ~1 + extension (8.3 paths won't have spaces).
Or, you can use quotes: "C:\Documents and Settings\Administrator\My Documents".
I don't know about make specficially, but the normal way around this is to put quotes around the path i.e.
cd "C:\Program Files\"
does that work?
Side note: the short name (8.3) for the same folder might not be the same on different OS installations. Thus, you can't be sure that C:\Program Files will always be C:\PROGRA~1.
Short names can't contain spaces in them either, so the usual short name for My Documents is MYDOCU~1, not MY DOC~1.
You can find the exact short name for any folder or file (including My Documents) using dir /x <filename>.
If you are using the GNU toolchain from Windows command line (cmd.exe), you should be able to use quotes (") around the folder/file names to work around this problem.
For some folders, including My Documents, you can specify an alternative location. To do this, right-click the folder, select Properties, select Location tab, and away you go. I use this to put my downloads and music on another drive (D:).
Write a wrapper script (e.g. batchfile) to translate the path names to short form.
I have a script "runwin" that does stuff like this - instead of, e.g. gcc <args> I can call runwin gcc <args>;
runwin will make heuristic guesses as to which arguments are filename paths and translate them, then call gcc on the resulting string of arguments.