Calling single/bunch of statements from within VIM on Windows - vim

I am totally new to Vim and just two days into learning it. Like every Vim user I am deeply impressed by the speed boost it has given me.
I create Windows batch(.bat) files with numerous call statements. Usually I run a single call statement with Run prompt and use a .bat file for a set of statements. This is done to ensure that the statements provide desired results. I read that it is possible to run similar scenarios from within Vim. Here are some sample statements which form a part of my batch file:
A single line statement:
call %VT_BATCH_ROOT%\Menu\Sub-menu\Name "Line Geometry" "" "" "OK"
A multi-line scenario:
call %VT_BATCH_ROOT%\Menu\Sub-menu\Command "Yes" "c:\temp\folder\file.ext"
call %VT_BATCH_ROOT%\Menu\Sub-menu\Command "No"
call %VT_BATCH_ROOT%\Menu\Sub-menu\Command "Yes" "" "c:\temp\folder\file.ext" "" "" ""
Can someone suggest me how can my requirements be achieved?

I'm not sure if this is what you're asking, but you can use :! to execute a shell command. For example, type :!dir to open a shell and list the current directory. If you already have the command you want to run open as part of the file you are editing, you could copy and paste it in this way.
Edit: To execute the current line as a shell command in Windows, you can do :.w !cmd -. For multiple lines, you could record a macro that did this and then moved to the next line, and execute the macro as many times as necessary.

Related

Vim function normal mode then execute

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.

Is there an editor that allows to evaluate the current line as a bash command?

I'd like to evaluate a bash script line by line. I also might want to jump back and execute a previous line again.
As described in How execute bash script line by line? , one could use the built-in debugging option -x, but this is not very handy, since you don't have the overview of previous and future commands.
For writing software in R, I used RStudio. The editor allows to evaluate the current line as an R-Command by hitting Ctrl+Enter. Afterwards the result is shown in a built-in shell, and the Cursor jumps to the next command.
Is there a simple text-editor (like gedit) that allows to send the current line to a built-in shell/console (bash, zsh,...) and view the result of the evlauation afterwards in the shell?
It's not built in to Emacs, but it's easy to do.
(defun shell-eval-line (pos)
"Evaluate the line around position as a shell command.
In interactive mode, use the cursor's position."
(interactive "d")
(save-excursion
(goto-char pos)
(shell-command (buffer-substring
(line-beginning-position) (line-end-position))) ))
Bind to a key of your liking (C-c ! maybe?) and go.
Add a (next-line) outside the (save-excursion) to make it advance to the next line when it's done, or create a simple macro around it to invoke the function and jump to the next line.
You can also do it with the editor geany. In their Wiki they have a detailed instruction. In short:
Install geany
Open the file ~/.config/geany/geany.conf and set send_selection_unsafe=true
Restart geany
Set a key-binding Edit > Preferences > Keybindings (It is under Format / Send selection to terminal)
Actually you don't have to select the code you want to send. So far I couldn't find out how to instruct geany to jump to the next line afterwards.

How to execute multiple-line selection in the Stata for Linux command line?

I need to debug my code from the Linux command line. I do not want to run the whole do-file by peforming "do mydofile.do".
I just need to rerun several lines of code (which are saved in the buffer).
Is that possible?
Did you try to run your specific lines in console by copy & paste? It will work if all blocks are placed correctly

How to have history in two files in linux

Is is possible to have the history of a specific user in one more file other than the default file mentioned as HISTFILE?
I would like to have as backup file if main file was removed and let it be like a backup for that one.
Regards,
Sriharsha Kalluru.
You can create a hardlink to the file
cp --link --verbose /home/$USER/.bash_history /somewhere/else/users_history
When the original file in his home is removed the file is still there and preserves the content from being lost.
Many times I've found myself using Ctrl-R in Bash to get a old command four times the terminal width, just to find out that too many days have passed and it's no longer in the .bash_history file. Here are two lines that will keep track of every command line you type at the bash prompt and use no external processes at all, just plain bash.
My first approach to this problem was increasing the maximum number of lines in the history to a very large quantity. But no matter how large it was, there was always a moment when I needed a long command I typed many months ago and it had already left the history. The current solution came to my mind when I learned about the PROMPT_COMMAND variable, a command that bash executes before showing each prompt. Here are the two lines:
export HISTTIMEFORMAT="%s "
PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND ; }"'echo $$ $USER \
"$(history 1)" >> ~/.bash_eternal_history'
One goal I set to myself was to achieve it without using any external process, so bash wouldn't have to fork a new process after every ENTER pressed at its prompt. The first line sets the format of history lines to include the date as a Unix timestamp, so you can now when you typed every command. The second line, which is the core of the solution, first ensures that, if a previous PROMPT_COMMAND was set, it gets executed before our stuff and then appends a line of the format:
PID USER INDEX TIMESTAMP COMMAND
to a file called .bash_eternal_history in the current user home.
Adding the username, which at first seemed unnecesary, became useful later to distiguish between "sudo -s" sessions and normal sessions which retain the same value for "~/", and so append lines to the same .bash_eternal_history file.
I hope some of you find these two lines as useful as I do. :-)
Would hard links solve your problem?
Also you can read the man page here.
i would write a cronjob that copies the original histfiel to a backuplocation every minute or so. the you don't have to worry about defining a second histfile.
otherwise you could write every command the user enters to a alternate file
for this approach take a look here:
bash, run some command before or after every command entered from console

