Monday, November 20, 2006

Sample Ex/Vim Ranges

Here we go.

:%s/[a-z]/\u&/g

Substitute in all lines (the range defined by '%') all lower case latin letters ('[a-z]') with upper case letters ('[A-Z]'). Substitute in all lines (the range defined by '%') every lower case latin letter ('[a-z]') with upper-case letter ('\u&', see for more info :h s/\u).

:<'>' w new_file_from_selection.txt

Write ('w') all selected lines ("<'>'") into new_file_from_selection.txt. (You do not need to type that "<'>'" thing. Select lines in visual mode (entered by Shift-V) and then press ':' - vim will put the <'>' in prompt line for you)

:5,+99 w new_file.txt

Write ('w') to the file "new_file.txt" lines: 5th and next 99 ones included, total of 100 lines. (Provided that the actual file has minimum 1054 lines).

:0,$ ! tac

Filter ('!') all lines ('%' is simple shortcut for '0,$') through the external application 'tac'. The filter command would then replace all affected lines with the output of the application - in that case the lines would reappear in inverse order, thanks to the 'tac' command. ('tac' is of course opposite of 'cat'. man tac.).

:<'>' ! wc -l

That would replace all selected (in visual mode) lines with the count of selected lines, as counted by 'wc -l'.

And to conclude, the most useless (unless you're vim scripting addict) range example:

:.=

Print current line (range '.') number (command '=').

Edit1 Fix the uppercase command, as per anon comment. It should have been some real weird booze I had that day. N.B. more optimal is of course this: :%s/.\+/\U&/.

ZQ

Friday, October 20, 2006

Off Topic :: GNU Arch (TLA) Commands Quick Reference

User identification

$ tla my-id  "John Doe <user@aol.com>"
$ tla my-id # to print currently set id

Create Archive

$ mkdir  ~/{archives}
$ tla make-archive user@aol.com--2006-quickref ~/{archives}/2006-quickref

Find Archives

$ tla archives                    # to print all available archives
$ tla whereis-archive user@aol.com--2006-quickref

Default Archive

$ tla  my-default-archive  user@aol.com--2006-quickref
$ tla my-default-archive # to print it
$ tla my-default-archive -d # to delete the preference

Provisioning Archive Space

$ tla archive-setup hello-world--mainline--1.0
$ tla categories # prints hello-world
$ tla branches hello-world # prints hello-world--mainline
$ tla versions hello-world--mainline # prints hello-world--mainline--1.0

Initializing before Import

$ cd ~/wd/hello-world
$ tla init-tree hello-world--mainline--1.0
$ tla tree-root # prints /home/jdoe/wd/hello-world
$ tla tree-version # prints user@aol.com--2006-quickref/hello-world--mainline--1.0
$ tla log-versions # prints user@aol.com--2006-quickref/hello-world--mainline--1.0
$ tla set-tree-version [new-version-name]
$ tla add-log-version [new-log-name]
$ tla remove-log-version [existing-log-name]

Checking Inventory

$ tla inventory --names --source  # to see what arch classifies as sources
$ tla inventory --source --ids # to see ids given by arch to sources
$ tla inventory --names --backups # to see what arch classifies as backups
$ tla inventory --junk | xargs rm # remove all what arch think is junk

Adding/Removing Files

$ tla add hw.c main.c
$ tla delete hw.c
$ mv hw.c hello.c
$ tla move hw.c hello.c
$ tla tree-lint # to see if all clean, tla won't import/ci from unclean directory

Import (Initial check in)

$ tla make-log                    # create log file and print its name
$ vim `tla make-log` # edit log in vim
$ tla import # copy working copy into archive
$ tla revisions hello-world--mainline--1.0 # prints base-0
$ tla revisions --summary --creator --date hello-world--mainline--1.0
$ tla log-revisions
$ tla logs hello-world--mainline--0.1 # prints base-0
$ tla logs --summary --creator --date hello-world--mainline--1.0
$ tla cat-log hello-world--mainline--1.0--base-0

Committing Changes

$ tla changes --diffs             # or (in tla 1.3) just "tla diff"
$ tla make-log # create log, required
$ tla commit # do it, creates patch-1
$ tla commit -s "Summary" -L "Log Message" # commit with log auto generated
$ tla revisions --summary hello-world--mainline--1.0 # last revision info
$ tla logs --summary hello-world--mainline--1.0 # last log entry info

Checking Out

$ tla my-default-archive          # check where is default archive is
$ tla whereis-archive user@aol.com--2006-example # display local/net path
$ tla categories # lists available project in default archive "hello-world"
$ tla branches hello-world # lists available branches of the project "*--mainline"
$ tla versions hello-world--mainline # lists available version of the branch "*--0.1"
$ tla revisions hello-world--mainline--0.1 # lists available revisions base-0 & patch-1
$ tla get hello-world--mainline--0.1 hello-world # check out most recent revision of into "hello-world" directory, or
$ tla get hello-world--mainline--0.1--base-0 hello-world # check out specific revision
$ ls # should list "hello-world"

Update (Replay)

$ tla undo              # back off local changes
$ tla replay # get latest patches from repository
$ tla redo # reapply local changes
$ tla update # all of three steps above with one command.

Networked Archives

$ tla register-archive lord@emf.net--2003b          
http://regexps.srparish.net/{archives}/lord@emf.net--2003b # HTTP, R/O
$ tla register-archive lord@regexps.com--2002
ftp://ftp.regexps.com/{archives}/lord@regexps.com--2002 # FTP, R/W
$ tla register-archive user@aol.com--2006
sftp://random.homeunix.org/home/jdoe/{archives}/2006-quickref # SFTP, R/W
$ tla my-default-archive [archive-name] # and the rest is just like described above

Mirroring (Locally) Network Archives

$ tla register-archive lord@emf.net--2003b-SOURCE $remote_location   # once
$ tla make-archive --mirror-from lord@emf.net--2003b-SOURCE $local_location # once
$ tla archive-mirror lord@emf.net--2003b # repeat to pull latest changes

Mirroring (Remotely) Local Archives

$ tla make-archive --mirror mine@somewhere.com $remote_location      # once
$ tla archive-mirror mine@somewhere.com # repeat to push latest changes

P.S. Made after this tutorial.

Wednesday, October 18, 2006

Thursday, October 12, 2006

Vim Cookbook by Steve Oualline

Vim Cookbook by Steve Oualline. Interesting reading. Lots of little tips.

P.S. Delves a bit into ranges supported in ex commands. I still cannot get myself to write entry on vim ranges.

Friday, September 15, 2006

VIM 7 :: RE: turn off paren/parenthesis/whatever highlighting

The fix submitted before isn't reliable. That piece of magic in .vimrc does the job:

let loaded_matchparen = 1

It tells some plug-in/script/whatever that it has already did the job. If you put that in .vimrc - it would think that way always and would not load anymore. Nice.

P.S. The Tip was found here :help pi_paren.txt. It would be all really nice if computers had a special interface to read my mind - and tell me how the devels named particular feature. That way I will not need to waste weeks to find the corresponding help entry.

Wednesday, September 13, 2006

VIM7 :: file type detection

New in VIM7 is file type detection. To get info whether it is present/activated try that:

:filetype

and that to turn it off:

:filetype off

File types are made to allow bulk customization for particular file type. At moment it doesn't provide any advantages over plain :au - but probably more to come in future.

P.S. :filetype off must be at top of .vimrc - it tries to manage everything so many options changed before would be reset.

P.P.S. Relevant help pages/see also: :help filetype, :help 'filetype' and :help ftplugin.

Monday, September 11, 2006

VIM 7 :: turn off paren/parenthesis/whatever highlighting

Put that line into .gvimrc:

NoMatchParen

Seems like due to serious Q&A problem that shit creeped into release of VIM7.

:help hl-MatchParen for more info on how to wear down your eye in under 5 minutes with minimum of options set. [sarcasm off]

Edit1: seems like that feature is automatically enabled only for GUI vim, in other words NoMatchParen is accepted only in .gvimrc.

Edit2: The solution is not reliable. Proper fix!

Thursday, August 31, 2006

Dangers of Wikipedia

That damm Wikipedia thing is addictive. It must be outlawed. Once you start reading it - page after page, link after link - you cannot stop.

Anyway. Pretty nice opinion from Tim O'Reilly about why he is vi guy.

Replace "emacs" with "random Wind0ze GUI IDE" - and what he said would be true to me too.

P.S. As for me, "Emacs vs. VI " holy war really comes down to "all-in-one v. modularized" debate. Or from another POV it can be seen as "shell vs. emacs lisp": to Emacs lisp is what shell to Unix. I like VIM since it works with shell directly - it does not have any layers distancing user from OS. I guess if one doesn't like shell but likes elisp instead - then Emacs may be the way to go.

Cult of vi

Cult of vi has among other interesting references the chart of vi commands.

P.S. :g/^/m0/ and ZZ look like fun!

VIM @ Wikipedia

VIM's Wikipedia Page

Off-Topic: dumping gcc/cpp predefined macros

echo | gcc -dM -E -

-dM tells cpp to out #define for every variable it has.

-E tells gcc to run cpp only

P.S. I dead tired to dig documentation every time I need to find how platform is identified by GCC. So putting that stuff here in hope that it would be easier locatable.

Monday, August 14, 2006

vim :: repetition counter (and period command)

One of the funniest (and obscure) VIM features is repetition counter. Most of the commands allow the counter. Consider example (that needs to be typed in in normal mode):

20l

The VIM's command 'l' is the command to move left (VIM supports motion keys as in old time games - 'h', 'j', 'k' and 'l' are correspondently left, down, up and right.) Prepended to it '20' is the repetition counter. If cursor was in position 1, after the command it would be in position 21 (or on end of line if it is shorter).

1000dd

Would delete 1000 lines starting from current.

3f<Space>

Would move cursor to third space in line, counting from current cursor position. (:help f for find motion command.)

It is very useful at times for example combined with command '.' which is used to repeat last command(s). Example how to make a nice C comment with 50 dashes.
<Insert>/*<Space><Space>*/
<Esc>lll
<Insert>-
<Esc>49.

I intentionally made typing of dash separate, thus it can be later repeated with '.' command. I yet to gain complete understanding on how '.' works precisely, but in most obvious cases it works as expected. :help . for more info. Experimentation plus 'u' undo command could help to get it right.

More info can be found in VIM under :help count & :help repeat.txt.

Friday, August 11, 2006

vertical selection from Nth to Mth character

ZOMG! I got e-mail. That stuff apparently got indexed by Google. So. Here we go.

I do have a question for you, however. When performing a vertical selection, is there any way to advance the screen other than the arrow keys? For instance, if a file were thousands of lines long, is there a way to quickly select characters 10 through 20 for the entire length?


All motion shortcuts must work as usual. (:help motion.txt) In other words. To select vertically across all lines in the file chars 10 to 20 you need something like that (those " are comments):


gg " move to beginning of file, beginning of line
9l " move to 10th symbol in line (l == move 1 char left,
" 9l == move 9 times chars left)
^V " start vertical selection
G " move to last line of file, beginning of line
19l " move to 20th symbol in line.


now y/d/whatever to yank/delete/etc. IOW, no magic - standard shortcuts. I hope that answers your question.

Though there might be problem: if last line of file shorter than 20 characters, or if first line shorter than 10 characters, or tab character is sitting somewhere there - VIM wouldn't be able to do precisely what you want it to do.

P.S. For later case shell comes in handy: man cut for -b & -c options. Using redirection and intermediate file you can get you part into separate file and then open it (along with original) in VIM - and use normal line blocks. With combination of head and tail (man head & man tail) you can get from file lines you need.

Thursday, August 10, 2006

vim :: turn that 'showmatch' crap off

I have just waisted hour to find that sucker:

set noshowmatch

SUSE (as well RedHat) have long tradition of shipping f*cked up configs for all major editors and terminal emulators. SUSE 10 (in addition to unusable xterm config and vim's "set backspace=0" (which renders backspace key in vim totally borken)) now started adding "set showmatch" to default exrc. As if anybody over there at SUSE/Novell actually used once xterm or vim. Why they keep crapping in the configs?? Are GNOME/KDE configs not enough for distros to shit into???

set showmatch, if you have just typed parens/bracket/comment opening/etc, makes cursor to jump shortly to its counterpart. That shit is creping off Wind0ze over-bloated unusable IDEs. It distracts your attention of what you were doing. It forces you to move your eye - as if you do not know your own source code - needlessly, wearing and tiring them down. Might it be OS vendors have a secret contract with ophthalmologists??? I have no other guess.

P.S. Linux Productivity Magazine, Volume 1 Issue 5, December 2002 "VI and Vim" - http://www.troubleshooters.com/lpm/200212/200212.htm - lots of vi/vim basics.

Edit1 Related: matching parens highlighting. Mistakenly attributed to VIM7, but also present in VIM6.

Edit2 Proper fix

Tuesday, July 18, 2006

vim :: tags keyboard shortcuts

Keyboard shortcuts used to work with tags. There are really few of them. All of them work in control/normal mode.

  • :set tags? needless to remind that VIM must be told which tag files to use. It can be done automatically as for example shown here.
  • :tag word is main one. Opens file and goes to line with first tag entry matching word.
  • ^] same as above, but uses word under cursor.
  • :tag /word is similar to :tag word. Opens file and goes to line with first tag entry matching regular expression in word.
  • :tselect word is what I use most often. The function - tag select - displays list of matching tags allowing you to select one to go to. Without word, it will display list of matching tags for word used last time.
  • g^] same as above, but uses word under cursor. Also, omits displaying list if only single match is found.
  • :tnext goes to next matching tag entry.
  • :tprev goes to previous matching tag entry.
  • :tlast goes to last matching tag entry.
  • :tfirst goes to first matching tag entry.
  • ^T Every time you do :tag word, the word with current file position is put on stack and vim goes to new file/position as it is told by tag file. To restore the previous file position you use ^T. The shortcut removes tag stack top element and moves to the file position saved there. So if you wandered off far away with ^] - to return back where you started you need to press ^T until vim would complain that it is at bottom of tag stack.
