I am trying to implement a boolean function in Vim and having some trouble and I am sure there is something I'm missing.
Just to be clear, I'm looking to implement a function that when called with ! it will do the opposite.
Vim has plenty of boolean functions, like list and paste. In my case, if I have a function that say, opens a buffer, like:
:call MyFunction()
Then I would like this to close the buffer when is called with a !:
:call MyFunction()!
Not sure if this is even possible, and I am not looking to find out how to open or close a buffer, but the actual boolean implementation.
Edit:
It seems that this is way more feasible if we talk about a user-defined command, like:
:MyCommand action
That can also be called as:
:MyCommand action!
When creating your command, give it the -bang option and then use the <bang>, which will expand to a bang or nothing. Then, to redirect this to your function create a special argument and analyze it to see whether it contains a bang or not. Something like this: (including what ZyX suggested)
function! Bang(bang)
echo "With".((a:bang)?"":"out")." bang."
endfunction
command! -bang Bg call Bang(<bang>0)
Of course, I'm not doing the correct tests here to check if a:bang is really a bang, but you got the idea.
:Bg
Without bang.
:Bg!
With bang.
Related
You can define a function to pass its keyword arguments to inner functions like this:
function example(data;xcol,ycol,kwargs...)
DoSomething(; spec=:EX, x=xcol, y=ycol, kwargs...)
end
Now, the function DoSomething accepts many arguments, such as color. This works for functions, but I'd like to do this with a macro from VegaLite.jl:
function example(data;xcol,ycol,kwargs...)
#vlplot(data=data,mark=:point, x=xcol, y=ycol,kwargs...)
end
example(df,xcol=:Miles_per_Gallon, ycol=:Horsepower, color=:Origin)
Note that the code above does not work.
So the answer here is... it's tricky. And in fact, in general, this isn't possible unless the macro itself supports it.
See, macros do their transformations at parse time — and often will exploit what you've actually written to mean something different and special. For example, #vlplot will specially handle and support JSON-like {} syntaxes. These aren't valid Julia code and can't be passed to a function you define (like example)!
Now, it's tempting to see this and think, ok, let's make that outer example thing into a macro, too! But it's not that easy. I'm not sure it's possible to have a general answer that will always pass the arguments appropriately and get the hygiene correct. I'm pretty sure you need to know something about how the macro you're calling handles its arguments.
you need to add ; before kwargs to signal they are kwargs not positional arguments e.g.:
DoSomething(;spec=:EX, x=xcol, y=ycol, kwargs...)
(this is the answer for DoSomething being a function as this was the original formulation of the question)
So I've been Googling function arguments and I would like to understand arguments better.
I am new to as3, to summarize arguments with my current knowledge, I would say they are like temporary variables? I don't fully get why you add parameters which are names that can be any value? Then you like call these parameters later and their order magically replace these parameters, but why? I'm missing some understanding here to fully grasp their use. Why make parameters in a function and then add the values later? If I'm even saying that right.
function name( applepie, sugar, healthyfood)
name( 1,2,3)
What was the point?
Also I haven't found a syntax book that describes what every symbol does yet that I can just search like () and it describes it, I heard some just use Google, but the results I got weren't very fruitful. Hence why I'm here asking. Personally I don't want to continue on until I fully grasps the use of (). I also tried Adobe website search but that didn't work out well either, was a good amount of searches trust me....
A function is a piece of code that can be reused many times in different contexts. You pass arguments to a function to tell the function something about the context in which it is being called; as a trivial example, when you call the print() function you must specify what you want the function to print. In your example name(applepie, sugar, healthyfood) the function should use the value supplied in place of each argument somewhere in its body, because the function doesn't know what values it will be passed, in the body of the function definition you use the names you chose (which should be descriptive) to refer to the values which will be passed in later and which will presumably be different each time it is called.
The parentheses are used for delimiting different semantic elements, in this case they are telling the interpreter where the argument list starts and stops.
First, here the way i'm calling the function :
eval([functionName '(''stringArg'')']); % functionName = 'someStringForTheFunctionName'
Now, I have two functionName functions in my path, one that take the stringArg and another one that takes something else. I'm getting some errors because right now the first one it finds is the function that doesn't take the stringArg. Considering the way i'm calling the functionName function, how is it possible to call the correct function?
Edit:
I tried the function which :
which -all someStringForTheFunctionName
The result :
C:\........\x\someStringForTheFunctionName
C:\........\y\someStringForTheFunctionName % Shadowed
The shadowed function is the one i want to call.
Function names must be unique in MATLAB. If they are not, so there are duplicate names, then MATLAB uses the first one it finds on your search path.
Having said that, there are a few options open to you.
Option 1. Use # directories, putting each version in a separate directory. Essentially you are using the ability of MATLAB to apply a function to specific classes. So, you might set up a pair of directories:
#char
#double
Put your copies of myfun.m in the respective directories. Now when MATLAB sees a double input to myfun, it will direct the call to the double version. When MATLAB gets char input, it goes to the char version.
BE CAREFUL. Do not put these # directories explicitly on your search path. DO put them INSIDE a directory that is on your search path.
A problem with this scheme is if you call the function with a SINGLE precision input, MATLAB will probably have a fit, so you would need separate versions for single, uint8, int8, int32, etc. You cannot just have one version for all numeric types.
Option 2. Have only one version of the function, that tests the first argument to see if it is numeric or char, then branches to perform either task as appropriate. Both pieces of code will most simply be in one file then. The simple scheme will have subfunctions or nested functions to do the work.
Option 3. Name the functions differently. Hey, its not the end of the world.
Option 4: As Shaun points out, one can simply change the current directory. MATLAB always looks first in your current directory, so it will find the function in that directory as needed. One problem is this is time consuming. Any time you touch a directory, things slow down, because there is now disk input needed.
The worst part of changing directories is in how you use MATLAB. It is (IMHO) a poor programming style to force the user to always be in a specific directory based on what code inputs they wish to run. Better is a data driven scheme. If you will be reading in or writing out data, then be in THAT directory. Use the MATLAB search path to categorize all of your functions, as functions tend not to change much. This is a far cleaner way to work than requiring the user to migrate to specific directories based on how they will be calling a given function.
Personally, I'd tend to suggest option 2 as the best. It is clean. It has only ONE main function that you need to work with. If you want to keep the functions district, put them as separate nested or sub functions inside the main function body. Inside of course, they will have distinct names, based on how they are driven.
OK, so a messy answer, but it should do it. My test function was 'echo'
funcstr='echo'; % string representation of function
Fs=which('-all',funcstr);
for v=1:length(Fs)
if (strcmp(Fs{v}(end-1:end),'.m')) % Don''t move built-ins, they will be shadowed anyway
movefile(Fs{v},[Fs{v} '_BK']);
end
end
for v=1:length(Fs)
if (strcmp(Fs{v}(end-1:end),'.m'))
movefile([Fs{v} '_BK'],Fs{v});
end
try
eval([funcstr '(''stringArg'')']);
break;
catch
if (strcmp(Fs{v}(end-1:end),'.m'))
movefile(Fs{v},[Fs{v} '_BK']);
end
end
end
for w=1:v
if (strcmp(Fs{v}(end-1:end),'.m'))
movefile([Fs{v} '_BK'],Fs{v});
end
end
You can also create a function handle for the shadowed function. The problem is that the first function is higher on the matlab path, but you can circumvent that by (temporarily) changing the current directory.
Although it is not nice imo to change that current directory (actually I'd rather never change it while executing code), it will solve the problem quite easily; especially if you use it in the configuration part of your function with a persistent function handle:
function outputpars = myMainExecFunction(inputpars)
% configuration
persistent shadowfun;
if isempty(shadowfun)
funpath1 = 'C:\........\x\fun';
funpath2 = 'C:\........\y\fun'; % Shadowed
curcd = cd;
cd(funpath2);
shadowfun = #fun;
cd(curcd); % and go back to the original cd
end
outputpars{1} = shadowfun(inputpars); % will use the shadowed function
oupputpars{2} = fun(inputparts); % will use the function highest on the matlab path
end
This problem was also discussed here as a possible solution to this problem.
I believe it actually is the only way to overload a builtin function outside the source directory of the overloading function (eg. you want to run your own sum.m in a directory other than where your sum.m is located.)
EDIT: Old answer no longer good
The run command won't work because its a function, not a script.
Instead, your best approach would be honestly just figure out which of the functions need to be run, get the current dir, change it to the one your function is in, run it, and then change back to your start dir.
This approach, while not perfect, seems MUCH easier to code, to read, and less prone to breaking. And it requires no changing of names or creating extra files or function handles.
I'm having a problem with my code and I don't know what's up, I've searched online and the _Gx method was suggested as the best way over ones like loadstring(x)... although I would be happy with either, can't get either one to work. What I want to do is, in ComputerCraft, send a function name and argument to a turtle, which I'm doing by saving both values to a table and sending across the table, and then on the turtle's program, have a big list of functions, and using a command, call them from the string sent and insert the arg as well. My error is "attempt to call nil", which I don't quite understand why it's saying that... Thanks in Advance!
EDIT
I've edited my code down, as asked, to show that even stripping all else away, this still fails. I could even strip it down even more by taking the variable completely out, and putting the string straight into the _G. This still fails even doing it like that. I've decided to keep it in because that's how I am actually going to be using it later. Calling the function normally works fine. I'm using version Luaj-jse 2.0.3
function foo ()
print ("HI!")
end
print (_VERSION)
I don't know what rednet is, but it seems like you passes name of function to another Lua VM, which doesn't know anything about this function (this function is absent in that VM's globals table).
So, passing function definition as string and executing it by receiver with loadstring is the only solution.
I'm a big fan of abbrev-mode and I'd like something a bit similar: you start typing and as soon as you enter some punctation (or just a space would be enough) it invokes a function (if I type space after a special abbreviation, of course, just like abbrev-mode does).
I definitely do NOT want to execute some function every single time I hit space...
So instead of expanding the abbreviation using abbrev-mode, it would run a function of my choice.
Of course it needs to be compatible with abbrev-mode, which I use all the time.
How can I get this behavior?
One approach could be to use pre-abbrev-expand-hook. I don't use abbrev mode myself, but it rather sounds as if you could re-use the abbrev mode machinery this way, and simply define some 'abbreviations' which expand to themselves (or to nothing?), and then you catch them in that hook and take whatever action you wish to.
The expand library is apparently related, and that provides expand-expand-hook, which may be another alternative?
edit: Whoops; pre-abbrev-expand-hook is obsolete since 23.1
abbrev-expand-functions is the correct variable to use:
Wrapper hook around `expand-abbrev'.
The functions on this special hook are called with one argument:
a function that performs the abbrev expansion. It should return
the abbrev symbol if expansion took place.
See M-x find-function RET expand-abbrev RET for the code, and you'll also want to read C-h f with-wrapper-hook RET to understand how this hook is used.
EDIT:
Your revised question adds some key details that my answer didn't address. phils has provided one way to approach this issue. Another would be to use yasnippet . You can include arbitrary lisp code in your snippet templates, so you could do something like this:
# -*- mode: snippet -*-
# name: foobars
# key: fbf
# binding: direct-keybinding
# --
`(foo-bar-for-the-win)`
You'd need to ensure your function didn't return anything, or it would be inserted in the buffer. I don't use abbrev-mode, so I don't know if this would introduce conflicts. yas/snippet takes a bit of experimenting to get it running, but it's pretty handy once you get it set up.
Original answer:
You can bind space to any function you like. You could bind all of the punctuation keys to the same function, or to different functions.
(define-key your-mode-map " " 'your-choice-function)
You probably want to do this within a custom mode map, so you can return to normal behaviour when you switch modes. Globally setting space to anything but self-insert would be unhelpful.
Every abbrev is composed of several elements. Among the main elements are the name (e.g. "fbf"), the expansion (any string you like), and the hook (a function that gets called). In your case it sounds like you want the expansion to be the empty string and simply specify your foo-bar-for-the-win as the hook.