Vim: How to handle newlines when storing multiple commands in registers?

I have a file where I store snippets of vim commands. When I need a snippet, I yank it and then execute it with #". The snippets are stored as a script, one line per command, like this:
:s/foo/bar/g
:echo "hello"
:s/1/2/g
Edit: I removed normal mode commands from the example, as they were not part of the problem.
Now this procedure doesn't work anymore: when executing the snippet, it just stops at the first line as if waiting for a newline.
Is there an option somewhere affecting how # is executed? I'm pretty sure it was working some time ago...
Substituting the newline with a ^M character works but makes the file more difficult to handle.
Additional information:
Here's another symptom: when I yank a snippet, if I execute it with #" it stops at the first line as I just explained. But if I execute it with :# it works. But the help file doesn't seem to imply any difference in how the two commands treat the register's content...
I don't think the problem is ^M vs. ^J. Vim macros will treat either one as a valid end-of-line character for recorded macros. I think the problem is extra newlines.
In your example, there's at least one spurious newline after 2j, and unless you're particularly careful when copying the snippet, there's probably another one after 10k as well. These extra newlines are like pressing <Enter> in Normal mode -- they move the cursor down one line.
Here's what I think you want the snippet to look like:
:s/foo/bar/g
2j:s/1/2/g
10k
(Even that's a little misleading -- you'd still have to be careful not to copy the newline after the 10k.)
Why do these extra newlines make such a big difference? Well, for one thing, they cause you to be at least one line away from where you expect to be, which throws off anything you want to do on a particular line (like execute the :s// command).
More importantly, however -- and this is what I think is happening in your example -- is that Vim stops macro playback if the macro attempts to use <Enter> on the last line of a buffer. (I'm guessing Vim considers it an error, and any error causes a macro to stop running.)
Here's an example. Suppose you've got this snippet stored in register x:
4j
:echo "Done"
(Notice the newline after 4j.)
Furthermore, suppose you have the following five lines (and only these five lines) in a buffer:
line 1
line 2
line 3
line 4
line 5
If you now press #x on line 1, the :echo "Done" never executes. Vim moves the cursor down 4 lines to line 5, then attempts to move down one more line because of the extra newline, but it can't. The macro stops executing at that point, before the :echo command gets a chance to run.
However, it works if you change the x register to this:
4j:echo "Done"
So to return to your original example, I'll bet what's happening is that the extra newline after 2j is attempting to move your cursor somewhere it can't go, and that causes the macro to stop. The bottom line of the screen contains the last command executed (:s/foo/bar/g), which makes it look like Vim is waiting for you to press Return.
Finally, I'd strongly recommend using another method to store and execute Vim command sequences. The technique you're using is tolerable for simple cases, but it's fragile and doesn't scale well. Vim has a full scripting language that includes functions and custom commands, and it can be used to do all the things you're doing now, but in a much more robust fashion. Vim scripting is a big topic, but I'd start here:
:help script
Be sure to read about the :normal command, which lets you execute Normal-mode commands (like 2j and 10k) within scripts.
Good luck!
I finally found the culprit. Somehow I had a command mapping on <C-J> in my .vimrc file. When read with the default cpoptions, this turned into a mapping on <NL>.
How I found out: I noticed that when starting vim with -u ~/.vimrc, it would indeed execute yanked snippets. I generated a session file with and without that commandline option and compared them. This way I found out that a different set of cpoptions where used to read the same .vimrc file, so that in one case the mapping was indeed on <C-J>, in the other it was converted into a mapping on <NL>!
If someone has a similar problem, I suggest to look carefully at the currently set command mappings, with :cmap.

Resources