That's about it. Both :tag word and :tselect word support wildcard key (Tab/^D) to show list of tags matching partially the word. That will work with regilar expressions too. But be warned that often tag files can host millions of entries: displaying list of thousands items can take some time. Use wildcard key carefully.

Friday, July 14, 2006

syntax highlight for non-standard file types

Following line once put into vimrc will tell vim which syntax highlighting to use:

au BufReadPost SCons* set syntax=python
au BufReadPost Cons* set syntax=perl
au BufReadPost *.mke set syntax=make
au BufReadPost make*.inc set syntax=make
au BufReadPost *.fcc set syntax=cpp
au BufReadPost *.fhh set syntax=cpp


This is selfexplanatory. e.g. SCons files are in fact python scripts - so tell vim to use python syntax highlighting on everything what matches 'SCons*'. Same goes for Construct - but done in perl.

:au BufReadPost <mask> tells vim to execute something right after file read into buffer. In that particular case we use that to set buffer local variable 'syntax' to name of one of standard syntax highlightings (perl, make, cpp, etc). :help :au for more info.

P.S. One can check what syntax module vim has loaded by looking at 'syntax' variable value: do :set syntax? after opening file recognized by vim.

P.P.S. Of course, :syntax on has to be put somewhere in the vimrc for syntax highlighting to work automatically. VIM 6.x doesn't have problem of previous versions (I experienced that in VIM 5.x), where loading of syntax from vimrc was slowing launch time, even if file had no syntax highlighting assigned. Hm.. or probably my PC now fast enough for me not to notice that launch time. Who cares. It works.

