     return self.server
       .run(as: self.localServerName)
       .andThen(Completable.create { completable in
+        self.runLocalServerAndNvimCompletable = completable
         self.launchNvimUsingLoginShell()
-
-        let deadline = Date().addingTimeInterval(timeout)
-        self.nvimReadyCondition.lock()
-        defer { self.nvimReadyCondition.unlock() }
-        while !self.isNvimReady && self.nvimReadyCondition.wait(until: deadline) {}
-
-        if self.isNvimReady {
-          self.streamSubject.onNext(.ready)
-          if self.isInitErrorPresent {
-            self.streamSubject.onNext(.initVimError)
-          }
-          completable(.completed)
-        } else {
-          self.streamSubject.onError(Error.launchNvim)
-          completable(.error(Error.launchNvim))
-        }
 
         return Disposables.create()
       })
+      .timeout(timeout, scheduler: self.scheduler)
   }
 
   func vimInput(_ str: String) -> Completable {

  private var nvimServerProc: Process?

  private var isNvimReady = false
  private let nvimReadyCondition = NSCondition()
  private var isInitErrorPresent = false

  private var initialWidth = 40
  private var initialHeight = 20

  private let streamSubject = PublishSubject<Message>()
  private let disposeBag = DisposeBag()

        .disposed(by: self.disposeBag)

    case .nvimReady:
      self.isNvimReady = true

      self.runLocalServerAndNvimCompletable?(.completed)
      self.runLocalServerAndNvimCompletable = nil

      self.streamSubject.onNext(.ready)

      let isInitErrorPresent = data?.asArray(ofType: Bool.self, count: 1)?[0] ?? false
      if isInitErrorPresent {
        self.streamSubject.onNext(.initVimError)
      }

    case .resize:
