Showing posts with label vim. Show all posts
Showing posts with label vim. Show all posts

01 September 2011

Creating new Vim filetype for server logs

In this post I'll show how to create a simple Vim syntax script to highlight source of common error and access logs.

First make sure you have the following folders and files:
~/.vimrc		- the main config
~/.vim/ftdetect		- directory with filetype scripts
~/.vim/syntax		- directory with specific syntax scripts
If something missing, you can copy it from $VIMRUNTIME directory. Find block starting with
if has("autocmd")
and add the following line there:
au BufRead,BufNewFile *.log set filetype=error_log

Create filetype script in ~/.vim/ftdetect/error_log.vim:

if did_filetype()	" filetype already set..
	finish		" ..don't do these checks
endif

au BufRead,BufNewFile *.error.log set filetype=error_log au BufRead,BufNewFile *.access.log set filetype=error_log
Finally you need syntax script itself, ~/.vim/syntax/error_log.vim:
" Vim syntax file
" Language:    error_log
" Maintainer:  Ruslan Osmanov <rrosmanov at gmail dot com>
" Last Change: Thu Sep  1 15:30:52 MSD 2011
" Version:     1.0

if version < 600
  syntax clear
elseif exists("b:current_syntax")
  finish
endif

" Always ignore case
syn case ignore

" General keywords which don't fall into other categories
syn keyword error_logKeyword 			error warning notice 

" Special values
syn keyword error_logSpecial         	referer client

" Strings (single- and double-quote)
syn region error_logString           start=+"+  skip=+\\\\\|\\"+  end=+"+
syn region error_logString           start=+'+  skip=+\\\\\|\\'+  end=+'+

" Numbers and hexidecimal values
syn match error_logNumber            "-\=\<[0-9]*\>"
syn match error_logNumber            "-\=\<[0-9]*\.[0-9]*\>"
syn match error_logNumber            "-\=\<[0-9][0-9]*e[+-]\=[0-9]*\>"
syn match error_logNumber            "-\=\<[0-9]*\.[0-9]*e[+-]\=[0-9]*\>"
syn match error_logNumber            "\<0x[abcdefABCDEF0-9]*\>"

" IP addresses
syn match error_logIP            	"-\=\<[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\>"

syn region error_logOperator         start="referrer\:" end="" contains=ALL

" URI
syn match error_logURI            	"http\:\/\/[^ ]*"

" Date 
syn match error_logDate 			"\[[0-9]*\/[a-zA-Z]\{3\}\/\d\{4\}:\d\{2\}:\d\{2\}:\d\{2\} +\d\{4\}\]"
syn match error_logDate				"\[[a-zA-Z]\{3\} [a-zA-Z]\{3\} \d\{2\} \d\{2\}:\d\{2\}:\d\{2\} \d\{4\}\]"

" Domain
syn match error_logDomain            "\(www\.\)\?[a-z0-9\-\_]*\.\(ru\|com\|by\|uz\|ua\|kz\|su\|net\|org\)"

" Define the default highlighting.
" For version 5.7 and earlier: only when not done already
" For version 5.8 and later: only when an item doesn't have highlighting yet
if version >= 508 || !exists("did_error_log_syn_inits")
	if version < 508
		let did_error_log_syn_inits = 1
		command -nargs=+ HiLink hi link <args>
	else
		command -nargs=+ HiLink hi def link <args>
	endif

	HiLink error_logKeyword         Statement
	HiLink error_logIP				Type
	HiLink error_logSpecial  	    Special
	HiLink error_logString          String
	HiLink error_logNumber          Number
	HiLink error_logDate			Comment 
	HiLink error_logURI				Underlined 
	HiLink error_logDomain			Underlined 

	delcommand HiLink
endif

let b:current_syntax = "error_log"
" vim:sw=4:

08 April 2011

Change indentation: spaces to tabs

To convert space indentation in significant number of files, you may use the
following script.

#!/bin/bash - 
#===============================================================================
#          FILE:  fixtab.sh
#         USAGE:  ./fixtab.sh <directory>
#   DESCRIPTION:  Convert expanded tabs into tabs with 4 space width
#       OPTIONS: $1 directory
#        AUTHOR: Ruslan Osmanov 
#       CREATED: 04/08/2011 03:26:00 PM UZT
#===============================================================================
set -o nounset                              # Treat unset variables as an error

DIR=$1

function usage(){
 echo "bash $0 <directory>"
}

[[ ! -d $DIR ]] && usage

# Correct existing modelines I used to include modelines beginning from set
# expandtab, so this worked for me. If you don't use modelines, comment it out 
find $DIR -name *.php -exec \
 sed -i -e 's%# vim: set expandtab:%# vim: set noet:%g' {} \;

