I know that I can get word completion through CTRL+N & CTRL+P and code completion through omnifunc with CTRL+X CTRL+O. I additionally tried Supertab (very nice), because I'm used to TAB-completion. That all worked all right. I would like to see possible matches while I'm typing, so I also tried autocomplpop.vim, witch does just that.
What I like to accomplish though, would be a combination of both together with a little twist: I would like to see suggestions pop up as I type (just like with autocompop) but when I use TAB the word should be expanded only to the largest common match:
foo bar testor booze test baz teter
te<TAB>
After I type te in the 2nd line, the popup should suggest test, teter and testor.
When I press TAB, it should do nothing, because there is no more common ground than te. After I typed an additional s and press TAB, it should expand tes to test (because it is the smallest common ground) and to testor after a 2nd TAB.
Edit: I try to be more clear...
te<TAB>
should do nothing because "we" don't know if a 't' (teter) or an 's' (test, testor) should follow.
tes<TAB>
should expand to test (because that works for both - test and testor - and teter is no longer a possible match).
test<TAB>
should expand to testor (only possible match).
Well, the suggestions popup is just bonus, but I really would love to see the TAB behavior. Hope I don't get to esoteric here and you can help me out with some script-tricks or plugins to tame VIM to do just that.
:set completeopt=longest,menu,preview
maybe?
(I'm not sure if your statement
"when I press TAB, it should do nothing, because there is no more common ground than te"
conflicts with your later statement
"to testor after a 2nd TAB."
It seems to me that there's no more common ground than "test" at that point... Unless you mean the first tab goes to the longest common ground, and then the subsequent tabs cycle through the other matches, in which case you're after what I have above...)
Related
This is not a programming question but an inconvenience in the android-studio editor.
If you have an unwanted tab before all your lines, how can you remove them all at once? Now I have to manually go over 50 lines to remove all the tabs to make my code look clean.
If you want to add multiple tabs at once you just select all your code and press the tab button. So I'm looking for the reverse of that.
If I understood you right, you want to beautify the code itself. Fortunately, you don't have to do that manually - at all.
There's a keybinding for it, which may vary by your OS and which layout you use by default. Go to file -> settings -> Keymap and search for auto-indent. Here's what I get on Windows 10 with the default keymap:
Again, which you have may depend on OS (I'm assuming that mainly applies to Mac though) and your keymap, but you can automatically indent your code as per language standards using Ctrl+Alt+I.
Note that this mainly does indentation. If you chose to golf code and want to ungolf it, this will not work. At least it doesn't for Java.
However: This only works with code files the IDE or plugins support. This won't work for i.e. a .txt file out of the box.
If I misunderstood you and you only want to remove tabs without doing the auto-indent, there's at least two other options.
The first option is using multiple cursors. You can add an additional cursor with shift+alt+a mouse click where you want the cursor, or holding the mouse wheel and moving the cursor with the mouse wheel held down. There might be other methods as well, but those are the two I know of.
Once you have multiple cursors, delete the tabs just like normal. But be careful! Doing so might delete the entire line itself. If it does, you can do 1 tab/n units per indent level to the left, and press delete instead.
There's (AFAIK) no limit to how many cursors you can have at once, but you can theoretically do it with 50 lines at once if you want to. But general advice - don't add more cursors than you can see at once. These do run in parallel and it's easy to lose track if you're not careful, and you might end up deleting stuff you didn't want to delete.
And finally, the regex solution:
Note: Be careful with this. If you use it incorrectly, you might get unwanted results.
If you only want to do this in a limited area, highlight it first. Then CTRL+R and you'll be presented with the regular replace menu. Make sure Regex and In Selection are selected.
A base regex to go off is ^([\s]{2,4}|\t). Explanation just for reference:
^ - At the start of the line
(
\s{4} - Match 4 spaces
|\t - Or a tab character
)
Replace with nothing and click "replace all" (or just use the regular "replace" button if you want to double-check before you do anything). This will replace one occurrence of 4 spaces or a single tab character. If you use indentation that isn't based on 4, change the number.
This is only useable and useful if you've found yourself with incorrect indentation that's the same across all the relevant lines - it will not fix indentation mistakes and/or inconsistencies such as 3-space indentation when you want 4, or random indetation for the same block. Use the first or alternatively second method for that instead.
In vim (in Insert mode, after running exuberant ctags), I am using ctrl-x followed by ctrl-] to bring up a dropdown of various possible words/tokens. It's a great feature.
The problem is that by default, this list starts with a bunch of numeric options and automatically inserts the first numeric option, and if I backspace to get rid of the numbers and start typing a part of a word fresh -- with the idea of searching from the middle of the word -- the autocompletion behavior exits entirely.
I know I could type the first letter of the word that I want, then go from there. But that assumes that I know the first letter of the word, which is not necessarily a given.
For example, if I'm working on a pair-programming project with a friend during a long weekend, I might not remember at any given moment whether he called his method promoteRecordStatus(), updateRecordStatus() or boostRecordStatus(). In this example, I would like to type RecordStatus and get the relevant result, which does not seem to be possible at a glance with the current behavior.
So with that scenario in mind: Is there a simple, vim-native way to tell the editor to start its autocompletion without any assumptions, then search all available tokens for my typed string in all parts of each token?
I will of course consider plugin suggestions helpful, but I would prefer a short, vim-native answer that doesn't require any plugins if possible. Ideally, the configuration could be set using just a line or two.
The built-in completions all require a match at the starting position. In some cases, you could drop separator characters from the 'iskeyword' option (e.g. in Vimscript, drop # to be able to complete individual components from foo#bar#BazFunction()), but this won't work for camelCaseWords at all.
Custom :help complete-functions can implement any completion search, though. To be based on the tags database, it would have to use taglist() as a source, and filter according to the completion base entered before triggering the completion. If you do not anchor this pattern match at the beginning, you have your desired completion.
Edit: I moved this over to the Vi and Vim site: https://vi.stackexchange.com/questions/13689/how-to-find-and-replace-in-vim-without-having-to-type-the-original-word
I'd like to optimize my "find and replace" workflow in Vim. It's something I do often, as I'm sure most of you do too. Usually something along the lines of -- copy a block and change the name of a variable in a few places. I know, I know, that probably triggers your "why are you copying and pasting code" reflex, but let's not go down that road... There are plenty of valid use cases :)
I'm well aware of the search and replace commands: :s or :%s but I don't like them. It forces me to type out both the full variable name I'm searching for and what I'm changing it to. Maybe there is a better way fix the the amount of typing with :%s? I often use long descriptive variable names, so that is really a deal breaker for me. I also don't like how typing out a variable name from scratch is typo prone and can consume time and brainpower hunting down typos. I much prefer typing it once, and then copying and pasting to just avoid this entirely if possible.
My current workflow uses some combination of movement/yank/select/search/put to move around the file and replace one by one. It is not great but has the benefit of avoiding typing out full variable names. I might just need to type the first few letters with / or use another movement command (i.e. fx) depending on what's around and then hit ve to select the whole word. I also don't mind that I have to repeat for every instance. I never do a full find replace without confirming each change. But it would be much preferable if I could repeat the replacement action with a single keystroke (which I can't do with this method). each replacement is usually something like n then ve then p (or even worse "0p)
Is there a faster way?
My own workflow is similar to yours:
To start, get the cursor on one instance, possibly with / or by navigation.
Hit * to find the next instance of that word.
Change one instance with cw and then the new variable name.
Then it's fast: n/N to get to the next/previous instance, and . to repeat the last edit.
This workflow gives me the same advantage as yours, in that I can review each case before applying the change, but it's just two keystrokes for each additional change.
Hope this helps.
I like the "visual highlight then edit" approach.
shift + v to highlight the region that you want to modify.
then :s/old/new/r where old is what word you want to replace with new.
r changes the first instance of that word old.
Note* There are options other than r which modify its behavior how you want to replace the word.
I am using vim for quite some time now, but several times per day I accidentally encounter an inconvenience by hitting ESC too early.
Assume I am editing the following file:
I want to change 'house' in this line.
'house' should stay like this.
This 'house' should become 'home'
The other 'house' should also change.
I want to change house to home in all lines except the second one. (In this simple example it would easy to write a :s command and perform the task, but usually the task is more specific and manual replacements are quicker and less error prone.) I navigate to the first occurrence of house, press cw, type hone, and hit ESC. After hitting ESC I realize that by accident I typed the letter n instead of m.
I could navigate to the next occurrence of house and hit . to repeat the faulty replacement. In this case I have to fix all hones and replace the n by m afterwards.
I could fix the mistake immediately, but then I can not repeat the same house->home replacement, since . would repeat the n->m replacement.
All of this would be no problem, if I had spotted the mistake before hitting ESC. My question is, if there is a way to undo leaving the insert mode, such that . will repeat both actions? Or similarly, is there a way to tell . to repeat the last to operations?
(Of course this sounds like recording a macro, but since I end up in this situation by mistake, I have not started a macro recording.)
As far as I am concerned, there's no command history of vim in that you could repeat the last two operations.
However, there's a plugin that could help you accomplish that. It's called the RepeatLast.vim plugin to address this exact requirement. It provides a 2\. key binding. The cost for using that plugin and how the plugin actually works is that... it actually enables macro recording all the time. But if you could live with that, it should deal with this sort of situation pretty fine.
[Edit: after reading comments I realize that the Surround plugin is adequate for my needs after all, so I'll leave this question for purely academic purposes to gain a better understanding of vimscript's inner workings]
I'd like to make adding/deleting tags, quotes, braces, and other symmetrical text structures easier to do in Vim, and I find the surround.vim plugin a little too quirky and specialized for my needs.
What I really need is more generally a "mirrored" input mode and "mirrored" deletion mode, whereby I could visually select a block of text, then type onto or delete from both ends of the selection at once. As an example workflow, I'd like to:
select the word hello
hit some keystroke combo to enter "mirror mode"
type "
my text now says "hello"
In this example I only typed one character at each end, but it's important that in step three I could have typed many characters, not just one, for instance I should be able to type <b> to produce <b>hello<b> (I still would need to manually add the / in the closing tag, which I'm OK doing).
So is this even possible in Vim? Could someone provide a broad outline of functions that would be involved in the solution? Specifically, I don't know how to intercept text as it's being inserted and then alter the location where it appears so that it's tacked onto the beginning and ending of the selection block instead of the cursor location. And ditto for deletion.
Well, the behavior you describe is exactly what Surround does:
select the word hello
hit S
type "
my text now says "hello"
The difference with what you ask is the "live updating" or "live mirroring" which I have no idea how to do. You could probably take a look at SnipMate or UltiSnips for that part.