Friday, June 30, 2006

highligting tabs and trailing spaces

Add the following to .vimrc:

highlight SpecialKey ctermfg=DarkGray
set listchars=tab:»-,trail:~
set list


That makes something like that:

map <silent> <F7> :exec ":e ".(expand("%") =~ ".h$"
\ ? glob(substitute(expand("%"), ".h$", ".cpp", ""))
\ : substitute(expand("%"), "\\.cpp$", ".h", ""));<CR>

to be displayed that way:
map <silent> <F7> :exec ":e ".(expand("%") =~ ".h$"~
»-------\»------? glob(substitute(expand("%"), ".h$", ".cpp", ""))
»-------\»------: substitute(expand("%"), "\\.cpp$", ".h", ""))<CR>


Tabs are now plainly visible and also public enemy trailing space on first line became apparent.

P.S. Nice character '»' requires set encoding=utf-8. That looks great with "Andale Mono" and "Black Bold" color set in PuTTY to (39,39,39).

Edit1:

to

tabs!!!

It's nice to know that there are reasonable people left. Read on.

http://derkarl.org/why_to_tabs.html

Attack of clowns^Wclones^Wamateurs of WYSIWYG/WYSIAYG at times is plain depressing.

Wednesday, June 28, 2006

vim :: windows and buffers

