how to understand this vim script? - editor

The following is vim script from a vim plugin:
vim's syntax is a bit strange:
!exists("*s:SetVals"), why their is a starmark before s:?
function!, why there is a ! character?
&iskeyword, is this a variable, if yes, where it is defined?
what is s: and g:, what is the difference between them?
why let should be used? such as let &dictionary = g:pydiction_location, can i change it to be &dictionary = g:pydiction_location?
if !exists("*s:SetVals")
function! s:SetVals()
" Save and change any config values we need.
" Temporarily change isk to treat periods and opening
" parenthesis as part of a keyword -- so we can complete
" python modules and functions:
let s:pydiction_save_isk = &iskeyword
setlocal iskeyword +=.,(
" Save any current dictionaries the user has set:
let s:pydiction_save_dictions = &dictionary
" Temporarily use only pydiction's dictionary:
let &dictionary = g:pydiction_location
" Save the ins-completion options the user has set:
let s:pydiction_save_cot = &completeopt
" Have the completion menu show up for one or more matches:
let &completeopt = "menu,menuone"
" Set the popup menu height:
let s:pydiction_save_pumheight = &pumheight
if !exists('g:pydiction_menu_height')
let g:pydiction_menu_height = 15
endif
let &pumheight = g:pydiction_menu_height
return ''
endfunction
endif

1. !exists("*s:SetVals"), why their is a starmark before
s:?
The asterisk is special syntax for exists function, and it means that we are checking if there's an existing function called SetVals. The option iskeyword could be checked with exists("&iskeyword") and the ex command echo with exists(":echo")
See :h exists(
2. function!, why there is a ! character?
The exclamation point means that the function is to be replaced if it already exists.
See :h user-functions
3. &iskeyword, is this a variable, if yes, where it is defined?
That is a vim option. You can check if it's set with :set iskeyword?
4. what is s: and g:, what is the difference between them?
These define the scope of the following symbol. s: means that the symbol is local to the script, while g: means that the symbol will be global.
See :h internal-variables and for s: see :h script-variable
5. why let should be used? such as let &dictionary =
g:pydiction_location, can i change it to be &dictionary =
g:pydiction_location?
Vimscript is one of the languages that require variables to be declared with a keyword. I don't think there's a way to declare variables more easily than with let.

I can answer on a few of those but i'll start with a general comment inspired by your recent questions.
The answers to most of your questions are laid out very clearly in Vim's awesomely exhaustive documentation. If you are serious about using Vim you must know how to use it. Start with :help and read carefully. It pays. Trust me.
You can find the answer to all these subquestions in :help expression.
!exists("*s:SetVals"), why their is a starmark before s:?
See :help exists().
function!, why there is a ! character?
Without an exclamation mark, Vim won't replace the previous definition if you re-source your script.
&iskeyword, is this a variable, if yes, where it is defined?
That's how you test the value of a vim option in a script. See :help iskeyword.
what is s: and g:, what is the difference between them?
These are namespaces. See :help internal-variables
why let should be used? such as let &dictionary = g:pydiction_location, can I change it to be &dictionary = g:pydiction_location?
No you can't, :let is how you define or update a variable. Get used to it.

See :help eval.txt. It describes most of vimscript syntax.

Related

Environment variables manipulation

When using:
echo "${env.PRODUCT_NAME}"
it will echo:
MyProdName
When using:
echo "${env.MyProdName_Key}"
it will echo:
123456789
I would like to use something as follows:
echo "${env.${env.PRODUCT_NAME}_Key}"
Is this possible? How?
In Bash this is termed as variable in direction
Try using variables to make it further simplified
PRODUCT_NAME=$(echo "${env.PRODUCT_NAME}")
This would assign PRODUCT_NAME=MyProdName
Similarly
MyProdName=$(echo "${env.MyProdName_Key}")
This would assign MyProdName=123456789
Now when you print PRODUCT_NAME value you will get
echo ${PRODUCT_NAME}
MyProdName
And adding '!' variable indirection will give you the value of another variable values
echo ${!PRODUCT_NAME}
123456789
Maybe this will help you somehow:
def env = [
PRODUCT_NAME:'MyProdName',
MyProdName_Key: 123456789,
]
println "${env[env.PRODUCT_NAME+'_Key']}"
env is Map in the example provided but it works in the exactly same way.
Important note, regardless of how you're deriving variables:
There's no need to use string interpolation if the only value in a
string is a variable itself. This just clutters your code.
Instead of:
echo "${env.PRODUCT_NAME}"
you can do:
echo.PRODUCT_NAME.
Additionally you can grab nested object values dynamically using bracket notation
def obj = [a: '1']
echo obj[a] // outputs '1'
Using these put together, you can do:
def prodName = env.PRODUCT_NAME //will set var prodName to "MyProdName"
echo env[prodName + '_Key'] //gets nested field with key "MyProdName_Key"
(Note: this is similar to Opal's answer, hopefully my breakdown helps)

Xcode is throwing me an error in swift

I'm following a tutorial(http://youtube.com/watch?v=xvvsG9Cl4HA 19 min 20sec) and to make his code look neat he puts some on a ew line like this
if let myPlacement = myPlacements?.first
{
let myAddress = "\(myPlacement.locality) \
(myPlacement.country) \
(myPlacement.postalCode)"
}
. But when I try I get an error
unterminated string literal
and
consecutive statements on a line must be seperated by a ';'
but the guy in the tutorial has done it the exact same way. What's going on?
I'm using the latest swift and and latest xcode 7.2 any help would be apreciated
if I write everything on the same line like this
if let myPlacement = myPlacements?.first
{
let myAddress = "\(myPlacement.locality) \(myPlacement.country) \(myPlacement.postalCode)"
}
it works fine though
if I write everything on the same line like this
Well, there's your answer. You are not permitted to break up a string literal into multiple lines as you are doing in your first example. There are languages that permit this, but Swift is not one of them. This is not legal:
let s = "hello
there"
There is no magic line-continuation character which, placed at the end of the first line, would make that legal.
If the window is narrower than the line, the editor may wrap the line, for display purposes; but you cannot put actual line breaks inside a string literal.
You can work around this by combining (concatenating) multiple string literals, if you think that makes for greater legibility. This, for example, is legal:
let myAddress = "\(myPlacement.locality) " +
"\(myPlacement.country) " +
"\(myPlacement.postalCode)"
I look your video tutorial carefully. You have a misunderstanding here.
You must pay attention to the video, the code in this picture is not break lines because he add a return here, it is because his screen is too narrow.
So, the real code is
let myAddress = "\(myPlacement.locality) \(myPlacement.country) \(myPlacement.postalCode)"
Please watch it carefully.
And you may need know first, \ in \(myPlacement.locality) is a escape character, it means to get the value of myPlacement.locality and put in the string.

How do I get lua string match to parse an environment variable string?

I have a config file parser written in lua.
I'd like to detect values that are environment variables and change them with os.getenv.
It's probably a bit ambitious because I can have values like
"a string with an embedded ${VARIABLE} in here"
or
"another string with an env $VARIABLE"
And I should probably allow escaping them with double $$ to allow a literal $.
How do I do this?
This is what I have so far, but it isn't right
local envvar = string.match(value, "%$([%w_]+)")
if envvar then
print("Envvar=", envvar)
value = value:gsub("(%$[%w_]+)", os.getenv(envvar))
end
For example, I can't figure out how to use the %b balance option here to properly match { } combinations. And make them optional. How do I make this work robustly?
In fact, I realise it's probably more complicated than this. What if more than one environment variable was specified?
local text = [[
Example: ${LANG}, $TEXTDOMAINDIR, $$10.00, $$LANG, $UNDEFINED
Nested braces: {{${SHELL}}}
]]
text = text:gsub('$%$','\0')
:gsub('${([%w_]+)}', os.getenv)
:gsub('$([%w_]+)', os.getenv)
:gsub('%z','$')
print(text)
--> Example: en_US.UTF-8, /usr/share/locale/, $10.00, $LANG, $UNDEFINED
--> Nested braces: {{/bin/bash}}

Print the target of an outlink

According to the DOORS Reference Manual, this code will print the source module identification of an inlink:
Object o = current
string srcModName
for srcModName in o<-"*" do print srcModName "\n"
This does work, however what I'm trying to do is print the target module identification of an outlink. I thought simply switching o<- to o-> would do the trick, but it doesn't. Does anyone know why, and how to fix this?
Not sure why that doesn't work but this does:
Object o = current
string tgtMod
Link l
for l in o -> "*" do
{
tgtMod = target(l)
print tgtMod "\n"
}
It doesn't work simply because there is no loop construct with that signature. All you have to work with is what's listed in the DXL Reference Manual.
EDIT: I forgot to mention though that Steve's answer is the way to do it if you just want the name of the target module.

string manipulation in ruby on rails

I have a string of the format,
/d.phpsoft_id=369242&url=http://f.1mobile.com/mobile_software/finance/com.mshift.android.achieva_2.apk
and i need to edit this string using regular expression that the result string should start from http: ie the resultatnt string should be
http://f.1mobile.com/mobile_software/finance/com.mshift.android.achieva_2.apk
please help
For these types of situations, I prefer to go with readily available tools that will help provide a solution or at the very least will point me in the right direction. My favourite for regex is txt2re because it will output example code in many languages, including ruby.
After running your string through the parser and selecting httpurl for matching, it output:
txt='/d.phpsoft_id=369242&url=http://f.1mobile.com/mobile_software/finance/com.mshift.android.achieva_2.apk'
re1='.*?' # Non-greedy match on filler
re2='((?:http|https)(?::\\/{2}[\\w]+)(?:[\\/|\\.]?)(?:[^\\s"]*))' # HTTP URL 1
re=(re1+re2)
m=Regexp.new(re,Regexp::IGNORECASE);
if m.match(txt)
httpurl1=m.match(txt)[1];
puts "("<<httpurl1<<")"<< "\n"
end
str = "/d.phpsoft_id=369242&url=http://f.1mobile.com/mobile_software/finance/com.mshift.android.achieva_2.apk"
str.spl­it("url=")­[1]
Simple Answer
You need to do following
str = "/d.phpsoft_id=369242&url=http://f.1mobile.com/mobile_software/finance/com.mshift.android.achieva_2.apk"
start=str.index('http://')
resultant=str[start,str.length]

Resources