Skip to content

Latest commit

 

History

History
175 lines (150 loc) · 7.1 KB

vimilla-emacs.org_archive

File metadata and controls

175 lines (150 loc) · 7.1 KB

Archived entries from file Users/jasonzhen.emacs.d/vimilla-emacs.org

eglot booster

https://gist.github.com/jdtsmith/d936801a4d7fd981bedf2e59dacd675e

(use-package eglot :defer t
  :config
  (require 'eglot)
  (require 'jsonrpc)
  (eval-when-compile (require 'cl-lib))

  (defun eglot-booster-plain-command (com)
    "Test if command COM is a plain eglot server command."
    (and (consp com)
         (not (integerp (cadr com)))
         (not (seq-intersection '(:initializationOptions :autoport) com))))

  (defun eglot-booster ()
    "Boost plain eglot server programs with emacs-lsp-booster.
  The emacs-lsp-booster program must be compiled and available on
  variable `exec-path'.  Only local stdin/out based lsp servers can
  be boosted."
    (interactive)
    (unless (executable-find "emacs-lsp-booster")
      (user-error "The emacs-lsp-booster program is not installed"))
    (if (get 'eglot-server-programs 'lsp-booster-p)
        (message "eglot-server-programs already boosted.")
      (let ((cnt 0)
            (orig-read (symbol-function 'jsonrpc--json-read)))
        (dolist (entry eglot-server-programs)
          (cond
           ((functionp (cdr entry))
            (cl-incf cnt)
            (let ((fun (cdr entry)))
              (setcdr entry (lambda (&rest r) ; wrap function
                              (let ((res (apply fun r)))
                                (if (eglot-booster-plain-command res)
                                    (cons "emacs-lsp-booster" res)
                                  res))))))
           ((eglot-booster-plain-command (cdr entry))
            (cl-incf cnt)
            (setcdr entry (cons "emacs-lsp-booster" (cdr entry))))))
        (defalias 'jsonrpc--json-read
          (lambda ()
            (or (and (= (following-char) ?#)
                     (let ((bytecode (read (current-buffer))))
                       (when (byte-code-function-p bytecode)
                         (funcall bytecode))))
                (funcall orig-read))))
        (message "Boosted %d eglot-server-programs" cnt))
      (put 'eglot-server-programs 'lsp-booster-p t)))
  ;; need to run it on eglot load
  (eglot-booster))

incremental project search

Acts like occur, deferring a lot of the work to the existing xref buffer functionality good enough without getting too complicated

don’t actually run it until we have at least 5 chars to prevent initial lag

then with prefix arg we basically do the normal project-find-regexp but we can specify the directory

(defun my/iproject-find-minibuf-after-edit (beg end len)
  (setq my/iproject-find-string (buffer-substring-no-properties (1+ (length my/iproject-find-prompt-string)) (point-max)))
  (when (gt (length (string-replace ".*" "" my/iproject-find-string)) 2)
    (cl-letf (((symbol-function 'pop-to-buffer) (lambda (buf &optional _ _) (display-buffer buf))))
      (ignore-errors (project-find-regexp my/iproject-find-string)))))

(setq my/iproject-find-prompt-string "Find in proj: ")
(setq my/iproject-find-string "")

(defun my/iproject-find (arg)
  "Run a pseudo interactive grep, which will incrementally update the xref buffer based on minibuffer input.
With a prefix-arg run normally and specfiy a directory"
  (interactive "P")
  (setq my/iproject-find-string "")
  (if arg
      (let ((current-prefix-arg '(4)))
        (call-interactively #'project-find-regexp))
    (let ((xref-show-xrefs-function #'xref--show-xref-buffer)
          (starting-regexp (read-regexp "start searching with: ")))
      (setq my/iproject-find-string starting-regexp)
      (minibuffer-with-setup-hook
          (lambda ()
            (local-set-key (kbd "SPC") (lambda () (interactive) (insert ".*")))
            (add-hook 'after-change-functions #'my/iproject-find-minibuf-after-edit nil 'local)
            (insert starting-regexp))
        (project-find-regexp (read-regexp my/iproject-find-prompt-string))))))

incremental xref-find-apropos

(defun my/ixref-apropos-minibuf-after-edit (beg end len)
  (setq my/ixref-apropos-string (buffer-substring-no-properties (1+ (length my/ixref-apropos-prompt-string)) (point-max)))
  (setq xref-find-apropos-prev my/ixref-apropos-string)
  (when (gt (length (string-replace ".*" "" my/ixref-apropos-string)) 2)
    (cl-letf (((symbol-function 'pop-to-buffer) (lambda (buf &optional _ _) (display-buffer buf))))
      (with-current-buffer current-xref-buffer (ignore-errors (xref-find-apropos my/ixref-apropos-string))))))

(setq my/ixref-apropos-prompt-string "Find symbol apropos: ")
(setq my/ixref-apropos-string "")

(defun my/ixref-apropos (arg)
  "Run a pseudo interactive grep, which will incrementally update the xref buffer based on minibuffer input.
With a prefix-arg run normally and specfiy a directory"
  (interactive "P")
  (setq my/ixref-apropos-string "")
  ;; this is needed, otherwise xref-apropos in the minibuf-after-edit fn will try to find the xref-backend using the minibuffer instead of the
  ;; a buffer belonging to the project we care about
  (setq current-xref-buffer (current-buffer))
  (if arg
      (let ((current-prefix-arg '(4)))
        (call-interactively #'xref-find-apropos))
    (let ((xref-show-xrefs-function #'xref--show-xref-buffer)
          (starting-regexp (read-regexp "start searching symbols with: ")))
      (setq my/ixref-apropos-string starting-regexp)
      (setq xref-find-apropos-prev starting-regexp)
      (minibuffer-with-setup-hook
          (lambda ()
            (local-set-key (kbd "SPC") (lambda () (interactive) (insert " ")))
            (add-hook 'after-change-functions #'my/ixref-apropos-minibuf-after-edit nil 'local)
            (insert starting-regexp))
        (xref-find-apropos (read-regexp my/ixref-apropos-prompt-string))))))

better tab completion

https://emacs.stackexchange.com/questions/8261/how-to-determine-if-the-current-character-is-a-letter simple dwim heuristic to check if the char before the cursor is a char which means we probably want to complete a symbol

Po is for “.”

(advice-add 'indent-for-tab-command
            :after (lambda (&optional arg)
                     (when (memq (get-char-code-property (char-before) 'general-category)
                                   '(Po Ll Lu Lo Lt Lm Mn Mc Me Nl))
                       (complete-symbol arg))))