Yuki KODAMA avatar Yuki KODAMA committed b8466c9

vim: introduce eclim for Eclipse

Comments (0)

Files changed (236)

vimfiles/eclim/autoload/eclim.vim

+" 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 - 2011  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 <http://www.gnu.org/licenses/>.
+"
+" }}}
+
+" Global Variables {{{
+  if !exists("g:EclimShowErrors")
+    let g:EclimShowErrors = 1
+  endif
+" }}}
+
+" Script Variables {{{
+  let s:command_patch_file =
+    \ '-command patch_file -f <file> -r <revision> -b <basedir>'
+  let s:command_patch_revisions = '-command patch_revisions -f <file>'
+  let s:command_ping = '-command ping'
+  let s:command_settings = '-command settings'
+  let s:command_settings_update = '-command settings_update -s "<settings>"'
+  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('<amatch>') != ''
+    " 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, "\<c-m>$", '', '')
+  endif
+
+  " an echo during startup causes an annoying issue with vim.
+  "call eclim#util#Echo(' ')
+
+  " check for errors
+  let error = ''
+  if result =~ '^[^\n]*Exception:\?[^\n]*\n\s\+\<at\> ' ||
+   \ result =~ '^[^\n]*ResourceException(.\{-})\[[0-9]\+\]:[^\n]*\n\s\+\<at\> '
+    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('<amatch>') == ''
+          call eclim#util#EchoWarning(
+            \ "unable to connect to eclimd (port: " . port . ") - " . error)
+        endif
+      else
+        let error = error . "\n" .
+          \ 'while executing command (port: ' . port . '): ' . command
+        " if we are not in an autocmd, echo the error, otherwise just log it.
+        if expand('<amatch>') == ''
+          call eclim#util#EchoError(error)
+        else
+          call eclim#util#EchoDebug(error)
+        endif
+      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 = eclim#UserHome() . '/.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, '<file>', a:file, '')
+  let command = substitute(command, '<revision>', a:revision, '')
+  let command = substitute(command, '<basedir>', 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, '<project>', a:project, '')
+    let command = substitute(command, '<settings>', 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 <buffer>
+      exec 'autocmd BufWriteCmd <buffer> ' .
+        \ '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 " }}}
+
+" UserHome() {{{
+function! eclim#UserHome()
+  let home = expand('$HOME')
+  if has('win32unix')
+    let home = eclim#cygwin#WindowsHome()
+  elseif has('win32') || has('win64')
+    let home = expand('$USERPROFILE')
+  endif
+  return substitute(home, '\', '/', 'g')
+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>', 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

vimfiles/eclim/autoload/eclim/client/nailgun.vim

+" Author:  Eric Van Dewoestine
+"
+" Description: {{{
+"
+" License:
+"
+" Copyright (C) 2005 - 2011  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 <http://www.gnu.org/licenses/>.
+"
+" }}}
+
+" Global Variables {{{
+  if !exists("g:EclimNailgunKeepAlive")
+    " keepAlive flag - can be re-defined in the user ~/.vimrc .
+    " Read once, on client initialization. Subsequent changes of
+    " this flag in run-time has no effect.
+    let g:EclimNailgunKeepAlive = 0
+  endif
+" }}}
+
+" Execute(port, command) {{{
+" Function which invokes nailgun.
+function! eclim#client#nailgun#Execute(port, command)
+  if !exists('g:EclimNailgunClient')
+    call s:DetermineClient()
+  endif
+
+  if g:EclimNailgunClient == 'python'
+    return eclim#client#python#nailgun#Execute(a:port, a:command)
+  endif
+
+  let eclim = eclim#client#nailgun#GetEclimCommand()
+  if string(eclim) == '0'
+    return [1, g:EclimErrorReason]
+  endif
+
+  let command = a:command
+  " on windows/cygwin where cmd.exe is used, we need to escape any '^'
+  " characters in the command args.
+  if has('win32') || has('win64') || has('win32unix')
+    let command = substitute(command, '\^', '^^', 'g')
+  endif
+
+  let eclim .= ' --nailgun-port ' . a:port . ' ' . command
+
+  " for windows/cygwin, need to add a trailing quote to complete the command.
+  if has('win32') || has('win64') || has('win32unix')
+    " for some reason, in cywin, if two double quotes are next to each other,
+    " then the preceding arg isn't quoted correctly, so add a space to prevent
+    " this.
+    let eclim = eclim . ' "'
+  endif
+
+  let result = eclim#util#System(eclim)
+  return [v:shell_error, result]
+endfunction " }}}
+
+" GetEclimCommand() {{{
+" Gets the command to exexute eclim.
+function! eclim#client#nailgun#GetEclimCommand()
+  if !exists('g:EclimPath')
+    let g:EclimPath = g:EclimEclipseHome . '/eclim'
+
+    if has('win32') || has('win64') || has('win32unix')
+      let g:EclimPath = g:EclimPath . (has('win95') ? '.bat' : '.cmd')
+    endif
+
+    if !filereadable(g:EclimPath)
+      let g:EclimErrorReason = 'Could not locate file: ' . g:EclimPath
+      unlet g:EclimPath
+      return
+    endif
+
+    " jump through the windows hoops
+    if has('win32') || has('win64') || has('win32unix')
+      if has("win32unix")
+        let g:EclimPath = eclim#cygwin#WindowsPath(g:EclimPath, 1)
+      endif
+
+      " on windows, the command must be executed on the drive where eclipse is
+      " installed.
+      let drive = substitute(g:EclimPath, '^\([a-zA-Z]:\).*', '\1', '')
+      let g:EclimPath = '" ' . drive . ' && "' . g:EclimPath . '"'
+
+      " in cygwin, we must use 'cmd /c' to prevent issues with eclim script +
+      " some arg containing spaces causing a failure to invoke the script.
+      if has('win32unix')
+        let g:EclimPath = 'cmd /c ' . g:EclimPath
+      endif
+
+    else
+      let g:EclimPath = '"' . g:EclimPath . '"'
+    endif
+  endif
+  return g:EclimPath
+endfunction " }}}
+
+" GetNgCommand() {{{
+" Gets path to the ng executable.
+function! eclim#client#nailgun#GetNgCommand()
+  if !exists('g:EclimNgPath')
+    let g:EclimNgPath = substitute(g:EclimHome, '\', '/', 'g') .  '/bin/ng'
+
+    " on windows, ng.exe is at the eclipse root
+    if has('win32') || has('win64') || has('win32unix')
+      let g:EclimNgPath = g:EclimEclipseHome . '/ng.exe'
+      if !has('win32unix')
+        let g:EclimNgPath = substitute(g:EclimNgPath, '/', '\', 'g')
+      endif
+    endif
+
+    if !filereadable(g:EclimNgPath)
+      let g:EclimErrorReason = 'Could not locate file: ' . g:EclimNgPath
+      return
+    endif
+
+    " on windows, the command must be executed on the drive where eclipse is
+    " installed.
+    "if has("win32") || has("win64")
+    "  let g:EclimNgPath =
+    "    \ '"' . substitute(g:EclimNgPath, '^\([a-zA-Z]:\).*', '\1', '') .
+    "    \ ' && "' . g:EclimNgPath . '"'
+    "else
+      let g:EclimNgPath = '"' . g:EclimNgPath . '"'
+    "endif
+  endif
+  return g:EclimNgPath
+endfunction " }}}
+
+" GetNgPort([workspace]) {{{
+" Gets port that the nailgun server is configured to run on.
+function! eclim#client#nailgun#GetNgPort(...)
+  let port = 9091
+  let eclimrc = eclim#UserHome() . '/.eclimrc'
+  if filereadable(eclimrc)
+    let lines = filter(
+      \ readfile(eclimrc),
+      \ 'v:val =~ "^\\s*nailgun\.server\.port\\s*="')
+    if len(lines) > 0
+      exec 'let port = ' .
+        \ substitute(lines[0], '^\s*.\{-}=\s*\(\d\+\).*', '\1', '')
+    endif
+  endif
+  let default = port
+
+  let instances = eclim#UserHome() . '/.eclim/.eclimd_instances'
+  if filereadable(instances)
+    let workspaces = {}
+    let entries = readfile(instances)
+    for entry in entries
+      let workspace = substitute(entry, '\(.*\):.*', '\1', '')
+      let workspace = substitute(workspace, '\', '/', 'g')
+      let workspace .= workspace !~ '/$' ? '/' : ''
+      exec 'let port = ' . substitute(entry, '.*:\(\d\+\).*', '\1', '')
+      let workspaces[workspace] = port
+    endfor
+
+    " a specific workspace was supplied
+    if len(a:000) > 0
+      let workspace = a:000[0]
+      let workspace = substitute(workspace, '\', '/', 'g')
+      let workspace .= workspace !~ '/$' ? '/' : ''
+      return get(workspaces, workspace, default)
+    endif
+
+    let path = expand('%:p')
+    " when we are in a temp window, use the initiating filename
+    if &buftype != '' && exists('b:filename')
+      let path = b:filename
+    endif
+
+    " project inside of a workspace dir
+    for workspace in keys(workspaces)
+      if path =~ '^' . workspace
+        return workspaces[workspace]
+      endif
+    endfor
+
+    " project outside of a workspace dir
+    let project = eclim#project#util#GetProject(path)
+    if len(project) > 0
+      return get(workspaces, project.workspace, default)
+    endif
+  endif
+
+  return port
+endfunction " }}}
+
+" s:DetermineClient() {{{
+function! s:DetermineClient()
+  " at least one ubuntu user had serious performance issues using the python
+  " client, so we are only going to default to python on windows machines
+  " where there is an actual potential benefit to using it.
+  if has('python') && (has('win32') || has('win64'))
+    let g:EclimNailgunClient = 'python'
+  else
+    let g:EclimNailgunClient = 'external'
+  endif
+endfunction " }}}
+
+" vim:ft=vim:fdm=marker

vimfiles/eclim/autoload/eclim/client/python/nailgun.py

+"""
+Copyright (C) 2005 - 2011  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 <http://www.gnu.org/licenses/>.
+
+@author: Anton Sharonov
+@author: Eric Van Dewoestine
+"""
+import socket
+
+try:
+  from cStringIO import StringIO
+except:
+  from StringIO import StringIO
+
+class Nailgun(object):
+  """
+  Client used to communicate with a nailgun server.
+  """
+
+  def __init__(self, **kwargs):
+    self.socket = None
+    self.port = kwargs.get('port')
+    self.keepAlive = int(kwargs.get('keepAlive', 0))
+    self.reconnectCounter = 0
+
+  def send(self, cmdline):
+    """
+    Sends a complete command to the nailgun server.  Handles connecting to the
+    server if not currently connected.
+    @param cmdline command, which is sent to server, for instance
+      "-command ping".
+    @return tuple consisting of:
+      - retcode from server (0 for success, non-0 for failure)
+      - string response from server
+    """
+    if not self.isConnected():
+      # with keepAlive do only first reconnect
+      if not self.keepAlive or self.reconnectCounter == 0:
+        (retcode, result) = self.reconnect()
+        if retcode:
+          return (retcode, result)
+
+    if not self.isConnected(): # Only for keepAlive
+      return (-1, "connect: ERROR - socket is not connected (nailgun.py)")
+
+    try: # outer try for pre python 2.5 support.
+      try:
+        for arg in self.parseArgs(cmdline):
+          self.sendChunk("A", arg)
+
+        if self.keepAlive:
+          self.sendChunk("K")
+
+        self.sendChunk("C", "org.eclim.command.Main")
+
+        (retcode, result) = self.processResponse()
+        if self.keepAlive and retcode:
+          # force reconnect on error (may not be necessary)
+          self.reconnect()
+
+        return (retcode, result)
+      except socket.error, ex:
+        args = ex.args
+        if len(args) > 1:
+          retcode, msg = args[0], args[1]
+        elif len(args):
+          retcode, msg = 1, args[0]
+        else:
+          retcode, msg = 1, 'No message'
+        return (retcode, 'send: %s' % msg)
+    finally:
+      if not self.keepAlive:
+        try:
+          self.close()
+        except:
+          # don't let an error on close mask any previous error.
+          pass
+
+  def connect(self, port=None):
+    """
+    Establishes the connection to specified port or if not supplied,
+    uses the default.
+    """
+    port = port or self.port
+    try:
+      sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+      sock.connect(('localhost', port))
+    except socket.error, ex:
+      args = ex.args
+      if len(args) > 1:
+        retcode, msg = args[0], args[1]
+      elif len(args):
+        retcode, msg = 1, args[0]
+      else:
+        retcode, msg = 1, 'No message'
+      return (retcode, 'connect: %s' % msg)
+
+    self.socket = sock
+    return (0, '')
+
+  def reconnect(self):
+    if self.socket != None:
+      self.close()
+    self.reconnectCounter += 1
+    return self.connect()
+
+  def close(self):
+    self.socket.close()
+    self.socket = None
+
+  def isConnected(self):
+    return self.socket != None
+
+  def parseArgs(self, cmdline):
+    # FIXME: doesn't handle escaping of spaces/quotes yet (may never need to)
+    args = []
+    arg = ''
+    quote = ''
+    for char in cmdline:
+      if char == ' ' and not quote:
+        if arg:
+          args.append(arg)
+          arg = ''
+      elif char == '"' or char == "'":
+        if quote and char == quote:
+          quote = ''
+        elif not quote:
+          quote = char
+        else:
+          arg += char
+      else:
+        arg += char
+
+    if arg:
+      args.append(arg)
+
+    return args
+
+  def sendChunk(self, chunkType, text=''):
+    """
+    Sends a nailgun 'chunk' to the server.
+    """
+    #print("sendChunk " + chunkType + " " + text)
+    length = len(text)
+    str = "%c%c%c%c%c" % (
+        (length / (65536*256)) % 256,
+        (length / 65536) % 256,
+        (length / 256) % 256,
+        length % 256,
+        chunkType)
+    nbytes = self.socket.sendall(str)
+    nbytes = self.socket.sendall(text)
+
+  def processResponse(self):
+    result = StringIO()
+    exit = 0
+    exitFlag = 1 # expecting 1 times exit chunk
+    while exitFlag > 0:
+      answer = self.recvBlocked(5)
+      if len(answer) < 5:
+        print("error: socket closed unexpectedly\n")
+        return None
+      lenPayload = ord(answer[0]) * 65536 * 256 \
+        + ord(answer[1]) * 65536 \
+        + ord(answer[2]) * 256 \
+        + ord(answer[3])
+      #print("lenPayload detected : %d" % lenPayload)
+      chunkType = answer[4]
+      if chunkType == "1":
+        # STDOUT
+        result.write(self.recvToFD(1, answer, lenPayload))
+      elif chunkType == "2":
+        # STDERR
+        result.write(self.recvToFD(2, answer, lenPayload))
+      elif chunkType == "X":
+        exitFlag = exitFlag - 1
+        exit = int(self.recvToFD(2, answer, lenPayload))
+      else:
+        print("error: unknown chunk type = %d\n" % chunkType)
+        exitFlag = 0
+
+    return [exit, result.getvalue()]
+
+  def recvBlocked(self, lenPayload):
+    """
+    Receives until all data is read - necessary because usual recv sometimes
+    returns with number of bytes read less then asked.
+    """
+    received = ""
+    while (len(received) < lenPayload):
+      received = received + self.socket.recv(lenPayload - len(received))
+    return received
+
+  def recvToFD(self, destFD, buf, lenPayload):
+    """
+    This function just mimics the function with the same name from the C
+    client.  We don't really care which file descriptor the server tells us to
+    write to - STDOUT and STDERR are the same on VIM side (see eclim.bat,
+    "2>&1" at the end of command).
+    """
+    received = self.recvBlocked(lenPayload)
+    return received

vimfiles/eclim/autoload/eclim/client/python/nailgun.vim

+" Author:  Anton Sharonov
+" Author:  Eric Van Dewoestine
+"
+" Description: {{{
+"
+" 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 <http://www.gnu.org/licenses/>.
+"
+" }}}
+
+" Script Variables {{{
+  let s:python_dir = expand("<sfile>:h")
+" }}}
+
+" Execute(port, command) {{{
+" Sends to the eclimd server command, supplied as argument string.
+" Returns server's respond.
+function! eclim#client#python#nailgun#Execute(port, command)
+  call s:InitClient(a:port)
+  let result_viml = ""
+  let retcode = 0
+
+  let begin = localtime()
+  try
+python << PYTHONEOF
+command = vim.eval('a:command')
+(retcode, result) = client.send(command)
+vim.command('let retcode = %i' % retcode)
+vim.command("let result = '%s'" % result.replace("'", "''"))
+PYTHONEOF
+  finally
+    call eclim#util#EchoTrace(
+      \ 'nailgun.py (port: ' . a:port . '): ' . a:command, localtime() - begin)
+  endtry
+
+  return [retcode, result]
+endfunction " }}}
+
+" Reconnect(port) {{{
+" Does unconditional reconnect of the python_if
+" (useful to manual recover from errors in the python_if)
+function! eclim#client#python#nailgun#Reconnect(port)
+  call s:InitClient(a:port)
+python << PYTHONEOF
+client.reconnect()
+PYTHONEOF
+endfunction " }}}
+
+" SetKeepAlive(port, value) {{{
+" Updates the in runtime value of the keepAlive flag.
+function! eclim#client#python#nailgun#SetKeepAlive(port, value)
+  call s:InitClient(a:port)
+python << PYTHONEOF
+client.keepAlive = int(vim.eval('a:value'))
+PYTHONEOF
+endfunction " }}}
+
+" GetKeepAlive(port) {{{
+" Retrieves the value of the keepAlive flag.
+function! eclim#client#python#nailgun#GetKeepAlive(port)
+  call s:InitClient(a:port)
+  let result = 0
+python << PYTHONEOF
+vim.command("let result = %s" % client.keepAlive)
+PYTHONEOF
+  return result
+endfunction " }}}
+
+" GetReconnectCounter(port) {{{
+" Retrieves the value of the reconnect counter.
+function! eclim#client#python#nailgun#GetReconnectCounter(port)
+  call s:InitClient(a:port)
+  let result = 0
+python << PYTHONEOF
+vim.command("let result = %d" % client.reconnectCounter)
+PYTHONEOF
+  return result
+endfunction " }}}
+
+" s:InitClient(port) {{{
+" Initializes the python interface to the nailgun server.
+function! s:InitClient(port)
+python << PYTHONEOF
+if not vars().has_key('clients'):
+  import sys, vim
+  sys.path.append(vim.eval('s:python_dir'))
+  import nailgun
+
+  clients = {}
+
+port = int(vim.eval('a:port'))
+if not clients.has_key(port):
+  clients[port] = nailgun.Nailgun(
+    port=port,
+    keepAlive=vim.eval('g:EclimNailgunKeepAlive'),
+  )
+client = clients[port]
+PYTHONEOF
+endfunction " }}}
+
+" vim:ft=vim:fdm=marker

vimfiles/eclim/autoload/eclim/common/buffers.vim

+" Author:  Eric Van Dewoestine
+"
+" Description: {{{
+"
+" License:
+"
+" Copyright (C) 2005 - 2011  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 <http://www.gnu.org/licenses/>.
+"
+" }}}
+
+" Global Variables {{{
+if !exists('g:EclimBuffersSort')
+  let g:EclimBuffersSort = 'file'
+endif
+if !exists('g:EclimBuffersSortDirection')
+  let g:EclimBuffersSortDirection = 'asc'
+endif
+if !exists('g:EclimBuffersDefaultAction')
+  let g:EclimBuffersDefaultAction = g:EclimDefaultFileOpenAction
+endif
+if !exists('g:EclimOnlyExclude')
+  let g:EclimOnlyExclude = '^NONE$'
+endif
+if !exists('g:EclimOnlyExcludeFixed')
+  let g:EclimOnlyExcludeFixed = 1
+endif
+" }}}
+
+" Buffers() {{{
+" Like, :buffers, but opens a temporary buffer.
+function! eclim#common#buffers#Buffers()
+  redir => list
+  silent exec 'buffers'
+  redir END
+
+  let buffers = []
+  let filelength = 0
+  for entry in split(list, '\n')
+    let buffer = {}
+    let buffer.status = substitute(entry, '\s*[0-9]\+\s\+\(.\{-}\)\s\+".*', '\1', '')
+    let buffer.path = substitute(entry, '.\{-}"\(.\{-}\)".*', '\1', '')
+    let buffer.path = fnamemodify(buffer.path, ':p')
+    let buffer.file = fnamemodify(buffer.path, ':p:t')
+    let buffer.dir = fnamemodify(buffer.path, ':p:h')
+    exec 'let buffer.bufnr = ' . substitute(entry, '\s*\([0-9]\+\).*', '\1', '')
+    exec 'let buffer.lnum = ' .
+      \ substitute(entry, '.*"\s\+line\s\+\([0-9]\+\).*', '\1', '')
+    call add(buffers, buffer)
+
+    if len(buffer.file) > filelength
+      let filelength = len(buffer.file)
+    endif
+  endfor
+
+  if g:EclimBuffersSort != ''
+    call sort(buffers, 'eclim#common#buffers#BufferCompare')
+  endif
+
+  let lines = []
+  for buffer in buffers
+    call add(lines, s:BufferEntryToLine(buffer, filelength))
+  endfor
+
+  call eclim#util#TempWindow('[buffers]', lines)
+
+  setlocal modifiable noreadonly
+  call append(line('$'), ['', '" use ? to view help'])
+  setlocal nomodifiable readonly
+
+  let b:eclim_buffers = buffers
+
+  " syntax
+  set ft=eclim_buffers
+  hi link BufferActive Special
+  hi link BufferHidden Comment
+  syntax match BufferActive /+\?active\s\+\(\[RO\]\)\?/
+  syntax match BufferHidden /+\?hidden\s\+\(\[RO\]\)\?/
+  syntax match Comment /^".*/
+
+  " mappings
+  nnoremap <silent> <buffer> <cr> :call <SID>BufferOpen(g:EclimBuffersDefaultAction)<cr>
+  nnoremap <silent> <buffer> E :call <SID>BufferOpen('edit')<cr>
+  nnoremap <silent> <buffer> S :call <SID>BufferOpen('split')<cr>
+  nnoremap <silent> <buffer> T :call <SID>BufferOpen('tablast \| tabnew')<cr>
+  nnoremap <silent> <buffer> D :call <SID>BufferDelete()<cr>
+  nnoremap <silent> <buffer> R :Buffers<cr>
+
+  " assign to buffer var to get around weird vim issue passing list containing
+  " a string w/ a '<' in it on execution of mapping.
+  let b:buffers_help = [
+      \ '<cr> - open buffer with default action',
+      \ 'E - open with :edit',
+      \ 'S - open in a new split window',
+      \ 'T - open in a new tab',
+      \ 'D - delete the buffer',
+      \ 'R - refresh the buffer list',
+    \ ]
+  nnoremap <buffer> <silent> ?
+    \ :call eclim#help#BufferHelp(b:buffers_help, 'vertical', 40)<cr>
+
+  "augroup eclim_buffers
+  "  autocmd!
+  "  autocmd BufAdd,BufWinEnter,BufDelete,BufWinLeave *
+  "    \ call eclim#common#buffers#BuffersUpdate()
+  "  autocmd BufUnload <buffer> autocmd! eclim_buffers
+  "augroup END
+endfunction " }}}
+
+" BuffersToggle() {{{
+function! eclim#common#buffers#BuffersToggle()
+  let name = eclim#util#EscapeBufferName('[buffers]')
+  if bufwinnr(name) == -1
+    call eclim#common#buffers#Buffers()
+  else
+    exec "bdelete " . bufnr(name)
+  endif
+endfunction " }}}
+
+" BufferCompare(buffer1, buffer2) {{{
+function! eclim#common#buffers#BufferCompare(buffer1, buffer2)
+  exec 'let attr1 = a:buffer1.' . g:EclimBuffersSort
+  exec 'let attr2 = a:buffer2.' . g:EclimBuffersSort
+  let compare = attr1 == attr2 ? 0 : attr1 > attr2 ? 1 : -1
+  if g:EclimBuffersSortDirection == 'desc'
+    let compare = 0 - compare
+  endif
+  return compare
+endfunction " }}}
+
+" Only() {{{
+function! eclim#common#buffers#Only()
+  let curwin = winnr()
+  let winnum = 1
+  while winnum <= winnr('$')
+    let fixed = g:EclimOnlyExcludeFixed && (
+      \ getwinvar(winnum, '&winfixheight') == 1 ||
+      \ getwinvar(winnum, '&winfixwidth') == 1)
+    let excluded = bufname(winbufnr(winnum)) =~ g:EclimOnlyExclude
+    if winnum != curwin && !fixed && !excluded
+      if winnum < curwin
+        let curwin -= 1
+      endif
+      exec winnum . 'winc w'
+      close
+      exec curwin . 'winc w'
+      continue
+    endif
+    let winnum += 1
+  endwhile
+endfunction " }}}
+
+" s:BufferDelete() {{{
+function! s:BufferDelete()
+  let line = line('.')
+  if line > len(b:eclim_buffers)
+    return
+  endif
+
+  let index = line - 1
+  setlocal modifiable
+  setlocal noreadonly
+  exec line . ',' . line . 'delete _'
+  setlocal nomodifiable
+  setlocal readonly
+  let buffer = b:eclim_buffers[index]
+  call remove(b:eclim_buffers, index)
+
+  let winnr = bufwinnr(buffer.bufnr)
+  if winnr != -1
+    " if active in a window, go to the window to delete the buffer since that
+    " keeps eclim's prevention of closing the last non-utility window working
+    " properly.
+    let curwin = winnr()
+    exec winnr . 'winc w'
+    bdelete
+    exec curwin . 'winc w'
+  else
+    exec 'bd ' . buffer.bufnr
+  endif
+endfunction " }}}
+
+" s:BufferEntryToLine(buffer, filelength) {{{
+function! s:BufferEntryToLine(buffer, filelength)
+  let line = ''
+  let line .= a:buffer.status =~ '+' ? '+' : ' '
+  let line .= a:buffer.status =~ 'a' ? 'active' : 'hidden'
+  let line .= a:buffer.status =~ '[-=]' ? ' [RO] ' : '      '
+  let line .= a:buffer.file
+
+  let pad = a:filelength - len(a:buffer.file) + 2
+  while pad > 0
+    let line .= ' '
+    let pad -= 1
+  endwhile
+
+  let line .= a:buffer.dir
+  return line
+endfunction " }}}
+
+" s:BufferOpen(cmd) {{{
+function! s:BufferOpen(cmd)
+  let line = line('.')
+  if line > len(b:eclim_buffers)
+    return
+  endif
+
+  let file = bufname(b:eclim_buffers[line - 1].bufnr)
+  let winnr = b:winnr
+  close
+  exec winnr . 'winc w'
+  call eclim#util#GoToBufferWindowOrOpen(file, a:cmd)
+endfunction " }}}
+
+" vim:ft=vim:fdm=marker

vimfiles/eclim/autoload/eclim/common/history.vim

+" Author:  Eric Van Dewoestine
+"
+" Description: {{{
+"
+" 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 <http://www.gnu.org/licenses/>.
+"
+" }}}
+
+" Global Variables {{{
+  if !exists('g:EclimHistoryDiffOrientation')
+    let g:EclimHistoryDiffOrientation = 'vertical'
+  endif
+" }}}
+
+" Script Variables {{{
+let s:command_add = '-command history_add -p "<project>" -f "<file>"'
+let s:command_list = '-command history_list -p "<project>" -f "<file>"'
+let s:command_revision =
+  \ '-command history_revision -p "<project>" -f "<file>" -r <revision>'
+let s:command_clear = '-command history_clear -p "<project>" -f "<file>"'
+" }}}
+
+" AddHistory() {{{
+" Adds the current state of the file to the eclipse local history (should be
+" invoked prior to saving to disk).
+function! eclim#common#history#AddHistory()
+  if !filereadable(expand('%')) || !eclim#project#util#IsCurrentFileInProject(0)
+    return
+  endif
+
+  let project = eclim#project#util#GetCurrentProjectName()
+  let file = eclim#project#util#GetProjectRelativeFilePath()
+  let command = s:command_add
+  let command = substitute(command, '<project>', project, '')
+  let command = substitute(command, '<file>', file, '')
+  call eclim#ExecuteEclim(command)
+endfunction " }}}
+
+" History() {{{
+" Opens a temporary buffer with a list of local history revisions.
+function! eclim#common#history#History()
+  if !eclim#project#util#IsCurrentFileInProject()
+    return
+  endif
+
+  let project = eclim#project#util#GetCurrentProjectName()
+  let file = eclim#project#util#GetProjectRelativeFilePath()
+  let command = s:command_list
+  let command = substitute(command, '<project>', project, '')
+  let command = substitute(command, '<file>', file, '')
+  let result = eclim#ExecuteEclim(command)
+  if result == "0"
+    return
+  endif
+
+  let history = eval(result)
+  let lines = [file]
+  let revisions = [0]
+  let indent = eclim#util#GetIndent(1)
+  for rev in history
+    call add(lines, indent . rev.datetime . ' (' . rev.delta . ')')
+    call add(revisions, rev.timestamp)
+  endfor
+  call add(lines, '')
+  call eclim#util#TempWindow('[History]', lines)
+
+  setlocal modifiable noreadonly
+  call append(line('$'), '" use ? to view help')
+  setlocal nomodifiable readonly
+  syntax match Comment /^".*/
+
+  let b:history_revisions = revisions
+  call s:Syntax()
+
+  command! -count=1 HistoryDiffNext call s:DiffNextPrev(1, <count>)
+  command! -count=1 HistoryDiffPrev call s:DiffNextPrev(-1, <count>)
+  augroup eclim_history_window
+    autocmd! BufWinLeave <buffer>
+    autocmd BufWinLeave <buffer>
+      \ delcommand HistoryDiffNext |
+      \ delcommand HistoryDiffPrev
+  augroup END
+  noremap <buffer> <silent> <cr> :call <SID>View()<cr>
+  noremap <buffer> <silent> d :call <SID>Diff()<cr>
+  noremap <buffer> <silent> r :call <SID>Revert()<cr>
+  noremap <buffer> <silent> c :call <SID>Clear(1)<cr>
+
+  " assign to buffer var to get around weird vim issue passing list containing
+  " a string w/ a '<' in it on execution of mapping.
+  let b:history_help = [
+      \ '<cr> - view the entry',
+      \ 'd - diff the file with the version under the cursor',
+      \ 'r - revert the file to the version under the cursor',
+      \ 'c - clear the history',
+      \ ':HistoryDiffNext - diff the file with the next version in the history',
+      \ ':HistoryDiffPrev - diff the file with the previous version in the history',
+    \ ]
+  nnoremap <buffer> <silent> ?
+    \ :call eclim#help#BufferHelp(b:history_help, 'vertical', 50)<cr>
+endfunction " }}}
+
+" HistoryClear(bang) {{{
+" Clear the history for the current file.
+function! eclim#common#history#HistoryClear(bang)
+  if !eclim#project#util#IsCurrentFileInProject()
+    return
+  endif
+
+  call s:Clear(a:bang == '', expand('%:p'))
+endfunction " }}}
+
+" s:View([cmd]) {{{
+" View the contents of the revision under the cursor.
+function s:View(...)
+  if line('.') == 1 || line('.') > len(b:history_revisions)
+    return
+  endif
+
+  let current = b:filename
+  let entry = line('.') - 1
+  let revision = b:history_revisions[entry]
+  if eclim#util#GoToBufferWindow(current)
+    let filetype = &ft
+    let project = eclim#project#util#GetCurrentProjectName()
+    let file = eclim#project#util#GetProjectRelativeFilePath()
+    let command = s:command_revision
+    let command = substitute(command, '<project>', project, '')
+    let command = substitute(command, '<file>', file, '')
+    let command = substitute(command, '<revision>', revision, '')
+    let result = eclim#ExecuteEclim(command)
+    if result == "0"
+      return
+    endif
+
+    let cmd = len(a:000) > 0 ? a:000[0] : 'split'
+    call eclim#util#GoToBufferWindowOrOpen(current . '_' . revision, cmd)
+
+    setlocal modifiable
+    setlocal noreadonly
+
+    let temp = tempname()
+    call writefile(split(result, '\n'), temp)
+    try
+      silent 1,$delete _
+      silent read ++edit `=temp`
+      silent 1,1delete _
+    finally
+      call delete(temp)
+    endtry
+
+    exec 'setlocal filetype=' . filetype
+    setlocal nomodified
+    setlocal readonly
+    setlocal nomodifiable
+    setlocal noswapfile
+    setlocal nobuflisted
+    setlocal buftype=nofile
+    setlocal bufhidden=delete
+    doautocmd BufReadPost
+
+    call s:HighlightEntry(entry)
+
+    return 1
+  else
+    call eclim#util#EchoWarning('Target file is no longer open.')
+  endif
+endfunction " }}}
+
+" s:Diff() {{{
+" Diff the contents of the revision under the cursor against the current
+" contents.
+function s:Diff()
+  let hist_buf = bufnr('%')
+  let winend = winnr('$')
+  let winnum = 1
+  while winnum <= winend
+    let bufnr = winbufnr(winnum)
+    if getbufvar(bufnr, 'history_diff') != ''
+      exec bufnr . 'bd'
+      continue
+    endif
+    let winnum += 1
+  endwhile
+  call eclim#util#GoToBufferWindow(hist_buf)
+
+  let current = b:filename
+  let orien = g:EclimHistoryDiffOrientation == 'horizontal' ? '' : 'vertical'
+  if s:View(orien . ' below split')
+    let b:history_diff = 1
+    diffthis
+    augroup history_diff
+      autocmd! BufWinLeave <buffer>
+      call eclim#util#GoToBufferWindowRegister(current)
+      autocmd BufWinLeave <buffer> diffoff
+    augroup END
+
+    call eclim#util#GoToBufferWindow(current)
+    diffthis
+  endif
+endfunction " }}}
+
+" s:DiffNextPrev(dir, count) {{{
+function s:DiffNextPrev(dir, count)
+  let winnr = winnr()
+  if eclim#util#GoToBufferWindow('[History]')
+    let num = v:count > 0 ? v:count : a:count
+    let cur = exists('b:history_current_entry') ? b:history_current_entry : 0
+    let index = cur + (a:dir * num)
+    if index < 0 || index > len(b:history_revisions)
+      call eclim#util#EchoError('Operation exceeds history stack range.')
+      exec winnr . 'winc w'
+      return
+    endif
+    call cursor(index + 1, 0)
+    call s:Diff()
+  endif
+endfunction " }}}
+
+" s:Revert() {{{
+" Revert the file to the revision under the cursor.
+function s:Revert()
+  if line('.') == 1 || line('.') > len(b:history_revisions)
+    return
+  endif
+
+  let current = b:filename
+  let revision = b:history_revisions[line('.') - 1]
+  if eclim#util#GoToBufferWindow(current)
+    let project = eclim#project#util#GetCurrentProjectName()
+    let file = eclim#project#util#GetProjectRelativeFilePath()
+    let command = s:command_revision
+    let command = substitute(command, '<project>', project, '')
+    let command = substitute(command, '<file>', file, '')
+    let command = substitute(command, '<revision>', revision, '')
+    let result = eclim#ExecuteEclim(command)
+    if result == "0"
+      return
+    endif
+
+    let ff = &ff
+    let temp = tempname()
+    call writefile(split(result, '\n'), temp)
+    try
+      silent 1,$delete _
+      silent read ++edit `=temp`
+      silent 1,1delete _
+    finally
+      call delete(temp)
+    endtry
+
+    if ff != &ff
+      call eclim#util#EchoWarning(
+        \ "Warning: the file format is being reverted from '" . ff . "' to '" .
+        \ &ff . "'. Using vim's undo will not restore the previous format so " .
+        \ "if you choose to undo the reverting of this file, you will need to " .
+        \ "manually set the file format back to " . ff . " (set ff=" . ff . ").")
+    endif
+  endif
+endfunction " }}}
+
+" s:Clear(prompt, [filename]) {{{
+" Clear the history.
+function s:Clear(prompt, ...)
+  let response = 1
+  if a:prompt
+    let response = eclim#util#PromptConfirm(
+      \ 'Clear local history?', g:EclimInfoHighlight)
+  endif
+
+  if response == 1
+    let filename = len(a:000) > 0 ? a:000[0] : b:filename
+    let current = eclim#project#util#GetProjectRelativeFilePath(filename)
+    let project = eclim#project#util#GetCurrentProjectName()
+    let command = s:command_clear
+    let command = substitute(command, '<project>', project, '')
+    let command = substitute(command, '<file>', current, '')
+    let result = eclim#ExecuteEclim(command)
+    if result == "0"
+      return
+    endif
+
+    if filename != expand('%:p')
+      quit
+    endif
+    call eclim#util#Echo(result)
+  endif
+endfunction " }}}
+
+" s:Syntax() {{{
+function! s:Syntax()
+  set ft=eclim_history
+  hi link HistoryFile Identifier
+  hi link HistoryCurrentEntry Constant
+  syntax match HistoryFile /.*\%1l.*/
+  syntax match Comment /^".*/
+endfunction " }}}
+
+" s:HighlightEntry(index) {{{
+function s:HighlightEntry(index)
+  let winnr = winnr()
+  if eclim#util#GoToBufferWindow('[History]')
+    let b:history_current_entry = a:index
+    try
+      " forces reset of syntax
+      call s:Syntax()
+      exec 'syntax match HistoryCurrentEntry /.*\%' . (a:index + 1) . 'l.*/'
+    finally
+      exec winnr . 'winc w'
+    endtry
+  endif
+endfunction " }}}
+
+" vim:ft=vim:fdm=marker

vimfiles/eclim/autoload/eclim/common/license.vim

+" Author:  Eric Van Dewoestine
+"
+" Description: {{{
+"
+" License:
+"
+" Copyright (C) 2005 - 2009  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 <http://www.gnu.org/licenses/>.
+"
+" }}}
+
+" Script Variables {{{
+  let s:year = exists('*strftime') ? strftime('%Y') : '2009'
+" }}}
+
+" GetLicense() {{{
+" Retrieves the file containing the license text.
+function! eclim#common#license#GetLicense()
+  let file = eclim#project#util#GetProjectSetting('org.eclim.project.copyright')
+  if type(file) == 0
+    return
+  elseif file == ''
+    call eclim#util#EchoWarning(
+      \ "Project setting 'org.eclim.project.copyright' has not been supplied.")
+    return
+  endif
+
+  let file = eclim#project#util#GetCurrentProjectRoot() . '/' . file
+  if !filereadable(file)
+    return
+  endif
+  return file
+endfunction " }}}
+
+" License(pre, post, mid) {{{
+" Retrieves the license configured license and applies the specified prefix
+" and postfix as the lines before and after the license and uses 'mid' as the
+" prefix for every line.
+" Returns the license as a list of strings.
+function! eclim#common#license#License(pre, post, mid)
+  let file = eclim#common#license#GetLicense()
+  if type(file) == 0 && file == 0
+    return ''
+  endif
+
+  let contents = readfile(file)
+  if a:mid != ''
+    call map(contents, 'a:mid . v:val')
+  endif
+
+  if a:pre != ''
+    call insert(contents, a:pre)
+  endif
+
+  if a:post != ''
+    call add(contents, a:post)
+  endif
+
+  call map(contents, "substitute(v:val, '${year}', s:year, 'g')")
+
+  let author = eclim#project#util#GetProjectSetting('org.eclim.user.name')
+  if type(author) != 0 && author != ''
+    call map(contents, "substitute(v:val, '${author}', author, 'g')")
+  endif
+
+  let email = eclim#project#util#GetProjectSetting('org.eclim.user.email')
+  if type(email) != 0 && email != ''
+    call map(contents, "substitute(v:val, '${email}', email, 'g')")
+  endif
+  call map(contents, "substitute(v:val, '\\s\\+$', '', '')")
+
+  return contents
+endfunction " }}}
+
+" vim:ft=vim:fdm=marker

vimfiles/eclim/autoload/eclim/common/locate.vim

+" Author:  Eric Van Dewoestine
+"
+" Description: {{{
+"   Implements the :LocateFile functionality.
+"
+" 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 <http://www.gnu.org/licenses/>.
+"
+" }}}
+
+" Global Variables {{{
+if !exists('g:EclimLocateFileDefaultAction')
+  let g:EclimLocateFileDefaultAction = g:EclimDefaultFileOpenAction
+endif
+
+if !exists('g:EclimLocateFileScope')
+  let g:EclimLocateFileScope = 'project'
+endif
+
+if !exists('g:EclimLocateFileFuzzy')
+  let g:EclimLocateFileFuzzy = 1
+endif
+
+if !exists('g:EclimLocateUserScopes')
+  let g:EclimLocateUserScopes = []
+endif
+
+let g:eclim_locate_default_updatetime = &updatetime
+
+" }}}
+
+" Script Variables {{{
+let s:command_locate = '-command locate_file -s "<scope>"'
+let s:scopes = [
+    \ 'project',
+    \ 'workspace',
+    \ 'buffers',
+    \ 'quickfix',
+  \ ]
+
+let s:help = [
+    \ '<esc> - close the locate prompt + results',
+    \ '<tab>, <down> - select the next file',
+    \ '<s-tab>, <up> - select the previous file',
+    \ '<cr> - open selected file w/ default action',
+    \ '<c-e> - open with :edit',
+    \ '<c-s> - open in a split window',
+    \ '<c-t> - open in a new tab',
+    \ '<c-l> - choose search scope',
+    \ '<c-h> - toggle help buffer',
+  \ ]
+" }}}
+
+" LocateFile(action, file, [scope]) {{{
+" Locates a file using the specified action for opening the file when found.
+"   action - '' (use user default), 'split', 'edit', etc.
+"   file - 'somefile.txt',
+"          '', (kick off completion mode),
+"          '<cursor>' (locate the file under the cursor)
+"   scope - optional scope to search in (project, workspace, buffers, etc.)
+function! eclim#common#locate#LocateFile(action, file, ...)
+  let project = eclim#project#util#GetCurrentProjectName()
+  let scope = a:0 > 0 ? a:1 : g:EclimLocateFileScope
+
+  if !eclim#util#ListContains(s:scopes, scope) &&
+   \ !eclim#util#ListContains(g:EclimLocateUserScopes, scope)
+    call eclim#util#EchoWarning('Unrecognized scope: ' . scope)
+    return
+  endif
+
+  if scope == 'project' && project == ''
+    let scope = 'workspace'
+  endif
+
+  let workspace = eclim#eclipse#ChooseWorkspace()
+  if workspace == '0'
+    return
+  endif
+
+  if !eclim#PingEclim(0, workspace)
+    call eclim#util#EchoError('Unable to connect to eclimd.')
+    return
+  endif
+
+  let results = []
+  let action = a:action
+  if action == ''
+    let action = g:EclimLocateFileDefaultAction
+  endif
+
+  let file = a:file
+  if file == ''
+    call s:LocateFileCompletionInit(action, scope, project, workspace)
+    return
+  elseif file == '<cursor>'
+    let file = eclim#util#GrabUri()
+
+    " if grabbing a relative url, remove any anchor info or query parameters
+    let file = substitute(file, '[#?].*', '', '')
+  endif
+
+  let name = fnamemodify(file, ':t')
+  if name == ''
+    call eclim#util#Echo('Please supply more than just a directory name.')
+    return
+  endif
+
+  let pattern = file
+  let pattern = s:LocateFileConvertPattern(pattern, 0)
+  let pattern = '[^/]*' . pattern
+  try
+    let b:workspace = workspace
+    let b:project = project
+    let results = s:LocateFileFunction(scope)(pattern)
+  finally
+    unlet! b:workspce
+    unlet! b:project
+  endtry
+
+  call map(results, "split(v:val, '|')[2]")
+
+  let result = ''
+  " One result.
+  if len(results) == 1
+    let result = results[0]
+
+  " More than one result.
+  elseif len(results) > 1
+    let message = "Multiple results, choose the file to open"
+    let response = eclim#util#PromptList(message, results, g:EclimInfoHighlight)
+    if response == -1
+      return
+    endif
+
+    let result = results[response]
+
+  " No results
+  else
+    call eclim#util#Echo('Unable to locate file pattern "' . file . '".')
+    return
+  endif
+
+  if has('win32unix')
+    let result = eclim#cygwin#CygwinPath(result)
+  endif
+
+  call eclim#util#GoToBufferWindowOrOpen(eclim#util#Simplify(result), action)
+  call eclim#util#Echo(' ')
+endfunction " }}}
+
+" LocateFileCompletion() {{{
+function! eclim#common#locate#LocateFileCompletion()
+  let line = getline('.')
+  if line !~ '^> '
+    call setline(1, substitute(line, '^>\?\s*', '> \1', ''))
+    call cursor(1, 3)
+    let line = getline('.')
+  endif
+
+  let completions = []
+  let display = []
+  let name = substitute(line, '^>\s*', '', '')
+  if name !~ '^\s*$'
+    let pattern = name
+    let pattern = s:LocateFileConvertPattern(pattern, g:EclimLocateFileFuzzy)