Skip to content
ferng edited this page Jun 23, 2020 · 54 revisions

vim vim vim vim

I've always liked unix's ethos of having one tool to do one job rather than bloatware trying to do absoutely everything.

I've also always liked the fact that you can do do everything through the keyboard without shifting my hand a yard to the right just to start a clicking session for something I can do by pressing a button, co-incidentally the keyboard is just a big collection of buttons and my hands are already there.

Finding the ideal editor and the ideal keyboard is something that will keep me busy for ever I think, but considering the fact that as a developer all I really do is work on my keyboard editing text files I think that's understandable. Ok, there are a couple of other things I do, namely thinking about what I'm doing and scratching stuff out on a notepad with a pencil.

A few editors I've known

In the beginning...

A long time ago my firm favourite was metacomco, and I think that helped developed a bias for clean, clutter-free text editors with a sensible number of commands I also used vi on a xenix machine around the same time. Then moving to Intel machines meant moving over to Borland and the superb Turbo Pascal and C devevelopment systems. A full IDE with simple keyboard commands.

More recent times

Fast forward a few years and the language of choice is now Java (well, by that I mean that's what I get paid for). As clever as Java is, it's a beast; with the amount of libraries, application servers, frameworks and all that XML all over the place a simple text editor won't cut it. Welcome to the world the massive IDEs.

In the commercial world there are really only two choices, Intellij and Eclipse. I used Eclipse until I came across Intellij, when I saw how fast that was I made the switch, and you don't have to configure every plugin, and backing up the config is already in the menu (you don't need new funny accounts on some other service to do so) and you don't have to fish around with trying to figure out where a plug-in you use keeps it's config.

How I yearn for simpler times

As I work commercially with Java I see on a day-to-day basis how some of the fun inherent in my profession gets sucked by silly things like class plath issues, nexus config issues and environment issues. I certainly don't want to play around with a weblogic server in my free time.

So when I'm off the clock I choose smaller languages with a small footprint, if it doesn't compile in a few seconds and run on my little raspberry home server I won't touch it. So I end up playing with java script (OK I use that a lot at work too but only for the front end), c or python.

And although you can use Intellij, or pycharm or Eclipse for that it's over kill.

A couple of years ago I came across Atom and Visual Studio Code at the same time when I started playing with Node js for a big chunk of my free time. Having tried both, VSCode was a clear winner, much faster and very clean. Roll forward a few years and there's now quite a bit of clutter in VSCode, the proliferation of icons everywhere for something as simple as file types was the first indication of it loosing some of it's edge.

Then I got a new PC and thought "ew! I don't want to clutter it all up with tons of junk" to that end I started looking at options. Luckily as it was a Unix box I was spoilt for choice, but the way forward was clear, having used vim for editing stuff directly on hosts, editing commit messages and a myriad of other little tasks I was quite happy to give that a go; also with it being something I getting on for 30 years ago suited me.

Plain VIM

So here we go, I want to use the same tools for personal and professional projects. But I don't want to have a myriad of editors and toolsets for each specific language I use. So it's settled then:

  • Intellij for java - there's no way round it java and it's projects are massive nests of dependencies and easy navigation is crucial.
  • Vim for eveything else.

Now, I know I both vim 8.0 and neoVim add a whole bunch of new features including async processirng which is something plug-ins can benefit from. In case you're interested that means plug-ins are able to run in the background without affecting any work you are currently doing, certainly not freezing the fron-end.

If all I used was my unix laptop I would just upgrade and use that. Unfortunately some of my clients prefer that I use their equipment and infrastructure, in fact most of my clients do, I've only ever come across two that had a BYO policy, this means using Windows. What's worse it's without without admin rights!!!, this means I'm pretty restricted on the tools and OS I can use.

Gitbash to the rescue

In the past cygwin was my go to windows bash shell, now of course, if my client has windows 10 I might be able to get Ubuntu running on that, but that's not normally the case. Instead I rely on gitbash, I'm gonna have to use it anyway as most places use Github or have Stash running within their infrastructure. So if it's not already there I can easily justify installing it on the PC. Gitbash comes with vim 7.4 (which is also what comes by default on Ubuntu), as a result I always use that version of Vim.

Not so plain then

OK so, vim on it's own is a great text editor and combined with your bog standard unix tools you'll be able to do what a regular IDE will do. But you can make things even easier with a few plug ins and a few scripts to automate mundane stuff.

plug ins

