vim - I'm looking for plugin what adds tabulation inside block - vim

This feature is available in Intelij, and works like this:
I have for example some code (| is a cursor in this example):
|
doSomething();
variable = "foo";
And I'm adding it inside block, for example if:
if (true)
{
doSomething();
variable = "foo";
|
Now after type closing bracket, plugin should add tabulation for code inside block:
if (true)
{
doSomething();
variable = "foo";
}|
I hope I explained how it should work. Is there plugin for this?

In-order to indent a block of code inside {}, you can use =%.
It's just a matter of an insert mode mapping for } to insert }, and run the command =%
It can be done with
:inoremap } }<esc>k :normal =%<cr>

Related

Pass a static string to a macro_rule in rust

I wrote the following code :
macro_rules! my_macro{
("A") => {
println!("Macro called !")
}
}
fn main(){
static test: &'static str = "A";
my_macro!(test);
}
but I have the following error :
error: no rules expected the token `test`
--> test.rt:9:19
|
1 | macro_rules! my_macro{
| --------------------- when calling this macro
...
9 | my_macro!(test);
| ^^^^ no rules expected this token in macro call
error: aborting due to previous error
However, it works fine if I directly call my_macro("A"). Is it possible to fix this ?
Is it possible to fix this ?
No. Macros are expanded at compile time before item names are resolved, therefore your macro has no idea what the value of test is (and would have no idea even if it were a const rather than a static).
so the first problem here is that you macro expects a pattern of "A" not a variable that contains "A"
when you create macros you define certain patterns and follow those patterns in your case your macro must always have "A" in it but it is not a string a it is a pattern of double quote followed by capital a followed by another double quote
If you want to pass a value you should use variable syntax and define what it should expect such as ($a:expr)=>{...}
here you can see all magic tokens possible just scroll down a bit on that docs there are a lot of great examples
PS. here is a macro I use for responding from my endpoints
macro_rules! resp {
(ok) => {
|_| actix_web::HttpResponse::Ok().body(r#"{"success":true}"#)
};
(ok,$data:expr) => {
|_| actix_web::HttpResponse::Ok().json(serde_json::json!({"success":true,"data":$data}))
};
(ok,) => {
|d| actix_web::HttpResponse::Ok().json(serde_json::json!({"success":true,"data":d}))
};
}

Selecting (and deleting) entire function with definition (INCLUDING whitespace) in Vim

I recently switched to using Vim (with VSCode) as my editor.
I'm trying to delete a function with it's definition in JavaScript. I looked on google and here on StackOverflow and found this question. Unfortunately the answers for this question only work for functions without white space.
Here is how my function looks:
const useBattery = () => {
const [battery, setBattery] = useState({ level: 0, charging: false });
const handleChange = ({ target: { level, charging } }) => setBattery({ level, charging });
useEffect(() => {
let battery;
navigator.getBattery().then(bat => {
battery = bat;
battery.addEventListener("levelchange", handleChange);
battery.addEventListener("chargingchange", handleChange);
handleChange({ target: battery });
});
return () => {
battery.removeEventListener("levelchange", handleChange);
battery.removeEventListener("chargingchange", handleChange);
};
}, []);
return battery;
};
I tried several approaches, the best one was da{ when my cursor is within the function. This motion will delete the function body, but not the definition.
Is there any way to delete the function and the definition in one motion using Vim, if there is white space in the function?
From inside the function, as you say da{ deletes only the braces and its content, without the preceding declaration or the following semicolon. However... if we switch to linewise...?
There is a semi-hidden section a bit under :help exclusive-linewise with bold heading but no tag to jump to: "FORCING A MOTION TO BE LINEWISE, CHARACTERWISE OR BLOCKWISE", saying that we can switch to a non-default selection by using v (characterwise), V (linewise) or Ctrl-V (blockwise) immediately after the operator. So...
dVa{
As mentioned in the post you linked to, d]] when the cursor is placed at the beginning of the function definition will delete the whole function.

Distinguish one sub invocation from another

In the following fragment, how can I distinguish the second invocation instance of my sub foo from the first?
while ($whatever) {
foo(); foo(); # foo() and foo() have the same caller package, file, and line
}
Something like a super-caller() that returned file, line and column would do the trick. I'd prefer not to use source filters.
Background, or, isn't this a bit of an XY Problem?
I have a convenience module, Local::Thread::Once, that exposes functionality like pthread_once/std::call_once in an OO-ish way and also as a subroutine attribute. These are easy enough, since there is a natural and unambiguous "once_control" or "once_flag" in either case.
However, there is additionally a procedural interface — once { ... } — that currently serializes based on the $filename and $line returned by caller. Something like this:
sub once(&) {
my $user_routine = shift;
my (undef, $file, $line) = caller;
my $once_control = get_a_shared_flag_just_for_this_invocation($file, $line);
lock($once_control);
if (! $once_control) { $once_control++; $user_routine->(); }
return;
}
That's not precisely how it works — the real one is more efficient — but the point, again, is that invocation is keyed off of the file and line of the caller. This works, except that it cannot distinguish two invocations on the same line.
while ($whatever) {
once { foo(); }
once { bar(); } # OK, foo() and bar() each called only once
once { baz(); }; once { buz(); }; # :( buz() not called, not even once
}
Note that the address of $user_routine cannot be used as an additional discriminant, since subs are copied from one ithread to another.
I can live with this problem as a documented limitation for a very contrived use case, but I'd prefer to fix it somehow.
Devel::Callsite was written precisely for this purpose.
I had to read this a couple of times before I understood what you are talking about. How about a "super caller" function like:
my #last_caller = ("","","",0);
sub super_caller {
my ($pkg,$file,$line) = caller(1 + shift);
if ($pkg eq $last_caller[0] &&
$file eq $last_caller[1] &&
$line eq $last_caller[2]) {
$last_caller[3]++;
} else {
#last_caller = ($pkg,$file,$line,1);
}
return #last_caller;
}
It's like caller but the 4th element is a count of how many times we've seen this exact package, file, and line in a row.
The optree is still so much black magic to me, but here are my observations:
in walking the optree of a code reference, you encounter one B::COP structure
The B::COP structure has file, line, and cop_seq properties (among others)
The cop_seq property is different for different subroutine definitions
Ass-u-me-ing these are true and not a horribly incomplete model of what is happening, you can use file, line, and cop_seq as a key, or maybe even just cop_seq. Here's a proof of concept:
use B;
sub once (&) {
my $code = shift;
my $key = get_cop_seq($code);
print "once called with code '$key'\n";
}
my $optreedata;
sub get_cop_seq {
my $code = shift;
$optreedata = "";
B::walkoptree( B::svref_2object($code)->ROOT, "find_cop_seq" );
return $optreedata;
}
sub B::OP::find_cop_seq {
my $op = shift;
if (ref $op eq 'B::COP') {
$optreedata .= sprintf "%s:%d:%d", $op->file, $op->line, $op->cop_seq;
}
}
sub foo { 42 }
sub bar { 19 };
once { foo }; # this is line 26
once { bar };
once { foo }; once { bar };
once { bar } for 1..5; # line 29
And here's the output (your results may vary):
once called with code 'super-caller2.pl:26:205'
once called with code 'super-caller2.pl:27:206'
once called with code 'super-caller2.pl:28:207' <--- two calls for line 28
once called with code 'super-caller2.pl:28:208' |- with different cop_seq
once called with code 'super-caller2.pl:29:209'
once called with code 'super-caller2.pl:29:209'
once called with code 'super-caller2.pl:29:209' <--- but 5 calls for line 29
once called with code 'super-caller2.pl:29:209' with the same cop_seq
once called with code 'super-caller2.pl:29:209'

Making a command only run in certain cases in Vim

I'm trying to figure out how to get this command to only run in certain cases:
au BufNewFile,BufRead *.js imap <buffer> {<cr> {<cr>}<c-o>O<Tab><Down>;<Up>
Examples:
// No!
if () {
}
// YES!
foo.x = function () {
};
// YES!
var x = {
// NO!
y: function () {
}
};
// YES!
foo(function () {
});
So the pattern would be, NO semi IF it starts with for|switch|if|else|if else (and whatever else) OR if there is a : on the same line.
I really don't even know where to look.
you could try mapping with <expr>.
I wrote a function, which returns the mapping you need with or without the semi. :
fun! Mapping()
return "{\<cr>}\<c-o>O\<Tab>\<Down>".(getline('.') =~# '^\s*for\s\|if\s\|else\s'||getline('.') =~# ':'? '' : ';')."\<up>"
endfunction
then you could add this mapping into your au
inoremap <buffer> <expr> {<cr> Mapping()
note that I didn't put all the keywords in the line, I just added if else for as example. you could add other keywords and test.

How does one return from a groovy closure and stop its execution?

I would like to return from a closure, like one would if using a break statement in a loop.
For example:
largeListOfElements.each{ element->
if(element == specificElement){
// do some work
return // but this will only leave this iteration and start the next
}
}
In the above if statement I would like to stop iterating through the list and leave the closure to avoid unnecessary iterations.
I've seen a solution where an exception is thrown within the closure and caught outside, but I'm not too fond of that solution.
Are there any solutions to this, other than changing the code to avoid this kind of algorithm?
I think you want to use find instead of each (at least for the specified example). Closures don't directly support break.
Under the covers, groovy doesn't actually use a closure either for find, it uses a for loop.
Alternatively, you could write your own enhanced version of find/each iterator that takes a conditional test closure, and another closure to call if a match is found, having it break if a match is met.
Here's an example:
Object.metaClass.eachBreak = { ifClosure, workClosure ->
for (Iterator iter = delegate.iterator(); iter.hasNext();) {
def value = iter.next()
if (ifClosure.call(value)) {
workClosure.call(value)
break
}
}
}
def a = ["foo", "bar", "baz", "qux"]
a.eachBreak( { it.startsWith("b") } ) {
println "working on $it"
}
// prints "working on bar"
I think you're working on the wrong level of abstraction. The .each block does exactly what it says: it executes the closure once for each element. What you probably want instead is to use List.indexOf to find the right specificElement, and then do the work you need to do on it.
If you want to process all elements until a specific one was found you could also do something like this:
largeListOfElements.find { element ->
// do some work
element == specificElement
}
Although you can use this with any kind of "break condition".
I just used this to process the first n elements of a collection by returning
counter++ >= n
at the end of the closure.
As I understand groovy, the way to shortcut these kinds of loops would be to throw a user-defined exception. I don't know what the syntax would be (not a grrovy programmer), but groovy runs on the JVM so it would be something something like:
class ThisOne extends Exception {Object foo; ThisOne(Object foo) {this.foo=foo;}}
try { x.each{ if(it.isOk()) throw new ThisOne(it); false} }
catch(ThisOne x) { print x.foo + " is ok"; }
After paulmurray's answer I wasn't sure myself what would happen with an Exception thrown from within a closure, so I whipped up a JUnit Test Case that is easy to think about:
class TestCaseForThrowingExceptionFromInsideClosure {
#Test
void testEearlyReturnViaException() {
try {
[ 'a', 'b', 'c', 'd' ].each {
System.out.println(it)
if (it == 'c') {
throw new Exception("Found c")
}
}
}
catch (Exception exe) {
System.out.println(exe.message)
}
}
}
The output of the above is:
a
b
c
Found c
But remember that "one should NOT use Exceptions for flow control", see in particular this Stack Overflow question: Why not use exceptions as regular flow of control?
So the above solution is less than ideal in any case. Just use:
class TestCaseForThrowingExceptionFromInsideClosure {
#Test
void testEarlyReturnViaFind() {
def curSolution
[ 'a', 'b', 'c', 'd' ].find {
System.out.println(it)
curSolution = it
return (it == 'c') // if true is returned, find() stops
}
System.out.println("Found ${curSolution}")
}
}
The output of the above is also:
a
b
c
Found c
Today I faced a similar problem while working with each closure. I wanted to break the flow of execution based on my condition but couldn't do it.
The easiest way to do in groovy is to use any() on a list instead of each if you wish to return a boolean based on some condition.
Good ole for loop still works in Groovy for your use case
for (element in largeListOfElements) {
if(element == specificElement){
// do some work
return
}
}

Resources