Delete till end of sentence in vim - vim

So I'm playing vim adventures and I got stuck. I need a Vim command that will delete the keys in red. I thought dd would do it, but that only deletes the current line.

Use das or dis to delete a sentence. Use dap or dip to delete a paragraph. See :help text-objects for details. Unrelated to your question, see this wiki page for plugins that provide other, highly useful text objects.

) jumps to the beginning of next sentence, so d) will delete (from the cursor) till the beginning of the next sentence. Vim detects sentences using ., meaning period + space. This does mean that d) will have some problems if your cursor is on either the period or space delimiting two sentences, and will only delete until the first character of the next sentence (meaning it deletes either a space or the period and space, which is almost never what is desired). das will work as you probably expect, deleting the sentence and the delimiter (period + space).
If you specifically want to move (and delete to) the last character in a sentence it is more complicated according to this vi.SE answer:

The solution was either dk which deletes the line and the line above it or dj which deletes the line and the line below it.
My original question was actually not the right question (there are multiple sentences).

To delete to the end of the sentence, from where your cursor is, use the letters, use "d)". the "d" is the delete command object, followed by a motion object ")" which advances the cursor (and the deletion process) to the end of the sentence.
To delete "around" a sentence, including all the extra whitespace, use "das" (delete around sentence). Or to delete inside the sentence, and not all the whitespace, then use "dis" (delete inside sentence).
Once you understand the VIM language, then you can easily memorize a plethora of operations. Use this table to understand VIM's vocabulary:
COUNT NUMERAL + TEXT OBJECT COMMAND + MOTION (or OPERATORS)
"3das" will perform "delete around sentence 3 times"
So, if practical, you could place a numeral followed by...
a command:
d=delete
y=yank (into memory buffer to "put" later)
c=change (delete then insert new text)
and then a motion:
) = move cursor to end of sentence
( = move cursor to beginning of prior sentence
} = move cursor to the next paragraph
{ = move cursor to the beginning of the prior paragraph
w = move cursor to next word
b = move cursor back a word
$ = move cursor to the end of the logical line
0 = (zero) move cursor to the beginning of the logical line
G = move cursor to the end of the file
gg = move cursor to the beginning of the file
h, j, k, or l (you might have to look those up)
OR instead of a Motion, define a field of area using:
a = around
i = inside
followed by the name of the area around the cursor:
s = sentence
p = paragraph
w = word
t = xml-tag <tag example> lots of text between tags </tag example>
< or > = inside or around a tag, frequently found in xml documents
{ [ ( ) ] } = inside or around any type of bracket ...
... {a large area [some more (a little stuff) things] of a great many things }

I actually find this table from the help file the best overview for block commands:
"dl" delete character (alias: "x")
"diw" delete inner word
"daw" delete a word
"diW" delete inner WORD (see |WORD|)
"daW" delete a WORD (see |WORD|)
"dgn" delete the next search pattern match
"dd" delete one line
"dis" delete inner sentence
"das" delete a sentence
"dib" delete inner '(' ')' block
"dab" delete a '(' ')' block
"dip" delete inner paragraph
"dap" delete a paragraph
"diB" delete inner '{' '}' block
"daB" delete a '{' '}' block
So deleting a sentence is das or deleting a paragraph is dap.

If you want to delete from J up to and including the . start at J and use df.
If you want to delete both lines then 2dd

Another option (not sure if it works in the game) is to delete up to and including the period:
d/\./e
You have to escape the period when using a search pattern like this after the delete command.
If you were limited to a single line, it is much simpler:
df.

You can use the command: d2d, but I do not know whether it works in the game.

Vim grammar is [Nubmer] [Operator/ Command] [Motion or Text Object]
So in this case, you can use: 2dd

Related

How to replace a `\norm{ some string }` by `\| some string\|` quickly? [duplicate]

This question already has answers here:
Find and replace strings in vim on multiple lines
(11 answers)
Vim - Capture strings on Search and use on Replace
(4 answers)
Closed 3 years ago.
I am editing a markdown file with vim. This file exist many string \norm{ some string }. I want to replace them by \| some string \|. Does there exist any quick way? Thanks very much.
The answer in Find and replace strings in vim on multiple lines can not answer my question. It just talk about general replacing for one line and multi line. Here I want to replace a surrounding and keep the string in the surrounding.
What you're looking for are so-called capture groups and backreferences. Provided there are no nested forms (curly braces inside do not mean a problem in themselves) and forms spanning multiple lines, a quick solution could be: %s/\\norm {\(.*\)}/\\|\1\\|/g.
The \1 in the substitution part refers to the group captured by \(.*\), i.e. the original content inside the outermost pair of curly braces. See e.g. http://www.vimregex.com/#backreferences for more.
You could also use a macro to accomplish what you want.
Place your cursor on the first line that have the pattern you want to substitute. Then start recording the macro:
qq0ldwr|$xi\|ESCjq
Meaning:
qq = start recording a macro (q) in register q
0 = move to the beginning of the line
l = move one char to the right
dw = delete the word
r| = substitute what is under the cursor with a "|"
$ = move to the end of line
x = delete last char of the line
i = insert mode
\| = insert chars "\|"
ESC = exit insert mode
j = move to next line
q = stop recording
Execute the macro with:
#q
Execute the macro once again:
##
Keep doing it for as many lines as needed, or use:
<number>##
ex. 100##
To execute the macro number times.

Vim: delete everything in a line after character without moving cursor in the first place

Suppose the following line and cursor position:
foo = some_func(1 +[ ]2)
^^^
cursor position
Using di + ( I could easily get rid of everything inside the brackets or delete everything to line start or end using d^ and d$ respectively, but what would I do if I would like to delete everything that comes after =?
The resulting line should be:
foo =[ ]
^^^
cursor position
dT+= deletes everything until (backwards) the character =, but it still leaves 2) in the line, ending up in:
foo =[2])
^^^
cursor position
I could, of course, jump to = first and then use d$ to delete everything until line ending, but I would prefer a simple shortcut based on current cursor position without the need to move the cursor (if such a shortcut exists).
T=D (Jump to after =, delete to end of line) is the shortest way, I believe.
You can do it without the movement first, but it is considerably more complex: :s/=\#<=.*// CR

