I'm trying to execute With...End With Statement in the Immediate Window,
but I'm not getting it to work.
So my question is how do you execute multiple line of Code concerning With...End With Statement in the Immediate window?
My code I'm trying to execute in the Immediate window:
With Date_Per_Month.Range("A2:H32")
.Offset(1).Resize(.rows.Count - 1, .Columns.Count - 1).select
end with
Ofcourse it works to write a single line of code like this in the immediate window (but that doesn't answer the question).:
Date_Per_Month.Range("A2:H32").Offset(1).Resize _(Date_Per_Month.Range("A2:H32").Rows.Count-1,Date_Per_Month.Range("A2:H32").Columns.Count-1).Select
Tried to concatenate each code line with ":" at the end of lines but it didn't work.
Any help is highly appreciated.
The immediate toolwindow is essentially a console. You can use it to evaluate expressions without an execution context, or in break mode in the context of the current procedure.
Each "line" can be [almost] any executable instruction, but
You can assign to a variable that doesn't exist...
foo = 42
...and then this identifier exists in the "immediate" context and you can use it in subsequent statements:
?TypeName(foo)
Integer
...until you explicitly reset that context:
End
?TypeName(foo)
Empty
But you can't declare a variable:
Dim foo
A With statement is special: it witholds an object reference, but syntactically it's a block statement that needs to be terminated with an End With token: if you try to type With Sheet1 in the immediate pane, you'll get a compile error saying End With is missing - again because each statement in the immediate pane is a standalone instruction.
We could try to inline it:
With Sheet1 : .Cells(1, 1).Value = 42 : End With
But then we get a weird "invalid watch expression" error:
Regardless of the reason, like declaring variables with a Dim statement, defining a With variable makes no sense in the context of the immediate pane, where the next instruction to run is whatever instruction you happen to hit ENTER on: there's no scope, no sequence of operations - an instruction runs immediately, and that's all: whatever the contents of the immediate pane is, no other instruction will run until you hit ENTER on it.
how do you execute multiple lines of code [...] in the Immediate window?
The answer is, you don't - because the immediate toolwindow has no concept of "lines of code".
Related
in GDB with C++ on LINUX:
How to step until the end of the current statement?
The n (next statement) command performs many steps and one never knows, if one already has reached the end of the current statement (or the beginning of the next).
I'm not talking about curly braces.
I'm talking about executing a single assignment.
How to step until the end of the current statement?
There isn't an easy way to achieve this, so don't put multiple statements on a single line.
If there is a single statement on each line, then next command will do what you want.
I have the following code:
function CSVTableFunc(command)
let cursor = getpos('.')
let l:winview = winsaveview()
normal(ggVG)
execute a:command
call setpos('.', cursor)
call winrestview(l:winview)
endfunction
Basically, what it does is it selects all lines from top to bottom, then executes the command that's passed in the function.
However, before the command is executed, the lines selected before hand are deselected.
What's the thing that I've missed?
Cheers!
A couple problems here.
First, you attempted to use normal(...) as if it's a function. It's not (and if it was, you used it wrong anyway, you'd be missing a call command).
What you actually told Vim was to run the following normal-mode commands:
( - back a sentence
ggVG - roughly, select all text in the buffer
) - forward a sentence
Some experimentation shows this probably actually doesn't cause any problems, but it's wrong, and it could cause problems in other circumstances.
Your bigger problem is that commands don't actually operate on a range unless you tell them to. In visual mode (i.e. when you've selected a range of lines), when you press : you automatically get '<,'> inserted on the command line. This text says "run the command on the visual selection".
Using execute does not automatically insert this range. You'd need to manually put the range at the beginning of the command, if the command supports a range. Since you did not do this, your command only runs with its default range, which is usually the current line. In your case, since you did ggVG before running your command, you probably see the command run on the last line only.
Anyway, you don't need the visual selection. Just use the special range % instead of selecting anything. % means "on every line".
The problem is, some commands may not support a range. For those commands, you will probably need to use a loop, or a :g command, to run the command on each line of interest one by one.
What are the difference between a GOTO and a GOSUB statements in BASIC programming language?
GOTO simply jumps to another line, GOSUB keeps track of where it came from (on a stack, presumably), so when the interpreter encounters a RETURN, it goes back to the last place GOSUB was called.
The other answers provided give a good explanation on how to use GOTO and GOSUB, but there is an important difference in how they are processed. When a GOTO is executed it starts at the top of the instruction set and flips through all the lines of code until it finds the line it is supposed to GOTO. Then if you use another GOTO statement to get back, it again goes to the top of the instruction set and flips through everything until it gets to the next location.
GOSUB does almost the same thing as GOTO, but it remembers where it was. When you use the RETURN statement it just jumps back without first going to the top of the instruction set and flipping through everything again, so it's much faster. If you want your code to run fast you should put your most called subroutines at the top of the stack and use GOSUB/RETURN instead of GOTO.
When you call GOTO the program will jump to the line in question and carry on executing.
If you use GOSUB, it will do the same, however at some point you can code a RETURN statement and the code will return to the line just after the GOSUB.
So GOTO is go to X while GOSUB is go to X but remember where you are now and so you can return later.
Is there a way to set the editing range for a file in Vim so that it will apply to any subsequent command? I'm about to do some major refactoring of a function and I would like to limit all of my changes (substitutions in this case) to just that function. In the past I've just copied the function to a new buffer, made the changes and copied it back to the main file, but I'm hoping there is a more clever way.
I know I can set a mark at the start and end of the function and use the marks for the range of the substitute command and I know I can use visual mode to select the range of lines, do something, use gv to reselect and then do the next command, but both of these methods rely on me remembering to specify the range before each command.
Any other suggestions?
Here is a cool trick with folds:
Fold your whole function.
Perform a substitution, :s/foo/bar/c<Enter>, note the c flag for "confirmation", it's vital when doing refactoring in Vim. The substitution will be applied to every line in the fold. AFAIK, you can run any Ex command that way but I've never used this trick with anything else than :s and :g/:v.
Hit y/n to accept/reject each substitution.
After you accepted/rejected the last substitution the fold goes back instantly to its "closed" state: you don't have to type a range for the next substitution.
GOTO 2
Assuming vim was compiled with +textobjects, you can select the function as a block. So perhaps you are looking for:
va{:s/foo/bar
To replace foo with bar only in the current {} bracketed function. If your functions are not delimted by braces, you could write a function to select the range according to some syntax rules, but perhaps this is good enough for your needs.
Use Narow Region Plugin of vim http://www.vim.org/scripts/script.php?script_id=3075 put them on your vim folder and use like this:
:[range]NR
See this page: https://github.com/chrisbra/NrrwRgn
I have blocks of code that look like:
ICar car = new Car<int>(10);
var result = car.Start(100);
Assert.IsTrue(result.IsValid);
That I want to convert to this:
Assert.IsTrue((new Car<int>(10).Start(100)).IsValid);
I have about 20 of these types of snippets with the exact same format, could this be automated in vim?
Crash course in macros:
Go to ICar in normal mode.
Press qq to start the macro.
Modify the code. Try using word-based movements instead of left/right arrows.
Go to the next snippet, like with /ICar.
Press q again in normal mode to stop recording.
You can then type #q to execute the q macro and reformat one snippet. If it works as expected then type 20#q to execute 20 times.
:%s:^.* = \([^;]\+\);\_.[^.]\+\([^;]\+\);\n\n\+\([^(]\+\)(.*\.\(.*$\):\3((\1\2).\4
Will do it with the exact same format (placement of .s and =, etc are important in the original pattern.
HTH
Macros are the easiest, but another way to do it is with global commands - :g/regular expression/Ex command. For example(not your example - we will get to it later), you can use :g/^\s*ICar/delete will delete all lines starting with ICar(^ is for start of line, \s* is for skipping the tabs and spaces used for indention).
The advantage of this method over macros is that you can use it on a range: go into visual mode, mark the part you want to refactor, and use the global command. Only matches in the marked block will be affected. If you use macros, you need to either press ## over and over again until you clear the block, count the exact number of times you want the macro to run, or set a high number and make the no-match error stop the macro. While the third option is quite easy to execute, it's also quite dangerous - you need to make sure the pattern appears only in the parts you want to refactor - so it won't affects unrelated parts of the code - and that the refactoring removes it - otherwise the macro will run on the same lines over and over again.
The advantage of macros is that they are easier to record. In complex refactoring like yours, the global command you need to run can be very long and complex. A macro to do the same thing is just as long and complex as a global command - but you can see how it works while you record it - much easier than calculating the result in your head while designing the global command.
Luckily, you can enjoy both world!
First you record your macro like cdleonard explained in his answer, with two main differences.
The first one is that the first keystroke in the macro should be ^ or _ - to go to the first non-white-space character in the line(that means you start with qq_ and then record as usual). This will guarantee the macro starts from the right place in the line every time.
The second difference is that you don't need to go to the next snippet in the end of the macro. The global command will take care of that for you.
After you've recorded the macro(I'll assume you recorded it to q) mark all the snippets using visual mode, and type :g/^\s*ICar/norm #q - this will search the marked range for all lines that begin with ICar(possibly with indentation before them) and performs the macro on them. This is assuming everything in the range that begins with ICar - and only those places - are snippets you want to refactor. If you have lines that begin with ICar and you don't want to refactor, or if you have lines that you do want to apply the macro to, but they don't begin with ICar - you will have to modify the regex.