" Author: Eric Van Dewoestine " " Description: {{{ " Plugin that integrates vim with the eclipse plugin eclim (ECLipse " IMproved). " " This plugin contains shared functions that can be used regardless of the " current file type being edited. " " License: " " Copyright (C) 2005 - 2010 Eric Van Dewoestine " " This program is free software: you can redistribute it and/or modify " it under the terms of the GNU General Public License as published by " the Free Software Foundation, either version 3 of the License, or " (at your option) any later version. " " This program is distributed in the hope that it will be useful, " but WITHOUT ANY WARRANTY; without even the implied warranty of " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the " GNU General Public License for more details. " " You should have received a copy of the GNU General Public License " along with this program. If not, see . " " }}} " Global Variables {{{ if !exists("g:EclimShowErrors") let g:EclimShowErrors = 1 endif " }}} " Script Variables {{{ let s:command_patch_file = \ '-command patch_file -f -r -b ' let s:command_patch_revisions = '-command patch_revisions -f ' let s:command_ping = '-command ping' let s:command_settings = '-command settings' let s:command_settings_update = '-command settings_update -s ""' let s:command_shutdown = "-command shutdown" let s:connect= '^connect: .*$' " list of commands that may fail using system() call, so using a temp file " instead. let s:exec_commands = ['java_complete'] let g:eclimd_running = 1 " }}} " ExecuteEclim(command, [port]) {{{ " Executes the supplied eclim command. function! eclim#ExecuteEclim(command, ...) if exists('g:EclimDisabled') return endif " eclimd appears to be down, so exit early if in an autocmd if !g:eclimd_running && expand('') != '' " check for file created by eclimd to signal that it is running. if !eclim#EclimAvailable() return endif endif let g:eclimd_running = 1 let command = a:command " encode special characters " http://www.w3schools.com/TAGS/ref_urlencode.asp let command = substitute(command, '\*', '%2A', 'g') let command = substitute(command, '\$', '%24', 'g') let command = substitute(command, '<', '%3C', 'g') let command = substitute(command, '>', '%3E', 'g') " execute the command. let port = len(a:000) > 0 ? a:000[0] : eclim#client#nailgun#GetNgPort() let [retcode, result] = eclim#client#nailgun#Execute(port, command) let result = substitute(result, '\n$', '', '') " not sure this is the best place to handle this, but when using the python " client, the result has a trailing ctrl-m on windows. also account for " running under cygwin vim. if has('win32') || has('win64') || has('win32unix') let result = substitute(result, "\$", '', '') endif call eclim#util#Echo(' ') " check for errors let error = '' if result =~ '^[^\n]*Exception:\?[^\n]*\n\s\+\ ' || \ result =~ '^[^\n]*ResourceException(.\{-})\[[0-9]\+\]:[^\n]*\n\s\+\ ' let error = substitute(result, '\(.\{-}\)\n.*', '\1', '') elseif retcode let error = result endif if retcode || error != '' if g:EclimShowErrors if error =~ s:connect " eclimd is not running, disable further eclimd calls let g:eclimd_running = 0 " if we are not in an autocmd, alert the user that eclimd is not " running. if expand('') == '' call eclim#util#EchoWarning( \ "unable to connect to eclimd (port: " . port . ") - " . error) endif else let error = error . "\n" . \ 'while executing command (port: ' . port . '): ' . command call eclim#util#EchoError(error) endif endif return endif return result endfunction " }}} " Disable() {{{ " Temporarily disables communication with eclimd. function! eclim#Disable() if !exists('g:EclimDisabled') let g:EclimDisabled = 1 endif endfunction " }}} " Enable() {{{ " Re-enables communication with eclimd. function! eclim#Enable() if exists('g:EclimDisabled') unlet g:EclimDisabled endif endfunction " }}} " EclimAvailable() {{{ function! eclim#EclimAvailable() let instances = has('win32unix') ? \ eclim#cygwin#WindowsHome() . '/.eclim/.eclimd_instances' : \ expand('~/.eclim/.eclimd_instances') return filereadable(instances) endfunction " }}} " PatchEclim(file, revision) {{{ " Patches an eclim vim script file. function! eclim#PatchEclim(file, revision) let command = s:command_patch_file let command = substitute(command, '', a:file, '') let command = substitute(command, '', a:revision, '') let command = substitute(command, '', EclimBaseDir(), '') let result = eclim#ExecuteEclim(command) if result != '0' call eclim#util#Echo(result) endif endfunction " }}} " PingEclim(echo, [workspace]) {{{ " Pings the eclimd server. " If echo is non 0, then the result is echoed to the user. function! eclim#PingEclim(echo, ...) let workspace_found = 1 if len(a:000) > 0 && a:1 != '' let workspace = substitute(a:1, '\', '/', 'g') let workspace .= workspace !~ '/$' ? '/' : '' if !eclim#util#ListContains(eclim#eclipse#GetAllWorkspaceDirs(), workspace) let workspace_found = 0 endif let port = eclim#client#nailgun#GetNgPort(workspace) else let workspace = eclim#eclipse#ChooseWorkspace() let port = eclim#client#nailgun#GetNgPort(workspace) endif if a:echo if !workspace_found call eclim#util#Echo('eclimd instance for workspace not found: ' . workspace) return endif let result = eclim#ExecuteEclim(s:command_ping, port) if result != '0' call eclim#util#Echo(result) endif else if !workspace_found return endif let savedErr = g:EclimShowErrors let savedLog = g:EclimLogLevel let g:EclimShowErrors = 0 let g:EclimLogLevel = 0 let result = eclim#ExecuteEclim(s:command_ping, port) let g:EclimShowErrors = savedErr let g:EclimLogLevel = savedLog return result != '0' endif endfunction " }}} " ParseSettingErrors() {{{ function! eclim#ParseSettingErrors(errors) let errors = [] for error in a:errors let setting = substitute(error, '^\(.\{-}\): .*', '\1', '') let message = substitute(error, '^.\{-}: \(.*\)', '\1', '') let line = search('^\s*' . setting . '\s*=', 'cnw') call add(errors, { \ 'bufnr': bufnr('%'), \ 'lnum': line > 0 ? line : 1, \ 'text': message, \ 'type': 'e' \ }) endfor return errors endfunction " }}} " SaveSettings(command, project, [port]) {{{ function! eclim#SaveSettings(command, project, ...) " don't check modified since undo seems to not set the modified flag "if &modified let tempfile = substitute(tempname(), '\', '/', 'g') silent exec 'write! ' . escape(tempfile, ' ') if has('win32unix') let tempfile = eclim#cygwin#WindowsPath(tempfile) endif let command = a:command let command = substitute(command, '', a:project, '') let command = substitute(command, '', tempfile, '') if len(a:000) > 0 let port = a:000[0] let result = eclim#ExecuteEclim(command, port) else let result = eclim#ExecuteEclim(command) endif if result =~ ':' call eclim#util#EchoError \ ("Operation contained errors. See location list for details.") call eclim#util#SetLocationList \ (eclim#ParseSettingErrors(split(result, '\n'))) else call eclim#util#ClearLocationList() call eclim#util#Echo(result) endif setlocal nomodified "endif endfunction " }}} " Settings(workspace) {{{ " Opens a window that can be used to edit the global settings. function! eclim#Settings(workspace) let workspace = a:workspace if workspace == '' let workspace = eclim#eclipse#ChooseWorkspace() if workspace == '0' return endif endif let port = eclim#client#nailgun#GetNgPort(workspace) if eclim#util#TempWindowCommand( \ s:command_settings, "Eclim_Global_Settings", port) setlocal buftype=acwrite setlocal filetype=jproperties setlocal noreadonly setlocal modifiable setlocal foldmethod=marker setlocal foldmarker={,} augroup eclim_settings autocmd! BufWriteCmd exec 'autocmd BufWriteCmd ' . \ 'call eclim#SaveSettings(s:command_settings_update, "", ' . port . ')' augroup END endif endfunction " }}} " ShutdownEclim() {{{ " Shuts down the eclimd server. function! eclim#ShutdownEclim() let workspace = eclim#eclipse#ChooseWorkspace() if workspace != '0' let port = eclim#client#nailgun#GetNgPort() call eclim#ExecuteEclim(s:command_shutdown, port) endif endfunction " }}} " CommandCompleteScriptRevision(argLead, cmdLine, cursorPos) {{{ " Custom command completion for vim script names and revision numbers. function! eclim#CommandCompleteScriptRevision(argLead, cmdLine, cursorPos) let cmdLine = strpart(a:cmdLine, 0, a:cursorPos) let args = eclim#util#ParseCmdLine(cmdLine) let argLead = cmdLine =~ '\s$' ? '' : args[len(args) - 1] " complete script name for first arg. if cmdLine =~ '^' . args[0] . '\s*' . escape(argLead, '.\') . '$' let dir = EclimBaseDir() let results = split(eclim#util#Glob(dir . '/' . argLead . '*'), '\n') call map(results, "substitute(v:val, '\\', '/', 'g')") call map(results, 'isdirectory(v:val) ? v:val . "/" : v:val') call map(results, 'substitute(v:val, dir, "", "")') call map(results, 'substitute(v:val, "^/", "", "")') return results endif " for remaining args, complete revision numbers let file = substitute(cmdLine, '^' . args[0] . '\s*\(.\{-}\)\s.*', '\1', '') let command = s:command_patch_revisions let command = substitute(command, '', file, '') "let argLead = len(args) > 2 ? args[len(args) - 1] : "" let result = eclim#ExecuteEclim(command) if result != '0' let results = split(result, '\n') call filter(results, 'v:val =~ "^' . argLead . '"') return results endif return [] endfunction " }}} " vim:ft=vim:fdm=marker