Visual Studio 2013's new feature, 'Auto Brace Complete', is quite useful, but I feel I have not unlocked its full potential to make it more useful.
So if I wanted to type newstr="Hello World" + oldstr;, before the 'Hello World' is typed in, the closing quotation mark is already typed in after the words. Now, how should I tell VS2013 that I finished typing in the braces so it can know that I want to leave the braces and go on to the next part?
In other words, for the above example, what is the expected behavior in step 4?
newstr=
"
Hello World
???
+ oldstr;
Should it be another " key? That seems to defeat the purpose of using auto braces.
Should it be the right arrow key then? But, that key is far from the typing area, so I might as well just use " instead.
Enter key or Shift+space seem like the logical choice to me, but neither works as I intended.
Can anyone shed any light on this issue? Thank you.
Press tab to jump outside of the quotes.
Just typing the closing quotation marks " is exactly what is expected. They only serve as a visual aid, or when you're inserting a string literal in the middle of a line.
Should it be another " key? That seems to defeat the purpose of using auto braces.
Why is using " the wrong key? Auto-braces provides 2 things to the editing experience:
Inserts the closing braces so you don't have to (in this case, you only had to type the opening quote)
Makes it easy to move past the closing brace (or quote) without having to use the arrow keys or mouse. As you correctly pointed out, the arrow keys are inefficient when typing because you have to move your hand away and back. Typing another " is a much faster way to move the cursor, and it will do the Right Thing and just move the cursor forward instead of typing an unwanted ".
Related
I use visual studio with C++. When typing a word, visual studio makes suggestions, as expected, but does not always highlight them. Here is what I mean:
I type "stri", and "string" gets highlighted, and this allows me to press enter and complete the word.
Then, if I erase only part of the statement, it no longer highlights string,
And finally, most importantly, if I want to use that string elsewhere, it does not highlight the name.
In the example you can see that pressing enter goes to a new line instead of completing the word. Pressing tab would work, however it still doesn't highlight the word, which I don't like, and also I am used to pressing enter, so I would prefer not to press tab.
Working solution:
Go to Tools > Options > Text Editor > C/C++ > Advanced. Then find Member List Commit Aggressive. Set this to true.
Then optionally find Member List Commit Characters and remove all the characters except the colon character.
This solution is almost perfect and it will work for anyone who wants to do the same thing as me.
Say I have my cursor position to the right of a right facing case curly brace, like so:
Now, if I press enter, I expect it to auto align the cursor two tabs in, just like the break statement. But what it does is this:
It adds a ridiculous five tabs! Knowing that Visual studio has a metric ton of settings, I navigate to Tools::Settings::Text Editor::C/C++::Formatting::Indentation, and see the following window:
But changing the highlighted options in any combination actually doesn't affect the indentation at all! None of the other options seem to apply to switch statements, so I don't know what to do. How do I make it not indent 5 spaces, without disabling auto formatting?
And I might add, it not only places 5 tabs when I press enter at the end of the curly brace, but when any auto format event takes place. So when I add a semicolon at the end of a line it places 5 tabs even if I had taken them out before.
This is probably a bit late for you now, but in case someone else finds this issue: it seems to be a Visual Studio bug, you're probably running the freshly installed version of the VS2K13 called REL.
Downloading the Update 4 at http://www.microsoft.com/en-us/download/details.aspx?id=44921 helped in my case.
The curly braces ({ and }) are throwing off the auto-indenter, and it's indenting to one tab beyond the brace.
Braces there are not illegal in a switch statement, but they usually don't do you any good. Unless you need it for scoping a variable declaration, just remove the curly braces. You'll get the same code flow, and you won't confuse the auto-indenter.
EDIT
Come to think of it, you can solve this by simply moving the brace to a new line. This isn't necessarily horrible - it highlights that you're using a brace.
case SDLK_g:
{
// etc
break;
}
I went into VS2013 and created a new project and just tried making a really simple switch but it formatted correctly for me, even with the curly braces. Are you able to post that set of code?
The only other thing I can think of is maybe a setting on how braces are set up, but I don't know why that would affect it. (Nor do I think there is really even a setting for that for C++...) Other than that though you could try just not using the braces at all since you are inside a case statement, you don't technically need them.
Other than that something may have happened during installation. So re-installing is an option too.
EDIT:
Also, could just go with it and finish the code and then when finished just highlight the rows and un-indent ([SHIFT]+[TAB]) them back to their correct spot.
When I begin my program and type
cout << "
it automatically puts the closing quote ("") and places the cursor in the middle, which is nice; however, I can't seem to find a way to get past the second one without having to move my hand to use the arrow keys, use the mouse, or put another " manually, which defeats the purpose.
My buddy said tab should skip it, but it just does an indent.
I am sorry if this sounds disappointing, but there is no other way than using:
a) arrow key.
b) end button on the keyboard in the regular way.
c) typing another quote.
Basically what you also mentioned yourself in the question. Even if the tab was working, you would not spare anything as you already have at least two keys with which you get over.
I'm a rather happy PhpStorm user, but there are a few things that really annoy me, but I'm not a settings expert and wish there is a solution for them (editing PHP files) :
Navigation
Often in the editor, one want to go back to where the cursor was 100 lines above etc... And in PhpStorm Back Alt-Shift-Left and Forward Alt-Shift-Right do this - but they follow an algorithm that is beyond me: it definitely misses "steps" (e.g. from line 500 go to line 300 using keys like arrows or -even worse- page-up/down, then Alt-Shift-Left doesn't bring you back to line 500)
=> Is there a way to refine the conditions that drive the behavior of Back and Forward?
Indentation
Is there a way to refine the indentor behavior? For instance
$a = array('X' => 'Something',
'Y' => 'Something else',[RETURN]
^ ^
now there
like in Emacs the cursor would go there right under the first quote after the spaces (and not at now where PS goes)?
=> Is a regexp (or something else) able to refine the behavior of the indentor, Not only for this very specific case but for the behavior in general?
(Not mentioning another problem when Shift-Inserting where the indent is often unreliable)
Quotes (automatic)
I don't want to disable the automatic quoting feature as it is sometimes convenient, but it seems the algorithm doesn't parse correctly the environment where the " or ' is inserted (don't have an example right now but at times it was annoying, like inserting 2 " unexpectedly while only one is required, deleting one will actually delete the 2 (normal because they were inserted automatically... but I needed 1 only!) so have in this case to trick PhpStorm to force a 1 ").
=> Is there a regexp or similar to control the quoting behavior?
Select via Shift-Arrow (for instance, to delete...)
Almost forgot: PhpStorm remembers at which column the cursor is when navigating Up and Down. Fine. But when one want to select (using Shift and Up/Down Arrows) from beginning of line it is usually to select lines. Not a line-to-where-cursor-was-earlier. An example will explain better: * is where the cursor is [beginning of line 3], % is where the cursor was [middle of line 2]
1. $x = 'string';
2. $y = %'string';
3.*
doing Shift-Up will select (all s)
1. $x = 'string';
2. $y = *sssssssss
3.
while in the specific case of a selection, it should select that:
1. $x = 'string';
2.*sssssssssssssssss
3.
not sure there is a way to configure that though - just in case there is?
Thanks
Oh well...
1) Is there a way to refine the conditions that drive the behavior of Back and Forward?
No. Maybe (just maybe) it takes into consideration what you were doing at that location (even if you done nothing, then maybe how long the pause was). But mainly it looks at editing activity, navigation events (jump to declaration/implementation etc).
2) Is a regexp (or something else) able to refine the behavior of the indentor, Not only for this very specific case but for the behavior in general?
RegEx -- definitely no. This question is not clear for me anyway -- are you talking about formatting or navigation? If first -- then all currently existing settings are in "Settings | Code Style". If second -- then check "Settings | Editor | Smart keys" -- maybe they will help.
Otherwise -- please record some screencast/bunch of screenshots for current and desired behaviour and submit it as a new ticket to the Issue Tracker: http://youtrack.jetbrains.com/issues/WI
3) Is there a regexp or similar to control the quoting behavior?
No. You explanation is not clear enough. I suggest the same as for #2 -- get a code example and submit it as a new ticket to the Issue Tracker: http://youtrack.jetbrains.com/issues/WI . This way it may gets implemented/fixed for next version
4) not sure there is a way to configure that though - just in case there is?
Don't know. I'm also facing this usability issue and would like to know workaround. The way I'm using it -- pressing "Home" before (or during/after) making the selection (not ideal "solution" as it is still annoying to do so, but works). Alternatively you can use mouse to select the lines (use it over editor gutter area -- where the line numbers are).
If selection is to just delete/duplicate the line -- then there are shortcuts just for that.
Regarding quotes, in cases when you just want the one quote, hit del instead of backspace after typing ".
I've some qualms about the indentation (and code (re)formatting in general) too, but it's that it changes from release to release, there's not much you can do about it though...
Re: selection - in your case you can just hit Home while still holding shift. It never even registered to me as unexpected behavior.
This is my string:
"this is my sentence"
I would like to have this output:
"sentence my is this"
I would like to select a few words on a line (in a buffer) and reverse it word by word.
Can anyone help me?
It's not totally clear what the context is here: you could be talking about text in a line in a buffer or about a string stored in a VimScript variable.
note: Different interpretations of the question led to various approaches and solutions.
There are some "old updates" that start about halfway through that have been rendered more or less obsolete by a plugin mentioned just above that section. I've left them in because they may provide useful info for some people.
full line replacement
So to store the text from the current line in the current buffer in a vimscript variable, you do
let words = getline('.')
And then to reverse their order, you just do
let words = join(reverse(split(words)))
If you want to replace the current line with the reversed words, you do
call setline('.', words)
You can do it in one somewhat inscrutable line with
call setline('.', join(reverse(split(getline('.')))))
or even define a command that does that with
command! ReverseLine call setline('.', join(reverse(split(getline('.')))))
partial-line (character-wise) selections
As explained down in the "old updates" section, running general commands on a character- or block-wise visual selection — the former being what the OP wants to do here — can be pretty complicated. Ex commands like :substitute will be run on entire lines even if only part of the line is selected using a character-wise visual select (as initiated with an unshifted v).
I realized after the OP commented below that reversing the words in a partial-line character-wise selection can be accomplished fairly easily with
:s/\%V.*\%V./\=join(reverse(split(submatch(0))))/
wherein
\%V within the RE matches some part of the visual selection. Apparently this does not extend after the last character in the selection: leaving out the final . will exclude the last selected character.
\= at the beginning of the replacement indicates that it is to be evaluated as a vimscript expression, with some differences.
submatch(0) returns the entire match. This works a bit like perl's $&, $1, etc., except that it is only available when evaluating the replacement. I think this means that it can only be used in a :substitute command or in a call to substitute()
So if you want to do a substitution on a single-line selection, this will work quite well. You can even pipe the selection through a system command using ...\=system(submatch(0)).
multiple-line character-wise selections
This seems to also work on a multiple-line character-wise selection, but you have to be careful to delete the range (the '<,'> that vim puts at the beginning of a command when coming from visual mode). You want to run the command on just the line where your visual selection starts. You'll also have to use \_.* instead of .* in order to match across newlines.
block-wise selections
For block-wise selections, I don't think there's a reasonably convenient way to manipulate them. I have written a plugin that can be used to make these sorts of edits less painful, by providing a way to run arbitrary Ex commands on any visual selection as though it were the entire buffer contents.
It is available at https://github.com/intuited/visdo. Currently there's no packaging, and it is not yet available on vim.org, but you can just git clone it and copy the contents (minus the README file) into your vimdir.
If you use vim-addon-manager, just clone visdo in your vim-addons directory and you'll subsequently be able to ActivateAddons visdo. I've put in a request to have it added to the VAM addons repository, so at some point you will be able to dispense with the cloning and just do ActivateAddons visdo.
The plugin adds a :VisDo command that is meant to be prefixed to another command (similarly to the way that :tab or :silent work). Running a command with VisDo prepended will cause that command to run on a buffer containing only the current contents of the visual selection. After the command completes, the buffer's contents are pasted into the original buffer's visual selection, and the temp buffer is deleted.
So to complete the OP's goal with VisDo, you would do (with the words to be reversed selected, and with the above-defined ReverseLine command available):
:'<,'>VisDo ReverseLine
old updates
...previous updates follow ... warning: verbose, somewhat obselete, and mostly unnecessary...
The OP's edit makes it more clear that the goal here is to be able to reverse the words contained in a visual selection, and specifically a character-wise visual selection.
This is decidedly not a simple task. The fact that vim does not make this sort of thing easy really confused me when I first started using it. I guess this is because its roots are still very much in the line-oriented editing functionality of ed and its predecessors and descendants. For example, the substitute command :'<,'>s/.../.../ will always work on entire lines even if you are in character-wise or block-wise (ctrlv) visual selection mode.
Vimscript does make it possible to find the column number of any 'mark', including the beginning of the visual selection ('<) and the end of the visual selection ('>). That is, as far as I can tell, the limit of its support. There is no direct way to get the contents of the visual selection, and there is no way to replace the visual selection with something else. Of course, you can do both of those things using normal-mode commands (y and p), but this clobbers registers and is kind of messy. But then you can save the initial registers and then restore them after the paste...
So basically you have to go to sort of extreme lengths to do with parts of lines what can easily done with entire lines. I suspect that the best way to do this is to write a command that copies the visual selection into a new buffer, runs some other command on it, and then replaces the original buffer's visual selection with the results, deleting the temp buffer. This approach should theoretically work for both character-wise and block-wise selections, as well as for the already-supported linewise selections. However, I haven't done that yet.
This 40-line code chunk declares a command ReverseCharwiseVisualWords which can be called from visual mode. It will only work if the character-wise visual selection is entirely on a single line. It works by getting the entire line containing the visual selection (using getline()) running a parameterized transformation function (ReverseWords) on the selected part of it, and pasting the whole partly-transformed line back. In retrospect, I think it's probably worth going the y/p route for anything more featureful.
" Return 1-based column numbers for the start and end of the visual selection.
function! GetVisualCols()
return [getpos("'<")[2], getpos("'>")[2]]
endfunction
" Convert a 0-based string index to an RE atom using 1-based column index
" :help /\%c
function! ColAtom(index)
return '\%' . string(a:index + 1) . 'c'
endfunction
" Replace the substring of a:str from a:start to a:end (inclusive)
" with a:repl
function! StrReplace(str, start, end, repl)
let regexp = ColAtom(a:start) . '.*' . ColAtom(a:end + 1)
return substitute(a:str, regexp, a:repl, '')
endfunction
" Replace the character-wise visual selection
" with the result of running a:Transform on it.
" Only works if the visual selection is on a single line.
function! TransformCharwiseVisual(Transform)
let [startCol, endCol] = GetVisualCols()
" Column numbers are 1-based; string indexes are 0-based
let [startIndex, endIndex] = [startCol - 1, endCol - 1]
let line = getline("'<")
let visualSelection = line[startIndex : endIndex]
let transformed = a:Transform(visualSelection)
let transformed_line = StrReplace(line, startIndex, endIndex, transformed)
call setline("'<", transformed_line)
endfunction
function! ReverseWords(words)
return join(reverse(split(a:words)))
endfunction
" Use -range to allow range to be passed
" as by default for commands initiated from visual mode,
" then ignore it.
command! -range ReverseCharwiseVisualWords
\ call TransformCharwiseVisual(function('ReverseWords'))
update 2
It turns out that doing things with y and p is a lot simpler, so I thought I'd post that too. Caveat: I didn't test this all too thoroughly, so there may be edge cases.
This function replaces TransformCharwiseVisual (and some of its dependencies) in the previous code block. It should theoretically work for block-wise selections too — it's up to the passed Transform function to do appropriate things with line delimiters.
function! TransformYankPasteVisual(Transform)
let original_unnamed = [getreg('"'), getregtype('"')]
try
" Reactivate and yank the current visual selection.
normal gvy
let #" = a:Transform(#")
normal gvp
finally
call call(function('setreg'), ['"'] + original_unnamed)
endtry
endfunction
So then you can just add a second command declaration
command! -range ReverseVisualWords
\ call TransformYankPasteVisual(function('ReverseWords'))
tangentially related gory detail
Note that the utility of a higher-level function like the ones used here is somewhat limited by the fact that there is no (easy or established) way to declare an inline function or block of code in vimscript. This wouldn't be such a limitation if the language weren't meant to be used interactively. You could write a function which substitutes its string argument into a dictionary function declaration and returns the function. However, dictionary functions cannot be called using the normal invocation syntax and have to be passed to call call(dictfunct, args, {}).
note: A more recent update, given above, obsoletes the above code. See the various sections preceding old updates for a cleaner way to do this.
Maybe:
:s/\v(.*) (.*) (.*) (.*)/\4 \3 \2 \1/
Of course you probably need to be more specific in the first part to find that particular sentence. Generally you can refer to match groups as \number with \0 being the whole match.
Here's a way to do by calling out to Ruby. After selecting the line you want to reverse, you can do this in command mode to replace it:
!ruby -e 'puts ARGF.read.strip.split(/\b/).reverse.join'
I found the solution myself thank to your answers and a lot of trying :)
This works:
function! Test()
exe 'normal ' . 'gv"ay'
let r = join(reverse(split(getreg('a'))))
let #a = r
exe 'normal ' . 'gv"ap'
endfunction
Didn't thought that I was enable to write such a function :)