Going down a level you can manage plugins manually (it actually only involves doing a git pull), but I don't know, it just feels right to use a plug-in manager, but I may infact decide to do it manually in the future. I'm currently using vim-plug as my plug-in manager, it's does one thing well, manage my plug-ins, additionally it will only load plug-ins when they are needed, so vim's start-up times don't suffer. For instance, I don't need jsx i a eslinter if I'm editing a .py file.

To install it just run:

curl -fLo ~/.vim/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim

installing plug-ins simply involves editing a text file but, rather than copy and paste their user guide, you might aswell read it here: https://github.com/junegunn/vim-plug

what plug-ins

As I decided to make the switch from VSccode to vim while I was working on a couple of node projects and a regular javascript front end one I've listed the plug-ins I use here, this will probably increase as I figure out I need new functionality or need to handle additional languages. These are the plug-ins I currently rely on:

plug in purpose
https://github.com/scrooloose/nerdtree file/project navigation
https://github.com/godlygeek/tabular for tabulating text, useful for parameterized tests
https://github.com/majutsushi/tagbar ctags navigation / display
https://github.com/pangloss/vim-javascript syntax highlighting for javascript
https://github.com/leafgarland/typescript-vim syntax highlighting for typescript
https://github.com/mxw/vim-jsx syntax highlighting for jsx
https://github.com/crusoexia/vim-monokai a coulour theme I like, might change, might not
https://github.com/vim-syntastic/syntastic so I can run linters in vim

now, even though this only takes a few minutes to set up I'm not gonna waste them everytime I come across a new PC i need to use, I also want to avoid the case where a plug-in suddenly dissapears or is updated with new features that change the expected behaviour. I'll manually check every so often, but I don't want to find out on the first day with a new client and I can't even edit a text file cause a new version of a plug-in is a bit broken. So instead I have the whole caboodle set up and ready to be downloaded at: https://github.com/ferng/config

And a couple of unix tools

My current setup relies on ctags for indexing the code, as you can tell by its name it originally tagged c code for easy cross referencing, but now it does a whole bunch of languages: https://github.com/universal-ctags/ctags I chose to build it from the latest version as it only takes a minute:

cd ctags
./autogen.sh
./configure
make
sudo make install

I also use ack, which is a faster and prettier grep, you don't need it, grep will work just aswell, all be it a bit slower: https://beyondgrep.com/

OK so how do I use any of it

some general vim stuff

Command Action
F2 turn paste on while in insert mode
CTRL-SHIFT-PGDN go to next tab
CTRL-SHIFT-PGUP go to previous tab
CTRL-SHIFT-LEFT move tab to the left
CTRL-SHIFT-RIGHT move tab to the right
gt go to next tab
gT go to previous tab
:tabclose close current tab
:tabonly close all other tabs but this one
K find word under the cursor in all project files
:Find find term in all project files
:ccl close quick fix window
:lclose close localtion list window (syntastic)
v select characters then yank
yiw yank current word excluding trailing space
CTRL-O go to older position
CTRL-I go to newer position
:CTRL-w s split windows horizontally
:res 10 change this split to 10 lines
:CTRL-w o close other window
CTRL-w w jump to other window
:e src/app/**/[partial filename]<TAB> walk through all matching files and press to open the one you want
"+yy yank line to ubuntu clipboard
"*y in visual yank selection to ubuntu clipboard
"*p paste from ubuntu clipboard
ciw change word under cursor
:so $MYVIMRC reload vimrc

sessions

VIM will open fern.sess if it exists or just plain NERDTree otherwise

Command Action
:mksession session.vim save session
:so session.vim load session
:WS save session to default 'fern.sess'
vi -S session.vim start vim with that session

replace text

Command Action
:s/foo/bar/ replace foo with bar on this line
:s/foo/bar/g all instances of foo with bar on this line
:%s/foo/bar/g all instances on all lines
:5,12/foo/bar/g all instances on lines 5-12 inclusive
:'a,'bs/foo/bar/g all instances on all lines between marks inclusive

marks - this will really change how you see vim and increase your productivity tremendously

