I'm writing a custom function in Vim which asks the user what they would like to rename the current file to:
let b:newname = input('Rename to: ', expand('%'))
It prepopulates the input field with the filename such as ExampleFile.php. However I would like to position the cursor just before the . as more often than not, users will be renaming the file as opposed to the extension.
However, I cannot figure out a way to move the cursor. Even <Left><Left><Left> would suffice if I could get it to work
You can insert special keys in a double quote string with \<xxx>. Check the help for expr-quote. So just concatenate that to your string:
let b:newname = input('Rename to: ', expand('%') . "\<left>\<left>\<left>\<left>")
Related
Say I have the following:
text function(contents) text
and I wanted it to be
text function() text
Placing the cursor right after the opening parenthesis, I thought the following command would work df); however, what I ended up with was the following
text function( text
So I would need someway to specify that I want the character just before the closing parenthesis, but I'm not sure how to do that. There may also be a better way to do this.
What would be the best way to go about this?
You were close! You need dt) as in delete till )
The f motion places the cursor on the ) (remember it like find)
As for the 'best' way to do it, there is at least a more general way: if the
cursor were somewhere in the middle of the ( and ) (or on one of them), you
can do di) (or equivalently di() to delete inside )
If you do da) (or equivalently da() to delete around ), you would
delete the stuff in between and including the brackets.
The same goes for di[, di{, di<, di', di" etc. Using these so-called
text objects, as opposed to the d{motion} way, has the advantage that you can
repeat the edit on other pairs of brackets/quotes without the cursor needing to
be in precisely the same place - it just needs to be on or in between them.
In the following you could position the cursor on e.g. the 'i' of 'initial' in
the first line, do di) to delete the words 'some initial text', then move the
cursor to the 'e' in 'more' in the second line and just do . to also delete
the words 'some more text'):
(some initial text)
(some more text)
This way also works when the brackets (or quotes) are on different lines. For
example, with the cursor somewhere between the {}, doing di} will change
this:
function( args ) {
body of function
}
to this:
function( args ) {
}
I'm trying to go from here:
const f = function() {
if (exists) { // delete this
const a = 'apple'
}
}
to:
const f = function() {
const a = 'apple'
}
What's the fastest way to delete and reindent everything in between?
Assuming that cursor is inside the braces; any number of lines and nested operators; "else"-branch is not supported:
[{"_dd<]}']"_dd
Explanation:
[{ go to previous unmatched brace
"_dd delete the "{"-line (now the cursor is in the first line of the block)
<]} decrease identation until the next unmatched "}"
'] go to the last changed line (i.e. "}"-line)
"_dd and delete it
If the cursor is initially set on the "{"-line and you don't care for 1-9 registers, the command can be simplified to dd<]}']dd
Assuming your cursor is somewhere on the line containing const a
?{^M%dd^Odd== (where ^M is you hitting the Enter key and ^O is you hitting Ctrl+O).
Broken down this is:
?{^M - search backwards/upwards for the opening brace
% - jump to the corresponding brace (closing brace)
dd - delete the current line
^O - jump to previous location (the opening brace)
dd - delete the line
== - indent current line
You don't need a special macro or function or anything to do this since vim gives you all the powerful text manipulation tools to do the task. If you find yourself doing this an awful lot then you could always map it to a key combination if you want.
The above only works for single lines inside curly braces, but the one below will work for multiple lines (again assuming you are on some line inside the curly braces)
<i{0f{%dd^Odd I'll leave you to figure out how this one works. Type the command slowly and see what happens.
Great answers all around, and, as pointed out, you can always map these keys to a shortcut. If you'd like to try a slightly more generic solution, you could check my "deleft" plugin: https://github.com/AndrewRadev/deleft.vim
i want to read a input from the user. I do this that way:
let wordUnderCursor = expand("<cword>")
call inputsave()
let filePattern = input('Searchterm: ')
call inputrestore()
Now my goal is to already put something into the searchterm so that the user (me) doesnt has to write the whole searchterm.
So is it possible to prepopulate the input-function with a string?
thx in advance
Check out :help input(); it tells you that there are optional additional arguments; the first one is exactly the default text you've been looking for:
input({prompt} [, {text} [, {completion}]])
[...]
If the optional {text} argument is present and not empty, this
is used for the default reply, as if the user typed this.
For your example:
let filePattern = input('Searchterm: ', wordUnderCursor)
If you don't want the preset, you can remove it via <BS> character-by-character, or in one fell swoop with <C-u> (as in any command-line).
I am trying to write a function in Vim that searches the current buffer for a certain pattern and returns it. But, I'm failing horribly. Basically, what I want is a function that returns the (PHP) namespace of the file I am working in. The namespace is defined in the file itself:
namespace Foo\Bar;
What I would like is a function that returns the Foo\Bar part as a string. I.e. something that searches like /namespace\s\([^;]\+\) and returns the first submatch.
Edit: Here's the function I build thanks to the help I got:
func! PhpNamespace()
let l:lnr = 0
while l:lnr < line('$')
let l:str = matchstr(getline(l:lnr), '^\s*namespace\s\+[^;]\+')
if len(l:str)
return substitute(l:str, '^\s*namespace\s\+', '', '')
endif
let l:lnr = l:lnr + 1
endwhile
return ''
endfunc
One option is to use searchpos(), which gets you the start position; you then need to extract the text yourself. This is fast and easy, especially if you need to search forward / backward from the cursor position. With the 'n' flag, the cursor position will not change. Otherwise, you have to save and restore the cursor position (getpos('.'), setpos('.', saved_cursor)).
For your problem, it looks like the namespace declaration is likely at the beginning of the file, and is limited to a single line. Then, you could also get individual lines with getline(lnum) in a loop and extract the text with matchstr(), and break out of the loop once you have it.
does anyone know if it is possible to concatenate matches resulting from a search into a single register? E.g, I have a file with following contents:
aaa :xxx 123
bb :y 8
ccccc :zzzzz 1923
Now what I want is to copy column starting with ':' somewhere else. Unfortunatelly I can't use visual block mode, because the first column hasn't fixed width.
I thought that I could search for the second column (:\w+) and store the maches into a register.
Another way:
:g/:/norm f:"Aye
Per :h quote_alpha, if you use an uppercase register name, it appends rather than replaces the contents of the register. If you run this and check the contents of register "a, you'll see
:xxx:y:zzzzz
(Possibly with linebreaks, depending on how you have cpoptions set.)
You could make a macro:
qa (make a macro and store it in register a).
"Rye (yank to end of word and append it to register r - capital means append, lowercase overwrite.)
n (next match)
q (end recording)
If there are 10 matches, do 10#a
Make sure register r is empty when you begin.
Add this to your .vimrc or create any file in the vim plugin folder with the following content.
After you execute this lines through .vimrc or plugin, use :CopyTextAfterColon command and then simply insert from the system buffer text you need.
function! s:copy_after_colon()
let values = ''
let pattern = '^.*:\(\w\+\).*$'
for line_number in range(1, line('$'))
let line = getline(line_number)
if line =~ pattern
let value = substitute(line, pattern, '\1', '')
let values .= value."\n"
endif
endfor
let #* = values
endfunction
command! -nargs=0 CopyTextAfterColon call <SID>copy_after_colon()
You can adapt this later for different purposes.
I would first start with parsing the file. For this use TextFieldReader rather than inventing your own CSV parser:
using Microsoft.VisualBasic.FileIO;
TextFieldParser reader = new TextFieldReader("C:\MyFile.txt");
reader.Delimiters = new string[] { " " };
string[] currentRow = null;
while (!reader.EndOfData)
{
try
{
currentRow = reader.ReadFields();
foreach(string field in currentRow)
{
//save this field...
}
}
catch (MalformedLineException ex)
{
//handle exception the way you want
}
}
Once I have the data I would extract just the column that I am interested in. If you can assume that each line has the same pattern then you can figure out the right column during parsing the first row and then while parsing the rest of the rows you can just save the appropriate column. You don't have to save the whole file into the memory.
EDIT: I am terribly sorry, I thought the question was about C# programming. My mistake - sorry.