the signature of the query-replace function in emacs looks like this :
(query-replace FROM-STRING TO-STRING &optional DELIMITED START END)
My question is how can I specify the DELIMITED argument.
The docs indicate: " Third arg DELIMITED (prefix arg if interactive), if non-nil, means replace
only matches surrounded by word boundaries."
So I'm assuming it would be just like a numeric argument specified before a command (i.e. calling undo 8 times with M-8 C-x u) but haven't figured it out. Can anyone help?
(query-replace "foo" "bar" "your demeter") or C-u M-%
Ross mentioned using M-< to get to the buffer beginning, then using M-%. Know too that you can always use C-x h to mark the whole buffer as the region. (But you do not need to do that here -- just use M-<.)
Related
How can I find and delete lines which start with the text in?
I use the command C-M-s ^in to find all lines starting with in, but then I don't really know what to do.
M-x flush-lines RET ^in RET
C-h f flush-lines tells you:
flush-lines is an interactive compiled Lisp function in replace.el.
It is bound to menu-bar edit flush-lines.
(flush-lines REGEXP &optional RSTART REND INTERACTIVE)
Delete lines containing matches for REGEXP.
When called from Lisp (and usually when called interactively as
well, see below), applies to the part of the buffer after point.
The line point is in is deleted if and only if it contains a
match for regexp starting after point.
If REGEXP contains upper case characters (excluding those preceded by \)
and search-upper-case is non-nil, the matching is case-sensitive.
Second and third arg RSTART and REND specify the region to operate on.
Lines partially contained in this region are deleted if and only if
they contain a match entirely contained in it.
Interactively, in Transient Mark mode when the mark is active, operate
on the contents of the region. Otherwise, operate from point to the
end of (the accessible portion of) the buffer. When calling this function
from Lisp, you can pretend that it was called interactively by passing
a non-nil INTERACTIVE argument.
If a match is split across lines, all the lines it lies in are deleted.
They are deleted before looking for the next match. Hence, a match
starting on the same line at which another match ended is ignored.
query-replace-regexp "in.*" to "" will be work. you should not input " to the prompt
Windows 10 (64 bit), Emacs 25.1
Suppose I has text:
aa11aaa aaaaa "api/method1" bbbbbbb
dddeeee ee "api/method2" ddddddd
ee2222ezzzzzzzzzzzzzzzzzz "api/method1" eeeeeee
aaaaaaa222222222222"api/method3" fffffff
xwwwwxx "api/method4" bbbbbbb
I want to cut all text that contain "api/XXX"
, where XXX is a method name (e.g. method4)
. So the result must be:
aa11aaa aaaaa bbbbbbb
dddeeee ee ddddddd
ee2222ezzzzzzzzzzzzzzzzzz eeeeeee
aaaaaaa222222222222 fffffff
xwwwwxx bbbbbbb
I want to use built-in capabilities of Emacs (without write custom elisp script or Emacs macros).
What you do is search for that string and replace it with an empty string (no characters):
With the cursor where you want to start searching and replacing, do this:
M-x replace-string RET api/XXX RET RET
Or if you need to match a regular-expression, use command replace-regexp instead.
Or if you want to check each search hit individually and tell Emacs whether to replace it, use query-replace (M-%) or query-replace-regexp (C-M-%). You can hit ! when queried to make replacements everywhere from the current position forward.
Use C-h f and enter a command name to get more information about that command. For example, C-h f replace-string tells you:
replace-string is an interactive compiled Lisp function in
replace.el.
(replace-string FROM-STRING TO-STRING &optional DELIMITED START END BACKWARD)
This function is for interactive use only;
in Lisp code use search-forward and replace-match instead.
Replace occurrences of FROM-STRING with TO-STRING.
Preserve case in each match if case-replace and case-fold-search
are non-nil and FROM-STRING has no uppercase letters.
(Preserving case means that if the string matched is all caps, or capitalized,
then its replacement is upcased or capitalized.)
Ignore read-only matches if query-replace-skip-read-only is non-nil,
ignore hidden matches if search-invisible is nil, and ignore more
matches using isearch-filter-predicate.
If replace-lax-whitespace is non-nil, a space or spaces in the string
to be replaced will match a sequence of whitespace chars defined by the
regexp in search-whitespace-regexp.
If replace-char-fold is non-nil, matching uses character folding,
i.e. it ignores diacritics and other differences between equivalent
character strings.
Third arg DELIMITED (prefix arg if interactive), if non-nil, means replace
only matches surrounded by word boundaries. A negative prefix arg means
replace backward.
Operates on the region between START and END (if both are nil, from point
to the end of the buffer). Interactively, if Transient Mark mode is
enabled and the mark is active, operates on the contents of the region;
otherwise from point to the end of the buffer’s accessible portion.
Use M-n to pull the last incremental search string to the minibuffer
that reads FROM-STRING.
This function is usually the wrong thing to use in a Lisp program.
What you probably want is a loop like this:
(while (search-forward FROM-STRING nil t)
(replace-match TO-STRING nil t))
which will run faster and will not set the mark or print anything.
(You may need a more complex loop if FROM-STRING can match the null string
and TO-STRING is also null.)
The 82-th solution of the challenge contains a fragment like the following:
V"=[<C-R><C-A>]<CR>p
I think here V enters the likewise visual mode, and then the help document says that
When typing the '=' after " or CTRL-R the cursor moves to the command-line,
where you can enter any expression (see |expression|). All normal
command-line editing commands are available, including a special history for
expressions. When you end the command-line by typing <CR>, Vim computes the
result of the expression. If you end it with <Esc>, Vim abandons the
expression. If you do not enter an expression, Vim uses the previous
expression (like with the "/" command).
Then I am confused: is that expression ended by an enter, and hence looks like [, following which we press ctrl-a?
If I repeat the sequence as above, some weird behavior happens that I don't think is what is intended. So I must have missed something important.
Thanks in advance for any help or reference.
The "= will evaluate the given expression, if you p(paste) the evaluated result would be converted into string. If you read the doc further, you will see:
The expression must evaluate to a String. A Number is always automatically
converted to a String. For the "p" and ":put" command, if the result is a
Float it's converted into a String. If the result is a List each element is
turned into a String and used as a line. A Dictionary or FuncRef results in
an error message (use string() to convert).
<c-r><c-a> will fill the WORD under cursor.
So the expression is [---...---2,3,5,..] what is this expression? It is a list. And as doc told us, when you p to paste, it will be converted into lines.
What is tricky here is the first element in the list, the -------...-2,
We have:
2 -> 2
-2 -> -2
--2 -> 2
---2 -> -2
.....
Now you can count, how many - before the 2, I think it must be even number. so we have 2 in first line, after you pasted.
I hope that now you understood it better.
I come upon one scenario when editing a file in vim and I still haven't found a way to do it quickly in vim way. When editing a call of a function, I offently put my arguments in a wrong order.
anyFunction(arg2, arg1)
When arriving on this situation, I have to find arg2 / delete it / append it before the ')' / deal with the ', ' / etc.
Isn't it a better way to this task quickly ? I am open to any idea (macro/ shortcut / plugin) even if I'd rather have a 'vim only' way of doing this
You need two things:
A text object to quickly select an argument (as they aren't always that simple like in your example). argtextobj plugin (my improved fork here) does this.
Though you can use delete + visual mode + paste + go back + paste, a plugin to swap text makes this much easier. My SwapText plugin or the already mentioned exchange plugin both do that job.
put this mapping in your _vimrc.
" gw : Swap word with next word
nmap <silent> gw :s/\(\%#\w\+\)\(\_W\+\)\(\w\+\)/\3\2\1/<cr><c-o><c-l>
then in normal mode with the cursor anywhere in arg1 type gw to swap parameters
anyFunction(arg1, arg2)
Explanation:-
arg1 the separator (here a comma) and arg2 are put into regexp memories 1 2 3
the substitute reverses them to 3 2 1
Control-O return to last position
Control-L redraw the screen
Note that the separator is any non-alphanumeric character or string e,g whitespace
I actually made a plugin to deal with a exact situation called argumentative.vim. (Sorry for the plug.)
Argumentative.vim provides the following mappings:
[, and ], motions which will go to the previous or next argument
<, and >, to shift an argument left or right
i, and a, argument text objects. e.g. da,, ci, or yi,
So with this plugin you move to the argument in question and then do a <, or >, as many times as needed. It can also take a count e.g. 2>,.
If you have Tim Pope's excellent repeat.vim plugin installed <, and >, become repeatable with the . command.
I would recommend a plugin: vim-exchange for that:
https://github.com/tommcdo/vim-exchange
This is a perfect use for a regular expression search and replace.
You want to find "anyFunction(", then swap anything up to the ',' with anything from the ',' to the ')'. This is fairly straightforward, using [^,]* for "anything up to the ','" and [^)]* for "anything up to the ')'". Use \(...\) to capture each thing, and \1, \2 to refer to those things in the replacement:
:s#anyFunction(\s*\([^,]*\),\s*\([^)]*\)#anyFunction(\2, \1#g
Note how I use \s* to allow any whitespace between the "anyFunction(" and the first thing, and also between the ',' and the second thing.
If you want this to be able to span multiple lines, you can use \_s instead of \s, and capture the whitespace if you want to maintain the multi-line format:
:s#anyFunction(\(\_s*\)\([^,]*\),\(\_s*\)\([^)]*\)#anyFunction(\1\4,\3\2#g
There is also a multi-line variant of [...] collections, for example \_[^,] meaning "anything (even a new line) except for a ',' " which you could use in the pattern if your use case demands it.
For details, consult the help topics for: /\s, /\_s, /\1, /\(, and /[.
If you want a more general-purpose mapping to use at every location, you can use the cursor position in your regular expression, rather than keying off the function name. The cursor position in a regular expression is matched using \%# as demonstrated here: http://vim.wikia.com/wiki/Exchanging_adjacent_words
Similar to what Peter Rincker suggested (Argumentative), sideways also does what you describe.
Having this LOC:
printf("%s (%d)\t(%d)\t%d-%d\t", meta_scanner_token_name($ret['major']), $ret['major'], (string)$ret['dirty'], $ret['start_line'], $ret['minor']);
What is the fastest way in terms of key strokes to enclose the call to meta_scanner_token_name in another function call to foo, yelding:
printf("%s (%d)\t(%d)\t%d-%d\t", foo(meta_scanner_token_name($ret['major'])), $ret['major'], (string)$ret['dirty'], $ret['start_line'], $ret['minor']);
given that
first scenario: my cursor is on 'm' at the beginning of the function?
second scenario: my cursor is somewhere on meta_scanner_token_name?
va)oB would select the entire line, and ys%) would enclose only the m, resulting in:
... (m)eta_sca...
Please answer to both scenarios.
(I am using spf13-vim with default settings except some visual changes, if that has any relevance)
ifoo(<Esc> then f)i)<Esc>
bifoo(<Esc> then f)i)<Esc>
but I'm still a Vim noob
-- EDIT --
I see "Surrounding.vim" is a modified version of "Surround.vim" if it's compatible with Surround you can do:
Scenario 1
vt,sffoo<CR>
vt, to select everything until the first ,
s to launch Surround.vim
f to instruct Surround to input a "function"
foo the identifier
<CR> Enter key.
That's 6 keystrokes not including typing foo which — I think — can't really be avoided.
Scenario 2
bvt,sffoo<CR>
It's the same as scenario 1 except that you type b first to go back to the first letter of meta_scanner_token_name.
Using normal vim you could do this (prefix with b for scenario 2)
`cf)foo()<esc>P`
If your vim plugins add the closing paren for you, you can drop that from the sequence. Depending on where it leaves your cursor, you might need to use p instead of P.