VIM can open and edit simultaneously many files. For that VIM uses two elements:

  1. Window - part of VIM's screen space. Screen of every VIM instance can be divided into several windows. When GUI available, one can of course launch several instances of VIM. But in terminal in common case user is limited to single 80x25. When you need to edit two files side by side - VIM windows come to help.
  2. Buffer - place in VIM's memory. That's where file content resides while you are editing it. Buffers is what you see in output of ":ls" command. Every file you open automatically put into new buffer. Buffers are numbered starting from 1. Single buffer can be displayed in more than one window at the same time.
Consult ":help windows" (":help buffers") for indepth info on buffers and windows.

[link] basics of search and replace

Linux.com has few word to say about VIM's search/replace facility. Read on.

http://www.linux.com/article.pl?sid=06/06/26/1525255

Monday, June 26, 2006

vim modes

Modes are probably the most obscure part of vim. I do not like them. But I do not like even more Emacs and PC's editors approach with terribly long and complicated shortcuts.

VIM mode defines how pressed keys are interpreted. One can tell currect VIM mode by content of left bottom corner of screen. Command (normal) mode has no special marker. When in insert mode one would see there '--INSERT--'. Replace & visual modes have similar markers: '--REPLACE--' & '--VISUAL--'.

  1. Command (normal) mode. The default mode used after invokation of vim. All keys are mapped into some command. Sleeping on keyboard in that mode can be dangerous: many key combos can be lethal to your document (or if you are root to your system). That's the main mode where one manipulates the content of file.

    Press <Esc> two times to get into command mode from any other mode/situation. Typing :q<Enter> would quit VIM.

    VIM's help for the shortcuts of command mode uses prefix "c_", e.g. ":help c_CTRL-D<Enter>" would bring the help for ^D shortcut of command mode. Type ":help c_" and press Tab/^D instead of Enter to see all standard shortcuts of command mode.

  2. Insert mode. The mode activated by pressing 'i' or <Insert> in command mode. Typing characters would insert the characters into the document. That's the mode one uses to input text. Shortcuts to manipulate text in insert mode are bound to non-printable characters and functional keys (e.g. keys with modifiers - Alt, Meta, Cmd, Shift, etc).

    VIM's help for the shortcuts of insert mode uses prefix "i_". Type ":help i_<Tab>" to see all standard shortcuts of insert mode. Insertion of text heavily covered in ":help insert.txt"

    N.B. Insert mode has a submode called "Replace mode". It's the same as insert mode, but typed letters instead of being inserted into the position under cursor - moving existing letters on the line right of cursor - would replace them. The submode is usually activated by pressing <Insert> in insert mode. I normally use 'R' (Shift-r) in command mode, since I do not like going into replace mode accidently hitting <Insert> twice (or hitting it once again in insert mode)

  3. Visual mode. The mode I use a lot, since I come from PCs/DOS and standard DOS editors depend heavily on visial text selection. Visual mode allows one to mark continuos part of text. Any invoked command allowing text range would use visual selection as the range. Commands are the same as in vim's command mode. The are three submodes:

    • Visual mode - by character. Activated by pressing 'v' in command mode. Use motions keys to select range character-wise. Selection starts on character under cursor when activating visual mode. End of selection is on characted under cursor. When finished selecting use command you like e.g. 'd' to delete selected text.

    • Visual mode - by line. Activated by pressing 'V' (Shift-v) in command mode. Allows to select lines of file. For example you can select several lines and send them to external filter application - e.g. ":r!sort" to sort them.

    • Visual mode - by block. Activated by pressing ^V (c_CTRL-V) in command mode. Most commonly refered as vertical selection. Allows you to select rectange-like part of text, spanning several lines. E.g. you can delete N characters in the beginning of several adjacent lines. Or every Nth character of several adjacent lines. Try it. It's hard to explain, but easy to understand by experimenting.

    Help for the shortcuts uses prefix 'v_', thou you would find that most of the shortcuts are the same as in command mode. ":help visual.txt" for more info.

