tabby icon indicating copy to clipboard operation
tabby copied to clipboard

Emacs Plugin

Open hhamud opened this issue 1 year ago • 21 comments

Just a way to use this in emacs


Please reply with a 👍 if you want this feature.

hhamud avatar Oct 18 '23 15:10 hhamud

I've written some basic Emacs support for Tabby: https://github.com/ragnard/tabby-mode

ragnard avatar Dec 25 '23 13:12 ragnard

Hi, everyone. I just create an Emacs plugin for Tabby. https://github.com/alan-w-255/tabby.el

It supports inline preview and auto completion.

alan-w-255 avatar Jan 16 '24 02:01 alan-w-255

@alan-w-255 looks cool, will try it out. Could you add a LICENSE to that repo please? Thanks!

paralin avatar Jan 16 '24 02:01 paralin

@alan-w-255 looks cool, will try it out. Could you add a LICENSE to that repo please? Thanks!

License added.

alan-w-255 avatar Jan 16 '24 02:01 alan-w-255

@alan-w-255 I noticed you have a lot of .wasm blobs as well as this minified js: https://github.com/alan-w-255/tabby.el/blob/master/node_scripts/tabby-agent.js

What is the rationale behind this, and can you post the source files for these? Or somehow make it possible to reproduce those files? A bit miffed about running a blob of js without being able to see the sources. Thanks!

paralin avatar Jan 16 '24 02:01 paralin

@alan-w-255 I noticed you have a lot of .wasm blobs as well as this minified js: https://github.com/alan-w-255/tabby.el/blob/master/node_scripts/tabby-agent.js

What is the rationale behind this, and can you post the source files for these? Or somehow make it possible to reproduce those files? A bit miffed about running a blob of js without being able to see the sources. Thanks!

I just copied from here

https://github.com/TabbyML/tabby/tree/main/clients%2Fvim%2Fnode_scripts

alan-w-255 avatar Jan 16 '24 03:01 alan-w-255

Hi, all Emacs users! Thank you for your contributions.

We are planning to release the tabby-agent with LSP support. This will give you an option to easily run it as a language server with minimal effort. By connecting Emacs to Tabby using a language client provided by lsp-mode, we can display suggestions from Tabby in a widely used code completion list interface. You may have noticed that inline completion provides a better experience for showing long, multi-line completions from the AI assistant. We are also excited about the upcoming textDocument/inlineCompletion protocol in LSP version 3.18.

Stay tuned for more updates!

icycodes avatar Jan 17 '24 08:01 icycodes

Hi, all Emacs users! Thank you for your contributions.

We are planning to release the tabby-agent with LSP support. This will give you an option to easily run it as a language server with minimal effort. By connecting Emacs to Tabby using a language client provided by lsp-mode, we can display suggestions from Tabby in a widely used code completion list interface. You may have noticed that inline completion provides a better experience for showing long, multi-line completions from the AI assistant. We are also excited about the upcoming textDocument/inlineCompletion protocol in LSP version 3.18.

Stay tuned for more updates!

Thank you for the update. Would this work with a tabby server on top of custom local LLM model?

Also, is there a way to consume the unreleased version (from source) to try this out for early testing?

Arun

sundaraa-deshaw avatar Jan 17 '24 13:01 sundaraa-deshaw

Thank you for the update. Would this work with a tabby server on top of custom local LLM model?

This improvement is purely client side - you can always use a custom local LLM model with tabby :)

wsxiaoys avatar Jan 17 '24 16:01 wsxiaoys

Also, is there a way to consume the unreleased version (from source) to try this out for early testing?

Hi @sundaraa-deshaw, you can check out tabby-agent directory and build it locally.

icycodes avatar Jan 18 '24 02:01 icycodes

Hi @sundaraa-deshaw, you can check out tabby-agent directory and build it locally.

Thank you. A dumb question. If we run the agent as a language server, using the npm exec tabby-agent command, curious how the emacs client (the LSP client in this case) knows how to connect to the LSP server? Also, does this work with eglot besides lsp-package. I tried adding the configuration to the emacs config but I could not get this working. It will be great if you can point me to any instructions on how to use this.

sundaraa-deshaw avatar Jan 19 '24 04:01 sundaraa-deshaw

To anyone that's joining this conversation a bit late,

@ragnard 's plugin is idiomatic, no extra dependencies and already upstreamed into MELPA. I'll help add missing functionality and polish so that it's usable. I have not managed to install @alan-w-255 's plugin yet, but I would suggest we combine our efforts and create one plugin, instead of fragmenting.

@sundaraa-deshaw On that note, if you are serious about targetting Emacs via LSP, I would strongly encourage you to target eglot instead, given that it is the official (and built-in) language server.

appetrosyan avatar Jan 20 '24 13:01 appetrosyan

With eglot we can use only one lsp server per file. So we can't use tabby and, for example, gopls in go file with eglot. And that's why I prefer to use dedicated tabby integration with emacs.

s-kostyaev avatar Jan 20 '24 14:01 s-kostyaev

I agree that it would be good combine efforts, if we have similar goals and scope. Happy to continue that discussion as issues in tabby-mode, and I'm happy to accept contributions. In genereal, I'd like to keep it lightweight, and use builtins as far as possible. If require something else (for example completion previews), I'd prefer it to be an optional add-on rather than a fundamental dependency.

