Skip to content

Support for native win32 gvim from cygwin ruby #41

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 32 additions & 5 deletions lib/vimrunner/client.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require "vimrunner/path"
require "vimrunner/command"
require "vimrunner/platform"

module Vimrunner
class Client
Expand All @@ -26,8 +27,7 @@ def initialize(server)
def add_plugin(dir, entry_script = nil)
append_runtimepath(dir)
if entry_script
entry_script_path = Path.new(entry_script)
command("runtime #{entry_script_path}")
runtime(entry_script)
end
end

Expand All @@ -41,8 +41,25 @@ def add_plugin(dir, entry_script = nil)
#
# Returns nothing.
def source(script)
script_path = Path.new(Platform.fix_path(script))
normal(":source #{script_path}<cr>")
# feedkeys doesn't seem to wait long enough
# feedkeys(":\\<C-u>source #{script_path}\\<CR>")
end

# Public: source a script in Vim server
#
# script - The Vim script to be sourced. The path is relative to
# &rtp.
#
# Examples
#
# vim.runtime 'plugin/rails.vim'
#
# Returns nothing.
def runtime(script)
script_path = Path.new(script)
feedkeys(":\\<C-u>source #{script_path}\\<CR>")
command("runtime #{script_path}")
end

# Public: Appends a directory to Vim's runtimepath
Expand All @@ -51,7 +68,7 @@ def source(script)
#
# Returns nothing.
def append_runtimepath(dir)
dir_path = Path.new(dir)
dir_path = Path.new(Platform.fix_path(dir))
command("set runtimepath+=#{dir_path}")
end

Expand All @@ -63,7 +80,7 @@ def append_runtimepath(dir)
#
# Returns nothing.
def prepend_runtimepath(dir)
dir_path = Path.new(dir)
dir_path = Path.new(Platform.fix_path(dir))
runtimepath = Path.new(echo('&runtimepath'))
command("set runtimepath=#{dir_path},#{runtimepath}")
end
Expand Down Expand Up @@ -182,6 +199,16 @@ def edit!(filename)
self
end

# Public: Changes the current directory
#
# The +path+ will be fixed on the fly
#
# Returns the String output.
def cd(path)
path = Platform.fix_path(path)
command("cd #{path}")
end

# Public: Executes the given command in the Vim instance and returns its
# output, stripping all surrounding whitespace.
#
Expand Down
31 changes: 31 additions & 0 deletions lib/vimrunner/platform.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,20 @@ def gvim
gvims.find { |gvim| suitable?(gvim) } or raise NoSuitableVimError
end

def fix_path(path)
return `cygpath -ml "#{path}"`.chomp if need_to_fix_path?
return path
end

def spawn_executable
if windows?
the_exec = "gvim.exe"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we not add this to gvims, e.g.

def gvims
  if mac?
    %w( mvim gvim )
  elsif windows?
    %w( gvim.exe )
  else
    %w( gvim )
  end
end

else
the_exec = vim
end
return the_exec
end

private

def gvims
Expand All @@ -48,16 +62,24 @@ def vims
%w( vim ) + gvims
end

@need_to_fix_path = false
def suitable?(vim)
features = features(vim)

@need_to_fix_path = ! features.include?("cygwin") && cygwin?
if gui?(vim)
features.include?("+clientserver")
elsif cygwin?
features.include?("+clientserver")
else
features.include?("+clientserver") && features.include?("+xterm_clipboard")
end
end

def need_to_fix_path?()
@need_to_fix_path
end

def gui?(vim)
executable = File.basename(vim)

Expand All @@ -73,5 +95,14 @@ def features(vim)
def mac?
RbConfig::CONFIG["host_os"] =~ /darwin/
end

def cygwin?
RbConfig::CONFIG["host_os"] == "cygwin"
end

def windows?
RbConfig::CONFIG["host_os"] =~ /mswin|cygwin/
end

end
end
7 changes: 6 additions & 1 deletion lib/vimrunner/rspec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,16 @@ def vim
config.include(Vimrunner::Testing)

# Each example is executed in a separate directory
# No trace shall be left in the tmp directory otherwise cygwin won't permit
# rmdir => vim is outside the directory at the end
# TODO: ensure a cd(pwd) à la RAII
pwd = Dir.pwd
config.around(:each) do |example|
Dir.mktmpdir do |dir|
Dir.chdir(dir) do
vim.command("cd #{dir}")
vim.cd(dir)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems a good idea in general but we might want to tweak the order a little and guard against test failures:

config.around(:each) do |example|
  original_dir = Dir.pwd

  Dir.mktmpdir do |dir|
    Dir.chdir(dir) do
      begin
        vim.cd(dir)
        example.run
      ensure
        vim.cd(original_dir)
      end
    end
  end
end

example.run
vim.cd(pwd)
end
end
end
Expand Down
13 changes: 9 additions & 4 deletions lib/vimrunner/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ class Server
VIMRC = File.expand_path("../../../vim/vimrc", __FILE__)
VIMRUNNER_RC = File.expand_path("../../../vim/vimrunner_rc", __FILE__)

attr_reader :name, :executable, :vimrc, :gvimrc
attr_reader :name, :executable, :spawn_executable, :vimrc, :gvimrc

# Public: Initialize a Server
#
# options - The Hash options used to define a server (default: {}):
# :executable - The String Vim executable to use (optional)
# (default: Platform.vim).
# :spawn_executable - The String Vim spawn executable to use (optional)
# (default: Platform.spawn_executable).
# :name - The String name of the Vim server (optional)
# (default: "VIMRUNNER#{rand}").
# :vimrc - The String vimrc file to source in the client (optional)
Expand All @@ -35,6 +37,7 @@ class Server
#
def initialize(options = {})
@executable = options.fetch(:executable) { Platform.vim }
@spawn_executable = options.fetch(:spawn_executable) { Platform.spawn_executable }
@name = options.fetch(:name) { "VIMRUNNER#{rand}" }.upcase
@vimrc = options.fetch(:vimrc) { VIMRC }
@gvimrc = options.fetch(:gvimrc) { "NONE" }
Expand Down Expand Up @@ -138,7 +141,7 @@ def new_client
#
# Returns an Array of String server names currently running.
def serverlist
execute([executable, "--serverlist"]).split("\n")
execute([executable, "--serverlist"]).split(/\r?\n/)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might be able to use $/ here which should return the platform-dependent end-of-line character.

end

# Public: Evaluates an expression in the Vim server and returns the result.
Expand Down Expand Up @@ -172,8 +175,10 @@ def execute(command)
end

def spawn
PTY.spawn(executable, *%W[
#{foreground_option} --servername #{name} -u #{vimrc} -U #{gvimrc}
the_exec = spawn_executable
# pp (%W[ #{the_exec} #{foreground_option} --servername #{name} -u #{vimrc} -U #{gvimrc} ])
PTY.spawn(the_exec, *%W[
#{foreground_option} --servername #{name} -u #{Platform.fix_path vimrc} -U #{gvimrc}
])
end

Expand Down
2 changes: 2 additions & 0 deletions vim/vimrc
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,7 @@ syntax on
set noswapfile nobackup

" remove default ~/.vim directories to avoid loading plugins
set runtimepath-=~/vimfiles
set runtimepath-=~/vimfiles/after
set runtimepath-=~/.vim
set runtimepath-=~/.vim/after