Sode note. Officially, there are more to vim modes. The three aforementioned are the modes I use. All other modes find little application in my day to day life. For more indepth info on vim modes try ":help vim-modes". Every mode serves its purpose. Probably you would find some other modes useful too.

Tuesday, June 13, 2006

little things

Bunch of little options normally found in my vimrc:

  • set nowrap
    disable long ling wrapping. since most of the time I do coding, I do not need wrapping. My coding style doesn't "allow" long lines anyway.
  • set ruler
    enables display of current line/column number at bottom of screen.
  • set title
    enables changing terminal title. Works with xterm and alike by printing specially crafted escape sequence understood by the terminal emulators.
  • set bs=2
    make Backspace work as expected. Be default, new VIMs allow backspacing only just typed text.
  • set cindent
    enables indentation for C-like languages. Pressing Enter will position cursor indented according currect context nesting.
  • set cinkeys-=:,0#
    disable indentation processing when typing colon and hash symbols.
  • set wildignore=.o:.lib:.dld
    when completing file names, ignore files with extensions on the (colon separated) list.
  • set wildmode=list:longest
    when completing, first complete to the longest common matching string and then list possible matches.
  • set bg=dark
    tell syntax highlighting to expect dark (black) backgroung.
  • syntax on
    turn on syntax highlighting.
