What is the shortcut to allow new lines in linux terminal? - linux

I'm searching for the couple of shortcuts to allow to write multilines commands in the terminal.
I know it exist, I used it many times, but I can't remberber them, and I don't find them in google...
The behavior it have:
Once in the middle of a line, it will "delete" the right part, and when we press the Enter button, it don't execute the command, but go to a new line (that start with '>' if I well remember).
When we are done, we press the second shortcut, and it paste the part that where deleted before, and the Enter key behavior come back as the original.
(I tought it was something like Ctrl+j / ctrl+f, but it's not, I also tried many combination but never succeed)
Hoping you remember them, you'll make my day. Thanks!
 Edit for a better understanding:
On a command like this (a call to a ros service, providing arguments):
rosservice call /operatorshift/updateProgramSteps "category: ''
name: ''
steps:
- command: ''
args: ''
othersarg ''"
The steps argument is an array, and I want to provide more than one step, without deleting and rewriting the next lines.
The behavior is as follow:
I move my cursor at the end of the 5th line (args: '' [HERE]), and I press the first shortcut. The command would look like:
rosservice call /operatorshift/updateProgramSteps "category: ''
name: ''
steps:
- command: ''
args: ''
and I press "enter", not to execute the command, but to add a new line (and the '>' character appear on the left of my cursor, instead of my computer's name). I can write my other "step", pressing "enter" many time if I want, so my terminal would look like this:
rosservice call /operatorshift/updateProgramSteps "category: ''
name: ''
steps:
- command: ''
args: ''
> - command: 'example'
> args: ''
>
Then I'm done editing this command, so I press the second shortcut, that retrieve what the first have deleted, and the "enter" key get its default behavior (execute the command)
rosservice call /operatorshift/updateProgramSteps "category: ''
name: ''
steps:
- command: ''
args: ''
> - command: 'example'
> args: ''
othersarg ''"
(not sure that '>' stay on screen after pressing the second shortcut)
I remember using it on Ubuntu 14.04, and on 16.04, with the default shell, without having to install a special package.

Just type "\", and when you press enter the ">" symbol you mentioned will appear

Sadly, I think the easiest solution is to use bash's edit-and-execute-command feature; from the manual:
edit-and-execute-command (C-xC-e)
Invoke an editor on the current command line, and execute the result as shell commands. Bash attempts to invoke $VISUAL, $EDITOR, and emacs as the editor, in that order.
if you use bash in vi mode, you can invoke it by simply pressing v in normal mode.
This will open your command in your editor set up by $VISUAL or $EDITOR environmental variables.

Could it be heredoc ?
$ cat << EOF
> \$ Working dir "$PWD" `pwd`
> EOF
$ Working dir "/home/user" /home/user

Related

call from command line, show file also if the search does not match

I use a msdos-script to search with vim for patterns and show me the result
Script: tel.bat
rem script is called: tel.bat <pattern>
gvim -R %WORKSPACE%\telliste.csv "+set ignorecase" "+set ft=javascript" -c /%1
This works fine if the pattern exist in the file. If the pattern is not matched, I get an error message and I am stuck. No keystroke or mouse action changes the state. Like:
Enter key - has no effect
Esc key - has no effect
Ctrl + C - the error-messages disappears, but the editor is frozen. No action possible
Mouse click in editor - has no effect
I can only close vim and try again. That's what I get as error, when I call the script tel.bat konez on the command line:
Error message translated:
Error during execution of "command line":
E486: Pattern not found: konez
Confirm with the ENTER Key or place a command
How can I work further on the file, even if the pattern is not found? In other words how can I avoid that I am stuck in vim.
I tried already with -c ":execute 'silent !'" in the batch file, but this was not recognized. Perhaps I did it in the wrong way...
This should work, and I cannot reproduce this on Linux with Vim version 8.0.1358; I can accept the error message with <Enter> and continue.
This could be a plugin / configuration issue; try launching with gvim --clean.
The multi-line error message is ugly. You could avoid it by moving to the lower-level search() function:
gvim ... -c "call search('%1')"
By evaluating its return value; you could also craft your own error message: if search(...) == 0 | echomsg 'No matches' | endif

Vim --- Read from an External Command, Inserting Right Where the Cursor Is

:r !program opens a new line, inserts my program's output and then inserts a line after it.
I simply want to insert the output right where the cursor is without that additional mess.
I figured I can:
Run a before macro
mai^M^[`a
"Mark where I'm at, insert a line and go back
Run my command
:r !echo -ne "line1\nline2\nline3"
Run an after macro (cleanup the lines)
$mb:j!^M`a:j!^M`b
"Go to the end of inserted outpu
"Mark it b
"Join with the next line
"Go to the first mark
"Delete the inserted newline with :j!
"Go to the second mark
How can I combine this into a single command?
I'd like to be able to do:
:Readhere !echo -ne "line1\nline2\nline3"
where :Readhere would be my custom command.
This might do what you want. (You don't need the !)
command! -nargs=1 ReadHere exec 'normal! i' . system(<q-args>)
This creates a command called ReadHere that takes everything as a quoted argument and passes it directly to the system command. Then we use exec to insert everything in normal mode. (This might not be robust enough)
Example: Starting buffer is
one two three
Running :ReadHere echo -ne "line1\nline2\nline3" where the cursor is on the w produces
one tline1
line2
line3wo three

Capture the output of an interactive script in vim

I have a an interactive Perl script, which prints prompts to STDERR and reads lines from STDIN. The final output of this script is an IP address, printed to STDOUT. Here's a numpty version of such a script as an example.
my #pieces;
for (1..4) {
print STDERR "please enter piece $_ of the IP:"; chomp(my $in = <>);
push #pieces, $in;
}
print join '.', #pieces;
print "\n";
I use the vim-fireplace vim plugin. This plugin has a feature where I can say:
:Connect nrepl://127.0.0.1:9999
I want to know how to configure vim so that when I issue a particular command, let's say:
:InteractiveConnect
it will do the following:
Run the Perl script, allowing me to enter 4 pieces of the IP address.
Capture the IP address output by the Perl script.
Interpolate the IP address into the :Connect command
Run the :Connect command.
A bit more info based on some of the responses:
If I call this script using:
:!/path/to/myscript.pl
Then it executes fine and I am able to see the result from it printed in the vim window, followed by
Press ENTER or type command to continue
If the output of the script is being saved in some buffer after execution via !, is it possible to get access to that buffer in vimscript and just capture the bit I want (the last line) with a regex?
Okay, there's probably a more elegant way to do this, but how about this:
function! <SID>InteractiveConnect()
let tempfile=tempname()
exe '!/path/to/your/script.pl >' . shellescape(tempfile)
try
exe 'Connect nrepl://' . readfile(tempfile, '', -1)[0]
finally
call delete(tempfile)
endtry
endfunction
command! -nargs=0 InteractiveConnect call <SID>InteractiveConnect()
This creates a temporary file, writes to it with the script (using system() doesn't work because it doesn't wait for input), reads the last line in the tempfile to the Connect command, and then finally deletes the tempfile.
Maybe something like:
exec 'Connect nrepl://' . matchstr(system('your/script.pl'), '^.\+\%$')
(Untested.) This runs the script using system() then matches the output against the regular expression ^.\+\%$, (where \%$ means end-of-file; if your file is terminated with a newline, an additional \n might be neccessary before it) and feeds the matched str to the Connect command. .

Moving cursor in bash with keyboard

Say I have a bash window like this:
# cmd 1
output of cmd 1
# cmd 2
output of cmd 2
# (cursor here)
Is it possible to move the cursor (with keyboard only) to previous line, say output of cmd 1, copy some words and paste them to the current cursor position?
I.e. Is there a bash equivalent of the following command in vim:
kkkvllyGp
Thanks
You can use GNU screen.
In a screen session, ctrl+a, esc enters copy mode, where you can move the cursor with the arrow keys, mark start and end points with space, and then paste with ctrl + a, ]
bash has no knowledge of what the terminal displays. If you want to capture the output of cmd 1 and do something with it, you either need to redirect it to a file or capture it in a variable. eg:
cmd 1 > cmd1out.txt
or
CMD1OUT="$(cmd 1)"
Then, once you've captured that output within the shell, you can use it as you like. For example, to execute that output directly as another command, you could do
source cmd1out.txt #if you sent it to a file
or
eval "$CMD1OUT" #if you captured it in a variable

Vim - how to start inserting at the end of the file in one step

Is there a single shortcut to start inserting in the new line at end of the file?
I'm aware of G + o combo.
There's also the command line option "+":
vim + myfile.txt
Will open myfile.txt and do an automatic G for you.
Not that I know of - G+o is what I would have suggested too, but that is 2 steps :)
You could always create a macro which does G+o, and then you can invoke the macro which will be 1 step.
Adding the following into ~/.vimrc will create one for you:
:nmap ^A Go
To type the "^A" first press Ctrl-V, then press Ctrl-A. You can then use Ctrl-A to append at the end of the file when not in insert or visual mode.
echo >> myfile.txt && vim -c 'startinsert' + myfile.txt
You can also save the above command in a script and then use $1 instead of myfile.txt, name your script myvim ( or whatever you like ) and always open your files and start writing away instantly.
myvim myfile.txt
You could stick the map definition in your .vimrc and then invoke it when the you open the file.
Or, if you only want to do this for a particular file, you could create an autocmd for that file type that does it automatically. See autocommand in the vim doc's.

Resources