Function: claude-code-ide-mcp-handle-close-tab

claude-code-ide-mcp-handle-close-tab is a natively compiled function defined in claude-code-ide-mcp-handlers.el.

Signature

(claude-code-ide-mcp-handle-close-tab ARGUMENTS &optional SESSION)

Documentation

Close a tab/buffer for SESSION.

ARGUMENTS should contain path or tab_name of the file to close.

Source Code

;; Defined in /nix/store/yjvbhwl7p6zrbw9xlnni7y4hra8sa3pl-emacs-packages-deps/share/emacs/site-lisp/claude-code-ide-mcp-handlers.el
(defun claude-code-ide-mcp-handle-close-tab (arguments &optional session)
  "Close a tab/buffer for SESSION.
ARGUMENTS should contain `path' or `tab_name' of the file to close."
  (let ((path (alist-get 'path arguments))
        (tab-name (alist-get 'tab_name arguments)))
    (cond
     (path
      (let ((buffer (find-buffer-visiting path)))
        (if buffer
            (progn
              (kill-buffer buffer)
              ;; Return in VS Code format
              (list `((type . "text")
                      (text . "TAB_CLOSED"))))
          ;; Error case
          (signal 'mcp-error (list (format "No buffer visiting %s" path))))))
     (tab-name
      ;; Diff tabs are looked up only in the REQUESTING session.  Sibling
      ;; instances of the same project produce identical CLI tab names, so
      ;; a cross-session search would close the wrong instance's diff.
      (let* ((found-diff-info (and session
                                   (gethash tab-name
                                            (claude-code-ide-mcp-session-active-diffs session))))
             (found-session (and found-diff-info session)))
        (if found-diff-info
            (progn
              ;; Check if ediff is still active and quit it using stored control buffer
              (when-let* ((control-buf (alist-get 'control-buffer found-diff-info)))
                (when (buffer-live-p control-buf)
                  ;; Set a flag in diff-info to indicate this quit is from Claude
                  (setf (alist-get 'quit-from-claude found-diff-info) t)
                  ;; Store all ediff buffer references in diff-info before quitting
                  (with-current-buffer control-buf
                    (when (and (boundp 'ediff-error-buffer) ediff-error-buffer)
                      (setf (alist-get 'error-buffer found-diff-info) ediff-error-buffer))
                    (when (and (boundp 'ediff-diff-buffer) ediff-diff-buffer)
                      (setf (alist-get 'diff-buffer found-diff-info) ediff-diff-buffer))
                    (when (and (boundp 'ediff-fine-diff-buffer) ediff-fine-diff-buffer)
                      (setf (alist-get 'fine-diff-buffer found-diff-info) ediff-fine-diff-buffer))
                    (when (and (boundp 'ediff-custom-diff-buffer) ediff-custom-diff-buffer)
                      (setf (alist-get 'custom-diff-buffer found-diff-info) ediff-custom-diff-buffer)))
                  (puthash tab-name found-diff-info (claude-code-ide-mcp-session-active-diffs found-session))
                  ;; Use ediff's proper quit mechanism if available
                  (condition-case err
                      (if (fboundp 'ediff-really-quit)
                          ;; Properly quit ediff which will run our quit hooks
                          (with-current-buffer control-buf
                            (ediff-really-quit nil))
                        ;; Fallback: just kill the control buffer
                        (kill-buffer control-buf))
                    (error
                     ;; If ediff-really-quit fails (e.g., side window issues),
                     ;; just kill the control buffer directly
                     (claude-code-ide-debug "Error quitting ediff: %s. Killing control buffer directly."
                                            (error-message-string err))
                     (when (buffer-live-p control-buf)
                       (kill-buffer control-buf))))))

              ;; Clean up the diff buffers with the found session
              (claude-code-ide-mcp--cleanup-diff tab-name found-session)

              ;; Return in VS Code format
              (list `((type . "text")
                      (text . "TAB_CLOSED"))))
          ;; Not a diff - treat tab_name as buffer name
          (let ((buffer (get-buffer tab-name)))
            (if buffer
                (progn
                  (kill-buffer buffer)
                  ;; Return in VS Code format
                  (list `((type . "text")
                          (text . "TAB_CLOSED"))))
              ;; Error case - VS Code returns isError: true
              (signal 'mcp-error (list (format "No buffer named %s" tab-name))))))))
     (t
      (signal 'mcp-error '("Either 'path' or 'tab_name' must be provided"))))))