-
Notifications
You must be signed in to change notification settings - Fork 0
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 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.
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.
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.
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.
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.
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.
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
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
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 installI 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/
| 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 |
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 |
| 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 |
| 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 |
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 |
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 |
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 |
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 |
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 |
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>
|
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 |
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 |
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 |
Bits that maybe needed at the command line
| Command | Action |
|---|---|
find . -iname '*.swp' -exec rm '{}' \; |
clean up swp after a pc shutdown |