Vim - delete until (inclusive) character in multiple lines

I have this code:
def foo(c: Char) = c match {
case 'a': 'B'
}
My cursor is on the space after =. I want to delete everything until, including, the }. How can I do that?
Can I do the same where the cursor is anywhere on the first line? Anywhere in the block (and place the cursor after the =)?
d/}/e
does the job.
d/} deletes until the } but adding the /e flag moves the cursor on the last char of the match, effectively deleting everything between the cursor and the }, inclusive.
Using visual selection works too, in a slightly more intuitive way:
v/}<CR>d
Try with this: d%.
The d is for delete and the % moves between braces.
This should work:
d}
This deletes one paragraph forward.
You can achieve something like this with the EasyMotion plugin.

How to add a word at the beginning of multiple lines in vim?

In Vim,
How do i add a word at the beginning of all lines?
Also how do i add it at end?
Eg..
If i have
A
B
C
D
I want to make it to
int A =
int B =
etc..
use visual block mode (Ctrl-v) to select the column you want, and then hit I, type the characters you want, and then hit Esc
So in this case, you'd put your cursor on A, hit Ctrl-v, go down to D, hit I and type int (it'll only appear on the first line while you type it), and then hit Esc at which point it'll apply that insert to all visually selected portions.
This works for anywhere in the document, beginning of line or end of line.
:he v_b_I for more info on Visual Block Insert
You can do this:
:%s/^/at the beginning/
:%s/$/at the end/
:%s/.\+/int & =
+ won't match on empty lines
If you need to copy just the first word, then do:
:%s/^\w\+/int & =/g
If you want to preserve indentation, then do:
:%s/^\(\s*\)\(\w\+\)/\1int \2 =/g
A global substitute should do i:
:%s/.\+/int & =/
This is how it works: in the second part of the substitution (ie in the int & =) the ampersand is replaced with what machted in the first part (the .*). Since .* matches the entire line, each line is subsituted as wanted.
If you have empty lines (in which you don't want to have any replacements), you could go with a
:%s/^\S\+$/int & =/

Vim: creating a C string literal around a block of text with vertically aligned quotes?

I would like to create a macro or a script in Vim that does the following:
wrap a block of text in double quotes
escaping any quotes that appear in the text itself
have the quotes on the right side in vertical alignment
For example:
<html>
<head></head>
<body>
<h1>High Score Server</h1>
<table>
ROWS
</table>
</body>
</html>
would become:
"<html> "
"<head></head> "
"<body> "
"<h1>High Score Server</h1>"
"<table> "
"ROWS "
"</table> "
"</body> "
"</html> ";
I am able to achieve this with a macro, but without the vertical alignment of the quotes on the right side. Can anyone help me with this one?
What I'd do :
With "surround" and "Align" plugins :
1) with cursor on first line (0,0), type <C-V>)$s"
2) then <S-V>):Align " and <Enter>.
Another solution without plugins :
1) set virtual mode
:set ve=all
2) <C-V> to go in block-wise selection, with cursor at the position 0,0
3) go down to the bottom of the text, then Shift-I, type " and Esc. This should prepend the quotes.
4) now go on the left end (since ve=all, you can go where there is no text)
5) <C-V>, go down to bottom, type r"
This is long to explain, but easy to do and reproduce. Also useful in lots of case.
function Enquote()
let [startline, endline]=sort([line("'<"), line("'>")])
let lines=getline(startline, endline)
let lengths=map(copy(lines), 'len(split(v:val, ''\zs''))')
let maxlen=max(lengths)
call map(lines, '''"''.v:val.repeat(" ", maxlen-lengths[v:key]).''"''')
return setline(startline, lines)
endfunction
Explanation:
line("'<") and line("'>") get the line numbers of start and end of last visual selection.
sort([...]) sorts this line numbers since you may have started selecting lines from the end of the selection.
let [a, b]=[c, d] is a parallel assignment: sort will produce a sorted list of two items, where first item is lesser or equal to second item. Obviously, lesser is a first selected line.
len(split(v:val, '\zs')) is an advanced strlen() which supports unicode.
max(list) finds a maximum value. Obvious.
So, map(copy(lines), 'len(split(v:val, ''\zs''))') applies this strlen to all items in list. copy() is required since we do not want our list to be modified.
map(lines, '''"''.v:val.repeat(" ", maxlen-lengths[v:key]).''"''') modifies an lines in a way you require. I switched from printf to repeat because printf does not handle multibyte characters correctly (by «correctly» I mean that «¥» is one character long, while printf considers it two bytes long).
setlines(linenumber, listoflines) actually modifies buffer.
Making use of the unix program "par" to do this may well solve your problem. There's a Vimcast showing how to integrate it into vim over at http://vimcasts.org/episodes/formatting-text-with-par/
Is it possible to make two passes over the list of lines in vim script? Then you can do something like this (pseudocode):
let N = length of longest line
for each line L:
insert a " character at the beginning
append N - len(L) spaces
append a " character
best i got is a 3-pass regex.
select block in visual mode, then use:
:'<,'>s#^#"#
:'<,'>s#$# #
:'<,'>s#\(.\{28\}\).*#\1"
with the 28 being the length of your longest line.
By all means heed the previous answers and get your vim-fu in shape. Or install/modify/poke-the-author of this plugin:
http://www.vim.org/scripts/script.php?script_id=4727
From the plugin's page:
This script converts multi-line text in a C++ file to a multi-line
string literal, escaping the quote and tab characters. It also does
the reverse conversion, un-escaping some characters. It's not too
complete for now, but it will be someday if needs come.
If you need to make changes use the source-code repository:
https://bitbucket.org/dsign/stringliteral.vim
In two passes:
let l = max(map(getline("'<", "'>"), 'strwidth(v:val)'))
'<,'>s/.*/\=('"'.submatch(0).repeat(' ', l-strwidth(submatch(0)) )).'"'

Resources