set -x "g++" "/usr/local/gcc-7.1/bin/g++-7.1"
will not work due to non-alphanumeric "++" characters. (Error message: "set: Invalid character “+” in variable name.")
Am I out of luck here or is there a work around? I just switched to fish less than 24 hours ago and not sure if there is a work around for aliasing g++.
Thanks for your time.
The simplest:
alias g++ /usr/local/gcc-7.1/bin/g++-7.1
set doesn't create an alias, it sets a variable.
So set -x g++ something is trying to set a variable called "g++" to the value "something" and export it (the "-x").
Now, you most likely want to do what ridiculous_fish suggested and define an actual alias (or a function - which alias desugars to, or an abbreviation) with alias or function or abbr.
Also, the "+" character isn't allowed in variable names. That's because, while fish could allow it, other shells don't. And since variables can be exported, their names need to be compatible with those (try g++=something in bash - it'll try to run it as a command). See Allowed characters in linux environment variable names for further information.
Related
I would like to create a filter folder, best inside .vim and be able to run a text filter just with one file name:! filter.pl
I put up a Perl text filter to change all special Characters in a LaTeX Math Formula, which is running fine so far - only problem it is running on the whole line not the selected formula, but I can live with it ...
#!/usr/bin/perl -np
use strict;
use warnings;
# this filter transforms all special characters in Mathformular for LaTeX
s/\\/\\backslash /g;
s/([\$\#&%_{}])/\\$1/g;
But to call this filter is cumbersome
: '<,'>!"/Users/username/Library/Mobile Documents/com~apple~CloudDocs/my_vim_cheat_sheet/perl_filter.pl"
Apple put in the path to the iCloud a white space, so I have to put "" around! Where I put a collection of text filters?
Thank you for your answers
marek
You can safely create a subfolder with any name different from ones Vim uses itself (see :h 'rtp'). So this is ok:
:*!$HOME/.vim/filters/perl_filter.pl
Also Vim has a predefined interface for a general purpose filter called 'equalprg'. To make use of it simply set a global-local (i.e. both set and setlocal are meaningful) option equalprg to a fully qualified name of your script. Then hit = in visual mode to apply filter (or ={motion} in normal mode). (Read :h 'equalprg' :h =).
If you need several filters at once, and switching equalprg is not convenient, you can still try different options to reduce typing.
For example, mappings, such as
vnoremap <Leader>f :!/path/to/my/filter<CR>
Then hitting \f (or whatever is your "leader" key set) in the visual mode will result in the executing :'<,'>!/path/to/my/filter (note that the visual selection will be applied automatically).
Another attempt is to set a dedicated environment variable (which will be inherited by all child processes including shell(s). For example,
:let $filters = '~/.vim/filters'
:*!$filters/myfilter.pl
Of course, you can put those set equalprg=... vnoremap ... let $filters=... etc.etc. in your vimrc.
I would like to create a filter folder, best inside .vim and be able to run a text filter just with one file name :! filter.pl
Simply add the script to somewhere within your $PATH. Or, if you really only intend to use that from within Vim, then add that directory to your $PATH in your .vimrc, so you have it available there.
For example, if you'd like to use ~/.vim/scripts for your external Perl or shell scripts, you can use this in your ~/.vimrc:
call setenv('PATH', expand('~/.vim/scripts').':'.$PATH)
After that, you can simply use :'<,'> !filter.pl to run it. And Tab completion will work with the name of the script, type :!fil<Tab> and Vim will complete it to filter.pl, assuming it's a unique prefix.
The snippet above for your .vimrc has one minor issue, that if you :source your .vimrc during Vim runtime, it will keep adding the entry to $PATH multiple times. That doesn't typically break anything, only the entry will become longer, you might run into variable length issues.
You can fix it by checking whether that's present in path or not before updating it, perhaps with something like:
let scripts_dir = expand('~/.vim/scripts')
if index(split($PATH, ':'), scripts_dir) < 0
call setenv('PATH', scripts_dir.':'.$PATH)
endif
But also, about this:
I put up a Perl text filter to change all special Characters in a LaTeX Math Formula
s/\\/\\backslash /g;
s/([\$\#&%_{}])/\\$1/g;
Consider writing that in Vim instead.
In fact, almost the same syntax will work as a Vim function:
function! EscapeLatexMathFormula()
s/\\/\\backslash /eg
s/\([$#&%_{}]\)/\\\1/eg
endfunction
You can call it on a range, with:
:'<,'>call EscapeLatexMathFormula()
Calling it without a range will affect the current line only.
You can also make it into a command, with:
command! -range EscapeLatexMathFormula <line1>,<line2> call EscapeLatexMathFormula()
In which case you can simply use:
:'<,'>EscapeLatexMathFormula
You can use tab-completion for the function and command names (though, of course, you can pick shorter names if you'd like, as well.)
Note that user-defined command names need to start with an uppercase letter. Function names can start with an uppercase letter too (there are more options for function names, but making this global with an uppercase is probably the easiest here.)
I am given a task to transition PL/SQL code to T-SQL.
Can anybody explain what SET DEFINE ON does in sqlplus and most impooirtantly how to translate it to T-SQL (I suppose using sqlcmd as a launcher?)
SET DEFINE is an SQL*Plus command setting the use and prefix for substitution variables. & is the default prefix and SET DEFINE ON resets it to this default and turns on the use of substitution variables.
So this is not a PL/SQL thing but an SQL*Plus thing.
As far as I know there's no such thing as substitution variables for sqlcmd, i.e. there's no equivalent for sqlcmd let alone T-SQL. But I might be wrong there.
'&' appears to be a token of the metalanguage used by SQL*Plus (the client, that is) to activate its "variable substitution" feature. So string literals containing '&' ("Marks & Spencer") tokens may not behave entirely as expected. SET DEFINE apparently serves to control that activation.
I've just noticed a pattern (in git and the CommandLineParser lib for .NET) for verb-style command arguments, and wondering if someone can confirm:
myprog dothis -a "someArg"
-a
--arg
What's the difference between the single-dash-prefix and the double-dash-prefix? Is the single dash prefix always for a single-letter argument specifier, where a double dash prefix always for a "long name" of the argument?
Is there a formal convention somewhere that drives this, or is it a generally accepted informal practice? (or am I just making something of nothing?)
Just curious... the I had never noticed the pattern in git and the CommandLineParser docs are pretty thin and some blog post or another implicated the convention.
(for that matter... what's this style of verb/args even called? I can't seem to find much of anything on it)
From the wikipedia: https://en.wikipedia.org/wiki/Command-line_interface
Option conventions in Unix-like systems
In Unix-like systems, the ASCII hyphen-minus begins options; the new
(and GNU) convention is to use two hyphens then a word (e.g. --create)
to identify the option's use while the old convention (and still
available as an option for frequently-used options) is to use one
hyphen then one letter (e.g. -c); if one hyphen is followed by two or
more letters it may mean two options are being specified, or it may
mean the second and subsequent letters are a parameter (such as
filename or date) for the first option.
Two hyphen-minus characters without following letters (--) may
indicate that the remaining arguments should not be treated as
options, which is useful for example if a file name itself begins with
a hyphen, or if further arguments are meant for an inner command (e.g.
sudo). Double hyphen-minuses are also sometimes used to prefix "long
options" where more descriptive option names are used. This is a
common feature of GNU software. The getopt function and program, and
the getopts command are usually used for parsing command-line options.
There is posix convention and getopt
But it's not always the case, e.g. java and find.
See also:
https://golang.org/pkg/flag/
http://docs.oracle.com/javase/8/javafx/api/javafx/application/Application.Parameters.html
A typical format for command line arguments is:
myApp --myArg=myValue
What if I want to pass in a set of key value pairs through the command line? Something like:
myApp --myList={arg1=val1;arg2=val2;arg3=val3...}
Since there seems to be no standard for this sort of thing, can anyone provide examples from well-used utilities that have this sort of command line argument input? I poked around some man pages but didn't find any.
Edit: I'm wondering both how the input should be formatted and what the help text might look like.
I think it largely depends on how you parse the arguments in your program.
Here are some examples that the programs accept multiple key-value pair values.
man php:
--define foo[=bar]
-d foo[=bar] Define INI entry foo with value bar
man git:
-c <name>=<value>
Pass a configuration parameter to the command. The value given will
override values from configuration files. The <name> is expected in
the same format as listed by git config (subkeys separated by
dots).
For both, one can pass multiple -d or -c arguments to the programs which gives you the ability to supply a list of key-value pairs to the programs.
IMO, it's not a big problem having your own style of accepting lists of key-value pairs for your program as long as it works and is well-documented. :)
P.S.: I think this question would be more appropriate be placed on Programmers Stack Exchange rather than on SO. See here and here.
If the app needs so many arguments, I would use a config file instead of passing them in command line:
myApp --config=file.cnf
This approach has the following advantages:
flexibility - you can have a bunch of configs prepared for different invocations, and just use them,
no problems with quoting - it's always painful if command line arguments have spaces, double quotes, <, >, or other special characters,
simplicity - you control the config file format, it can be for example INI, JSON, XML etc. It's easy to create it and as easy to parse as parsing command line -- if not easier,
security - if any argument may be sensitive, it's not visible from tools displaying command line arguments.
Could you please tell me how to get the file separator of current operating system, for example \ in Windows and / in Unix, in Fortran at run-time.
You can use Fortran 2003 Standard intrinsic procedure GET_ENVIRONMENT_VARIABLE to do something like this. Example:
CHARACTER(LEN=99999) :: path
CHARACTER(LEN=1) :: path_separator
CALL GET_ENVIRONMENT_VARIABLE('PATH',path)
path_separator=path(1:1)
WRITE(*,*)'Path separator is ',path_separator
END
This program will output "/" as a path separator in UNIX or Linux. You could get this from other environment variables as well. Notice that this example is hardwired for UNIX/Linux. You would need a bit different logic to extract e.g. "\" for Windows, but I am not familiar with this system. I vaguely remember from Win95 having something like "c:\.....", so it is likely that in case of Windows you would look for "\" in path(3:3).
Hope this helps.
As far as I know the Fortran standard does not say anything about the file system path separator. The best I can suggest is to define a macro which defines the appropriate separator. For example
#if __unix__
character(len=1), parameter :: path_sep='/'
#elif _WIN32
character(len=1), parameter :: path_sep='\'
#else
#error "path_sep not defined. Set this constant for your system."
#endif
However, on Windows you can use either / or \ as your path separator (try it!) so on most systems there is no need to do anything special with the path separator.
Note that you don't need to determine the path separator at run-time. Since you must recompile your Fortran source for each new system you want to run it on, you just need to ensure that the correct path separator is specified at compile time for each new system (the path separator won't change between runs of your program on the same system).
Using preprocessor macros like those above it the obvious way of doing this: you can just add a new #elif clause for each new system you port your code to. This is alot easier than introducing picemeal solutions which check particular environment variables like the other answers suggest.
In addition the specifying the path separator you may also need to set parameters for other aspects of the operating system environment. For example, the current and parent directory characters (. and .. respectively under Windows and POSIX systems).
Finally, note that the preprocessor defines __unix__ and _WIN32 are widely used macros which indicate which system you are on and one, depending which system you are on, should be set by most compilers. If they are not set you can usually use the flag -D__unix__=1 or -D_WIN32=1 when you are compiling your source to set one of these macros. To preprocess your code using the -cpp (gfortran) or -fpp (ifort) command line options or change your source files extensions from .f to .F or from .f90 to .F90.
Following IRO-bot suggestion, you could make a new environment variable, eg
export DELIMITER='/'
in unix
Now make a corresponding variable in windows, just with '\', and you are good to go.
If you don't want to set a global variable in windows, or doesn't have the rights to do so, put the following in an .bat file
set DELIMITER=\
For more on set, see http://www.ss64.com/nt/set.html
You may have to run the fortran program from CMD when using set.
Finaly put the following in your fortran file
CHARACTER :: delimiter
CALL get_environment_variable('DELIMITER',delimiter)
I rather favor the solution of 4 above, but with one modification:
function delimiter_detect() result(delim)
character(LEN=1) :: delim
character(LEN=258) :: path
integer :: ii, stat_out
call GET_ENVIRONMENT_VARIABLE('HOME',path,status=stat_out)
if (stat_out/=0) go to 999
! xxx path='xx\' ! alternate test
do ii=1, 258
delim=path(ii:ii)
if (delim=='/'.or.delim=='\') return
! ... Note: emacs does not recognize the second delimiter test
enddo
999 continue
write(*,'(1x,a/1x,a/1x,a)') 'Could not obtain home directory path.', &
'Restart program and manually insert path', &
'to folder/directory containing input files.'
stop
end function delimiter_detect
That said, I haven't tested the concept on windows OS.