As for completion previews, support is coming (https://eshelyaron.com/posts/2023-11-17-completion-preview-in-emacs.html) in next Emacs, so personally I will probably wait for that.

ragnard avatar Jan 20 '24 16:01 ragnard

As for completion previews, support is coming (https://eshelyaron.com/posts/2023-11-17-completion-preview-in-emacs.html) in next Emacs, so personally I will probably wait for that.

As a middle ground, knowing that the package is upstreamed, and its release is only a matter of time, we could target that already, and anticipate it becoming a built-in. Just like with use-package and `eglot.

Relating to minimalism, I'm fully behind this approach. My main issue with the current state is that the user is given feedback from the underlying libraries, and therefore can't tell what's going on. For example, it says connecting to localhost:8080 instead of connecting to tabby; it doesn't tell you if the request timed out, you can only tell that something's wrong based on nothing happening.

If we can address those, make sure that the package is small, but well-documented and well-organised, I think it'd be just the thing for most configs.

appetrosyan avatar Jan 20 '24 23:01 appetrosyan

Bump :) Has anyone gotten this to work?

RomeoV avatar May 09 '24 20:05 RomeoV

We didn’t manage to collaborate, I’m writing my own

appetrosyan avatar May 09 '24 20:05 appetrosyan

We've got this working tabby+emacs setup at https://jolibrain.com office, here is our config.

Server

Tabby server is started on a gpu machine, with docker-compose and can be configured by modifying the associated .env file.

docker-compose.yml :

services:
  tabby:
    container_name: tabby_deepseek
    runtime: nvidia
    restart: always
    image: tabbyml/tabby
    command: serve --device cuda --model ${TABBY_MODEL}
    volumes:
      - ${TABBY_VOLUME}:/data
    ports:
      - ${TABBY_BIND_IP}:${TABBY_BIND_PORT}:8080
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              device_ids: ['${TABBY_DEVICE_IDS}']
              capabilities: [gpu]

All configuration variables must be modified in .env file:

TABBY_MODEL=DeepseekCoder-6.7B
TABBY_VOLUME=/data/alx/tabby
TABBY_BIND_IP=GPU_SERVER_EXTERNAL_IP
TABBY_BIND_PORT=18088
TABBY_DEVICE_IDS=1

Client

mkdir -p $HOME/.tabby-client/agent/
cat <<EOF> $HOME/.tabby-client/agent/config.toml
[server]
endpoint = "http://GPU_SERVER_IP_EXTERNAL:18088"

[anonymousUsageTracking]
disable = true
EOF

GPU_SERVER_IP_EXTERNAL:18088 endpoint has to be the same as the one specified inside .env from the server-side docker-compose.yml.

Emacs

Usage:

  • M-x tabby-complete to start completion

early-init.el

;; Disable package.el in favor of straight.el
(setq package-enable-at-startup nil)

init.el

;; Install straight.el
(defvar bootstrap-version)
(let ((bootstrap-file
            (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
            (bootstrap-version 6))
(unless (file-exists-p bootstrap-file)
      (with-current-buffer
          (url-retrieve-synchronously
            "https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el"
                  'silent 'inhibit-cookies)
                (goto-char (point-max))
                      (eval-print-last-sexp)))
  (load bootstrap-file nil 'nomessage))

;; Install tabby.el packages
(straight-use-package 'use-package)
(use-package tabby
          :straight (tabby
                      :type git
                      :host github
                      :files ("*.el" "node_scripts")
                      :repo "alan-w-255/tabby.el")
          :hook (prog-mode . tabby-mode)
          :init
            (setq tabby-idle-delay -1.5)
            (setq tabby--connection "http://GPU_SERVER_IP_EXTERNAL:18088"))

Doom Emacs

Usage:

  • C-f to validate proposed completion.

packages.el

(package! tabby
  :recipe (:host github :files ("*.el" "node_scripts")
                    :repo "alan-w-255/tabby.el"))

config.el

(defvar my-C-f-funcs '())
(defun my-C-f ()
  (interactive)
  (unless (call-interactively 'tabby-accept-completion)
    (forward-char)))

(use-package tabby
  :hook (prog-mode . tabby-mode)
  :init
  (setq tabby-idle-delay 0.5)
  (setq tabby--connection "http://GPU_SERVER_IP_EXTERNAL:18088")
  :config
  (add-to-list 'my-C-f-funcs 'tabby-accept-completion)
  ;; (evil-define-key 'insert tabby-mode-map (kbd "C-f") 'tabby-accept-completion)
  ;; (evil-define-key 'insert tabby-mode-map (kbd "C-f") 'my-C-f)
  (evil-define-key 'insert tabby-mode-map (kbd "C-f") 'my-C-f)
  (evil-define-key 'insert tabby-mode-map (kbd "C-M-j") 'tabby-dismiss)
  (evil-define-key 'insert tabby-mode-map (kbd "C-M-l") 'tabby-accept-completion-by-line))

edit: use alan-w-255/tabby.el

alx avatar May 13 '24 07:05 alx

@alx why not upstream https://github.com/alan-w-255/tabby.el ? Your fix already merged.

s-kostyaev avatar May 13 '24 09:05 s-kostyaev

thanks @s-kostyaev , comment has been updated with correct alan-w-255/tabby.el repo

alx avatar May 13 '24 09:05 alx