From 5b25805cbf6559ae7aa1c981455ad1bfba94a796 Mon Sep 17 00:00:00 2001 From: Michal Au Date: Tue, 4 Aug 2015 09:14:04 +0200 Subject: [PATCH] versioned Vim config --- .gitignore | 1 + .netrwhist | 3 + .vimrc | 155 +++ README | 1 + autoload/pathogen.vim | 347 ++++++ bundle/ctrlp.vim | 1 + bundle/fonts | 1 + bundle/jedi-vim | 1 + bundle/nerdtree | 1 + bundle/powerline | 1 + bundle/python-mode | 1 + bundle/vim-airline | 1 + bundle/vim-fugitive | 1 + bundle/vim-gitgutter | 1 + bundle/vim-powerline | 1 + bundle/vim-sensible | 1 + colors/darkspectrum.vim | 130 +++ colors/distinguished.vim | 181 +++ colors/wombat256mod.vim | 96 ++ ftplugin/python_editing.vim | 85 ++ plugin/vimchat.vim | 1742 +++++++++++++++++++++++++++++ syntax/vimchat.vim | 8 + vimchat-master/.gitignore | 3 + vimchat-master/README.md | 137 +++ vimchat-master/config | 36 + vimchat-master/icon.gif | Bin 0 -> 2375 bytes vimchat-master/icon_away.gif | Bin 0 -> 1827 bytes vimchat-master/icon_dnd.gif | Bin 0 -> 4490 bytes vimchat-master/icon_xa.gif | Bin 0 -> 1620 bytes vimchat-master/install.sh | 23 + vimchat-master/plugin/vimchat.vim | 1742 +++++++++++++++++++++++++++++ vimchat-master/syntax/vimchat.vim | 8 + 32 files changed, 4709 insertions(+) create mode 100644 .gitignore create mode 100755 .netrwhist create mode 100755 .vimrc create mode 100644 README create mode 100755 autoload/pathogen.vim create mode 160000 bundle/ctrlp.vim create mode 160000 bundle/fonts create mode 160000 bundle/jedi-vim create mode 160000 bundle/nerdtree create mode 160000 bundle/powerline create mode 160000 bundle/python-mode create mode 160000 bundle/vim-airline create mode 160000 bundle/vim-fugitive create mode 160000 bundle/vim-gitgutter create mode 160000 bundle/vim-powerline create mode 160000 bundle/vim-sensible create mode 100755 colors/darkspectrum.vim create mode 100755 colors/distinguished.vim create mode 100755 colors/wombat256mod.vim create mode 100755 ftplugin/python_editing.vim create mode 100644 plugin/vimchat.vim create mode 100644 syntax/vimchat.vim create mode 100644 vimchat-master/.gitignore create mode 100644 vimchat-master/README.md create mode 100644 vimchat-master/config create mode 100644 vimchat-master/icon.gif create mode 100644 vimchat-master/icon_away.gif create mode 100644 vimchat-master/icon_dnd.gif create mode 100644 vimchat-master/icon_xa.gif create mode 100755 vimchat-master/install.sh create mode 100644 vimchat-master/plugin/vimchat.vim create mode 100644 vimchat-master/syntax/vimchat.vim diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2dd0183 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +swap/ diff --git a/.netrwhist b/.netrwhist new file mode 100755 index 0000000..94070e4 --- /dev/null +++ b/.netrwhist @@ -0,0 +1,3 @@ +let g:netrw_dirhistmax =10 +let g:netrw_dirhist_cnt =1 +let g:netrw_dirhist_1='/home/misa/Documents/skola/diplomka/code/ML/mass_count' diff --git a/.vimrc b/.vimrc new file mode 100755 index 0000000..167e294 --- /dev/null +++ b/.vimrc @@ -0,0 +1,155 @@ +"automatic reoloading of .vimrc +autocmd! bufwritepost .vimrc source % + + +"Rebind key +let mapleader="," + +set guioptions-=T "remove the icon bar +:set guioptions-=r "remove right-hand scroll bar +:set guioptions-=L "remove left-hand scroll bar +" 'hide' pale gray areas by ~/.gtkrc-2.0 + + +"firefox-like tab navigation +"nnoremap :tabnext +"nnoremap :tabprevious + +" vim-airline +set laststatus=2 +let g:Powerline_symbols = 'fancy' +let g:airline#extensions#tabline#enabled = 1 +let g:airline_theme = "murmur" +let g:airline_powerline_fonts = 1 + +set hidden +nnoremap :bnext +nnoremap :bprevious +nmap t :enew +nnoremap q :bp:bd # + +"set swap directory: +set directory=~/.vim/swap + +"better copy & paste behaviour +"set pastetoggle= +"set clipboard=unnamed + + +"map sort function to a key +vnoremap s :sort + +"easier moving of code blocks +vnoremap < >gv + +"copy - paste +vmap "+yi +vmap "+c +vmap c"+p +imap + + +"navigating among splits +nnoremap +nnoremap +nnoremap +nnoremap +set splitbelow +set splitright + +"Color scheme +set t_Co=256 +colorscheme wombat256mod + +"syntax highlighting +filetype off +filetype plugin indent on +syntax on + +"showing line numbers and length +set number "show line numbers +"set tw=79 "width of lines +set nowrap "prevent automatic wrapping on load +set fo-=t "prevent automatic wrapping while typing +"set colorcolumn=80 +"highlight ColorColumn ctermbg=Black + +"easier formatting of paragraphs +vmap Q gq +nmap Q gqap + +"history +set history=700 +set undolevels=700 + +" Tabstops +set tabstop=4 +set softtabstop=4 +set shiftwidth=4 +set shiftround +set expandtab + +"Setup Pathogen to manage the plugins +execute pathogen#infect() + +nmap l iprint "\n{}\n".format()i + +"NERDTree +nmap nt :NERDTree +let NERDTreeIgnore = ['\.pyc$', '\.hi', '\.o'] +if has("autocmd") + " autorun nerdtree + autocmd VimEnter * NERDTree +endif + +"================================ +" PYTHON IDE SETUP +"================================ + +"Powerline setup +set laststatus=2 + +"Ctrlp setup +let g:ctrlp_max_height=30 +set wildignore+=*.pyc +set wildignore+=*_build/* +set wildignore+=*/coverage/* + +"Jedi setup +let g:jedi#use_splits_not_buffers = "right" +let g:pymode_rope_lookup_project = 0 +let g:pymode_rope = 0 +let g:pymode_options_colorcolumn = 0 + +""Python-mode setup +"map g :call RopeGotoDefinition() +"let ropevim_enable_shortcuts=1 +"let g:pymode_rope_goto_def_newwin = "vnew" +"let g:pymode_rope_extend_complete = 1 +"let g:pymode_breakpoint = 0 +"let g:pymode_syntax = 1 +"let g:pymode_syntax_builtin_objs = 0 +"let g:pymode_syntax_builtin_funcs = 0 +"map b Oimport ipdb; ipdb.set_trace() # BREAKPOINT + +""Navigation through omnicomplete option list +"set completeopt=longest,menuone +"function! OmniPopup(action) +" if pumbisible() +" if a:action=='j' +" return "\" +" elseif a:action=='k' +" return "\" +" endif +" endif +" return a:action +"endfunction + +"inoremap =OmniPopup('j') +"inoremap =OmniPopup('k') + +"Python_editing.vim - folding setup +set nofoldenable + +"Python execute code +autocmd FileType python nnoremap :exec '!clear;python' shellescape(@%, 1) diff --git a/README b/README new file mode 100644 index 0000000..cc2ab5a --- /dev/null +++ b/README @@ -0,0 +1 @@ +This is my Vim config. diff --git a/autoload/pathogen.vim b/autoload/pathogen.vim new file mode 100755 index 0000000..a13ae08 --- /dev/null +++ b/autoload/pathogen.vim @@ -0,0 +1,347 @@ +" pathogen.vim - path option manipulation +" Maintainer: Tim Pope +" Version: 2.3 + +" Install in ~/.vim/autoload (or ~\vimfiles\autoload). +" +" For management of individually installed plugins in ~/.vim/bundle (or +" ~\vimfiles\bundle), adding `execute pathogen#infect()` to the top of your +" .vimrc is the only other setup necessary. +" +" The API is documented inline below. + +if exists("g:loaded_pathogen") || &cp + finish +endif +let g:loaded_pathogen = 1 + +" Point of entry for basic default usage. Give a relative path to invoke +" pathogen#interpose() (defaults to "bundle/{}"), or an absolute path to invoke +" pathogen#surround(). Curly braces are expanded with pathogen#expand(): +" "bundle/{}" finds all subdirectories inside "bundle" inside all directories +" in the runtime path. +function! pathogen#infect(...) abort + for path in a:0 ? filter(reverse(copy(a:000)), 'type(v:val) == type("")') : ['bundle/{}'] + if path =~# '^\%({\=[$~\\/]\|{\=\w:[\\/]\).*[{}*]' + call pathogen#surround(path) + elseif path =~# '^\%([$~\\/]\|\w:[\\/]\)' + call s:warn('Change pathogen#infect('.string(path).') to pathogen#infect('.string(path.'/{}').')') + call pathogen#surround(path . '/{}') + elseif path =~# '[{}*]' + call pathogen#interpose(path) + else + call s:warn('Change pathogen#infect('.string(path).') to pathogen#infect('.string(path.'/{}').')') + call pathogen#interpose(path . '/{}') + endif + endfor + call pathogen#cycle_filetype() + if pathogen#is_disabled($MYVIMRC) + return 'finish' + endif + return '' +endfunction + +" Split a path into a list. +function! pathogen#split(path) abort + if type(a:path) == type([]) | return a:path | endif + if empty(a:path) | return [] | endif + let split = split(a:path,'\\\@]','\\&','') + endif +endfunction + +" Like findfile(), but hardcoded to use the runtimepath. +function! pathogen#runtime_findfile(file,count) abort "{{{1 + let rtp = pathogen#join(1,pathogen#split(&rtp)) + let file = findfile(a:file,rtp,a:count) + if file ==# '' + return '' + else + return fnamemodify(file,':p') + endif +endfunction + +" Section: Deprecated + +function! s:warn(msg) abort + echohl WarningMsg + echomsg a:msg + echohl NONE +endfunction + +" Prepend all subdirectories of path to the rtp, and append all 'after' +" directories in those subdirectories. Deprecated. +function! pathogen#runtime_prepend_subdirectories(path) abort + call s:warn('Change pathogen#runtime_prepend_subdirectories('.string(a:path).') to pathogen#infect('.string(a:path.'/{}').')') + return pathogen#surround(a:path . pathogen#slash() . '{}') +endfunction + +function! pathogen#incubate(...) abort + let name = a:0 ? a:1 : 'bundle/{}' + call s:warn('Change pathogen#incubate('.(a:0 ? string(a:1) : '').') to pathogen#infect('.string(name).')') + return pathogen#interpose(name) +endfunction + +" Deprecated alias for pathogen#interpose(). +function! pathogen#runtime_append_all_bundles(...) abort + if a:0 + call s:warn('Change pathogen#runtime_append_all_bundles('.string(a:1).') to pathogen#infect('.string(a:1.'/{}').')') + else + call s:warn('Change pathogen#runtime_append_all_bundles() to pathogen#infect()') + endif + return pathogen#interpose(a:0 ? a:1 . '/{}' : 'bundle/{}') +endfunction + +if exists(':Vedit') + finish +endif + +let s:vopen_warning = 0 + +function! s:find(count,cmd,file,lcd) + let rtp = pathogen#join(1,pathogen#split(&runtimepath)) + let file = pathogen#runtime_findfile(a:file,a:count) + if file ==# '' + return "echoerr 'E345: Can''t find file \"".a:file."\" in runtimepath'" + endif + if !s:vopen_warning + let s:vopen_warning = 1 + let warning = '|echohl WarningMsg|echo "Install scriptease.vim to continue using :V'.a:cmd.'"|echohl NONE' + else + let warning = '' + endif + if a:lcd + let path = file[0:-strlen(a:file)-2] + execute 'lcd `=path`' + return a:cmd.' '.pathogen#fnameescape(a:file) . warning + else + return a:cmd.' '.pathogen#fnameescape(file) . warning + endif +endfunction + +function! s:Findcomplete(A,L,P) + let sep = pathogen#slash() + let cheats = { + \'a': 'autoload', + \'d': 'doc', + \'f': 'ftplugin', + \'i': 'indent', + \'p': 'plugin', + \'s': 'syntax'} + if a:A =~# '^\w[\\/]' && has_key(cheats,a:A[0]) + let request = cheats[a:A[0]].a:A[1:-1] + else + let request = a:A + endif + let pattern = substitute(request,'/\|\'.sep,'*'.sep,'g').'*' + let found = {} + for path in pathogen#split(&runtimepath) + let path = expand(path, ':p') + let matches = split(glob(path.sep.pattern),"\n") + call map(matches,'isdirectory(v:val) ? v:val.sep : v:val') + call map(matches,'expand(v:val, ":p")[strlen(path)+1:-1]') + for match in matches + let found[match] = 1 + endfor + endfor + return sort(keys(found)) +endfunction + +command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Ve :execute s:find(,'edit',,0) +command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vedit :execute s:find(,'edit',,0) +command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vopen :execute s:find(,'edit',,1) +command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vsplit :execute s:find(,'split',,1) +command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vvsplit :execute s:find(,'vsplit',,1) +command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vtabedit :execute s:find(,'tabedit',,1) +command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vpedit :execute s:find(,'pedit',,1) +command! -bar -bang -range=1 -nargs=1 -complete=customlist,s:Findcomplete Vread :execute s:find(,'read',,1) + +" vim:set et sw=2 foldmethod=expr foldexpr=getline(v\:lnum)=~'^\"\ Section\:'?'>1'\:getline(v\:lnum)=~#'^fu'?'a1'\:getline(v\:lnum)=~#'^endf'?'s1'\:'=': diff --git a/bundle/ctrlp.vim b/bundle/ctrlp.vim new file mode 160000 index 0000000..b5d3fe6 --- /dev/null +++ b/bundle/ctrlp.vim @@ -0,0 +1 @@ +Subproject commit b5d3fe66a58a13d2ff8b6391f4387608496a030f diff --git a/bundle/fonts b/bundle/fonts new file mode 160000 index 0000000..97dc451 --- /dev/null +++ b/bundle/fonts @@ -0,0 +1 @@ +Subproject commit 97dc451724fb24e1dd9892c988642b239b5dc67c diff --git a/bundle/jedi-vim b/bundle/jedi-vim new file mode 160000 index 0000000..b3978bc --- /dev/null +++ b/bundle/jedi-vim @@ -0,0 +1 @@ +Subproject commit b3978bc4aa6c1a5d890a201479945464b2deeb8b diff --git a/bundle/nerdtree b/bundle/nerdtree new file mode 160000 index 0000000..3b98a7f --- /dev/null +++ b/bundle/nerdtree @@ -0,0 +1 @@ +Subproject commit 3b98a7fcae8f9fff356907171f0406ff8cd28921 diff --git a/bundle/powerline b/bundle/powerline new file mode 160000 index 0000000..090cd13 --- /dev/null +++ b/bundle/powerline @@ -0,0 +1 @@ +Subproject commit 090cd1397cf61efe7cd7d7bc389a7e8f8963f707 diff --git a/bundle/python-mode b/bundle/python-mode new file mode 160000 index 0000000..9c8468e --- /dev/null +++ b/bundle/python-mode @@ -0,0 +1 @@ +Subproject commit 9c8468e83232c3e45b730d2d0b28d609053dec05 diff --git a/bundle/vim-airline b/bundle/vim-airline new file mode 160000 index 0000000..cdc6d98 --- /dev/null +++ b/bundle/vim-airline @@ -0,0 +1 @@ +Subproject commit cdc6d98a09db60d3dda58815616f78338cbdaa9d diff --git a/bundle/vim-fugitive b/bundle/vim-fugitive new file mode 160000 index 0000000..03cc95c --- /dev/null +++ b/bundle/vim-fugitive @@ -0,0 +1 @@ +Subproject commit 03cc95cc198ea94a6a003a92cd0e58af4416ec25 diff --git a/bundle/vim-gitgutter b/bundle/vim-gitgutter new file mode 160000 index 0000000..fe10e64 --- /dev/null +++ b/bundle/vim-gitgutter @@ -0,0 +1 @@ +Subproject commit fe10e6474d70c382edcda84dc6bcd6fcd575a6c5 diff --git a/bundle/vim-powerline b/bundle/vim-powerline new file mode 160000 index 0000000..09c0cea --- /dev/null +++ b/bundle/vim-powerline @@ -0,0 +1 @@ +Subproject commit 09c0cea859a2e0989eea740655b35976d951a84e diff --git a/bundle/vim-sensible b/bundle/vim-sensible new file mode 160000 index 0000000..b30dcf3 --- /dev/null +++ b/bundle/vim-sensible @@ -0,0 +1 @@ +Subproject commit b30dcf387af977acfa21732592bfca05598b2188 diff --git a/colors/darkspectrum.vim b/colors/darkspectrum.vim new file mode 100755 index 0000000..26ed7f3 --- /dev/null +++ b/colors/darkspectrum.vim @@ -0,0 +1,130 @@ +" Vim color file +" +" Author: Brian Mock +" +" Note: Based on Oblivion color scheme for gedit (gtk-source-view) +" +" cool help screens +" :he group-name +" :he highlight-groups +" :he cterm-colors + +hi clear + +set background=dark +if version > 580 + " no guarantees for version 5.8 and below, but this makes it stop + " complaining + hi clear + if exists("syntax_on") + syntax reset + endif +endif +let g:colors_name="darkspectrum" + +hi Normal guifg=#efefef guibg=#2A2A2A + +" highlight groups +hi Cursor guibg=#ffffff guifg=#000000 +hi CursorLine guibg=#000000 +"hi CursorLine guibg=#3e4446 +hi CursorColumn guibg=#464646 + +"hi DiffText guibg=#4e9a06 guifg=#FFFFFF gui=bold +"hi DiffChange guibg=#4e9a06 guifg=#FFFFFF gui=bold +"hi DiffAdd guibg=#204a87 guifg=#FFFFFF gui=bold +"hi DiffDelete guibg=#5c3566 guifg=#FFFFFF gui=bold + +hi DiffAdd guifg=#ffcc7f guibg=#a67429 gui=none +hi DiffChange guifg=#7fbdff guibg=#425c78 gui=none +hi DiffText guifg=#8ae234 guibg=#4e9a06 gui=none +"hi DiffDelete guifg=#252723 guibg=#000000 gui=none +hi DiffDelete guifg=#000000 guibg=#000000 gui=none +"hi ErrorMsg + +hi Number guifg=#fce94f + +hi Folded guibg=#000000 guifg=#FFFFFF gui=bold +hi vimFold guibg=#000000 guifg=#FFFFFF gui=bold +hi FoldColumn guibg=#000000 guifg=#FFFFFF gui=bold + +hi LineNr guifg=#535353 guibg=#202020 +hi NonText guifg=#535353 guibg=#202020 +hi Folded guifg=#535353 guibg=#202020 gui=bold +hi FoldeColumn guifg=#535353 guibg=#202020 gui=bold +"hi VertSplit guibg=#ffffff guifg=#ffffff gui=none + +hi VertSplit guibg=#3C3C3C guifg=#3C3C3C gui=none +hi StatusLine guifg=#FFFFFF guibg=#3C3C3C gui=none +hi StatusLineNC guifg=#808080 guibg=#3C3C3C gui=none + +hi ModeMsg guifg=#fce94f +hi MoreMsg guifg=#fce94f +hi Visual guifg=#FFFFFF guibg=#3465a4 gui=none +hi VisualNOS guifg=#FFFFFF guibg=#204a87 gui=none +hi IncSearch guibg=#FFFFFF guifg=#ef5939 +hi Search guibg=#ad7fa8 guifg=#FFFFFF +hi SpecialKey guifg=#8ae234 + +hi Title guifg=#ef5939 +hi WarningMsg guifg=#ef5939 +hi Number guifg=#fcaf3e + +hi MatchParen guibg=#ad7fa8 guifg=#FFFFFF +hi Comment guifg=#8a8a8a +hi Constant guifg=#ef5939 gui=none +hi String guifg=#fce94f +hi Identifier guifg=#729fcf +hi Statement guifg=#ffffff gui=bold +hi PreProc guifg=#ffffff gui=bold +hi Type guifg=#8ae234 gui=bold +hi Special guifg=#e9b96e +hi Underlined guifg=#ad7fa8 gui=underline +hi Directory guifg=#729fcf +hi Ignore guifg=#555753 +hi Todo guifg=#FFFFFF guibg=#ef5939 gui=bold +hi Function guifg=#ad7fa8 + +"hi WildMenu guibg=#2e3436 guifg=#ffffff gui=bold +"hi WildMenu guifg=#7fbdff guibg=#425c78 gui=none +hi WildMenu guifg=#ffffff guibg=#3465a4 gui=none + +hi Pmenu guibg=#000000 guifg=#c0c0c0 +hi PmenuSel guibg=#3465a4 guifg=#ffffff +hi PmenuSbar guibg=#444444 guifg=#444444 +hi PmenuThumb guibg=#888888 guifg=#888888 + +hi cppSTLType guifg=#729fcf gui=bold + +hi spellBad guisp=#fcaf3e +hi spellCap guisp=#73d216 +hi spellRare guisp=#ad7fa8 +hi spellLocal guisp=#729fcf + +hi link cppSTL Function +hi link Error Todo +hi link Character Number +hi link rubySymbol Number +hi link htmlTag htmlEndTag +"hi link htmlTagName htmlTag +hi link htmlLink Underlined +hi link pythonFunction Identifier +hi link Question Type +hi link CursorIM Cursor +hi link VisualNOS Visual +hi link xmlTag Identifier +hi link xmlTagName Identifier +hi link shDeref Identifier +hi link shVariable Function +hi link rubySharpBang Special +hi link perlSharpBang Special +hi link schemeFunc Statement +"hi link shSpecialVariables Constant +"hi link bashSpecialVariables Constant + +" tabs (non gui) +hi TabLine guifg=#A3A3A3 guibg=#202020 gui=none +hi TabLineFill guifg=#535353 guibg=#202020 gui=none +hi TabLineSel guifg=#FFFFFF gui=bold +"hi TabLineSel guifg=#FFFFFF guibg=#000000 gui=bold +" vim: sw=4 ts=4 diff --git a/colors/distinguished.vim b/colors/distinguished.vim new file mode 100755 index 0000000..db3af12 --- /dev/null +++ b/colors/distinguished.vim @@ -0,0 +1,181 @@ +" Author: Kim Silkebækken +" Source repository: https://github.com/Lokaltog/vim-distinguished + +" Initialization {{{ + set background=dark + + hi clear + if exists('syntax_on') + syntax reset + endif + + let g:colors_name = 'distinguished' + + if ! has('gui_running') + if &t_Co != 256 + echoe 'The ' . g:colors_name . ' color scheme requires gvim or a 256-color terminal' + + finish + endif + endif +" }}} +" Color dictionary parser {{{ + function! s:ColorDictParser(color_dict) + for [group, group_colors] in items(a:color_dict) + exec 'hi ' . group + \ . ' ctermfg=' . (group_colors[0] == '' ? 'NONE' : group_colors[0]) + \ . ' ctermbg=' . (group_colors[1] == '' ? 'NONE' : group_colors[1]) + \ . ' cterm=' . (group_colors[2] == '' ? 'NONE' : group_colors[2]) + \ + \ . ' guifg=' . (group_colors[3] == '' ? 'NONE' : '#' . group_colors[3]) + \ . ' guibg=' . (group_colors[4] == '' ? 'NONE' : '#' . group_colors[4]) + \ . ' gui=' . (group_colors[5] == '' ? 'NONE' : group_colors[5]) + endfor + endfunction +" }}} + +" | Highlight group | CTFG | CTBG | CTAttributes | || | GUIFG | GUIBG | GUIAttributes | +" |--------------------------------|-------|-------|-----------------| || |---------|----------|-----------------| +call s:ColorDictParser({ + \ 'Normal' : [ 231, 16, '', 'ffffff', '000000', ''] + \ , 'Visual' : [ 240, 253, '', '585858', 'dadada', ''] + \ + \ , 'Cursor' : [ '', '', '', 'ffffff', 'dd4010', ''] + \ , 'lCursor' : [ '', '', '', 'ffffff', '89b6e2', ''] + \ + \ , 'CursorLine' : [ '', 236, '', '', '3a3a3a', ''] + \ , 'CursorLineNr' : [ 231, 240, '', 'ffffff', '585858', ''] + \ , 'CursorColumn' : [ 231, 237, '', 'ffffff', '3a3a3a', ''] + \ + \ , 'Folded' : [ 249, 234, '', 'b2b2b2', '1c1c1c', ''] + \ , 'FoldColumn' : [ 243, 234, '', '767676', '1c1c1c', ''] + \ , 'SignColumn' : [ 231, 233, 'bold', 'ffffff', '121212', 'bold'] + \ , 'ColorColumn' : [ '', 233, '', '', '262626', ''] + \ + \ , 'StatusLine' : [ 231, 236, 'bold', 'ffffff', '303030', 'bold'] + \ , 'StatusLineNC' : [ 244, 232, '', '808080', '080808', ''] + \ + \ , 'LineNr' : [ 243, 235, '', '767676', '262626', ''] + \ , 'VertSplit' : [ 240, '', '', '585858', '1c1c1c', ''] + \ + \ , 'WildMenu' : [ 234, 231, '', '1c1c1c', 'ffffff', ''] + \ , 'Directory' : [ 143, '', 'bold', 'afaf5f', '', 'bold'] + \ , 'Underlined' : [ 130, '', '', 'af5f00', '', ''] + \ + \ , 'Question' : [ 74, '', 'bold', '5fafd7', '', 'bold'] + \ , 'MoreMsg' : [ 214, '', 'bold', 'ffaf00', '', 'bold'] + \ , 'WarningMsg' : [ 202, '', 'bold', 'ff5f00', '', 'bold'] + \ , 'ErrorMsg' : [ 196, '', 'bold', 'ff0000', '', 'bold'] + \ + \ , 'Comment' : [ 243, 233, '', '767676', '121212', ''] + \ , 'vimCommentTitleLeader' : [ 250, 233, '', 'bcbcbc', '121212', ''] + \ , 'vimCommentTitle' : [ 250, 233, '', 'bcbcbc', '121212', ''] + \ , 'vimCommentString' : [ 245, 233, '', '8a8a8a', '121212', ''] + \ + \ , 'TabLine' : [ 231, 238, '', 'ffffff', '444444', ''] + \ , 'TabLineSel' : [ 255, '', 'bold', 'eeeeee', '', 'bold'] + \ , 'TabLineFill' : [ 240, 238, '', '585858', '444444', ''] + \ , 'TabLineNumber' : [ 160, 238, 'bold', 'd70000', '444444', 'bold'] + \ , 'TabLineClose' : [ 245, 238, 'bold', '8a8a8a', '444444', 'bold'] + \ + \ , 'SpellCap' : [ 231, 31, 'bold', 'ffffff', '0087af', 'bold'] + \ + \ , 'SpecialKey' : [ 239, '', '', '4e4e4e', '', ''] + \ , 'NonText' : [ 88, '', '', '870000', '', ''] + \ , 'MatchParen' : [ 231, 25, 'bold', 'ffffff', '005faf', 'bold'] + \ + \ , 'Constant' : [ 137, '', 'bold', 'af875f', '', 'bold'] + \ , 'Special' : [ 150, '', '', 'afd787', '', ''] + \ , 'Identifier' : [ 66, '', 'bold', '5f8787', '', 'bold'] + \ , 'Statement' : [ 186, '', 'bold', 'd7d787', '', 'bold'] + \ , 'PreProc' : [ 247, '', '', '9e9e9e', '', ''] + \ , 'Type' : [ 67, '', 'bold', '5f87af', '', 'bold'] + \ , 'String' : [ 143, '', '', 'afaf5f', '', ''] + \ , 'Number' : [ 173, '', '', 'd7875f', '', ''] + \ , 'Define' : [ 173, '', '', 'd7875f', '', ''] + \ , 'Error' : [ 208, 124, '', 'ff8700', 'af0000', ''] + \ , 'Function' : [ 179, '', '', 'd7af5f', '', ''] + \ , 'Include' : [ 173, '', '', 'd7875f', '', ''] + \ , 'PreCondit' : [ 173, '', '', 'd7875f', '', ''] + \ , 'Keyword' : [ 173, '', '', 'd7875f', '', ''] + \ , 'Search' : [ 231, 131, '', '000000', 'ffff5f', 'underline,bold'] + \ , 'Title' : [ 231, '', '', 'ffffff', '', ''] + \ , 'Delimiter' : [ 246, '', '', '949494', '', ''] + \ , 'StorageClass' : [ 187, '', '', 'd7d7af', '', ''] + \ , 'Operator' : [ 180, '', '', 'd7af87', '', ''] + \ + \ , 'TODO' : [ 228, 94, 'bold', 'ffff87', '875f00', 'bold'] + \ + \ , 'SyntasticWarning' : [ 220, 94, '', 'ffff87', '875f00', 'bold'] + \ , 'SyntasticError' : [ 202, 52, '', 'ffff87', '875f00', 'bold'] + \ + \ , 'Pmenu' : [ 248, 240, '', 'a8a8a8', '585858', ''] + \ , 'PmenuSel' : [ 253, 245, '', 'dadada', '8a8a8a', ''] + \ , 'PmenuSbar' : [ 253, 248, '', 'dadada', 'a8a8a8', ''] + \ + \ , 'phpEOL' : [ 245, '', '', 'dadada', '', ''] + \ , 'phpStringDelim' : [ 94, '', '', '875f00', '', ''] + \ , 'phpDelimiter' : [ 160, '', '', 'd70000', '', ''] + \ , 'phpFunctions' : [ 221, '', 'bold', 'ffd75f', '', 'bold'] + \ , 'phpBoolean' : [ 172, '', 'bold', 'd78700', '', 'bold'] + \ , 'phpOperator' : [ 215, '', '', 'ffaf5f', '', ''] + \ , 'phpMemberSelector' : [ 138, '', 'bold', 'af8787', '', 'bold'] + \ , 'phpParent' : [ 227, '', '', 'ffff5f', '', ''] + \ + \ , 'PHPClassTag' : [ 253, '', '', 'dadada', '', ''] + \ , 'PHPInterfaceTag' : [ 253, '', '', 'dadada', '', ''] + \ , 'PHPFunctionTag' : [ 222, '', 'bold', 'ffd787', '', 'bold'] + \ + \ , 'pythonDocString' : [ 240, 233, '', '585858', '121212', ''] + \ , 'pythonDocStringTitle' : [ 245, 233, '', 'dadada', '121212', ''] + \ , 'pythonRun' : [ 65, '', '', '5f875f', '', ''] + \ , 'pythonBuiltinObj' : [ 67, '', 'bold', '5f87af', '', 'bold'] + \ , 'pythonSelf' : [ 250, '', 'bold', 'bcbcbc', '', 'bold'] + \ , 'pythonFunction' : [ 179, '', 'bold', 'd7af5f', '', 'bold'] + \ , 'pythonClass' : [ 221, '', 'bold', 'ffd75f', '', 'bold'] + \ , 'pythonExClass' : [ 130, '', '', 'af5f00', '', ''] + \ , 'pythonException' : [ 130, '', 'bold', 'af5f00', '', 'bold'] + \ , 'pythonOperator' : [ 186, '', '', 'd7d787', '', ''] + \ , 'pythonPreCondit' : [ 152, '', 'bold', 'afd7d7', '', 'bold'] + \ , 'pythonDottedName' : [ 166, '', '', 'd75f00', '', ''] + \ , 'pythonDecorator' : [ 124, '', 'bold', 'af0000', '', 'bold'] + \ + \ , 'PythonInterfaceTag' : [ 109, '', '', '87afaf', '', ''] + \ , 'PythonClassTag' : [ 221, '', '', 'ffd75f', '', ''] + \ , 'PythonFunctionTag' : [ 109, '', '', '87afaf', '', ''] + \ , 'PythonVariableTag' : [ 253, '', '', 'dadada', '', ''] + \ , 'PythonMemberTag' : [ 145, '', '', 'afafaf', '', ''] + \ + \ , 'CTagsImport' : [ 109, '', '', '87afaf', '', ''] + \ , 'CTagsClass' : [ 221, '', '', 'ffd75f', '', ''] + \ , 'CTagsFunction' : [ 109, '', '', '87afaf', '', ''] + \ , 'CTagsGlobalVariable' : [ 253, '', '', 'dadada', '', ''] + \ , 'CTagsMember' : [ 145, '', '', 'afafaf', '', ''] + \ + \ , 'xmlTag' : [ 149, '', 'bold', 'afd75f', '', 'bold'] + \ , 'xmlTagName' : [ 250, '', '', 'bcbcbc', '', ''] + \ , 'xmlEndTag' : [ 209, '', 'bold', 'ff875f', '', 'bold'] + \ + \ , 'cssImportant' : [ 166, '', 'bold', 'd75f00', '', 'bold'] + \ + \ , 'DiffAdd' : [ 112, 22, '', '87d700', '005f00', ''] + \ , 'DiffChange' : [ 220, 94, '', 'ffd700', '875f00', ''] + \ , 'DiffDelete' : [ 160, '', '', 'd70000', '', ''] + \ , 'DiffText' : [ 220, 94, 'reverse,bold', 'ffd700', '875f00', 'reverse,bold'] + \ + \ , 'diffLine' : [ 68, '', 'bold', '5f87d7', '', 'bold'] + \ , 'diffFile' : [ 242, '', '', '6c6c6c', '', ''] + \ , 'diffNewFile' : [ 242, '', '', '6c6c6c', '', ''] +\ }) + +hi link htmlTag xmlTag +hi link htmlTagName xmlTagName +hi link htmlEndTag xmlEndTag + +hi link phpCommentTitle vimCommentTitle +hi link phpDocTags vimCommentString +hi link phpDocParam vimCommentTitle + +hi link diffAdded DiffAdd +hi link diffChanged DiffChange +hi link diffRemoved DiffDelete diff --git a/colors/wombat256mod.vim b/colors/wombat256mod.vim new file mode 100755 index 0000000..1137eb8 --- /dev/null +++ b/colors/wombat256mod.vim @@ -0,0 +1,96 @@ +" Vim color file +" Original Maintainer: Lars H. Nielsen (dengmao@gmail.com) +" Last Change: 2010-07-23 +" +" Modified version of wombat for 256-color terminals by +" David Liang (bmdavll@gmail.com) +" based on version by +" Danila Bespalov (danila.bespalov@gmail.com) + +set background=dark + +if version > 580 + hi clear + if exists("syntax_on") + syntax reset + endif +endif + +let colors_name = "wombat256mod" + + +" General colors +hi Normal ctermfg=252 ctermbg=234 cterm=none guifg=#e3e0d7 guibg=#242424 gui=none +hi Cursor ctermfg=234 ctermbg=228 cterm=none guifg=#242424 guibg=#eae788 gui=none +hi Visual ctermfg=251 ctermbg=239 cterm=none guifg=#c3c6ca guibg=#554d4b gui=none +hi VisualNOS ctermfg=251 ctermbg=236 cterm=none guifg=#c3c6ca guibg=#303030 gui=none +hi Search ctermfg=177 ctermbg=241 cterm=none guifg=#d787ff guibg=#636066 gui=none +hi Folded ctermfg=103 ctermbg=237 cterm=none guifg=#a0a8b0 guibg=#3a4046 gui=none +hi Title ctermfg=230 cterm=bold guifg=#ffffd7 gui=bold +hi StatusLine ctermfg=230 ctermbg=238 cterm=none guifg=#ffffd7 guibg=#444444 gui=italic +hi VertSplit ctermfg=238 ctermbg=238 cterm=none guifg=#444444 guibg=#444444 gui=none +hi StatusLineNC ctermfg=241 ctermbg=238 cterm=none guifg=#857b6f guibg=#444444 gui=none +hi LineNr ctermfg=241 ctermbg=232 cterm=none guifg=#857b6f guibg=#080808 gui=none +hi SpecialKey ctermfg=241 ctermbg=235 cterm=none guifg=#626262 guibg=#2b2b2b gui=none +hi WarningMsg ctermfg=203 guifg=#ff5f55 +hi ErrorMsg ctermfg=196 ctermbg=236 cterm=bold guifg=#ff2026 guibg=#3a3a3a gui=bold + +" Vim >= 7.0 specific colors +if version >= 700 +hi CursorLine ctermbg=236 cterm=none guibg=#32322f +hi MatchParen ctermfg=228 ctermbg=101 cterm=bold guifg=#eae788 guibg=#857b6f gui=bold +hi Pmenu ctermfg=230 ctermbg=238 guifg=#ffffd7 guibg=#444444 +hi PmenuSel ctermfg=232 ctermbg=192 guifg=#080808 guibg=#cae982 +endif + +" Diff highlighting +hi DiffAdd ctermbg=17 guibg=#2a0d6a +hi DiffDelete ctermfg=234 ctermbg=60 cterm=none guifg=#242424 guibg=#3e3969 gui=none +hi DiffText ctermbg=53 cterm=none guibg=#73186e gui=none +hi DiffChange ctermbg=237 guibg=#382a37 + +"hi CursorIM +"hi Directory +"hi IncSearch +"hi Menu +"hi ModeMsg +"hi MoreMsg +"hi PmenuSbar +"hi PmenuThumb +"hi Question +"hi Scrollbar +"hi SignColumn +"hi SpellBad +"hi SpellCap +"hi SpellLocal +"hi SpellRare +"hi TabLine +"hi TabLineFill +"hi TabLineSel +"hi Tooltip +"hi User1 +"hi User9 +"hi WildMenu + + +" Syntax highlighting +hi Keyword ctermfg=111 cterm=none guifg=#88b8f6 gui=none +hi Statement ctermfg=111 cterm=none guifg=#88b8f6 gui=none +hi Constant ctermfg=173 cterm=none guifg=#e5786d gui=none +hi Number ctermfg=173 cterm=none guifg=#e5786d gui=none +hi PreProc ctermfg=173 cterm=none guifg=#e5786d gui=none +hi Function ctermfg=192 cterm=none guifg=#cae982 gui=none +hi Identifier ctermfg=192 cterm=none guifg=#cae982 gui=none +hi Type ctermfg=186 cterm=none guifg=#d4d987 gui=none +hi Special ctermfg=229 cterm=none guifg=#eadead gui=none +hi String ctermfg=113 cterm=none guifg=#95e454 gui=italic +hi Comment ctermfg=246 cterm=none guifg=#9c998e gui=italic +hi Todo ctermfg=101 cterm=none guifg=#857b6f gui=italic + + +" Links +hi! link FoldColumn Folded +hi! link CursorColumn CursorLine +hi! link NonText LineNr + +" vim:set ts=4 sw=4 noet: diff --git a/ftplugin/python_editing.vim b/ftplugin/python_editing.vim new file mode 100755 index 0000000..531ea70 --- /dev/null +++ b/ftplugin/python_editing.vim @@ -0,0 +1,85 @@ +" Only do this when not done yet for this buffer +if exists("b:did_ftplugin") +finish +endif +let b:did_ftplugin = 1 + +map :w:!/usr/bin/env python % +map gd /def + +set foldmethod=expr +set foldexpr=PythonFoldExpr(v:lnum) +set foldtext=PythonFoldText() + +map f za +map F :call ToggleFold() +let b:folded = 1 + +function! ToggleFold() + if( b:folded == 0 ) + exec "normal! zM" + let b:folded = 1 + else + exec "normal! zR" + let b:folded = 0 + endif +endfunction + +function! PythonFoldText() + + let size = 1 + v:foldend - v:foldstart + if size < 10 + let size = " " . size + endif + if size < 100 + let size = " " . size + endif + if size < 1000 + let size = " " . size + endif + + if match(getline(v:foldstart), '"""') >= 0 + let text = substitute(getline(v:foldstart), '"""', '', 'g' ) . ' ' + elseif match(getline(v:foldstart), "'''") >= 0 + let text = substitute(getline(v:foldstart), "'''", '', 'g' ) . ' ' + else + let text = getline(v:foldstart) + endif + + return size . ' lines:'. text . ' ' + +endfunction + +function! PythonFoldExpr(lnum) + + if indent( nextnonblank(a:lnum) ) == 0 + return 0 + endif + + if getline(a:lnum-1) =~ '^\(class\|def\)\s' + return 1 + endif + + if getline(a:lnum) =~ '^\s*$' + return "=" + endif + + if indent(a:lnum) == 0 + return 0 + endif + + return '=' + +endfunction + +" In case folding breaks down +function! ReFold() + set foldmethod=expr + set foldexpr=0 + set foldnestmax=1 + set foldmethod=expr + set foldexpr=PythonFoldExpr(v:lnum) + set foldtext=PythonFoldText() + echo +endfunction + diff --git a/plugin/vimchat.vim b/plugin/vimchat.vim new file mode 100644 index 0000000..51ecdc0 --- /dev/null +++ b/plugin/vimchat.vim @@ -0,0 +1,1742 @@ +" VImChat Plugin for vim +" This plugin allows you to connect to jabber servers and chat with +" multiple people. +" +" It does not currently support other IM networks or group chat, +" but these are on the list to be added. +" +" It is also worth noting that you can use aim/yahoo via jabber transports, +" but the transports must be set up on another client as vimchat does not +" support setting them up yet +" +" This branchh supports multiple versions at a time, but probably still +" has a decent amount of bugs! +" +" Note: The vimchat_jid and vimchat_password variables have been *changed* +" into the vimchat_accounts dictionary. This version of vimchat will not +" work unless you make this change! +" +" Supported ~/.vimrc Variables: +" g:vimchat_accounts = {'jabber id':'password',...} +" g:vimchat_buddylistwidth = width of buddy list +" g:vimchat_libnotify = (0 or 1) default is 1 +" g:vimchat_logpath = path to store log files +" g:vimchat_logchats = (0 or 1) default is 1 +" g:vimchat_otr = (0 or 1) default is 0 +" g:vimchat_logotr = (0 or 1) default is 1 +" g:vimchat_statusicon = (0 or 1) default is 1 +" g:vimchat_blinktimeout = timeout in seconds default is -1 +" g:vimchat_buddylistmaxwidth = max width of buddy list window default '' +" g:vimchat_timestampformat = format of the msg timestamp default "[%H:%M]" +" g:vimchat_showPresenceNotification = +" notify if buddy changed status default "" + +python < ~/.vimchat/vimchat.debug') + vim.command('nnoremap B :py VimChat.toggleBuddyList()') + vim.command('let s:hasVars = VimChatCheckVars()') + self.setupLeaderMappings() + hasVars = int(vim.eval('s:hasVars')) + + if hasVars < 1: + print "Could not start VimChat!" + return 0 + + #Libnotify + libnotify = int(vim.eval('g:vimchat_libnotify')) + if not libnotify: + pynotify_enabled = False + + #Growl Setup + if self.growl_enabled: + self.growl_notifier = Growl.GrowlNotifier("VimChat", + ["msg txrx", "account status"]) + self.growl_notifier.register() + self.growl_icon = Image.imageFromPath( + os.path.expanduser('~/.vimchat/icon.gif')) + + otr_enabled = int(vim.eval('g:vimchat_otr')) + otr_logging = int(vim.eval('g:vimchat_logotr')) + if otr_enabled == 1: + if otr_logging == 1: + pyotr_logging = True + else: + pyotr_logging = False + else: + pyotr_enabled = False + pyotr_logging = False + + # Timestamp format + self.timeformat = vim.eval('g:vimchat_timestampformat') + + # Signon to accounts listed in .vimrc + if vim.eval("exists('g:vimchat_accounts')") == '1': + vimChatAccounts = vim.eval('g:vimchat_accounts') + for jid,password in vimChatAccounts.items(): + self._signOn(jid,password) + + # Signon to accounts listed in .vimchat/config + if os.path.exists(self.configFilePath): + config = RawConfigParser() + config.read(self.configFilePath) + if config.has_section('accounts'): + for jid in config.options('accounts'): + password = config.get('accounts', jid) + self._signOn(jid, password) + + if len(self.accounts) and self.statusIcon == None: + isStatusIcon = int(vim.eval('g:vimchat_statusicon')) + if isStatusIcon != 1: + self.gtk_enabled = False + if self.gtk_enabled: + self.statusIcon = self.StatusIcon() + self.statusIcon.start() + self.blinktimeout = int(vim.eval('g:vimchat_blinktimeout')) + + self.toggleBuddyList() + + def stop(self): + if self.statusIcon != None: + self.statusIcon.stop() + self.signOffAll() + + class OtrOps: + def __init__(self,parent=None): + self.parent = parent + + def policy(self, opdata=None, context=None): + """ checks for the contacts username in policylist and returns it + if available, otherwise checks for a default entry and returns it + if available, otherwise just return python-otr's default """ + return otr.OTRL_POLICY_DEFAULT + + def create_privkey(self, opdata=None, accountname=None, protocol=None): + # should give the user some visual feedback here, + # generating can take some time! the private key MUST + # be available when this method returned + print "Need OTR key for: %s :VimChatGenerateKey to create one" % ( + accountname) + + #TODO + #VimChat.otrGenerateKey() + + def is_logged_in(self, opdata=None, accountname=None, + protocol=None, recipient=None): + + if accountname in VimChat.accounts.keys(): + if recipient: + roster = VimChat.accounts[accountname]._roster + priority = roster.getPriority(recipient) + if priority: + return True + return False + else: + return False + else: + return False + + def inject_message(self, opdata=None, accountname=None, + protocol=None, recipient=None, message=None): + + if accountname in VimChat.accounts.keys(): + if recipient and message: + VimChat.accounts[accountname].jabberSendMessage(recipient, + message) + else: + print "Error in inject_message" + + def notify(sef, opdata=None, level=None, accountname=None, + protocol=None, username=None,title=None, primary=None, + secondary=None): + + # show a small dialog or something like that + # level is otr.OTRL_NOTIFY_ERROR, otr.OTRL_NOTIFY_WARNING + # or otr.OTRL_NOTIFY_INFO primary and secondary are the + # messages that should be displayed + print "Notify: title: " + title + " primary: " + primary + \ + " secondary: " + secondary + + def display_otr_message(self, opdata=None, accountname=None, + protocol=None, username=None, msg=None): + + # this usually logs to the conversation window + + #write_message(our_account=accountname, proto=protocol, + # contact=username, message=msg) + # NOTE: this function MUST return 0 if it processed the message + # OR non-zero, the message will then be passed to notify() by OTR + print "Got OTR Message" + return 0 + + def update_context_list(self, opdata=None): + # this method may provide some visual feedback when + # the context list was updated. This may be useful + # if you have a central way of setting fingerprints' trusts + # and you want to update the list of contexts to consider + #in this way + pass + + def protocol_name(self, opdata=None, protocol=None): + """ returns a "human-readable" version of the given protocol """ + if protocol == "xmpp": + return "XMPP (eXtensible Messaging and Presence Protocol)" + + def new_fingerprint( + self, opdata=None, userstate=None, accountname=None, + protocol=None, username=None, fingerprint=None): + + human_fingerprint = "" + try: + human_fingerprint = otr.otrl_privkey_hash_to_human(fingerprint) + #write_message(our_account=accountname, proto=protocol, + # contact=username, + # message="New fingerprint: %s"%human_fingerprint) + return human_fingerprint + except: + pass + + def write_fingerprints(self, opdata=None): + fpath = os.path.expanduser( + VimChat.otr_basedir + '/' + VimChat.otr_fingerprints) + for jid,account in VimChat.accounts.items(): + otr.otrl_privkey_write_fingerprints( + account._otr_userstate, fpath) + else: + print "User: " + str(account) + " not connected" + + def gone_secure(self, opdata=None, context=None): + trust = context.active_fingerprint.trust + if trust: + trust = "V" + else: + trust = "U" + + buf = VimChat.beginChat(context.accountname, context.username) + if buf: + VimChat.appendStatusMessage(context.accountname, + buf,"[OTR]","-- " + trust + " OTR Connection Started") + print trust + " OTR Connection Started with " + \ + str(context.username) + + def gone_insecure(self, opdata=None, context=None): + connection = VimChat.accounts[context.accountname] + buf = self.getBufByName(connection._chats[context.username]) + if buf: + VimChat.appendStatusMessage(context.accountname, + buf,"[OTR]","-- Secured OTR Connection Ended") + print "Secure OTR Connection Ended with " + context.username + + def still_secure(self, opdata=None, context=None, is_reply=0): + # this is called when the OTR session was refreshed + # (ie. new session keys have been created) + # is_reply will be 0 when we started that refresh, + # 1 when the contact started it + try: + connection = VimChat.accounts[context.accountname] + buf = self.getBufByName(connection._chats[context.username]) + if buf: + jid = "[OTR]" + VimChat.appendStatusMessage(context.accountname, + buf,"[OTR]","-- Secured OTR Connection Refreshed") + print "Secure OTR Connection Refreshed with " + \ + str(context.username) + except Exception, e: + print "Error in still_secure: " + str(e) + + def log_message(self, opdata=None, message=None): + # log message to a logfile or something + pass + + def max_message_size(self, opdata=None, context=None): + """ looks up the max_message_size for the relevant protocol """ + # return 0 when no limit is defined + #return msg_size[context.protocol] + return 0 + + def account_name( + self, opdata=None, account=None, context=None, protocol=None): + + #return find_account(accountname=account, protocol).name + if account in VimChat.accounts.keys(): + jid = VimChat.accounts[account]._jid.split('/')[0] + print "accountname: " + jid + return jid + else: + print "Could not get account name" + + + class JabberConnection(threading.Thread): + _roster = {} + _chats = {} + + def __init__(self, parent, jid, jabberClient, roster): + self._parent = parent + self._jid = jid + self._jids = jid.split('/')[0] + self._roster = roster + threading.Thread.__init__(self) + self.jabber = jabberClient + self.online = 0 + self._protocol = 'xmpp' + + def run(self): + self.jabber.RegisterHandler('message',self.jabberMessageReceive) + self.jabber.RegisterHandler('presence',self.jabberPresenceReceive) + self.jabberPresenceUpdate() + + #Socket stuff + RECV_BUF = 4096 + self.xmppS = self.jabber.Connection._sock + socketlist = [self.xmppS] + self.online = 1 + + #set up otr + self.otrSetup() + while self.online: + (i, o, e) = select.select(socketlist, [], [], 1) + for each in i: + if each == self.xmppS: + self.jabber.Process(1) + else: + pass + time.sleep(1) + + def stop(self): + self.online = 0 + + #From Jabber Functions + def jabberMessageReceive(self, conn, msg): + if msg.getBody(): + fromJid = str(msg.getFrom()) + type = str(msg.getType()).lower() + jid = fromJid.split('/')[0] + body = unicode(msg.getBody()) + body = str(body.encode('utf8')) + + if pyotr_enabled and type != "groupchat": + #OTR Stuff + is_internal, message, tlvs = otr.otrl_message_receiving( + self._otr_userstate, (VimChat.OtrOps(),None), + self._jids,self._protocol,jid, body) + + context = otr.otrl_context_find( + self._otr_userstate,jid,self._jids,self._protocol,1)[0] + + if otr.otrl_tlv_find(tlvs, + otr.OTRL_TLV_SMP_ABORT) is not None: + self.otrAbortVerify(context) + elif otr.otrl_tlv_find(tlvs, + otr.OTRL_TLV_SMP1) is not None: + if context.smstate.nextExpected != \ + otr.OTRL_SMP_EXPECT1: + self.otrAbortVerify(context) + else: + #TODO: prompt user for secret + pass + elif otr.otrl_tlv_find(tlvs, + otr.OTRL_TLV_SMP1Q) is not None: + if context.smstate.nextExpected != \ + otr.OTRL_SMP_EXPECT1: + self.otrAbortVerify(context) + else: + tlv = otr.otrl_tlv_find(tlvs, otr.OTRL_TLV_SMP1Q) + VimChat.otrSMPRequestNotify( + context.accountname, context.username,tlv.data) + elif otr.otrl_tlv_find(tlvs, + otr.OTRL_TLV_SMP2) is not None: + if context.smstate.nextExpected != \ + otr.OTRL_SMP_EXPECT2: + self.otrAbortVerify(context) + else: + context.smstate.nextExpected = otr.OTRL_SMP_EXPECT4 + elif otr.otrl_tlv_find(tlvs, + otr.OTRL_TLV_SMP3) is not None: + if context.smstate.nextExpected != \ + otr.OTRL_SMP_EXPECT3: + self.otrAbortVerify(context) + else: + if context.smstate.sm_prog_state == \ + otr.OTRL_SMP_PROG_SUCCEEDED: + self.otrSMPVerifySuccess(context) + print "Successfully verified " + \ + context.username + else: + self.otrSMPVerifyFailed(context) + print "Failed to verify " + context.username + elif otr.otrl_tlv_find(tlvs, + otr.OTRL_TLV_SMP4) is not None: + if context.smstate.nextExpected != \ + otr.OTRL_SMP_EXPECT4: + self.otrAbortVerify(context) + else: + context.smstate.nextExpected = otr.OTRL_SMP_EXPECT1 + if context.smstate.sm_prog_state == \ + otr.OTRL_SMP_PROG_SUCCEEDED: + self.otrSMPVerifySuccess(context) + print "Successfully verified " + \ + context.username + else: + self.otrSMPVerifyFailed(context) + print "Failed to verify " + context.username + #}}} + + secure = False + type = otr.otrl_proto_message_type(body) + if type == otr.OTRL_MSGTYPE_DATA \ + and type != otr.OTRL_MSGTYPE_NOTOTR \ + and type != otr.OTRL_MSGTYPE_TAGGEDPLAINTEXT: + + if context.active_fingerprint: + trust = context.active_fingerprint.trust + if trust: + secure = "V" + else: + secure = "U" + + if not is_internal: + VimChat.messageReceived(self._jids, fromJid, + message.strip(),secure) + + elif type == "groupchat": + parts = fromJid.split('/') + chatroom = parts[0] + if len(parts) > 1: + user = parts[1] + else: + user = "--" + VimChat.messageReceived( + self._jids, user, body.strip(), False, chatroom) + else: + VimChat.messageReceived(self._jids, fromJid,body.strip()) + + def jabberPresenceReceive(self, conn, msg): + #TODO: figure out better way than this try/except block + try: + fromJid = msg.getFrom() + type = str(msg.getType()).lower() + show = str(unicode(msg.getShow()).encode('utf-8')) + status = str(unicode(msg.getStatus()).encode('utf-8')) + priority = str(unicode(msg.getPriority()).encode('utf-8')) + # print fromJid, ' jid: ', msg.getJid(), ' status: ', + # status, ' reason: ', msg.getReason(), ' stat code: ', + # msg.getStatusCode() + + if show == "None": + if priority != "None": + show = 'online' + else: + show = 'offline' + + accountName = "" + chat = "" + if type == "groupchat": + parts = fromJid.split('/') + # in this case it is equal to the chatroom + accountName = str(parts[0]) + user = "" + if len(parts) > 1: + user = parts[1] + chat = str(user) + else: + accountName = str(fromJid) + chat = fromJid + + # notify if somebody is now available + if str(vim.eval('g:vimchat_showPresenceNotification')).find( + str(show)) != -1: + onlineUser = VimChat.getJidParts(accountName)[0] + if VimChat.hasBuddyShowChanged(self._jids, onlineUser, + str(show)): + VimChat.pyNotification('Presence event',""+onlineUser+ + "\nis now "+str(show),'dialog-information') + VimChat.presenceUpdate(self._jids, accountName, chat, show, + status, priority) + except: + pass + + #To Jabber Functions + def jabberOnSendMessage(self, tojid, msg): + msg = msg.strip() + if not pyotr_enabled: + self.jabberSendMessage(tojid,msg) + return 0 + + #only if otr is enabled + new_message = otr.otrl_message_sending( + self._otr_userstate,(VimChat.OtrOps(),None), + self._jids,self._protocol,tojid,msg,None) + + context = otr.otrl_context_find( + self._otr_userstate,tojid,self._jids,self._protocol,1)[0] + + #if context.msgstate == otr.OTRL_MSGSTATE_ENCRYPTED + otr.otrl_message_fragment_and_send( + (VimChat.OtrOps(), None), context, new_message, + otr.OTRL_FRAGMENT_SEND_ALL) + + def jabberSendMessage(self, tojid, msg): + msg = msg.strip() + m = xmpp.protocol.Message(to=tojid,body=msg,typ='chat') + self.jabber.send(m) + + def jabberSendGroupChatMessage(self, room, msg): + msg = msg.strip() + m = xmpp.protocol.Message(to=room,body=msg,typ='groupchat') + self.jabber.send(m) + + def jabberJoinGroupChat(self, room, name): + roomStr = room + '/' + name + self.jabber.send(xmpp.Presence(to=roomStr)) + + def jabberLeaveGroupChat(self, room): + self.jabber.send(xmpp.Presence(to=room,typ='unavailable')) + + def jabberPresenceUpdate(self, show='', status='', priority=5): + m = xmpp.protocol.Presence( + None, + show=show, + priority=priority, + status=status) + self._presence = m + self.jabber.send(m) + + def jabberGetPresence(self): + show = self._presence.getShow() + status = self._presence.getStatus() + return [show,status] + + def disconnect(self): + try: + self.jabber.disconnect() + except: + pass + + def isConnected(self): + return self.jabber.isConnected() + + #Roster Functions + def getRosterItems(self): + if self._roster: + return self._roster.getItems() + else: + return None + + #OTR Functions + def otrSetup(self): + #Set Up OTR Stuff If Available + if not pyotr_enabled: + return 0 + + self._otr_userstate = otr.otrl_userstate_create() + + keypath = os.path.expanduser( + VimChat.otr_basedir + '/' + VimChat.otr_keyfile) + + #Make the otr directory + basedir = os.path.expanduser(VimChat.otr_basedir) + if not os.path.exists(basedir): + os.makedirs(basedir) + + if not os.path.isfile(keypath): + #Create it if it doesn't exist + file(keypath,'w') + jid = self._jid.split('/')[0] + + print "No OTR Key found for " + self._jids + \ + ". :VimChatOtrGenerateKey to make one." + else: + pass + if os.access(keypath, os.R_OK): + try: + otr.otrl_privkey_read(self._otr_userstate,keypath) + except: + pass + + fprintPath = os.path.expanduser( + VimChat.otr_basedir + '/' + VimChat.otr_fingerprints) + if not os.path.isfile(fprintPath): + #Create it if it doesn't exist + file(fprintPath,'w') + else: + if os.access(fprintPath, os.R_OK): + try: + otr.otrl_privkey_read_fingerprints( + self._otr_userstate,fprintPath) + except: + pass + + def otrDisconnectChat(self, jid): + context = otr.otrl_context_find( + self._otr_userstate,jid,self._jids,self._protocol,1)[0] + + if context.msgstate == otr.OTRL_MSGSTATE_ENCRYPTED: + otr.otrl_message_disconnect( + self._otr_userstate,(VimChat.OtrOps(),None), + self._jids,self._protocol,jid) + + def otrManualVerifyBuddy(self, jid): + self.otrSetTrust(jid,"manual") + buf = VimChat.beginChat(self._jids, jid) + if buf: + VimChat.appendStatusMessage(self._jids, + buf,"[OTR]","-- Verified Fingerprint of " + jid) + print "Verified "+jid + + def otrSMPVerifyBuddy(self, jid, question, secret): + context = otr.otrl_context_find( + self._otr_userstate,jid,self._jids,self._protocol,1)[0] + + otr.otrl_message_initiate_smp_q( + self._otr_userstate, (VimChat.OtrOps(), None), + context,question,secret) + + buf = VimChat.beginChat(self._jids, jid) + if buf: + VimChat.appendMessage(context.accountname, + buf,"-- Sent Question to "+ jid +" for verification.") + print "Sent Question for verification to " + \ + str(context.username) + + def otrSMPVerifySuccess(self,context): + jid = context.username + self.otrSetTrust(jid,"smp") + buf = VimChat.beginChat(context.accountname, jid) + if buf: + VimChat.appendStatusMessage(context.accountname, + buf,"[OTR]", + "-- Secret answered! "+ jid +" is verified.") + print jid + " Gave correct secret -- verified!" + + def otrSMPVerifyFailed(self,context): + jid = context.username + self.otrSetTrust(jid,"") + buf = VimChat.beginChat(context.accountname, jid) + if buf: + VimChat.appendStatusMessage(context.accountname, + buf,"[OTR]", + "-- Secret response Failed! "+ jid + " is NOT verified.") + print jid + " Failed to answer secret, NOT verified!" + + def otrSMPRespond(self,jid,secret): + context = otr.otrl_context_find( + self._otr_userstate,jid,self._jids,self._protocol,1)[0] + + otr.otrl_message_respond_smp( + self._otr_userstate,(VimChat.OtrOps(),None),context,secret) + buf = VimChat.beginChat(self._jids, jid) + if buf: + VimChat.appendStatusMessage(context.accountname, + buf,"[OTR]","-- Sent Secret to "+ jid +"") + print "Sent secret response to " + jid + + def otrGeneratePrivateKey(self): + keypath = os.path.expanduser( + VimChat.otr_basedir + '/' + VimChat.otr_keyfile) + jid = self._jid.split('/')[0] + otr.otrl_privkey_generate( + self._otr_userstate, keypath, jid, self._protocol) + + def otrAbortVerify(self,context): + otr.otrl_message_abort_smp( + self._otr_userstate, (VimChat.OtrOps(), None), context) + + def otrSetTrust(self, jid, trust): + context = otr.otrl_context_find( + self._otr_userstate,jid,self._jids,self._protocol,1)[0] + otr.otrl_context_set_trust(context.active_fingerprint,trust) + + def otrIsChatEncrypted(self, account, jid): + context = otr.otrl_context_find( + VimChat.accounts[account]._otr_userstate,jid, + VimChat.accounts[account]._jids, + VimChat.accounts[account]._protocol,1)[0] + + if context.msgstate == otr.OTRL_MSGSTATE_ENCRYPTED: + return True + else: + return False + + + class StatusIcon(threading.Thread): + def __init__(self): + self.status_icon_default = "~/.vimchat/icon.gif" + self.status_icon_path = self.status_icon_default + threading.Thread.__init__(self) + + def run(self): + # GTK StausIcon + gtk.gdk.threads_init() + self.status_icon = StatusIcon() + self.changeStatus() + self.status_icon.set_tooltip("VimChat") + self.status_icon.set_visible(True) + gtk.main() + + def blink(self, value): + self.status_icon.set_blinking(value) + + def changeStatus(self,statusText=""): + if len(statusText)>0: + statusText = "_"+statusText + file_path = os.path.expanduser(re.sub("(\..[^.]*)$", + statusText+"\\1", self.status_icon_default)) + if not os.path.exists(file_path): + file_path = os.path.expanduser(self.status_icon_default) + if not os.path.exists(file_path): + return + self.status_icon_path = file_path + self.status_icon.set_from_file(self.status_icon_path) + + def stop(self): + self.status_icon.set_visible(False) + gtk.main_quit() + + + class BlinkClearer(threading.Thread): + def __init__(self, tt): + self.timeoutTime = tt + threading.Thread.__init__(self) + + def run(self): + time.sleep(self.timeoutTime) + VimChat.clearNotify() + + + def signOn(self): + accounts = self.getAccountsFromConfig() + if len(accounts) == 0: + print 'No accounts found in the vimchat config %s.'\ + % (self.configFilePath) + return + for account in accounts: + print account + account = vim.eval( + 'input("Enter the account from the above list: ")') + if account in accounts: + password = accounts[account] + self._signOn(account, password) + else: + print 'Error: [%s] is an invalid account.' % (account) + + def _signOn(self, jid, password): + if not password: + password = vim.eval('inputsecret("' + jid + ' password: ")') + [jidSmall,user,resource] = self.getJidParts(jid) + print "Connecting user " + jid + "..." + if jidSmall in self.accounts: + try: self.accounts[jidSmall].disconnect() + except: pass + + JID=xmpp.protocol.JID(jid) + jabberClient = xmpp.Client(JID.getDomain(),debug=[]) + + con = jabberClient.connect() + if not con: + print 'could not connect!\n' + if self.growl_enabled: + self.growl_notifier.notify("account status", "VimChat", + "Could not connect.", self.growl_icon) + return 0 + + auth=jabberClient.auth( + JID.getNode(), password, resource=JID.getResource()) + if not auth: + print 'could not authenticate!\n' + if self.growl_enabled: + self.growl_notifier.notify("account status", "VimChat", + "Could not authenticate.", self.growl_icon) + return 0 + + jabberClient.sendInitPresence(requestRoster=1) + roster = jabberClient.getRoster() + + [accountJid,user,resource] = self.getJidParts(jid) + if accountJid in self.accounts: + try: + self.accounts[accountJid].disconnect() + except: pass + self.accounts[accountJid] = self.JabberConnection( + self, jid, jabberClient, roster) + self.accounts[accountJid].start() + print "Connected with " + jid + if self.growl_enabled: + self.growl_notifier.notify("account status", "VimChat", + "Signed into " + jid + " successfully", self.growl_icon) + + def signOff(self): + accounts = self.accounts + if len(accounts) == 0: + print 'No accounts found' + return + for account in accounts: + print account + account = vim.eval( + 'input("Enter the account from the above list: ")') + self._signOff(account) + + def signOffAll(self): + accounts = self.accounts + if len(accounts) == 0: + return + size=len(accounts) + while(size > 0): + account = accounts.keys()[0] + self._signOff(account) + if len(accounts) >= size: + print "Error while signing off" + break + else: + size=len(accounts) + + def _signOff(self, account): + accounts = self.accounts + if account in accounts: + try: + accounts[account].disconnect() + accounts[account].stop() + del accounts[account] + print "%s was signed off of VimChat!" % (account) + if self.growl_enabled: + self.growl_notifier.notify("account status", "VimChat", + "%s was signed off of VimChat!" %(account), + self.growl_icon) + except: + print "Error signing off %s VimChat!" % (account) + print sys.exc_info()[0:2] + else: + print 'Error: [%s] is an invalid account.' % (account) + if self.growl_enabled: + self.growl_notifier.notify("account status", "VimChat", + "Error signing off %s VimChat" %(account), + self.growl_icon) + + def showStatus(self): + print self.accounts[self.accounts.keys()[0]].jabberGetPresence() + + def formatPresenceUpdateLine(self, fromJid, show, status): + tstamp = self.getTimestamp() + return tstamp + " -- " + str(fromJid) + \ + " is " + str(show) + ": " + str(status) + + def getJidParts(self, jid): + jidParts = str(jid).split('/') + # jid: bob@foo.com + jid = jidParts[0] + # user: bob + user = jid.split('@')[0] + + #Get A Resource if exists + if len(jidParts) > 1: + resource = jidParts[1] + else: + resource = '' + + return [jid,user,resource] + + def getTimestamp(self): + return time.strftime(self.timeformat) + + def getBufByName(self, name): + for buf in vim.buffers: + if buf.name and buf.name.split('/')[-1] == name: + return buf + return None + + def isGroupChat(self): + try: + groupchat = int(vim.eval('b:groupchat')) + if groupchat == 1: + return True + except: + pass + + return False + + def toggleBuddyList(self): + # godlygeek's way to determine if a buffer is hidden in one line: + # :echo len(filter(map(range(1, tabpagenr('$')), + # 'tabpagebuflist(v:val)'), 'index(v:val, 4) == 0')) + + if not self.accounts: + print "Could not display buddy list. Type on to connect." + return 0 + + if self.buddyListBuffer: + bufferList = vim.eval('tabpagebuflist()') + if str(self.buddyListBuffer.number) in bufferList: + vim.command('sbuffer ' + str(self.buddyListBuffer.number)) + vim.command('hide') + return + + #Write buddy list to file + self.writeBuddyList() + + buddyListWidth = vim.eval('g:vimchat_buddylistwidth') + + try: + vim.command("silent vertical sview " + self.rosterFile) + vim.command("silent wincmd H") + vim.command("silent vertical resize " + buddyListWidth) + vim.command("silent e!") + vim.command("setlocal noswapfile") + vim.command("setlocal nomodifiable") + vim.command("setlocal buftype=nowrite") + except Exception, e: + print e + vim.command("new " + self.rosterFile) + + commands = """ + setlocal foldtext=VimChatFoldText() + setlocal nowrap + setlocal foldmethod=marker + nmap :py VimChat.beginChatFromBuddyList() + nnoremap l :py VimChat.openLogFromBuddyList() + nnoremap B :py VimChat.toggleBuddyList() + nnoremap q :py VimChat.toggleBuddyList() + nnoremap r :py VimChat.refreshBuddyList() + nnoremap R :py VimChat.refreshBuddyList() + nnoremap n /{{{ ( + nnoremap c :py VimChat.openGroupChat() + nnoremap ss :py VimChat.setStatus() + nnoremap :silent exec 'vertical resize ' . (winwidth('.') > g:vimchat_buddylistwidth ? (g:vimchat_buddylistwidth) : (g:vimchat_buddylistmaxwidth)) + """ + vim.command(commands) + self.setupLeaderMappings() + + self.buddyListBuffer = vim.current.buffer + + def getBuddyListItem(self): + vim.command("normal zo") + vim.command("normal ]z") + vim.command("normal [z") + vim.command("normal j") + + toJid = vim.current.line + toJid = toJid.strip() + + vim.command(r"call search('\V{{{ [+]', 'b')") + + account = str(vim.current.line).split(' ')[2] + return account, toJid + + def beginChatFromBuddyList(self): + account, toJid = self.getBuddyListItem() + [jid,user,resource] = self.getJidParts(toJid) + + print '**** beginning chat with account:', account + buf = VimChat.beginChat(account, jid) + if not buf: + #print "Error getting buddy info: " + jid + return 0 + + vim.command('sbuffer ' + str(buf.number)) + VimChat.toggleBuddyList() + vim.command('wincmd K') + + def refreshBuddyList(self): + self.writeBuddyList() + vim.command("silent e!") + + def hasBuddyShowChanged(self,accountJid,jid,showNew): + showList = self.oldShowList + if showList != None: + account = showList.get(accountJid) + if account != None: + showOld = str(account.get(jid)) + if account.get('online-since')+6 < int(time.time()) and \ + showOld != showNew: + return True + return False + + def writeBuddyList(self): + #write roster to file + import codecs + rF = codecs.open(self.rosterFile,'w','utf-16') + + for curJid, account in self.accounts.items(): + if not account.isConnected(): + rF.write( + u""" + ****************************** + ERROR: %s IS NOT CONNECTED!!! + You can type on to reconnect. + ****************************** + """ % (curJid)) + continue + accountText = u"{{{ [+] %s\n"%(curJid) + rF.write(accountText) + + roster = account._roster + rosterItems = roster.getItems() + rosterItems.sort() + for item in rosterItems: + name = roster.getName(item) + status = roster.getStatus(item) + show = roster.getShow(item) + priority = roster.getPriority(item) + groups = roster.getGroups(item) + + if not name: + name = item + if not status: + status = u'' + if not show: + if priority: + show = u'on' + else: + show = u'off' + if not priority: + priority = u'' + if not groups: + groups = u'' + if show != u'off': + buddyText =\ + u"{{{ (%s) %s\n\t%s \n\tGroups: %s\n\t%s:\n%s\n}}}\n" %\ + (show, name, item, groups, show, status) + rF.write(buddyText) + + rF.write("}}}\n") + + rF.close() + + def beginChat(self, fromAccount, toJid, groupChat=False): + #Set the ChatFile + connection = self.accounts[fromAccount] + if toJid in connection._chats.keys(): + chatFile = connection._chats[toJid] + else: + if groupChat: + chatFile = 'groupchat:' + toJid + else: + chatFile = 'chat:' + toJid + + connection._chats[toJid] = chatFile + bExists = int(vim.eval('buflisted("' + chatFile + '")')) + if bExists: + #TODO: Need to call sbuffer only if buffer is hidden. + #vim.command('sbuffer ' + chatFile) + return self.getBufByName(chatFile) + else: + vim.command("split " + chatFile.replace('%', r'\%')) + #Only do this stuff if its a new buffer + if groupChat: + vim.command('let b:groupchat=1') + else: + vim.command('let b:groupchat=0') + + vim.command("let b:buddyId = '" + toJid + "'") + vim.command("let b:account = '" + fromAccount + "'") + self.setupChatBuffer(groupChat) + return vim.current.buffer + + def setupChatBuffer(self, isGroupChat=False): + commands = """ + setlocal noswapfile + setlocal buftype=nowrite + setlocal noai + setlocal nocin + setlocal nosi + setlocal filetype=vimchat + setlocal syntax=vimchat + setlocal wrap + setlocal foldmethod=marker + nnoremap i :py VimChat.sendBufferShow() + nnoremap o :py VimChat.sendBufferShow() + nnoremap a :py VimChat.sendBufferShow() + nnoremap B :py VimChat.toggleBuddyList() + nnoremap q :py VimChat.deleteChat() + au CursorMoved exe 'py VimChat.clearNotify()' + """ + vim.command(commands) + self.setupLeaderMappings() + if isGroupChat: + vim.command('setlocal foldmethod=syntax') + + def setupLeaderMappings(self): + commands = """ + nnoremap l :py VimChat.openLogFromChat() + nnoremap ov :py VimChat.otrVerifyBuddy() + nnoremap or :py VimChat.otrSmpRespond() + nnoremap c :py VimChat.openGroupChat() + nnoremap j :py VimChat.joinChatroom() + nnoremap on :py VimChat.signOn() + nnoremap off :py VimChat.signOff() + """ + vim.command(commands) + + def sendBufferShow(self): + toJid = vim.eval('b:buddyId') + account = vim.eval('b:account') + groupChat = vim.eval('b:groupchat') + + #Create sending buffer + sendBuffer = "sendTo:" + toJid + vim.command("silent bo new " + sendBuffer) + vim.command("silent let b:buddyId = '" + toJid + "'") + vim.command("silent let b:account = '" + account + "'") + vim.command("setlocal filetype=vimchat") + + commands = """\ + resize 4 + setlocal noswapfile + setlocal nocin + setlocal noai + setlocal nosi + setlocal buftype=nowrite + setlocal wrap + setlocal foldmethod=marker + noremap :py VimChat.sendMessage() + inoremap :py VimChat.sendMessage() + nnoremap q :hide + """ + vim.command(commands) + vim.command('normal G') + vim.command('normal o') + vim.command('normal zt') + vim.command('star') + vim.command('let b:groupchat=' + str(groupChat)) + + def appendMessage( + self, account, buf, message, showJid='Me',secure=False): + + if not buf: + print "VimChat: Invalid Buffer to append to!" + return 0 + + lines = message.split("\n") + tstamp = self.getTimestamp() + + jid,user,resource = self.getJidParts(showJid) + logJid = buf.name.split('/')[-1].split(':')[1] + + secureString = "" + if secure: + secureString = "(*" + secure + "*)" + + #Get the first line + if resource: + line = tstamp + " " + secureString + \ + user + "/" + resource + ": " + lines.pop(0) + else: + line = tstamp + " " + secureString + user + ": " + lines.pop(0) + + buf.append(line) + #TODO: remove these lines + #line = line.replace("'", "''") + #vim.command("call append(line('$'),'" + line + "')") + if not secure or pyotr_logging: + VimChat.log(account, logJid, line) + + for line in lines: + line = '\t' + line + buf.append(line) + #line = line.replace("'", "''") + #vim.command("call append(line('$'),'" + line + "')") + #if message is not secure, or if otr logging is on + if not secure or pyotr_logging: + VimChat.log(account, logJid, line) + + #move cursor to bottom of buffer + self.moveCursorToBufBottom(buf) + + def appendStatusMessage(self, account, buf, prefix, message): + if not buf: + print "VimChat: Invalid Buffer to append to!" + return 0 + + jid = buf.name.split('/')[-1].split(':')[1] + jid,user,resource = self.getJidParts(jid) + + lines = message.split("\n") + tstamp = self.getTimestamp() + + #Get the first line + line = tstamp + prefix + ": " + lines.pop(0) + + buf.append(line) + VimChat.log(account, jid, line) + + for line in lines: + line = '\t' + line + buf.append(line) + VimChat.log(account, jid, line) + + #move cursor to bottom of buffer + #self.moveCursorToBufBottom(buf) + + def deleteChat(self): + #remove it from chats list + jid = vim.eval('b:buddyId') + account = vim.eval('b:account') + + if pyotr_enabled: + self.accounts[account].otrDisconnectChat(jid) + + del self.accounts[account]._chats[jid] + + #Check if it was a groupchat + if self.isGroupChat(): + self.accounts[account].jabberLeaveGroupChat(jid) + vim.command('bdelete!') + + def openGroupChat(self): + accounts = self.showAccountList() + + input = vim.eval( + 'input("Account (enter the number from the above list): ")') + if not re.match(r'\d+$', input): + vim.command('echohl ErrorMsg') + vim.command('echo "\\nYou must enter an integer corresponding' + + ' to an account."') + vim.command('echohl None') + return + index = int(input) + if index < 0 or index >= len(accounts): + vim.command('echohl ErrorMsg') + vim.command(r'echo "\nInvalid account number. Try again."') + vim.command('echohl None') + return + + account = accounts[index] + chatroom = vim.eval('input("Chat Room to join: ")') + name = vim.eval('input("Name to Use: ")') + self._openGroupChat(account, chatroom, name) + + def _openGroupChat(self, account, chatroom, name): + self.groupChatNames.append(name) + buf = VimChat.beginChat(account._jids, chatroom, True) + vim.command('sbuffer ' + str(buf.number)) + account.jabberJoinGroupChat(chatroom, name) + + def echoError(self, msg): + vim.command('echohl ErrorMsg') + vim.command(r'echo "\n"') + vim.command("echo '" + msg.replace("'", "''") + "'") + vim.command('echohl None') + + def joinChatroom(self): + if not os.path.exists(self.configFilePath): + print 'Error: Config file %s does not exist' % (self.configFilePath) + return + + chatrooms = {} + try: + config = RawConfigParser() + config.read(self.configFilePath) + for section in config.sections(): + if not section.startswith('chatroom:'): + continue + tokens = section.split(':') + if len(tokens) < 2: + continue + roomAlias = tokens[1] + data = {} + data['account'] = config.get(section, 'account') + data['room'] = config.get(section, 'room') + data['username'] = config.get(section, 'username') + chatrooms[roomAlias] = data + except: + print 'Error: Problems reading the vimchat config %s.'\ + % (self.configFilePath) + print sys.exc_info()[0], sys.exc_info()[1] + return + + for room in chatrooms: + print room + input = vim.eval( + 'input("Enter the room name from the above list: ")') + if input in chatrooms: + self._openGroupChat(self.accounts[chatrooms[input]['account']], + chatrooms[input]['room'], chatrooms[input]['username']) + else: + print 'Error: [%s] is an invalid chatroom.' % (input) + + def moveCursorToBufBottom(self, buf): + # TODO: Need to make sure this only happens if this buffer doesn't + # have focus. Otherwise, this hijacks the users cursor. + return + for w in vim.windows: + if w.buffer == buf: + w.cursor = (len(buf), 0) + + def showAccountList(self): + accounts = [] + i = 0 + for jid,account in self.accounts.items(): + accounts.append(account) + print str(i) + ": " + jid + i = i + 1 + + return accounts + + def getAccountsFromConfig(self): + accounts = {} + if not os.path.exists(self.configFilePath): + print 'Error: Config file %s does not exist' % (self.configFilePath) + return {} + try: + config = RawConfigParser() + config.read(self.configFilePath) + for account in config.options('accounts'): + accounts[account] = config.get('accounts', account) + except: + print 'Error reading accounts from the vimchat config %s.'\ + % (self.configFilePath), sys.exc_info()[0:2] + return {} + return accounts + + def log(self, account, user, msg): + logChats = int(vim.eval('g:vimchat_logchats')) + if logChats > 0: + logPath = vim.eval('g:vimchat_logpath') + logDir = \ + os.path.expanduser(logPath + '/' + account + '/' + user) + if not os.path.exists(logDir): + os.makedirs(logDir) + + day = time.strftime('%Y-%m-%d') + log = open(logDir + '/' + user + '-' + day, 'a') + log.write(msg + '\n') + log.close() + + def openLogFromBuddyList(self): + account, jid = VimChat.getBuddyListItem() + VimChat.openLog(account, jid) + + def openLogFromChat(self): + try: + jid = vim.eval('b:buddyId') + except: + print "You may only open the log from a chat buffer" + return + account = vim.eval('b:account') + if jid != '' and account != '': + VimChat.openLog(account, jid) + else: + print "Invalid chat window!" + + def openLog(self, account, jid): + logPath = vim.eval('g:vimchat_logpath') + logDir = \ + os.path.expanduser(logPath + '/' + account + '/' + jid) + print logDir + if not os.path.exists(logDir): + print "No Logfile Found" + return 0 + else: + print "Opening log for: " + logDir + vim.command('tabe ' + logDir) + + def sendMessage(self): + try: + toJid = vim.eval('b:buddyId') + account = vim.eval('b:account') + except: + print "No valid chat found!" + return 0 + + connection = self.accounts[account] + chatBuf = self.getBufByName(connection._chats[toJid]) + if not chatBuf: + print "Chat Buffer Could not be found!" + return 0 + + r = vim.current.range + body = "" + for line in r: + body = body + line + '\n' + + body = body.strip() + + if self.isGroupChat(): + connection.jabberSendGroupChatMessage(toJid, body) + else: + connection.jabberOnSendMessage(toJid, body) + + secure = False + + if pyotr_enabled: + secure = connection.otrIsChatEncrypted(account, toJid) + if secure: + secure = "e" + + if not self.isGroupChat(): + VimChat.appendMessage(account, chatBuf,body,'Me',secure) + + vim.command('hide') + vim.command('sbuffer ' + str(chatBuf.number)) + vim.command('normal G') + + def setStatus(self, status=None): + if not status: + status = str(vim.eval( + 'input("Status: (away,xa,dnd,chat),message,priority: ")')) + + parts = status.split(',') + show = parts[0] + status = '' + priority = 10 + if len(parts) > 1: + status = parts[1] + if len(parts) > 2: + priority = parts[2] + + for jid,account in self.accounts.items(): + account.jabberPresenceUpdate(show,status,priority) + + # update Icon if there are several icons available + if self.statusIcon != None: + self.statusIcon.changeStatus(show) + print "Updated status to: " + str(priority) + " -- " + show + \ + " -- " + status + + def presenceUpdate(self, account, chat, fromJid, show, status, priority): + try: + # update chat window + fullJid = fromJid + [fromJid,user,resource] = self.getJidParts(fromJid) + [chat,nada,nada2] = self.getJidParts(fromJid) + + connection = VimChat.accounts[account] + + if chat in connection._chats.keys(): + #Make sure buffer exists + chatFile = connection._chats[fromJid] + if chatFile.startswith('groupchat'): + return + chatBuf = self.getBufByName(chatFile) + bExists = int(vim.eval('buflisted("' + chatFile + '")')) + if chatBuf and bExists: + statusUpdateLine = self.formatPresenceUpdateLine(fullJid, + show,status) + if chatBuf[-1] != statusUpdateLine: + chatBuf.append(statusUpdateLine) + self.moveCursorToBufBottom(chatBuf) + else: + #Should never get here! + print "Buffer did not exist for: " + fromJid + + # update old show list + if len(self.oldShowList)<1: + self.oldShowList = defaultdict(dict) + self.oldShowList[account][chat] = show + if not self.oldShowList[account].get('online-since'): + self.oldShowList[account]['online-since'] = int(time.time()) + except Exception, e: + print "Error in presenceUpdate: " + str(e) + + def messageReceived(self, account, fromJid, message, secure=False, + groupChat=""): + #Store the buffer we were in + origBufNum = vim.current.buffer.number + + # Commented out the next 2 lines. For some reason, when the orig + # buffer is the buddy list, it causes a bug that makes it so you + # don't receive any more messages. + # + #if origBufNum == self.buddyListBuffer.number: + # vim.command('wincmd w') + + #Get Jid Parts + [jid,user,resource] = self.getJidParts(fromJid) + + if groupChat: + if re.search('has (joined|quit|part).+\(.=.+@.+\)$', message): + return + buf = VimChat.beginChat(account, groupChat) + else: + buf = VimChat.beginChat(account, jid) + + try: + VimChat.appendMessage(account, buf, message, fromJid, secure) + except: + print 'Error zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz' + print 'could not appendMessage:', message, 'from:', fromJid + + # Highlight the line. + # TODO: This only works if the right window has focus. Otherwise it + # highlights the wrong lines. + # vim.command("call matchadd('Error', '\%' . line('$') . 'l')") + + try: + self.notify(jid, message, groupChat) + except: + print 'Could not notify:', message, 'from:', jid + + if self.growl_enabled: + self.growl_notifier.notify("msg txrx", "VimChat - %s" % (jid), + message, self.growl_icon) + + def notify(self, jid, msg, groupChat): + # refreshes the buffer so the new message shows up + vim.command("echo ") + + if groupChat: + msgLowered = msg.lower() + myNames = map(lambda x: x.split('@')[0], self.accounts.keys()) + myNames.extend(self.groupChatNames) + myNames = map(lambda x: x.lower(), myNames) + foundMyName = False + for name in myNames: + if name in msgLowered: + foundMyName = True + print (jid + ' said your name in #' + + groupChat.split('%')[0].split('@')[0]) + break + if not foundMyName: + return + + vim.command("set tabline=%#Error#New-message-from-" + jid) + + self.pyNotification(jid+' says: ', msg, 'dialog-warning'); + if self.gtk_enabled: + self.statusIcon.blink(True) + if self.blinktimeout != -1: + thr1 = self.BlinkClearer(self.blinktimeout) + thr1.start() + + def pyNotification(self, subject, msg, type): + if pynotify_enabled: + pynotify.init('vimchat') + n = pynotify.Notification(subject, msg, type) + n.set_timeout(10000) + n.show() + + def clearNotify(self): + vim.command('set tabline&') + if self.gtk_enabled: + self.statusIcon.blink(False) + + def otrVerifyBuddy(self): + if not pyotr_enabled: + print "OTR Not enabled!" + return 0 + try: + jid = vim.eval('b:buddyId') + account = vim.eval('b:account') + except: + print "Invalid chat buffer!" + return + + response = str(vim.eval('input("Verify ' + jid + \ + ' (1:manual, 2:Question/Answer): ")')) + if response == "1": + response2 = str(vim.eval("input('Verify buddy? (y/n): ')")).lower() + if response2 == "y": + self.accounts[account].otrManualVerifyBuddy(jid) + else: + print "Verify Aborted." + elif response == "2": + question = vim.eval('input("Enter Your Question: ")') + secret = vim.eval('inputsecret("Enter your secret answer: ")') + self.accounts[account].otrSMPVerifyBuddy(jid,question,secret) + else: + print "Invalid Response." + + def otrGenerateKey(self): + if not pyotr_enabled: + print "Otr not enabled!" + return 0 + + accounts = self.showAccountList() + + try: + response = int(vim.eval("input('Account: ')")) + + if response < len(accounts): + print "Generating Key for " + \ + accounts[response]._jids + "(please bear with us)..." + accounts[response].otrGeneratePrivateKey() + print "Generated OTR Key!" + else: + print "Not Generating Key Now." + except: + print "Error generating key!" + + def otrSMPRequestNotify(self, account, jid, question): + if not pyotr_enabled: + return 0 + + buf = VimChat.beginChat(account, jid) + if buf: + message = "-- OTR Verification Request received! " + \ + "Press or to answer the question below:\n" + question + VimChat.appendMessage(account, buf,message, "[OTR]") + print "OTR Verification Request from " + jid + + def otrSmpRespond(self): + if not pyotr_enabled: + return 0 + + try: + jid = vim.eval('b:buddyId') + account = vim.eval('b:account') + except: + print "Invalid chat buffer!" + return + + response = str(vim.eval( + "inputsecret('Answer to "+ jid +": ')")).lower() + self.accounts[account].otrSMPRespond(jid, response) + + +VimChat = VimChatScope() +EOF + +if exists('g:vimchat_loaded') + finish +endif +let g:vimchat_loaded = 1 + +com! VimChat py VimChat.init() +com! VimChatStop py VimChat.stop() +com! VimChatBuddyList py VimChat.toggleBuddyList() +com! VimChatViewLog py VimChat.openLogFromChat() +com! VimChatJoinGroupChat py VimChat.openGroupChat() +com! VimChatOtrVerifyBuddy py VimChat.otrVerifyBuddy() +com! VimChatOtrSMPRespond py VimChat.otrSmpRespond() +com! VimChatOtrGenerateKey py VimChat.otrGenerateKey() +com! -nargs=0 VimChatSetStatus py VimChat.setStatus() +com! VimChatShowStatus py VimChat.showStatus() +com! VimChatJoinChatroom py VimChat.joinChatroom() +autocmd! VIMLeave * :VimChatStop + +set switchbuf=usetab + +fu! VimChatCheckVars() + if !exists('g:vimchat_buddylistwidth') + let g:vimchat_buddylistwidth=30 + endif + if !exists('g:vimchat_buddylistmaxwidth') + let g:vimchat_buddylistmaxwidth='' + endif + if !exists('g:vimchat_libnotify') + let g:vimchat_libnotify=1 + endif + if !exists('g:vimchat_logpath') + let g:vimchat_logpath="~/.vimchat/logs" + endif + if !exists('g:vimchat_logchats') + let g:vimchat_logchats=1 + endif + if !exists('g:vimchat_otr') + let g:vimchat_otr=0 + endif + if !exists('g:vimchat_logotr') + let g:vimchat_logotr=1 + endif + if !exists('g:vimchat_statusicon') + let g:vimchat_statusicon=1 + endif + if !exists('g:vimchat_blinktimeout') + let g:vimchat_blinktimeout=-1 + endif + if !exists('g:vimchat_timestampformat') + let g:vimchat_timestampformat="[%H:%M]" + endif + if !exists('g:vimchat_showPresenceNotification') + let g:vimchat_showPresenceNotification="" + endif + + return 1 +endfu + +function! VimChatFoldText() + let line=substitute(getline(v:foldstart),'^[ \t#]*\([^=]*\).*', '\1', '') + let line=strpart(' ', 0, (v:foldlevel - 1)).substitute(line,'\s*{\+\s*', '', '') + return line +endfunction + +" vim:et:sts=4:sw=4:ts=4 diff --git a/syntax/vimchat.vim b/syntax/vimchat.vim new file mode 100644 index 0000000..a249261 --- /dev/null +++ b/syntax/vimchat.vim @@ -0,0 +1,8 @@ +syn match vimChatMsg /^\[\d\d\(:\d\d\)\{0,2\}].\{-}:/ contains=vimChatTime,vimChatMe +syn match vimChatTime /\[\d\d\(:\d\d\)\{0,2\}]/ contained nextgroup=vimChatMe +syn match vimChatMe /Me:/ contained + +" Comment, Type, String, Statement +hi link vimChatMsg Comment +hi link vimChatTime String +hi link vimChatMe Type diff --git a/vimchat-master/.gitignore b/vimchat-master/.gitignore new file mode 100644 index 0000000..f025940 --- /dev/null +++ b/vimchat-master/.gitignore @@ -0,0 +1,3 @@ +*.swp +*~ +*.pyc diff --git a/vimchat-master/README.md b/vimchat-master/README.md new file mode 100644 index 0000000..f3da7da --- /dev/null +++ b/vimchat-master/README.md @@ -0,0 +1,137 @@ +# About + +Vimchat is a chat plugin for the vim text editor. It allows you to send and receive instant messages and participate in chat rooms all inside of vim. It supports the XMPP/jabber protocol, but you can also connect to other services such as IRC, AIM, ICQ, MSN, etc. via jabber transports. It's amazing isn't it. See the screenshots: + +[Screenshot 1](http://ironcamel.com/files/vimchat1.png) [Screenshot 2](http://ironcamel.com/files/vimchat2.png) + +# Features + +Vimchat supports encryption via OTR (off the record). + +Vimchat supports status icons which will blink in the system tray when you receive new messages. +The default icons are installed at `~/.vimchat/icon*.gif`. +You can overwrite these with your own custom icons. +For example, to use a different icon for the away status, copy your custom icon to `~/.vimchat/icon_away.gif`. + +# Requirements + +* linux or Mac OS X +* vim >= 7.3.154 +* xmpppy + +Suggested libraries: + +* python-gtk2 +* python-notify +* python-dns +* growl (for OSX only) + +This works on linux and Mac (tested with MacVim, but required a recompile against newer python libraries). You must have python support in vim, and you must have xmpppy installed (the python-xmpp package in most distros). The python-notify package is not necessary, but if it is installed, you will get pretty libnotify alerts for new messages. It also throws some warning messages if you do not have python-dns installed (though it will still work without it). The python-gtk2 package is needed if you want a status icon in your system tray that blinks when new messages arrive. + +If you are running ubuntu linux, here is a command you can run to install all the dependencies: + + sudo apt-get install vim-gtk python-xmpp python-notify python-dns python-gtk2 + +On ubuntu the python-xmpp package seems to work fine. But on arch linux, the corrresponding package is named xmpppy, which for me was giving this error when starting vimchat: + + AttributeError: '_ssl._SSLSocket' object has no attribute 'issuer' + +It is because of a bug in the xmpppy library: +https://github.com/eventlet/eventlet/issues/124#issuecomment-69775480 + +I got around it by installing this forked version of xmppy: +https://github.com/ArchipelProject/xmpppy + + pip install git+https://github.com/ArchipelProject/xmpppy + +# Installation + +Just run: + + chmod +x install.sh + ./install.sh + +The installation script is very simple. +All it does is copy a few files. + +# Configuration + +It is important to update the configuration file before you run vimchat for the first time. +The `install.sh` script should have created a config file `~/.vimchat/config`. +When you open this file you will see directions and examples. +Edit this file and add at least one account entry to it. + +# Usage + +To start using vimchat just start vim and enter `:VimChat`. +You should see a window on the left with a list of all your buddies. +Type `B` to toggle this list. +Hit enter on someone's name to open a chat buffer. + +In a chat buffer, type `i` (or `a` or `o`) to open a send buffer. +Type a message and hit enter. + +# Buddy List + +The buddy list can be toggled by typing `B` in normal mode from any vimchat +buffer. +Toggling the buddy list also refreshes it. +If you are not currently in a vimchat buffer, you can open it with the +`:VimChatBuddyList` command. + +The buddy list is comprised of folds, and unfolding any buddy will show items like status, away message, and the groups that he or she belongs to. + +Once in the buddy list, you can scroll through your buddies and hit enter when your cursor is on the buddy you want to chat with. + +Pressing `l` while on a buddy entry in the buddy list will bring up the log files (if any) for that user. + +# Chat Buffers + +When you enter into insert mode from a chat window (for example by typing `i`), +it will pop up a send buffer. +In the send buffer you simply type your message and hit enter. +To send multiple lines, select the lines in visual mode and then hit enter. + +Typing `l` will bring up a new tab containing log files for the current +user. + +# Chat Rooms + +You can configure chat rooms in your vimchat config file. +To join a chat room type `j`. +This will display a list of rooms which you can choose from. + +# Growl Integration + +First install the growl notification system: http://growl.info/ + +Then download the growl SDK from: http://growl.info/downloads_developers.php + +Finally navigate into the Bindings/python folder and run: + sudo python setup.py install + +# Optional Settings + +You can can update your `~/.vimrc` with these settings to customize vimchat. All of these settings are optional. + +* let g:vimchat\_buddylistwidth = width of buddy list, default is 30 +* let g:vimchat\_logpath = path to store log files, default is ~/.vimchat/logs +* let g:vimchat\_logchats = (0 or 1) default is 1 -- 0 will not log, +* let g:vimchat\_otr = (0 or 1) default is 0 -- enable otr or not +* let g:vimchat\_logotr = (0 or 1) default is 1 -- log otr convos or not +* let g:vimchat\_statusicon = (0 or 1) default is 1 -- use a gtk status icon? +* let g:vimchat\_blinktimeout = timeout in seconds, default is -1 +* let g:vimchat\_buddylistmaxwidth = max width of buddy list window, default '' +* let g:vimchat\_timestampformat = format of the message timestamp, default "[%H:%M]" +* let g:vimchat\_showPresenceNotification = notification if buddy changed status, comma-separated list of states, default "" + +# Contributing + +Pull requests are welcome. Please follow the pep 8 style guidelines for the python code. + +# Contributors + +* Philipp [philsmd](https://github.com/philsmd) +* Michael Dillon [michaelcdillon](https://github.com/michaelcdillon) +* Naveed Massjouni [ironcamel](https://github.com/ironcamel) (author) +* William Wolf [throughnothing](https://github.com/throughnothing) (author) diff --git a/vimchat-master/config b/vimchat-master/config new file mode 100644 index 0000000..418cd07 --- /dev/null +++ b/vimchat-master/config @@ -0,0 +1,36 @@ +# This is the vimchat config file. Note that while vimchat is running, you can +# edit and write this file and vimchat will update itself on the fly. +# +# Accounts entries are in the form: username@server/resource = password. +# The '/resource' part of the account is optional. It is a jabber feature that +# lets you associate physical locations with your accounts. The password is +# optional as well. If you leave the password blank, vimchat will prompt you +# for it when you connect. These accounts will be connected to automatically +# when vimchat starts. You may connect or disconnect from a particular account +# with \on and \off. + +[accounts] +#bob@gmail.com = +#bob@jaim.at = password +#bob@jabber.no = password +#bob@max06.de = password +#bob@jabber1.acme.com/vimchat = password + +# Here you may list groupchat and irc rooms. +# The format is [chatroom:alias] where alias is what you will use to refer to it +# when you want to join a room. To join a room, type j in vimchat. + +#[chatroom:work] +#account = bob@jabber1.acme.com +#room = messaging@chat.jabber1.acme.com +#username = bobbypunjabi +# +#[chatroom:perl] +#account = bob@jaim.at +#room = perl%irc.freenode.net@irc.jaim.at +#username = bobby +# +#[chatroom:vim] +#account = bob@jaim.at +#room = vim%irc.freenode.net@irc.jaim.at +#username = bobby diff --git a/vimchat-master/icon.gif b/vimchat-master/icon.gif new file mode 100644 index 0000000000000000000000000000000000000000..b65f1cc7c11dcde7bbef083bcf6bfdc1e2a0d621 GIT binary patch literal 2375 zcmeIx`CHO?0>JUl_X`N9AclC58VDi+BAy&+f+rY`7b>Rt;F)QYnC8|tPNbpe*raHd zSK(2PTCJs)J<}msjn-CLv(sgzX-x-NO=e>?w!8ns{0y7o_XhP%yXf;yTg1sPDCejJ%A6B?$31Rdk_U2Hro&K=X&^f za$SUg%eNGHyYfZOoFE)GXoYXUDrT^SP{gG~07e*w6Jp~mgM~rf&T<4N+}1aQCKL9qg0{J0*(u4NVZ~>nr!*#H`{*)A8#8FWQZkU@Kf3B#aV}Q*o9V zfU=I{6X)p{%V#IjxCuZX z_u8ig+^UJYT;uQniWGQf2J!2Zk4)jNt=C)jf46`j7uWu%URz$09y|2X-)7%1_gJRO zp)nE$0|;VG0R)wOT)Yl0YI)msN>fcLO#$#eHDY?VL$meq4Ky-|vVpTw*Yke4TJ5Y7 z>)I@@eoediePEe+VwLzyzF1QN+m!Sc+&ome{S`tp(V)UTbls1<=w+yo2R?6XEBz~h zuR&OdF|9=~g(r!25zvzWAn?TS>M+7g)p-=}7IgDOw-c~1Da=An3lqwb=5Heo$_Wb< z)autz?Ti!)-p>C0K31*4@UX@hv%n_IT!W%RFe3GQd*tC(V{(#nJpk|5;q7feNvcf?;vIxJQg}Diz%e%5cm4L3P3Ze#alv}{$b-(L`PhRuE}$x5d5q%R zZQ@r{j5^II6oGcKVX7bKniY%Uu=jJF%b;RcsR>0JI(x8oT3>uxy!{P*4vfPknrVd# zFYdIpnOHnSb6Spm;*IOpq+5!eb5EN8`8s9Rb>qA=8gn-yBb}i8F+)dlP0t?BqSc&{ zr7tXsRB@u_O>f*_l|&vw91M;A=y2*mr#@xVC!lKn)m9RA87F>xvXeRF$i$P0o9^0? zQXg(#KjCix(-v^`Py0h7B#AZ&5^!NQyX%EmKe%-_TqeU=Zb5Z2RXcVr?Jw%MGth{m zgqr(QA@R3t5T?zXFRNoqq$dX(KQLel8;ixC+;!w=ln3g$;L*g~k6luVP+ zSuy39sgPGJyC8k>bIP(dCJOb59)SPjjh2@l9Bez(^zpB%04q+_)NcbCi+Ly>lRTP3 z>2H~TA(c^X@B0DPgg*Lv&FoUwE zMw<@Wu^$sCWxS=T;0e_}v@a@T&F4LJ|IF@s=m^%VE)>&C>!HxbOGw;_>Q8X8-c2P< znj4Qn=>d!zUV%I~C&Mk?WuldZR^usSL#4aj$x~9UDA6t1MQPQ6~lmSG{0`U@4k=ZM!81 md;3v}s)ZETWi-#oEmOAxEvI1ypCzCb?7uektk;hMR{tAak4S<5 literal 0 HcmV?d00001 diff --git a/vimchat-master/icon_away.gif b/vimchat-master/icon_away.gif new file mode 100644 index 0000000000000000000000000000000000000000..5922132ffd210607584360019945ed74bf6bf4d7 GIT binary patch literal 1827 zcmV+;2i*8aNk%w1VPpVg0LFU&0{{g80R#X700#g72>}2M00;^L0TBTK7Xbtt00kKW z0387UApig$00$)i11JCnDggi^1OzSv1tAFsD+dfF3=K304=M`}FAEMd2^KL995oOX zI1n5v6%{2H89EXrIu;{58ZI{u1RI2N@uW2Yqd&jvtDe0VQha41ejE#xVfT4w!MXMBf7${XmY-`p~K3#$DT_x%h9+e&6LvDxjfa6O4#18 zCU)D4-{r7bWA=OnOb8S zBGi&fqQp;SEH?boX`RM~C@g){NQuWtiD)KyA^3rS00035$P^HuW=xq3AaIa}L()G7 z17rf|;p)lE0Z3&A9Z*xjw=|GE%99Z^zyKAn7+9UjwJTQyAELd1G|zwlrUW#=+Um7! zSF8R=2ecTruaP_nHW|Qr;&SO(w?_v!Sn!u-Pyq-mtHG@MW(65Q|Cxz%^H<0uIP9WrY!lT$Nu7AAWg&s2?zy zCasCo>h4ld6eV-zfaXo&*t5$7Evg2B>oXH5c7;KasTy(5Ce_aV_0|ARN(qrsOqcmm zO55vi9~PGk38o~02pFb-x8H%oDVHByaRu;0DM27of-8j~XklBevBed0>H$bf4v3K8 ziiQ`K$ld{_L}5q~uh?edi^BzgVks;b0*i|<>W3S4v6&KqjjqTLTaFgOgk4bQ0sd)9 zbwd)l-v^r!homV=mI9Pp%>fXBh`9V-UO_O=frZK;fpAQzTFM%w;&MPt%;DqGe#XgR)uuDmRD&s8)QSsS z0i-EUO*+O$LZV&8Rv#(F4r1!DfB6G!j62EUD4YVgQmr7@!V=p6Gvaf=x56Qi=e9Hv zAg-}%$>dZ%46u8djG`z2Z*KDraz`!*oHbcK5a??eWTO;kD6wnm64Sx>{sgCAy6^&! zfh(lOlM7n@ytJRYqQE=AbETl;F)q&npsm7|$tuUb@wrlnFf~ov4hPJ(2LP8XT$XMr zZWMBbE*}IyaXYpBd)X+v0ydW^P8dRjFbcT5YI|Fe?5UjtFzkv1hYVxDJWhjp7Aeru zB*4R_ba2Q9!zlYr0SEp(%C|8M>q>NnxbTq!X@jb@90dc$Z;*&Yq0tBGT};Zqew#u@ zA{GVBUR7bU%`SJY2#AP85WEDlS3wO;VrKzVZb}u2+<*{mb!r#W&}XgA)p%nsBE&%7 z0UP#FN--4^03@LNtyvkN|-0 z6&aX>2$u1f{8;9OBSC`{CSiveM#eoS8AXIBAqEucD*y)^2?;uJ0crFwd_t+s0eB`6 zCosViRFFmuz~mOT*w7*d@kA4_frkDaMmfVPfX)c=j#OOD8ziv60}`+R30MGS5}AQ5 zx{*Y4)X^4ZDC9R{&sgfvp~6J78C1d<605=>wUOZcWh+Hf=^xRVQ9I0GBx Rpaj^d^Pc$3XD0&z06TwI|5yM3 literal 0 HcmV?d00001 diff --git a/vimchat-master/icon_dnd.gif b/vimchat-master/icon_dnd.gif new file mode 100644 index 0000000000000000000000000000000000000000..f39776fe09320602f84bccab28fe6e9f26755a4f GIT binary patch literal 4490 zcmWmDc|6pK{|E5*=a?BYu9-3JFm8qzCXuVb$gyOc2^CRMza0SpL$;6wmG zf%H?1NJf4Jpa60d451;2I)ZBhK@$ZX1oQ#)fMg7q84y_r7~;4Uf^q;j2+093X9QMa zs6LtG2Dk@+0}h@D;tTi+66O!EiYRAICVOF+iGrdJ1}u5yFn|ys2B4S+5pgHVtw*p; z02_c9185`)!32m!@C1NFKoUSM4uxcZB)~#Qp%kDDev0|i7-fJLU{H=g6+o0Sts0OTK#u?%1}u!OR0~jnK^UE}LR-HABL*_) ze1>|QGPM@L>j6#z97RC_h?oEkfO2$o8UegCHJcG=16Zr6E(Ky80XhJhQM?n7EaY!rx&b{65UH+l3WqZQX94>EU*b7{ZK|5*0c04o5PypK>*{XM(z^mM1aK8#07ZrX zzXos}poa(?Go!UkqhSOhb@lAcSib>!kpLG7=v{z2fZYZB9^f}|SZi$h1i;Z^c^uPd z9D_{;hCXH%BP4LMU~#Oi?5(W4Sf)`XX4?!6LM<%)*|tH}93NYo02?b8dz(ZH3wMWA zNy}}*Ikr)@oXs}YYwcGCue9H6Yv=Fayv@ee%gNr^)ydD%-p|?9$8~kMqZ8lN$* z_xE4R_YdU<1cru(t_z6>3k`^fjEdM0x-lYr!=}yg+qTAUNl4z2p1LD7O^}|Jxi_yc zzc8<8f64x$!u_S?l~v+n^>u9>(!O(NfBg8NzeMxcxg}=TmN;hSwp|HKFCTwC=zql# z3j6@epKthilQ;mmCHO&J<}H&9<;$tCqDEv5*A7q(eUE$hOnKyfwN0Ff?`iTXex7CX zho^C|+H!u7dyIj{A@-KXeS43u`un-AR^rmEJA=38H_OK3AhqZW6*QBR9Fv+)1;$j-T6yksV@Ny}yWNLVOY0c}f2G37pF*e=F z4^pnT@L0S@%ca*U=@zbgvQmB@$o?cgI(_@JSJv{yPXB`Np4azE4RyLZY7*`{ z{Q{rX4hd96sQ*A;0>9+#+Z7wCD~`r=>gC4nOwV}lQwOln7sC>ilD62dE6U+9>%SK{`M zHZ+FmYYjiv$zvvNZZdUvCLPWD`_Ve>;;%1noYYF-$0#PHN?#r>W3D~qV+>3C((%8{M3>(firjKnH4j842jUJ4#U`&yp*LpV8zp~8O15Z% zs8UvYS??{QLTTVNCGIJ`RZB9jfR!~R2qP)TTZd$<5Ro)v$;ORqJhNRh!(Qm&j zuujhg@`xlVRS0;9zYxNMH`w8fUB6N5^t4cjd``=yUfz!wxJ?P;9+KxERc!De>MWr}q3W zO?&T_@hp!2ep0SHpG&kAHxLtZ{?#v1ph{Cdy+8NjF3d%8gNkxD(MLJ2c5(}@rFnD} z{&in(`uS;H3U%TiM2*+EU$>a~n4;YG`h&}dc8iT%Quc9;=kv+xLz_Jw&jf}nG$aLa zD)dPgOH4h(#df$QL$qJ3tmwLFoEwSC>q;H}zHy4e6p@VP6LSp#vtnZRXk>*Wv41d} zC#am6Qx-{qWhb5QlY9LQsGd)TlyIsLV@MFcC#dF!c~Xe;X_WF?%p;tc&$67@v2-pi z3Uv9nT{JZQc1qg^>z`?U$`g80cD^fZy!-cK&0Ogw~5 z`|$s&>Dk>M+ibO*kB7St;d1w(1a8R{s4X^Li~^PDHiG8JHRj8)t82u>`%0Un!Ax{jLBYLb-{pg}z27$)Vtho=GL6!0c>H>XFi+l@ zo8)+>1)TW>BKjfFf+SkWAf86OuE&~C_Wb^NZ3h9+2{STHOm$|rAbSjz~Xw@ChU*RGCZ21xZm)8Rw0=-Z(-Kc zf~*Oj`1O2K9YHL)H>5VHiBBF-*!cajdHAj*!6OeN=gP?MT~h-SgwsPSkdoCxNsphZ zQ1=Wsg5Y=;b;@GJRJw_GpX-!X*Ku7Z4#H)S$qZdAn*I~o+2Q2jEN8CQ73H7N7I_=d8m4dRbZjK`J)Ipc1E2n7T571x&!Lk0D+M%6~95TdY=irOU=#nk7)ai zXIGj!K8*_$H*&Y8A+ct>Uw4;_mT^^Y`AMwZve^3GoJML+?TJq0tTo7Y-s?YHw^EZ& z*naQ==tgf#JSxjyq{gXbN1v_vA(;Vw4&5v1OA5y&I&@@8=`q2W(CdN)90YR7R+OH> zwaL?%-uLjoDE*~jp`98o_&sNMao~z&>AK{>kxL3f;-I8RX;${oPb}!!!mY@2#%5A; zH!&%d2(p4Zz${tWl5ZJ}avIB>xwo>G1MCKEcV%J+X2SmtST?PJn^qKe$A~MIkMB^Pe}>T;I>r z4c@Lwj-n4s4&eI^C#n`5FDR9LG+f5RdGvE5oDQVfX>{C&qcQzny%--1er4d_-#`Ym z^Diedr?%Nm;MN{z5gAlQ#Xo{=dO`FvzAQ-ATMwE>K~Bp7l91g^lVNUN@NM33lc#QaZ0JIZx9cdt&4+|e6PXkm z`XOkap=Y3VBgyqp7WpxyP~dB+CM>?@P~l;x0BB{6ifGVh;V?fm4Or2Me;vSW*=m$Y zMZu%pFV!;I8%Zh>O-_*@c${3%#ApvUR%|KUH*Jr|pz{I0FI2TaKw9!-B74H^^d#u2 zexY_hW;I6L%JfLl*tvm5wkDx*;&`KnlqxonMRilFaimux7GsE(tVD;u-w%8u#iSM0 zsyRYpEE~>L}G_ps~R1v8rZRCVdRi6*{hq6_z)Ft%MLO+53Va zk~Xl8(~L5?M8kP5Issc|a|=|9S5H$p6L~k}@=soqbK=L><8A{pF7h%on7Z=yu(9Sf zji&qT9IjF8bq5pbDi7~)Ry8&>Pc32-Y14Uy*sg%MD2XxBT|g{jYa7r_jjvj%mjZ;<{A($-_^OFgQZSIz1N-7P?EH+W$JmKxRL(&EmpK!lC!z-t$ z?+DZ=+H7#Ymy?7CC{S$CCKX%)hqJ0n6$j|T021W0#SOz9Ol z+>olQOZ&MNVc*lE*5RT5F400WKe;>)uJL?Wak27v>4N`nZ2`x;4zY}|*eTivajtk* z{f$}@@+BafUvDXc^w;?%Rcpv&s|D$#jSICeM>(=L{D~HKF5o|GR346D!PJw-&sY3m z>Kx3*v;>IC7$`?0>Jv!Pnj*{ddR^O29LZlL=UZTzCg=ZA@na}~?prn|E%>j85X{|s zXBRzm!g2SCz{a4I#cdL^k`pd%HBMs^f03dswZZ0@_-}L31^4CGSp@kKU%|AN2KtsnmzufE;7;USZkw~*0MQhIE^=L zb!>RDty-im&C|+Sax1AfU)B0`7d@lxghjjV3t_<5>#cil9erC=zo^-qT6gLI#X2g7 zo?cfo_a++_l=qJDD_Lz-zGVsDT2E)U|3%E>a`sma7`?vOozFp&Q+cMTyM65!ujCGO_ zdAo_WORTP^b=_}RU4Pu_y8E&#!Uq{Q?+>Ykf8cM!GW%D*rERj)zG zmy1{q_Ub1!2YpAi29f8W?0Z{lR-$-MtZ-%i?4>dJ5x(N|ydtaiY{Id=M5lHH0jK{1 DoK4|D literal 0 HcmV?d00001 diff --git a/vimchat-master/icon_xa.gif b/vimchat-master/icon_xa.gif new file mode 100644 index 0000000000000000000000000000000000000000..ebc0c47745d50d8e89b1b7fdff8bd7f7baf8e12c GIT binary patch literal 1620 zcmd7SjX%?Q0KoC@Z#J8?g+?AGwp6U4v*aN;!y=J-$m`RX3VG>{V33<|Ch;p_KDOvU zM?{jfY2bzxJ4ongj}=Vv%J^-#=s^5|0CQFVmKly^My+PX*z*`TQHD)cc1F(Oq=MW8 z1=BhwH>)5g^GI&KxM(f!WDx%(t@*f}m>qb6&28k^HFEH!Tz0KstAHou3Al|y0~Udb)R?amN~Uwa6K=@%P&|=IwH)>w$Tr%GzXsWwT& zaY+GJ({`SR&(QWUnoqon5~y1HVwoUit{j7__G09Z_4u3-lF@fL0v`&3g)neTpJvzh zF2y;5g%>U;oVn0OA{vjWd!D_POVNvW6^$vku^pbGi`SPqH}J>At_e~5rzt3GOQFFE zb(5y)3sH(}SR!ZDDV!`|32GuE3u$>x|v*BaD5Jg&|#e@uX(2|LWnbXV~>r>g%v; z>_xtX){QEK>-vsH&tVpAp7!>EXS9Ud$ z-Ja-2{4BTArn6Zdo^CzU#t*KZvl0p1f=0Jr1MZuhQneKWoKD-iq+h-6kUiG)kgk)e zJLHABQ|dQtzSPy)F;z#FovPoD=Jc z<~PQs6?5oAlZFtwB5^ctZ3htHcXo3f zb>XViA$R8vke=@YgKFH}$J&=Kjtl4E#v|m-krbL|`!R;g#3w6v=*Buf->K7iFG3vd zQLf#0IkqU{v_>wRQP@vHvgKU1%g80mc#XVASSUx_+p{JqWmF5ZksyXu3WrgIL>C`c=g=~_Wn})! ~/.vimchat/vimchat.debug') + vim.command('nnoremap B :py VimChat.toggleBuddyList()') + vim.command('let s:hasVars = VimChatCheckVars()') + self.setupLeaderMappings() + hasVars = int(vim.eval('s:hasVars')) + + if hasVars < 1: + print "Could not start VimChat!" + return 0 + + #Libnotify + libnotify = int(vim.eval('g:vimchat_libnotify')) + if not libnotify: + pynotify_enabled = False + + #Growl Setup + if self.growl_enabled: + self.growl_notifier = Growl.GrowlNotifier("VimChat", + ["msg txrx", "account status"]) + self.growl_notifier.register() + self.growl_icon = Image.imageFromPath( + os.path.expanduser('~/.vimchat/icon.gif')) + + otr_enabled = int(vim.eval('g:vimchat_otr')) + otr_logging = int(vim.eval('g:vimchat_logotr')) + if otr_enabled == 1: + if otr_logging == 1: + pyotr_logging = True + else: + pyotr_logging = False + else: + pyotr_enabled = False + pyotr_logging = False + + # Timestamp format + self.timeformat = vim.eval('g:vimchat_timestampformat') + + # Signon to accounts listed in .vimrc + if vim.eval("exists('g:vimchat_accounts')") == '1': + vimChatAccounts = vim.eval('g:vimchat_accounts') + for jid,password in vimChatAccounts.items(): + self._signOn(jid,password) + + # Signon to accounts listed in .vimchat/config + if os.path.exists(self.configFilePath): + config = RawConfigParser() + config.read(self.configFilePath) + if config.has_section('accounts'): + for jid in config.options('accounts'): + password = config.get('accounts', jid) + self._signOn(jid, password) + + if len(self.accounts) and self.statusIcon == None: + isStatusIcon = int(vim.eval('g:vimchat_statusicon')) + if isStatusIcon != 1: + self.gtk_enabled = False + if self.gtk_enabled: + self.statusIcon = self.StatusIcon() + self.statusIcon.start() + self.blinktimeout = int(vim.eval('g:vimchat_blinktimeout')) + + self.toggleBuddyList() + + def stop(self): + if self.statusIcon != None: + self.statusIcon.stop() + self.signOffAll() + + class OtrOps: + def __init__(self,parent=None): + self.parent = parent + + def policy(self, opdata=None, context=None): + """ checks for the contacts username in policylist and returns it + if available, otherwise checks for a default entry and returns it + if available, otherwise just return python-otr's default """ + return otr.OTRL_POLICY_DEFAULT + + def create_privkey(self, opdata=None, accountname=None, protocol=None): + # should give the user some visual feedback here, + # generating can take some time! the private key MUST + # be available when this method returned + print "Need OTR key for: %s :VimChatGenerateKey to create one" % ( + accountname) + + #TODO + #VimChat.otrGenerateKey() + + def is_logged_in(self, opdata=None, accountname=None, + protocol=None, recipient=None): + + if accountname in VimChat.accounts.keys(): + if recipient: + roster = VimChat.accounts[accountname]._roster + priority = roster.getPriority(recipient) + if priority: + return True + return False + else: + return False + else: + return False + + def inject_message(self, opdata=None, accountname=None, + protocol=None, recipient=None, message=None): + + if accountname in VimChat.accounts.keys(): + if recipient and message: + VimChat.accounts[accountname].jabberSendMessage(recipient, + message) + else: + print "Error in inject_message" + + def notify(sef, opdata=None, level=None, accountname=None, + protocol=None, username=None,title=None, primary=None, + secondary=None): + + # show a small dialog or something like that + # level is otr.OTRL_NOTIFY_ERROR, otr.OTRL_NOTIFY_WARNING + # or otr.OTRL_NOTIFY_INFO primary and secondary are the + # messages that should be displayed + print "Notify: title: " + title + " primary: " + primary + \ + " secondary: " + secondary + + def display_otr_message(self, opdata=None, accountname=None, + protocol=None, username=None, msg=None): + + # this usually logs to the conversation window + + #write_message(our_account=accountname, proto=protocol, + # contact=username, message=msg) + # NOTE: this function MUST return 0 if it processed the message + # OR non-zero, the message will then be passed to notify() by OTR + print "Got OTR Message" + return 0 + + def update_context_list(self, opdata=None): + # this method may provide some visual feedback when + # the context list was updated. This may be useful + # if you have a central way of setting fingerprints' trusts + # and you want to update the list of contexts to consider + #in this way + pass + + def protocol_name(self, opdata=None, protocol=None): + """ returns a "human-readable" version of the given protocol """ + if protocol == "xmpp": + return "XMPP (eXtensible Messaging and Presence Protocol)" + + def new_fingerprint( + self, opdata=None, userstate=None, accountname=None, + protocol=None, username=None, fingerprint=None): + + human_fingerprint = "" + try: + human_fingerprint = otr.otrl_privkey_hash_to_human(fingerprint) + #write_message(our_account=accountname, proto=protocol, + # contact=username, + # message="New fingerprint: %s"%human_fingerprint) + return human_fingerprint + except: + pass + + def write_fingerprints(self, opdata=None): + fpath = os.path.expanduser( + VimChat.otr_basedir + '/' + VimChat.otr_fingerprints) + for jid,account in VimChat.accounts.items(): + otr.otrl_privkey_write_fingerprints( + account._otr_userstate, fpath) + else: + print "User: " + str(account) + " not connected" + + def gone_secure(self, opdata=None, context=None): + trust = context.active_fingerprint.trust + if trust: + trust = "V" + else: + trust = "U" + + buf = VimChat.beginChat(context.accountname, context.username) + if buf: + VimChat.appendStatusMessage(context.accountname, + buf,"[OTR]","-- " + trust + " OTR Connection Started") + print trust + " OTR Connection Started with " + \ + str(context.username) + + def gone_insecure(self, opdata=None, context=None): + connection = VimChat.accounts[context.accountname] + buf = self.getBufByName(connection._chats[context.username]) + if buf: + VimChat.appendStatusMessage(context.accountname, + buf,"[OTR]","-- Secured OTR Connection Ended") + print "Secure OTR Connection Ended with " + context.username + + def still_secure(self, opdata=None, context=None, is_reply=0): + # this is called when the OTR session was refreshed + # (ie. new session keys have been created) + # is_reply will be 0 when we started that refresh, + # 1 when the contact started it + try: + connection = VimChat.accounts[context.accountname] + buf = self.getBufByName(connection._chats[context.username]) + if buf: + jid = "[OTR]" + VimChat.appendStatusMessage(context.accountname, + buf,"[OTR]","-- Secured OTR Connection Refreshed") + print "Secure OTR Connection Refreshed with " + \ + str(context.username) + except Exception, e: + print "Error in still_secure: " + str(e) + + def log_message(self, opdata=None, message=None): + # log message to a logfile or something + pass + + def max_message_size(self, opdata=None, context=None): + """ looks up the max_message_size for the relevant protocol """ + # return 0 when no limit is defined + #return msg_size[context.protocol] + return 0 + + def account_name( + self, opdata=None, account=None, context=None, protocol=None): + + #return find_account(accountname=account, protocol).name + if account in VimChat.accounts.keys(): + jid = VimChat.accounts[account]._jid.split('/')[0] + print "accountname: " + jid + return jid + else: + print "Could not get account name" + + + class JabberConnection(threading.Thread): + _roster = {} + _chats = {} + + def __init__(self, parent, jid, jabberClient, roster): + self._parent = parent + self._jid = jid + self._jids = jid.split('/')[0] + self._roster = roster + threading.Thread.__init__(self) + self.jabber = jabberClient + self.online = 0 + self._protocol = 'xmpp' + + def run(self): + self.jabber.RegisterHandler('message',self.jabberMessageReceive) + self.jabber.RegisterHandler('presence',self.jabberPresenceReceive) + self.jabberPresenceUpdate() + + #Socket stuff + RECV_BUF = 4096 + self.xmppS = self.jabber.Connection._sock + socketlist = [self.xmppS] + self.online = 1 + + #set up otr + self.otrSetup() + while self.online: + (i, o, e) = select.select(socketlist, [], [], 1) + for each in i: + if each == self.xmppS: + self.jabber.Process(1) + else: + pass + time.sleep(1) + + def stop(self): + self.online = 0 + + #From Jabber Functions + def jabberMessageReceive(self, conn, msg): + if msg.getBody(): + fromJid = str(msg.getFrom()) + type = str(msg.getType()).lower() + jid = fromJid.split('/')[0] + body = unicode(msg.getBody()) + body = str(body.encode('utf8')) + + if pyotr_enabled and type != "groupchat": + #OTR Stuff + is_internal, message, tlvs = otr.otrl_message_receiving( + self._otr_userstate, (VimChat.OtrOps(),None), + self._jids,self._protocol,jid, body) + + context = otr.otrl_context_find( + self._otr_userstate,jid,self._jids,self._protocol,1)[0] + + if otr.otrl_tlv_find(tlvs, + otr.OTRL_TLV_SMP_ABORT) is not None: + self.otrAbortVerify(context) + elif otr.otrl_tlv_find(tlvs, + otr.OTRL_TLV_SMP1) is not None: + if context.smstate.nextExpected != \ + otr.OTRL_SMP_EXPECT1: + self.otrAbortVerify(context) + else: + #TODO: prompt user for secret + pass + elif otr.otrl_tlv_find(tlvs, + otr.OTRL_TLV_SMP1Q) is not None: + if context.smstate.nextExpected != \ + otr.OTRL_SMP_EXPECT1: + self.otrAbortVerify(context) + else: + tlv = otr.otrl_tlv_find(tlvs, otr.OTRL_TLV_SMP1Q) + VimChat.otrSMPRequestNotify( + context.accountname, context.username,tlv.data) + elif otr.otrl_tlv_find(tlvs, + otr.OTRL_TLV_SMP2) is not None: + if context.smstate.nextExpected != \ + otr.OTRL_SMP_EXPECT2: + self.otrAbortVerify(context) + else: + context.smstate.nextExpected = otr.OTRL_SMP_EXPECT4 + elif otr.otrl_tlv_find(tlvs, + otr.OTRL_TLV_SMP3) is not None: + if context.smstate.nextExpected != \ + otr.OTRL_SMP_EXPECT3: + self.otrAbortVerify(context) + else: + if context.smstate.sm_prog_state == \ + otr.OTRL_SMP_PROG_SUCCEEDED: + self.otrSMPVerifySuccess(context) + print "Successfully verified " + \ + context.username + else: + self.otrSMPVerifyFailed(context) + print "Failed to verify " + context.username + elif otr.otrl_tlv_find(tlvs, + otr.OTRL_TLV_SMP4) is not None: + if context.smstate.nextExpected != \ + otr.OTRL_SMP_EXPECT4: + self.otrAbortVerify(context) + else: + context.smstate.nextExpected = otr.OTRL_SMP_EXPECT1 + if context.smstate.sm_prog_state == \ + otr.OTRL_SMP_PROG_SUCCEEDED: + self.otrSMPVerifySuccess(context) + print "Successfully verified " + \ + context.username + else: + self.otrSMPVerifyFailed(context) + print "Failed to verify " + context.username + #}}} + + secure = False + type = otr.otrl_proto_message_type(body) + if type == otr.OTRL_MSGTYPE_DATA \ + and type != otr.OTRL_MSGTYPE_NOTOTR \ + and type != otr.OTRL_MSGTYPE_TAGGEDPLAINTEXT: + + if context.active_fingerprint: + trust = context.active_fingerprint.trust + if trust: + secure = "V" + else: + secure = "U" + + if not is_internal: + VimChat.messageReceived(self._jids, fromJid, + message.strip(),secure) + + elif type == "groupchat": + parts = fromJid.split('/') + chatroom = parts[0] + if len(parts) > 1: + user = parts[1] + else: + user = "--" + VimChat.messageReceived( + self._jids, user, body.strip(), False, chatroom) + else: + VimChat.messageReceived(self._jids, fromJid,body.strip()) + + def jabberPresenceReceive(self, conn, msg): + #TODO: figure out better way than this try/except block + try: + fromJid = msg.getFrom() + type = str(msg.getType()).lower() + show = str(unicode(msg.getShow()).encode('utf-8')) + status = str(unicode(msg.getStatus()).encode('utf-8')) + priority = str(unicode(msg.getPriority()).encode('utf-8')) + # print fromJid, ' jid: ', msg.getJid(), ' status: ', + # status, ' reason: ', msg.getReason(), ' stat code: ', + # msg.getStatusCode() + + if show == "None": + if priority != "None": + show = 'online' + else: + show = 'offline' + + accountName = "" + chat = "" + if type == "groupchat": + parts = fromJid.split('/') + # in this case it is equal to the chatroom + accountName = str(parts[0]) + user = "" + if len(parts) > 1: + user = parts[1] + chat = str(user) + else: + accountName = str(fromJid) + chat = fromJid + + # notify if somebody is now available + if str(vim.eval('g:vimchat_showPresenceNotification')).find( + str(show)) != -1: + onlineUser = VimChat.getJidParts(accountName)[0] + if VimChat.hasBuddyShowChanged(self._jids, onlineUser, + str(show)): + VimChat.pyNotification('Presence event',""+onlineUser+ + "\nis now "+str(show),'dialog-information') + VimChat.presenceUpdate(self._jids, accountName, chat, show, + status, priority) + except: + pass + + #To Jabber Functions + def jabberOnSendMessage(self, tojid, msg): + msg = msg.strip() + if not pyotr_enabled: + self.jabberSendMessage(tojid,msg) + return 0 + + #only if otr is enabled + new_message = otr.otrl_message_sending( + self._otr_userstate,(VimChat.OtrOps(),None), + self._jids,self._protocol,tojid,msg,None) + + context = otr.otrl_context_find( + self._otr_userstate,tojid,self._jids,self._protocol,1)[0] + + #if context.msgstate == otr.OTRL_MSGSTATE_ENCRYPTED + otr.otrl_message_fragment_and_send( + (VimChat.OtrOps(), None), context, new_message, + otr.OTRL_FRAGMENT_SEND_ALL) + + def jabberSendMessage(self, tojid, msg): + msg = msg.strip() + m = xmpp.protocol.Message(to=tojid,body=msg,typ='chat') + self.jabber.send(m) + + def jabberSendGroupChatMessage(self, room, msg): + msg = msg.strip() + m = xmpp.protocol.Message(to=room,body=msg,typ='groupchat') + self.jabber.send(m) + + def jabberJoinGroupChat(self, room, name): + roomStr = room + '/' + name + self.jabber.send(xmpp.Presence(to=roomStr)) + + def jabberLeaveGroupChat(self, room): + self.jabber.send(xmpp.Presence(to=room,typ='unavailable')) + + def jabberPresenceUpdate(self, show='', status='', priority=5): + m = xmpp.protocol.Presence( + None, + show=show, + priority=priority, + status=status) + self._presence = m + self.jabber.send(m) + + def jabberGetPresence(self): + show = self._presence.getShow() + status = self._presence.getStatus() + return [show,status] + + def disconnect(self): + try: + self.jabber.disconnect() + except: + pass + + def isConnected(self): + return self.jabber.isConnected() + + #Roster Functions + def getRosterItems(self): + if self._roster: + return self._roster.getItems() + else: + return None + + #OTR Functions + def otrSetup(self): + #Set Up OTR Stuff If Available + if not pyotr_enabled: + return 0 + + self._otr_userstate = otr.otrl_userstate_create() + + keypath = os.path.expanduser( + VimChat.otr_basedir + '/' + VimChat.otr_keyfile) + + #Make the otr directory + basedir = os.path.expanduser(VimChat.otr_basedir) + if not os.path.exists(basedir): + os.makedirs(basedir) + + if not os.path.isfile(keypath): + #Create it if it doesn't exist + file(keypath,'w') + jid = self._jid.split('/')[0] + + print "No OTR Key found for " + self._jids + \ + ". :VimChatOtrGenerateKey to make one." + else: + pass + if os.access(keypath, os.R_OK): + try: + otr.otrl_privkey_read(self._otr_userstate,keypath) + except: + pass + + fprintPath = os.path.expanduser( + VimChat.otr_basedir + '/' + VimChat.otr_fingerprints) + if not os.path.isfile(fprintPath): + #Create it if it doesn't exist + file(fprintPath,'w') + else: + if os.access(fprintPath, os.R_OK): + try: + otr.otrl_privkey_read_fingerprints( + self._otr_userstate,fprintPath) + except: + pass + + def otrDisconnectChat(self, jid): + context = otr.otrl_context_find( + self._otr_userstate,jid,self._jids,self._protocol,1)[0] + + if context.msgstate == otr.OTRL_MSGSTATE_ENCRYPTED: + otr.otrl_message_disconnect( + self._otr_userstate,(VimChat.OtrOps(),None), + self._jids,self._protocol,jid) + + def otrManualVerifyBuddy(self, jid): + self.otrSetTrust(jid,"manual") + buf = VimChat.beginChat(self._jids, jid) + if buf: + VimChat.appendStatusMessage(self._jids, + buf,"[OTR]","-- Verified Fingerprint of " + jid) + print "Verified "+jid + + def otrSMPVerifyBuddy(self, jid, question, secret): + context = otr.otrl_context_find( + self._otr_userstate,jid,self._jids,self._protocol,1)[0] + + otr.otrl_message_initiate_smp_q( + self._otr_userstate, (VimChat.OtrOps(), None), + context,question,secret) + + buf = VimChat.beginChat(self._jids, jid) + if buf: + VimChat.appendMessage(context.accountname, + buf,"-- Sent Question to "+ jid +" for verification.") + print "Sent Question for verification to " + \ + str(context.username) + + def otrSMPVerifySuccess(self,context): + jid = context.username + self.otrSetTrust(jid,"smp") + buf = VimChat.beginChat(context.accountname, jid) + if buf: + VimChat.appendStatusMessage(context.accountname, + buf,"[OTR]", + "-- Secret answered! "+ jid +" is verified.") + print jid + " Gave correct secret -- verified!" + + def otrSMPVerifyFailed(self,context): + jid = context.username + self.otrSetTrust(jid,"") + buf = VimChat.beginChat(context.accountname, jid) + if buf: + VimChat.appendStatusMessage(context.accountname, + buf,"[OTR]", + "-- Secret response Failed! "+ jid + " is NOT verified.") + print jid + " Failed to answer secret, NOT verified!" + + def otrSMPRespond(self,jid,secret): + context = otr.otrl_context_find( + self._otr_userstate,jid,self._jids,self._protocol,1)[0] + + otr.otrl_message_respond_smp( + self._otr_userstate,(VimChat.OtrOps(),None),context,secret) + buf = VimChat.beginChat(self._jids, jid) + if buf: + VimChat.appendStatusMessage(context.accountname, + buf,"[OTR]","-- Sent Secret to "+ jid +"") + print "Sent secret response to " + jid + + def otrGeneratePrivateKey(self): + keypath = os.path.expanduser( + VimChat.otr_basedir + '/' + VimChat.otr_keyfile) + jid = self._jid.split('/')[0] + otr.otrl_privkey_generate( + self._otr_userstate, keypath, jid, self._protocol) + + def otrAbortVerify(self,context): + otr.otrl_message_abort_smp( + self._otr_userstate, (VimChat.OtrOps(), None), context) + + def otrSetTrust(self, jid, trust): + context = otr.otrl_context_find( + self._otr_userstate,jid,self._jids,self._protocol,1)[0] + otr.otrl_context_set_trust(context.active_fingerprint,trust) + + def otrIsChatEncrypted(self, account, jid): + context = otr.otrl_context_find( + VimChat.accounts[account]._otr_userstate,jid, + VimChat.accounts[account]._jids, + VimChat.accounts[account]._protocol,1)[0] + + if context.msgstate == otr.OTRL_MSGSTATE_ENCRYPTED: + return True + else: + return False + + + class StatusIcon(threading.Thread): + def __init__(self): + self.status_icon_default = "~/.vimchat/icon.gif" + self.status_icon_path = self.status_icon_default + threading.Thread.__init__(self) + + def run(self): + # GTK StausIcon + gtk.gdk.threads_init() + self.status_icon = StatusIcon() + self.changeStatus() + self.status_icon.set_tooltip("VimChat") + self.status_icon.set_visible(True) + gtk.main() + + def blink(self, value): + self.status_icon.set_blinking(value) + + def changeStatus(self,statusText=""): + if len(statusText)>0: + statusText = "_"+statusText + file_path = os.path.expanduser(re.sub("(\..[^.]*)$", + statusText+"\\1", self.status_icon_default)) + if not os.path.exists(file_path): + file_path = os.path.expanduser(self.status_icon_default) + if not os.path.exists(file_path): + return + self.status_icon_path = file_path + self.status_icon.set_from_file(self.status_icon_path) + + def stop(self): + self.status_icon.set_visible(False) + gtk.main_quit() + + + class BlinkClearer(threading.Thread): + def __init__(self, tt): + self.timeoutTime = tt + threading.Thread.__init__(self) + + def run(self): + time.sleep(self.timeoutTime) + VimChat.clearNotify() + + + def signOn(self): + accounts = self.getAccountsFromConfig() + if len(accounts) == 0: + print 'No accounts found in the vimchat config %s.'\ + % (self.configFilePath) + return + for account in accounts: + print account + account = vim.eval( + 'input("Enter the account from the above list: ")') + if account in accounts: + password = accounts[account] + self._signOn(account, password) + else: + print 'Error: [%s] is an invalid account.' % (account) + + def _signOn(self, jid, password): + if not password: + password = vim.eval('inputsecret("' + jid + ' password: ")') + [jidSmall,user,resource] = self.getJidParts(jid) + print "Connecting user " + jid + "..." + if jidSmall in self.accounts: + try: self.accounts[jidSmall].disconnect() + except: pass + + JID=xmpp.protocol.JID(jid) + jabberClient = xmpp.Client(JID.getDomain(),debug=[]) + + con = jabberClient.connect() + if not con: + print 'could not connect!\n' + if self.growl_enabled: + self.growl_notifier.notify("account status", "VimChat", + "Could not connect.", self.growl_icon) + return 0 + + auth=jabberClient.auth( + JID.getNode(), password, resource=JID.getResource()) + if not auth: + print 'could not authenticate!\n' + if self.growl_enabled: + self.growl_notifier.notify("account status", "VimChat", + "Could not authenticate.", self.growl_icon) + return 0 + + jabberClient.sendInitPresence(requestRoster=1) + roster = jabberClient.getRoster() + + [accountJid,user,resource] = self.getJidParts(jid) + if accountJid in self.accounts: + try: + self.accounts[accountJid].disconnect() + except: pass + self.accounts[accountJid] = self.JabberConnection( + self, jid, jabberClient, roster) + self.accounts[accountJid].start() + print "Connected with " + jid + if self.growl_enabled: + self.growl_notifier.notify("account status", "VimChat", + "Signed into " + jid + " successfully", self.growl_icon) + + def signOff(self): + accounts = self.accounts + if len(accounts) == 0: + print 'No accounts found' + return + for account in accounts: + print account + account = vim.eval( + 'input("Enter the account from the above list: ")') + self._signOff(account) + + def signOffAll(self): + accounts = self.accounts + if len(accounts) == 0: + return + size=len(accounts) + while(size > 0): + account = accounts.keys()[0] + self._signOff(account) + if len(accounts) >= size: + print "Error while signing off" + break + else: + size=len(accounts) + + def _signOff(self, account): + accounts = self.accounts + if account in accounts: + try: + accounts[account].disconnect() + accounts[account].stop() + del accounts[account] + print "%s was signed off of VimChat!" % (account) + if self.growl_enabled: + self.growl_notifier.notify("account status", "VimChat", + "%s was signed off of VimChat!" %(account), + self.growl_icon) + except: + print "Error signing off %s VimChat!" % (account) + print sys.exc_info()[0:2] + else: + print 'Error: [%s] is an invalid account.' % (account) + if self.growl_enabled: + self.growl_notifier.notify("account status", "VimChat", + "Error signing off %s VimChat" %(account), + self.growl_icon) + + def showStatus(self): + print self.accounts[self.accounts.keys()[0]].jabberGetPresence() + + def formatPresenceUpdateLine(self, fromJid, show, status): + tstamp = self.getTimestamp() + return tstamp + " -- " + str(fromJid) + \ + " is " + str(show) + ": " + str(status) + + def getJidParts(self, jid): + jidParts = str(jid).split('/') + # jid: bob@foo.com + jid = jidParts[0] + # user: bob + user = jid.split('@')[0] + + #Get A Resource if exists + if len(jidParts) > 1: + resource = jidParts[1] + else: + resource = '' + + return [jid,user,resource] + + def getTimestamp(self): + return time.strftime(self.timeformat) + + def getBufByName(self, name): + for buf in vim.buffers: + if buf.name and buf.name.split('/')[-1] == name: + return buf + return None + + def isGroupChat(self): + try: + groupchat = int(vim.eval('b:groupchat')) + if groupchat == 1: + return True + except: + pass + + return False + + def toggleBuddyList(self): + # godlygeek's way to determine if a buffer is hidden in one line: + # :echo len(filter(map(range(1, tabpagenr('$')), + # 'tabpagebuflist(v:val)'), 'index(v:val, 4) == 0')) + + if not self.accounts: + print "Could not display buddy list. Type on to connect." + return 0 + + if self.buddyListBuffer: + bufferList = vim.eval('tabpagebuflist()') + if str(self.buddyListBuffer.number) in bufferList: + vim.command('sbuffer ' + str(self.buddyListBuffer.number)) + vim.command('hide') + return + + #Write buddy list to file + self.writeBuddyList() + + buddyListWidth = vim.eval('g:vimchat_buddylistwidth') + + try: + vim.command("silent vertical sview " + self.rosterFile) + vim.command("silent wincmd H") + vim.command("silent vertical resize " + buddyListWidth) + vim.command("silent e!") + vim.command("setlocal noswapfile") + vim.command("setlocal nomodifiable") + vim.command("setlocal buftype=nowrite") + except Exception, e: + print e + vim.command("new " + self.rosterFile) + + commands = """ + setlocal foldtext=VimChatFoldText() + setlocal nowrap + setlocal foldmethod=marker + nmap :py VimChat.beginChatFromBuddyList() + nnoremap l :py VimChat.openLogFromBuddyList() + nnoremap B :py VimChat.toggleBuddyList() + nnoremap q :py VimChat.toggleBuddyList() + nnoremap r :py VimChat.refreshBuddyList() + nnoremap R :py VimChat.refreshBuddyList() + nnoremap n /{{{ ( + nnoremap c :py VimChat.openGroupChat() + nnoremap ss :py VimChat.setStatus() + nnoremap :silent exec 'vertical resize ' . (winwidth('.') > g:vimchat_buddylistwidth ? (g:vimchat_buddylistwidth) : (g:vimchat_buddylistmaxwidth)) + """ + vim.command(commands) + self.setupLeaderMappings() + + self.buddyListBuffer = vim.current.buffer + + def getBuddyListItem(self): + vim.command("normal zo") + vim.command("normal ]z") + vim.command("normal [z") + vim.command("normal j") + + toJid = vim.current.line + toJid = toJid.strip() + + vim.command(r"call search('\V{{{ [+]', 'b')") + + account = str(vim.current.line).split(' ')[2] + return account, toJid + + def beginChatFromBuddyList(self): + account, toJid = self.getBuddyListItem() + [jid,user,resource] = self.getJidParts(toJid) + + print '**** beginning chat with account:', account + buf = VimChat.beginChat(account, jid) + if not buf: + #print "Error getting buddy info: " + jid + return 0 + + vim.command('sbuffer ' + str(buf.number)) + VimChat.toggleBuddyList() + vim.command('wincmd K') + + def refreshBuddyList(self): + self.writeBuddyList() + vim.command("silent e!") + + def hasBuddyShowChanged(self,accountJid,jid,showNew): + showList = self.oldShowList + if showList != None: + account = showList.get(accountJid) + if account != None: + showOld = str(account.get(jid)) + if account.get('online-since')+6 < int(time.time()) and \ + showOld != showNew: + return True + return False + + def writeBuddyList(self): + #write roster to file + import codecs + rF = codecs.open(self.rosterFile,'w','utf-16') + + for curJid, account in self.accounts.items(): + if not account.isConnected(): + rF.write( + u""" + ****************************** + ERROR: %s IS NOT CONNECTED!!! + You can type on to reconnect. + ****************************** + """ % (curJid)) + continue + accountText = u"{{{ [+] %s\n"%(curJid) + rF.write(accountText) + + roster = account._roster + rosterItems = roster.getItems() + rosterItems.sort() + for item in rosterItems: + name = roster.getName(item) + status = roster.getStatus(item) + show = roster.getShow(item) + priority = roster.getPriority(item) + groups = roster.getGroups(item) + + if not name: + name = item + if not status: + status = u'' + if not show: + if priority: + show = u'on' + else: + show = u'off' + if not priority: + priority = u'' + if not groups: + groups = u'' + if show != u'off': + buddyText =\ + u"{{{ (%s) %s\n\t%s \n\tGroups: %s\n\t%s:\n%s\n}}}\n" %\ + (show, name, item, groups, show, status) + rF.write(buddyText) + + rF.write("}}}\n") + + rF.close() + + def beginChat(self, fromAccount, toJid, groupChat=False): + #Set the ChatFile + connection = self.accounts[fromAccount] + if toJid in connection._chats.keys(): + chatFile = connection._chats[toJid] + else: + if groupChat: + chatFile = 'groupchat:' + toJid + else: + chatFile = 'chat:' + toJid + + connection._chats[toJid] = chatFile + bExists = int(vim.eval('buflisted("' + chatFile + '")')) + if bExists: + #TODO: Need to call sbuffer only if buffer is hidden. + #vim.command('sbuffer ' + chatFile) + return self.getBufByName(chatFile) + else: + vim.command("split " + chatFile.replace('%', r'\%')) + #Only do this stuff if its a new buffer + if groupChat: + vim.command('let b:groupchat=1') + else: + vim.command('let b:groupchat=0') + + vim.command("let b:buddyId = '" + toJid + "'") + vim.command("let b:account = '" + fromAccount + "'") + self.setupChatBuffer(groupChat) + return vim.current.buffer + + def setupChatBuffer(self, isGroupChat=False): + commands = """ + setlocal noswapfile + setlocal buftype=nowrite + setlocal noai + setlocal nocin + setlocal nosi + setlocal filetype=vimchat + setlocal syntax=vimchat + setlocal wrap + setlocal foldmethod=marker + nnoremap i :py VimChat.sendBufferShow() + nnoremap o :py VimChat.sendBufferShow() + nnoremap a :py VimChat.sendBufferShow() + nnoremap B :py VimChat.toggleBuddyList() + nnoremap q :py VimChat.deleteChat() + au CursorMoved exe 'py VimChat.clearNotify()' + """ + vim.command(commands) + self.setupLeaderMappings() + if isGroupChat: + vim.command('setlocal foldmethod=syntax') + + def setupLeaderMappings(self): + commands = """ + nnoremap l :py VimChat.openLogFromChat() + nnoremap ov :py VimChat.otrVerifyBuddy() + nnoremap or :py VimChat.otrSmpRespond() + nnoremap c :py VimChat.openGroupChat() + nnoremap j :py VimChat.joinChatroom() + nnoremap on :py VimChat.signOn() + nnoremap off :py VimChat.signOff() + """ + vim.command(commands) + + def sendBufferShow(self): + toJid = vim.eval('b:buddyId') + account = vim.eval('b:account') + groupChat = vim.eval('b:groupchat') + + #Create sending buffer + sendBuffer = "sendTo:" + toJid + vim.command("silent bo new " + sendBuffer) + vim.command("silent let b:buddyId = '" + toJid + "'") + vim.command("silent let b:account = '" + account + "'") + vim.command("setlocal filetype=vimchat") + + commands = """\ + resize 4 + setlocal noswapfile + setlocal nocin + setlocal noai + setlocal nosi + setlocal buftype=nowrite + setlocal wrap + setlocal foldmethod=marker + noremap :py VimChat.sendMessage() + inoremap :py VimChat.sendMessage() + nnoremap q :hide + """ + vim.command(commands) + vim.command('normal G') + vim.command('normal o') + vim.command('normal zt') + vim.command('star') + vim.command('let b:groupchat=' + str(groupChat)) + + def appendMessage( + self, account, buf, message, showJid='Me',secure=False): + + if not buf: + print "VimChat: Invalid Buffer to append to!" + return 0 + + lines = message.split("\n") + tstamp = self.getTimestamp() + + jid,user,resource = self.getJidParts(showJid) + logJid = buf.name.split('/')[-1].split(':')[1] + + secureString = "" + if secure: + secureString = "(*" + secure + "*)" + + #Get the first line + if resource: + line = tstamp + " " + secureString + \ + user + "/" + resource + ": " + lines.pop(0) + else: + line = tstamp + " " + secureString + user + ": " + lines.pop(0) + + buf.append(line) + #TODO: remove these lines + #line = line.replace("'", "''") + #vim.command("call append(line('$'),'" + line + "')") + if not secure or pyotr_logging: + VimChat.log(account, logJid, line) + + for line in lines: + line = '\t' + line + buf.append(line) + #line = line.replace("'", "''") + #vim.command("call append(line('$'),'" + line + "')") + #if message is not secure, or if otr logging is on + if not secure or pyotr_logging: + VimChat.log(account, logJid, line) + + #move cursor to bottom of buffer + self.moveCursorToBufBottom(buf) + + def appendStatusMessage(self, account, buf, prefix, message): + if not buf: + print "VimChat: Invalid Buffer to append to!" + return 0 + + jid = buf.name.split('/')[-1].split(':')[1] + jid,user,resource = self.getJidParts(jid) + + lines = message.split("\n") + tstamp = self.getTimestamp() + + #Get the first line + line = tstamp + prefix + ": " + lines.pop(0) + + buf.append(line) + VimChat.log(account, jid, line) + + for line in lines: + line = '\t' + line + buf.append(line) + VimChat.log(account, jid, line) + + #move cursor to bottom of buffer + #self.moveCursorToBufBottom(buf) + + def deleteChat(self): + #remove it from chats list + jid = vim.eval('b:buddyId') + account = vim.eval('b:account') + + if pyotr_enabled: + self.accounts[account].otrDisconnectChat(jid) + + del self.accounts[account]._chats[jid] + + #Check if it was a groupchat + if self.isGroupChat(): + self.accounts[account].jabberLeaveGroupChat(jid) + vim.command('bdelete!') + + def openGroupChat(self): + accounts = self.showAccountList() + + input = vim.eval( + 'input("Account (enter the number from the above list): ")') + if not re.match(r'\d+$', input): + vim.command('echohl ErrorMsg') + vim.command('echo "\\nYou must enter an integer corresponding' + + ' to an account."') + vim.command('echohl None') + return + index = int(input) + if index < 0 or index >= len(accounts): + vim.command('echohl ErrorMsg') + vim.command(r'echo "\nInvalid account number. Try again."') + vim.command('echohl None') + return + + account = accounts[index] + chatroom = vim.eval('input("Chat Room to join: ")') + name = vim.eval('input("Name to Use: ")') + self._openGroupChat(account, chatroom, name) + + def _openGroupChat(self, account, chatroom, name): + self.groupChatNames.append(name) + buf = VimChat.beginChat(account._jids, chatroom, True) + vim.command('sbuffer ' + str(buf.number)) + account.jabberJoinGroupChat(chatroom, name) + + def echoError(self, msg): + vim.command('echohl ErrorMsg') + vim.command(r'echo "\n"') + vim.command("echo '" + msg.replace("'", "''") + "'") + vim.command('echohl None') + + def joinChatroom(self): + if not os.path.exists(self.configFilePath): + print 'Error: Config file %s does not exist' % (self.configFilePath) + return + + chatrooms = {} + try: + config = RawConfigParser() + config.read(self.configFilePath) + for section in config.sections(): + if not section.startswith('chatroom:'): + continue + tokens = section.split(':') + if len(tokens) < 2: + continue + roomAlias = tokens[1] + data = {} + data['account'] = config.get(section, 'account') + data['room'] = config.get(section, 'room') + data['username'] = config.get(section, 'username') + chatrooms[roomAlias] = data + except: + print 'Error: Problems reading the vimchat config %s.'\ + % (self.configFilePath) + print sys.exc_info()[0], sys.exc_info()[1] + return + + for room in chatrooms: + print room + input = vim.eval( + 'input("Enter the room name from the above list: ")') + if input in chatrooms: + self._openGroupChat(self.accounts[chatrooms[input]['account']], + chatrooms[input]['room'], chatrooms[input]['username']) + else: + print 'Error: [%s] is an invalid chatroom.' % (input) + + def moveCursorToBufBottom(self, buf): + # TODO: Need to make sure this only happens if this buffer doesn't + # have focus. Otherwise, this hijacks the users cursor. + return + for w in vim.windows: + if w.buffer == buf: + w.cursor = (len(buf), 0) + + def showAccountList(self): + accounts = [] + i = 0 + for jid,account in self.accounts.items(): + accounts.append(account) + print str(i) + ": " + jid + i = i + 1 + + return accounts + + def getAccountsFromConfig(self): + accounts = {} + if not os.path.exists(self.configFilePath): + print 'Error: Config file %s does not exist' % (self.configFilePath) + return {} + try: + config = RawConfigParser() + config.read(self.configFilePath) + for account in config.options('accounts'): + accounts[account] = config.get('accounts', account) + except: + print 'Error reading accounts from the vimchat config %s.'\ + % (self.configFilePath), sys.exc_info()[0:2] + return {} + return accounts + + def log(self, account, user, msg): + logChats = int(vim.eval('g:vimchat_logchats')) + if logChats > 0: + logPath = vim.eval('g:vimchat_logpath') + logDir = \ + os.path.expanduser(logPath + '/' + account + '/' + user) + if not os.path.exists(logDir): + os.makedirs(logDir) + + day = time.strftime('%Y-%m-%d') + log = open(logDir + '/' + user + '-' + day, 'a') + log.write(msg + '\n') + log.close() + + def openLogFromBuddyList(self): + account, jid = VimChat.getBuddyListItem() + VimChat.openLog(account, jid) + + def openLogFromChat(self): + try: + jid = vim.eval('b:buddyId') + except: + print "You may only open the log from a chat buffer" + return + account = vim.eval('b:account') + if jid != '' and account != '': + VimChat.openLog(account, jid) + else: + print "Invalid chat window!" + + def openLog(self, account, jid): + logPath = vim.eval('g:vimchat_logpath') + logDir = \ + os.path.expanduser(logPath + '/' + account + '/' + jid) + print logDir + if not os.path.exists(logDir): + print "No Logfile Found" + return 0 + else: + print "Opening log for: " + logDir + vim.command('tabe ' + logDir) + + def sendMessage(self): + try: + toJid = vim.eval('b:buddyId') + account = vim.eval('b:account') + except: + print "No valid chat found!" + return 0 + + connection = self.accounts[account] + chatBuf = self.getBufByName(connection._chats[toJid]) + if not chatBuf: + print "Chat Buffer Could not be found!" + return 0 + + r = vim.current.range + body = "" + for line in r: + body = body + line + '\n' + + body = body.strip() + + if self.isGroupChat(): + connection.jabberSendGroupChatMessage(toJid, body) + else: + connection.jabberOnSendMessage(toJid, body) + + secure = False + + if pyotr_enabled: + secure = connection.otrIsChatEncrypted(account, toJid) + if secure: + secure = "e" + + if not self.isGroupChat(): + VimChat.appendMessage(account, chatBuf,body,'Me',secure) + + vim.command('hide') + vim.command('sbuffer ' + str(chatBuf.number)) + vim.command('normal G') + + def setStatus(self, status=None): + if not status: + status = str(vim.eval( + 'input("Status: (away,xa,dnd,chat),message,priority: ")')) + + parts = status.split(',') + show = parts[0] + status = '' + priority = 10 + if len(parts) > 1: + status = parts[1] + if len(parts) > 2: + priority = parts[2] + + for jid,account in self.accounts.items(): + account.jabberPresenceUpdate(show,status,priority) + + # update Icon if there are several icons available + if self.statusIcon != None: + self.statusIcon.changeStatus(show) + print "Updated status to: " + str(priority) + " -- " + show + \ + " -- " + status + + def presenceUpdate(self, account, chat, fromJid, show, status, priority): + try: + # update chat window + fullJid = fromJid + [fromJid,user,resource] = self.getJidParts(fromJid) + [chat,nada,nada2] = self.getJidParts(fromJid) + + connection = VimChat.accounts[account] + + if chat in connection._chats.keys(): + #Make sure buffer exists + chatFile = connection._chats[fromJid] + if chatFile.startswith('groupchat'): + return + chatBuf = self.getBufByName(chatFile) + bExists = int(vim.eval('buflisted("' + chatFile + '")')) + if chatBuf and bExists: + statusUpdateLine = self.formatPresenceUpdateLine(fullJid, + show,status) + if chatBuf[-1] != statusUpdateLine: + chatBuf.append(statusUpdateLine) + self.moveCursorToBufBottom(chatBuf) + else: + #Should never get here! + print "Buffer did not exist for: " + fromJid + + # update old show list + if len(self.oldShowList)<1: + self.oldShowList = defaultdict(dict) + self.oldShowList[account][chat] = show + if not self.oldShowList[account].get('online-since'): + self.oldShowList[account]['online-since'] = int(time.time()) + except Exception, e: + print "Error in presenceUpdate: " + str(e) + + def messageReceived(self, account, fromJid, message, secure=False, + groupChat=""): + #Store the buffer we were in + origBufNum = vim.current.buffer.number + + # Commented out the next 2 lines. For some reason, when the orig + # buffer is the buddy list, it causes a bug that makes it so you + # don't receive any more messages. + # + #if origBufNum == self.buddyListBuffer.number: + # vim.command('wincmd w') + + #Get Jid Parts + [jid,user,resource] = self.getJidParts(fromJid) + + if groupChat: + if re.search('has (joined|quit|part).+\(.=.+@.+\)$', message): + return + buf = VimChat.beginChat(account, groupChat) + else: + buf = VimChat.beginChat(account, jid) + + try: + VimChat.appendMessage(account, buf, message, fromJid, secure) + except: + print 'Error zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz' + print 'could not appendMessage:', message, 'from:', fromJid + + # Highlight the line. + # TODO: This only works if the right window has focus. Otherwise it + # highlights the wrong lines. + # vim.command("call matchadd('Error', '\%' . line('$') . 'l')") + + try: + self.notify(jid, message, groupChat) + except: + print 'Could not notify:', message, 'from:', jid + + if self.growl_enabled: + self.growl_notifier.notify("msg txrx", "VimChat - %s" % (jid), + message, self.growl_icon) + + def notify(self, jid, msg, groupChat): + # refreshes the buffer so the new message shows up + vim.command("echo ") + + if groupChat: + msgLowered = msg.lower() + myNames = map(lambda x: x.split('@')[0], self.accounts.keys()) + myNames.extend(self.groupChatNames) + myNames = map(lambda x: x.lower(), myNames) + foundMyName = False + for name in myNames: + if name in msgLowered: + foundMyName = True + print (jid + ' said your name in #' + + groupChat.split('%')[0].split('@')[0]) + break + if not foundMyName: + return + + vim.command("set tabline=%#Error#New-message-from-" + jid) + + self.pyNotification(jid+' says: ', msg, 'dialog-warning'); + if self.gtk_enabled: + self.statusIcon.blink(True) + if self.blinktimeout != -1: + thr1 = self.BlinkClearer(self.blinktimeout) + thr1.start() + + def pyNotification(self, subject, msg, type): + if pynotify_enabled: + pynotify.init('vimchat') + n = pynotify.Notification(subject, msg, type) + n.set_timeout(10000) + n.show() + + def clearNotify(self): + vim.command('set tabline&') + if self.gtk_enabled: + self.statusIcon.blink(False) + + def otrVerifyBuddy(self): + if not pyotr_enabled: + print "OTR Not enabled!" + return 0 + try: + jid = vim.eval('b:buddyId') + account = vim.eval('b:account') + except: + print "Invalid chat buffer!" + return + + response = str(vim.eval('input("Verify ' + jid + \ + ' (1:manual, 2:Question/Answer): ")')) + if response == "1": + response2 = str(vim.eval("input('Verify buddy? (y/n): ')")).lower() + if response2 == "y": + self.accounts[account].otrManualVerifyBuddy(jid) + else: + print "Verify Aborted." + elif response == "2": + question = vim.eval('input("Enter Your Question: ")') + secret = vim.eval('inputsecret("Enter your secret answer: ")') + self.accounts[account].otrSMPVerifyBuddy(jid,question,secret) + else: + print "Invalid Response." + + def otrGenerateKey(self): + if not pyotr_enabled: + print "Otr not enabled!" + return 0 + + accounts = self.showAccountList() + + try: + response = int(vim.eval("input('Account: ')")) + + if response < len(accounts): + print "Generating Key for " + \ + accounts[response]._jids + "(please bear with us)..." + accounts[response].otrGeneratePrivateKey() + print "Generated OTR Key!" + else: + print "Not Generating Key Now." + except: + print "Error generating key!" + + def otrSMPRequestNotify(self, account, jid, question): + if not pyotr_enabled: + return 0 + + buf = VimChat.beginChat(account, jid) + if buf: + message = "-- OTR Verification Request received! " + \ + "Press or to answer the question below:\n" + question + VimChat.appendMessage(account, buf,message, "[OTR]") + print "OTR Verification Request from " + jid + + def otrSmpRespond(self): + if not pyotr_enabled: + return 0 + + try: + jid = vim.eval('b:buddyId') + account = vim.eval('b:account') + except: + print "Invalid chat buffer!" + return + + response = str(vim.eval( + "inputsecret('Answer to "+ jid +": ')")).lower() + self.accounts[account].otrSMPRespond(jid, response) + + +VimChat = VimChatScope() +EOF + +if exists('g:vimchat_loaded') + finish +endif +let g:vimchat_loaded = 1 + +com! VimChat py VimChat.init() +com! VimChatStop py VimChat.stop() +com! VimChatBuddyList py VimChat.toggleBuddyList() +com! VimChatViewLog py VimChat.openLogFromChat() +com! VimChatJoinGroupChat py VimChat.openGroupChat() +com! VimChatOtrVerifyBuddy py VimChat.otrVerifyBuddy() +com! VimChatOtrSMPRespond py VimChat.otrSmpRespond() +com! VimChatOtrGenerateKey py VimChat.otrGenerateKey() +com! -nargs=0 VimChatSetStatus py VimChat.setStatus() +com! VimChatShowStatus py VimChat.showStatus() +com! VimChatJoinChatroom py VimChat.joinChatroom() +autocmd! VIMLeave * :VimChatStop + +set switchbuf=usetab + +fu! VimChatCheckVars() + if !exists('g:vimchat_buddylistwidth') + let g:vimchat_buddylistwidth=30 + endif + if !exists('g:vimchat_buddylistmaxwidth') + let g:vimchat_buddylistmaxwidth='' + endif + if !exists('g:vimchat_libnotify') + let g:vimchat_libnotify=1 + endif + if !exists('g:vimchat_logpath') + let g:vimchat_logpath="~/.vimchat/logs" + endif + if !exists('g:vimchat_logchats') + let g:vimchat_logchats=1 + endif + if !exists('g:vimchat_otr') + let g:vimchat_otr=0 + endif + if !exists('g:vimchat_logotr') + let g:vimchat_logotr=1 + endif + if !exists('g:vimchat_statusicon') + let g:vimchat_statusicon=1 + endif + if !exists('g:vimchat_blinktimeout') + let g:vimchat_blinktimeout=-1 + endif + if !exists('g:vimchat_timestampformat') + let g:vimchat_timestampformat="[%H:%M]" + endif + if !exists('g:vimchat_showPresenceNotification') + let g:vimchat_showPresenceNotification="" + endif + + return 1 +endfu + +function! VimChatFoldText() + let line=substitute(getline(v:foldstart),'^[ \t#]*\([^=]*\).*', '\1', '') + let line=strpart(' ', 0, (v:foldlevel - 1)).substitute(line,'\s*{\+\s*', '', '') + return line +endfunction + +" vim:et:sts=4:sw=4:ts=4 diff --git a/vimchat-master/syntax/vimchat.vim b/vimchat-master/syntax/vimchat.vim new file mode 100644 index 0000000..a249261 --- /dev/null +++ b/vimchat-master/syntax/vimchat.vim @@ -0,0 +1,8 @@ +syn match vimChatMsg /^\[\d\d\(:\d\d\)\{0,2\}].\{-}:/ contains=vimChatTime,vimChatMe +syn match vimChatTime /\[\d\d\(:\d\d\)\{0,2\}]/ contained nextgroup=vimChatMe +syn match vimChatMe /Me:/ contained + +" Comment, Type, String, Statement +hi link vimChatMsg Comment +hi link vimChatTime String +hi link vimChatMe Type