For more help on the options use e.g. :help 'ruler' - single quotes telling help command where to look for the given keyword. For help on syntax highlighting use :help syntax.

Wednesday, May 31, 2006

purpose of the blog

If somebody comes across the blog, I want to make sure what people see here.

Another hard drive crashed, another non-backed-up $HOME died - and again I have to ressurect my .vimrc from ashes. Piece by piece. This becomes a habit.

With the blog I hope to record as much knowledge as possible, so next time creation of my .vimrc - full fledged, ready for production environment - wouldn't take as long as it takes now. There would be single place with all things I need. And it will be smaller than vim's online ":help"

P.S. Some people argued that I just need to save my up-to-date .vimrc somewhere on the net. But this is a way of Emacs users. I do not like NNN kilobytes of black magic everybody copied from Joe The Emacs Pro and nobody understand meaning of. I like to have things I (1) need and (2) understand. I do not like black magic.

Monday, May 29, 2006

VIM's buffers

Buffer is what VIM uses for holding all information related to a file open during editing session. One can think of buffer as file. The only case when buffer is not file - is when we started editing file and not yet saved it.

VIM keeps inactive files closed. Only file(s) currently displayed is(are) open. (You can have of course more than one file displayed with multiple windows).

":ls" lists all buffers. (Conveniently, common mistype ":sl" is call to function sleep with default to sleep for 1 second.)

":b1" - switch to buffer number 1 - will reopen first file open for editing in the vim session. If file in current buffer was modified, the command would fail.

":bd" deletes current buffer. Makes vim forget that it edited the file in the buffer. Buffer numbers are not reused. Trying later to switch to that buffer number will reopen the file. In other words, ":bd" only removes the buffer from output of command ":ls".

":b#" switches to previously open buffer. Something I use a lot. Similar to ":b1" command, but instead of literal buffer number it uses vim's shortcut '#' for previous active buffer. '%' is shortcut to currently active buffer and consequently ":b%" is nop, since there is nothing to be done to activate already active buffer.

So all of my .vimrc have the line:

map <F6> :b#<CR>

what allows me to work with two files very quickly: I just need to press F6 to go to second file.

Type ":help windows.txt" in VIM for more info.

P.S. The buffers is where VIM stores info about files to open, if more than single file was specified. If vim is called that way:
$ vim *.c
you would find all of .c files vim is to open by ":ls" command. Usual :next/:prev are used to browse thru all the files.