Command Action
ma set mark 'a' in current buffer
mA set mark 'A' here across all buffers
`a jump to line and column of mark
'a jump to line of mark
d`a delete between here and position of mark
d'a delete between here and line of mark
c`a change text between here and position of mark
c'a change text between here and line of mark
y`a yank text from here to position of mark
] jump to next lower case mark
[ jump to previous lower case mark
:marks list all marks
`. jump to previous change
`" jump to last exited buffer
`0 last file edited when exited (1-9 will go back to previous files)
`` jump to previous position
'' jump to previous line
M a delete mark a
:delmarks a delete mark a
:delmarks a-d delete marks: a, b, c, d
:delmarks xyz delete marks: x, y, z
:delmarks! delete all marks

buffers

Sometimes it helps to work with buffers directly, I find that's the case specially when getting acquainted with a new project

Command Action
ls list all the open buffers (in the current tab)
:b5 open buffer #5

vim plug

Just to check what plug-ins we have or to install a new one

Command Action
CTRL-p display Current Plugin status. 'U' update/install. 'L' whatever one you want

ctags

Need to find that declaration, ctags to the rescue. You could configure vim to do this on save, or plonk in a githook to do it on pull and commit. I haven't bothered I'll run it as I go.

#build tags
git clone https://github.com/universal-ctags/ctags.git
cd ctags
./autogen.sh
./configure
make
sudo make install

#run ctags in the shell for the current project
ctags -R --exclude=.git --exclude=node_modules --exclude=package-lock.json --exclude=target --exclude=lib --exclude=dist --exclude=build
Command Action
CTRL-] jump to definition
CTRL-t jump back up
:tag /^asserts_* create list of tags starting with asserts
:ts shows the list
:tn go to next tag in list
:tp go to previous tag in list
:tf go to first tag in list
:tl go to last tag in list
F8 display tagbar

NERDTree - file navigation

Walk through the project tree and all the usual stuff that happens on the left hand side on a regular IDE

Command Action
F7 toggle nerdTree navigator on and off
O open directory recursively
X close directory recursively
t open file in a new tab and move focus to it
T open file in a new tab but retain focus on nerdtree
:Bookmark <name> create bookmark
:ClearAllBookmarks delete them all
D delete current bookmark
p jump to parent node
P jump to project root
CTRL-j jump to next sibling node
CTRL-k jump to previous sibling node
I toggle display hidden files
F toggle display files
B toggle display bookmarks
q close nerdtree window
,n locate open file in project directory
m manipulate nodes: add, delete, etc
r reload directory listing from current node
R reload directory listing from root

Linting

Syntastic runs the linters stuff

Command Action
CTRL-h run SyntasticCheck to run the appropriate linter against the file type and report any problems
Fix run SyntasticCheck and fix any problems reported by the file type's linter
WL write and lint the file
WF write, fix, reload and lint the file

Coding

Ok, it's all for coding (well mostly) but these are very specific tasks

Command Action
,/ comment / un-comment all lines between current line and mark a inclusive or just current line if no mark is set
<range>Com comment / uncomment all lines in the range
vip:Com in visual mode comment / uncomment in surrounding paragraph / function
vi:Com in visual mode comment / uncomment whatever you selected
== opinionated formatting: current line
retab! apply current tab settings
gg=G opinionated formatting: whole file
FT retab! and gg=G
>> indent current line
5>> indent 5 lines from current line
>> indent current line
>i{ indent inner block
<i{ un-indent inner block
=i{ re-indent contents of block
=a{ re-indent contents of block and braces
=2{ re-indent this block and containing block
]p paste indenting lines to block level
TAB indent all lines between current line and mark a inclusive or just current line if no mark is set
SHIFT-TAB un-indent all lines between current line and mark a inclusive or just current line if no mark is set
ciw""<ESC>p surround current word with quotes
ciw<p><CTL-r><CTL-o>"</p> surround current word with <p></p>

Tabular

Tabulate text, useful to prettify parameterized tests, and that sort of thing

Command Action
:Tabularize /,/r1c1l0 tabularize text based on commas
:Tabularize /^[^,]*\zs,/r0c0l0 tabularize text on the first comma only
:AddTabularPattern first_comma /^[^,]*\zs,/r0c0l0 assign a name to a pattern // add to a .vim file

vimdiff

Use vim as a your diff tool. Start it with:

vimdiff file1 file2
Command Action
dp put from left (file1) to right (file2)
do obtain from right (file2) to left (file1)
:diffput put from left (file1) to right (file2) if using visual select
:diffget get from right (file2) to left (file1) if using visual select
]c next difference
[c previous difference
:diffu update the display if needed

Word Processing mode

Makes vi act a bit more like a word processor

Command Action
:WP enter word processing mode for this session
<UP> or k now moves one line at a time
<DOWN> or j now moves one line at a time
[s go to previous misspelling
]s go to next misspelling
z= list corrections for misspelling under cursor

Command line

Bits that maybe needed at the command line

Command Action
find . -iname '*.swp' -exec rm '{}' \; clean up swp after a pc shutdown

Clone this wiki locally