# Retab & format source code
find $DIR -name *.php -exec \
 vim -u NONE \
 -c 'set ft=php' \
 -c 'set shiftwidth=4' \
 -c 'set tabstop=4' \
 -c 'set noexpandtab!' \
 -c 'set noet' \
 -c 'retab!' \
 -c 'bufdo! "execute normal gg=G"' \
 -c wq \
 {} \;

For example:
$ bash ./fixtab.sh /srv/www/myproject
I would be glad, if this helped somebody.

21 March 2011

When middle click doesn't work in Vim

I mean the Linux feature to use mouse middle click to paste selected text. In vim(not gvim) it sometimes doesn't work. Here I post how to fix it.

In ~/.vimrc find line like
set mouse=a
and change it to
set mouse=r

That's it!

09 March 2011

Snippets in Vim

For common programming snippets in Vim install snipMate plugin.

SnipMate supports autoit, cpp, c, html, javascript, java, mako, objc, perl, php, python, ruby, sh, _, snippet, tcl, tex, vim and zsh file types by default. Default completion is <tab> key. I found it useful to change <tab> to ex. Ctrl+J:
in ~/.vim/after/plugin/snipMate.vim changed
ino <silent> <tab> <c-r>=TriggerSnippet()<cr>
snor <silent> <tab> <esc>i<right><c-r>=TriggerSnippet()<cr>
to
ino <c-j> <c-r>=TriggerSnippet()<cr>
snor <c-j> <esc>i<right><c-r>=TriggerSnippet()<cr>
To use multiple filetypes(as well, as corresponding snippets), you can use whether autoCmd in ~/.vimrc like:
au BufRead *.php set ft=php.html
au BufNewFile *.php set ft=php.html
or modeline like:
/* vim: set ft=html.php: */

Really nice plug-in with intellectual features. E.g. in an HTML file you type:
doctype<c-j>
,
and it suggests to choose one of 7 DOCTYPEs:
HTML 4.01 Strict
HTML 4.01 Transitional
HTML 5
XHTML 1.0 Frameset 
etc.


Enjoy!

UPDATE
Some extra snippets could be found here.

To create your own snippet clone a .snippet file in ~/.vim/snippets/ and modify it on your needs. For instance, I've created this one:

$ cat ~/.vim/snippets/sql/s3_localized.snippet
INSERT INTO \`s3_localized\` (\`localized_code\`) VALUES ('${1:SOMETHING}'); 
SET @ins_id:=(SELECT LAST_INSERT_ID());
INSERT INTO \`s3_localized_text\` (\`localized_id\`, \`lang_id\`, \`localized_text\`)
VALUES 
(@ins_id, 1, '${2:rus}'),
(@ins_id, 2, '${3:eng}'),
(@ins_id, 3, '$3'),
(@ins_id, 4, '$3'),
(@ins_id, 5, '$3'),
(@ins_id, 6, '$3'),
(@ins_id, 7, '$3');

It generates
INSERT INTO `s3_localized` (`localized_code`) VALUES ('SOMETHING'); 
SET @ins_id:=(SELECT LAST_INSERT_ID());
INSERT INTO `s3_localized_text` (`localized_id`, `lang_id`, `localized_text`)
VALUES 
(@ins_id, 1, 'rus'),
(@ins_id, 2, 'eng'),
(@ins_id, 3, 'eng'),
(@ins_id, 4, 'eng'),
(@ins_id, 5, 'eng'),
(@ins_id, 6, 'eng'),
(@ins_id, 7, 'eng');

Ctrl+J moves to the next variable declared in snippet. $-references allow change repeated strings simultaneously(as 'eng' above)

08 March 2011

Cyrillic-to-English key mapping in Vim and Vimperator

To avoid switching between keyboard layouts in navigation, visual mode etc. within a mixed Cyrillic/English text append the following to your ~/.vimrc:

set langmap=ФИСВУАПРШОЛДЬТЩЗЙКЫЕГМЦЧНЯ;ABCDEFGHIJKLMNOPQRSTUVWXYZ,фисвуапршолдьтщзйкыегмцчня;abcdefghijklmnopqrstuvwxyz
Similar mapping works for Vimperator. If you use Vimperator, append the following whether to ~/.vimperatorrc, or ~/.vimperatorrc.local(where appropriate):

map пе gt
map пЕ gT

map Ф A
map И B
map С C
map В D
map У E
map А F
map П G
map Р H
map Ш I
map О J
map Л K
map Д L
map Ь M
map Т N
map Щ O
map З P
map Й Q
map К R
map Ы S
map Е T
map Г U
map М V
map Ц W
map Ч X
map Н Y
map Я Z
map ф a
map и b
map с c
map в d
map у e
map а f
map п g
map р h
map ш i
map о j
map л k
map д l
map ь m
map т n
map щ o
map з p
map й q
map к r
map ы s
map е t
map г u
map м v
map ц w
map ч x
map н y
map я z