useful shortcuts

Something I use often in command mode.

:q

close current file. closes vim is last file.

'"
move to last stored position in edited file

g<Ctrl-]>
list all symbols found in tags

<Ctrl-]>
go to first symbol found in tags. :tnext/:tprev/:tlast to browse all matching tags

*
find next occurence of symbol under cursor

#
find previous occurence of symbol under cursor

%
find matching opening/closing bracket

gf
"go file" - open file with name of word under cursor

x
delete characted under cursor. Unlike <Delete> works on all terminals.

dd
delete current line

G
go to the end of file

gg
go to the beginning of file


Command mode with its simple shortcuts was saving my ass on numerous occasions. Broken terminals are still around. Even if another day all borken terminals get fixed, tools like busybox working over raw serial line will be with us for quite some time ;-)

restoring last edited position

The simple trick from vim's online help is used to send cursor to last edited line in the file upon reopening.


au BufReadPost * if line("'\"") > 0 &&
\ line("'\"") <= line("$") | exe "normal g'\"" | endif


Type in vim ":help :au" for more info.

Wednesday, May 24, 2006

C++ :: load counterpart file

Ever wondered how to load counterpart file? IOW, when you have open header file - automatically open corresponding c file.

That's what I use:


map <silent> <F7> :exec ":e ".(expand("%") =~ ".h$"
\ ? glob(substitute(expand("%"), ".h$", ".cpp", ""))
\ : substitute(expand("%"), "\\.cpp$", ".h", ""))<CR>


Hanged on <F7>. First we look if it's header file open. If header, then we replace .h with .cpp and try to ":e"dit that file. If it's not header, we presume it's cpp file and try to replace .cpp with .h and ":e"dit that file.

P.S. <silent> in :map ensures that command wouldn't be displayed during its execution.

prevent vim from going to replace mode

Simpliest trick on the block. Took me long time to figure out.


imap <Insert> <Nop>

And that's it. Now regardless of how many times you press Insert in command mode - or whether in insert mode already - you will be/remain in insert mode.

Of course, you still can go to replace mode by pressing R in command mode.

making vim and ctags real friends

When one has multiple working copies of the source code repository, managing tags can be quite a burden.

The following script from my .vimrc does the trick - it looks for tags file in the enclosing directories and adds first match to the vim's 'tags' variable. The script is also modified to take care of Win32 version of vim.



let tag_dir=getcwd()
if match(tag_dir, "^/") == 0
let end_dir='/'
while !filereadable(tag_dir."/tags") && tag_dir!=$HOME && tag_dir!=end_dir
let tag_dir = substitute(tag_dir, '/[^/]\+$', "", "")
endwhile
if filereadable(tag_dir."/tags")
exe "set tags+=".tag_dir."/tags"
endif
elseif match(tag_dir, "^[a-zA-Z]:[\\/]") == 0
let end_dir=tag_dir[0].tag_dir[1]
while !filereadable(tag_dir."\\tags") && tag_dir!=end_dir
let tag_dir = substitute(tag_dir, '\\[^\\]\+$', "", "")
endwhile
if filereadable(tag_dir."\\tags")
exe "set tags+=".tag_dir."\\tags"
endif
endif



Lookup stops when root or home directory is reached.

First script checks to see if the system Unix or Win32: '/' as first character of pwd identifies Unix system (or CygWin). Then script check to see if there is "tags" file in the current working directory. If not found it strips from path one directory level and tries in loop again. Loop ends when "tags" file found or root/$HOME directory reached. If "tags" file was found script adds it to 'tags' vim variable.

Update: you can find newer version of my script here.

broken terminals - cure for the vim

Many times I have come across broken terminals screwing vim handling of shortcuts. Or vim just do not expect that some keys may produce such long sequences.

The most common sign - '--INSERT--' isn't displayed immedaitely after pressing insert key.

The cure is:


set notimeout
set ttimeout
set timeoutlen=100


Put that three lines into the beggining of the ~/.vimrc.

P.S. The tips is located in vim's excelent help system under the keyword "xterm-cursor-keys". Type that in vim - :help xterm-cursor-keys - to get there.