diff --git a/config.org b/config.org index f7711ee..d2a8197 100644 --- a/config.org +++ b/config.org @@ -732,15 +732,15 @@ Install the package, enable it and ensure that it always is installed, and then **** Company Base Company is a text completion framework for Emacs. The name stands for "complete anything". It uses pluggable back-ends and front-ends to retrieve and display completion candidates. Install the package, enable it and ensure that it always is installed, and then make sure that company-mode is enabled by default: -#+BEGIN_SRC emacs-lisp ++BEGIN_SRC emacs-lisp (use-package company :ensure t :init (global-company-mode)) -#+END_SRC ++END_SRC ***** Configuration -#+BEGIN_SRC emacs-lisp ++BEGIN_SRC emacs-lisp ; No delay in showing suggestions. (setq company-idle-delay 0) @@ -767,23 +767,23 @@ Install the package, enable it and ensure that it always is installed, and then ; ('tng' means 'tab and go') (company-tng-configure-default) -#+END_SRC ++END_SRC **** Company Quickhelp Company Quickhelp is an extension to company which introduces documentation popups that appears when idling on a company completion candidate. Install the package, enable it and ensure that it always is installed, and then make sure that company-quickhelp-mode is enabled by default: -#+BEGIN_SRC emacs-lisp ++BEGIN_SRC emacs-lisp (use-package company-quickhelp :ensure t :init (company-quickhelp-mode)) -#+END_SRC ++END_SRC **** Company Box Company Box Mode is a mode that gives Company menu options icons. -#+BEGIN_SRC emacs-lisp ++BEGIN_SRC emacs-lisp (use-package company-box :ensure t :hook (company-mode . company-box-mode)) -#+END_SRC ++END_SRC ** Multiple Cursors The Multiple Cursors package is pretty self explanatory, you can select and manipulate multiple lines of the same text at the same time, move the cursors in unison. Etc. Install the package, enable it and ensure that it always is installed, and then bind the useful functions to a mnenomic key chord: @@ -978,7 +978,7 @@ Flycheck is a modern version of Flymake, provides error messages *** Eglot Mode Emacs Polyglot is the Emacs LSP client that stays out of your way, built into emacs. -#+BEGIN_SRC emacs-lisp ++BEGIN_SRC emacs-lisp ;;(with-eval-after-load 'eglot ;; (add-to-list 'eglot-server-programs '(swift-mode . ("/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/sourcekit-lsp"))) ;; ) @@ -995,7 +995,7 @@ Emacs Polyglot is the Emacs LSP client that stays out of your way, built into em (global-flycheck-eglot-mode 1)) (add-hook 'prog-mode-hook 'eglot-ensure) -#+END_SRC ++END_SRC *** LSP Mode LSP mode will give you IDE capabilities in Emacs, using Microsoft's Universal Language Server Protocol. The same one that VSCode uses for @@ -1007,17 +1007,27 @@ the custom prefix. Please check on how to install the Programming Language Servers that you want. **** Lsp Mode +BEGIN_SRC emacs-lisp + ;; For some reason this logging variable being set SOMETIMES fixes LSP not working over TRAMP. https://github.com/emacs-lsp/lsp-mode/issues/2709 + (setq *lsp-log-io* t) + (setq lsp-log-io t) + + + + (use-package lsp-mode :ensure t :hook (;; replace XXX-mode with concrete major-mode(e. g. python-mode) (prog-mode . lsp) ;; if you want which-key integration (lsp-mode . lsp-enable-which-key-integration)) + :config + (setq *lsp-log-io* t) + (setq lsp-log-io t) :commands lsp) ;; set prefix for lsp-command-keymap (few alternatives - "C-l", "C-c l") (setq lsp-keymap-prefix "C-l") -+END_SRC +#+END_SRC **** Configuration +BEGIN_SRC emacs-lisp @@ -1048,6 +1058,47 @@ on how to install the Programming Language Servers that you want. (with-eval-after-load 'lsp-mode (defun return-true () t) + + ;; Connect to LSP via SSH port forwarding instead + (defun lsp-tramp-connection-over-ssh-port-forwarding (command) + "Like lsp-tcp-connection, but uses SSH portforwarding." + (print command) + (list + :connect (lambda (filter sentinel name environment-fn _workspace) + (let* ((host "localhost") + (lsp-port (lsp--find-available-port host (cl-incf lsp--tcp-port))) + (command (with-parsed-tramp-file-name buffer-file-name nil + (message "[tcp/ssh hack] running LSP %s on %s / %s" command host localname) + (let* ((unix-socket (format "/tmp/lsp-ssh-portforward-%s.sock" lsp-port)) + (command (list + "ssh" + ;; "-vvv" + "-L" (format "%s:%s" lsp-port unix-socket) + host + "socat" + (format "unix-listen:%s" unix-socket) + (format "system:'\"cd %s && %s\"'" (file-name-directory localname) command) + ))) + (message "using local command %s" command) + command))) + (final-command (if (consp command) command (list command))) + (_ (unless (executable-find (cl-first final-command)) + (user-error (format "Couldn't find executable %s" (cl-first final-command))))) + (process-environment + (lsp--compute-process-environment environment-fn)) + (proc (make-process :name name :connection-type 'pipe :coding 'no-conversion + :command final-command :sentinel sentinel :stderr (format "*%s::stderr*" name) :noquery t)) + (tcp-proc (progn + (sleep-for 1) ; prevent a connection before SSH has run socat. Ugh. + (lsp--open-network-stream host lsp-port (concat name "::tcp"))))) + + ;; TODO: Same :noquery issue (see above) + (set-process-query-on-exit-flag proc nil) + (set-process-query-on-exit-flag tcp-proc nil) + (set-process-filter tcp-proc filter) + (cons tcp-proc proc))) + :test? (lambda () t))) + (add-to-list 'lsp-language-id-configuration '(lua-mode . "luau")) @@ -1056,14 +1107,56 @@ on how to install the Programming Language Servers that you want. :activation-fn (lsp-activate-on "luau") :server-id 'luau-lsp)) + ;;(lsp-register-client + ;; (make-lsp-client :new-connection (lsp-tramp-connection "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/sourcekit-lsp" 'return-true) + ;; :major-modes '(swift-mode) + ;; :remote? t + ;; :server-id 'sourcekit-lsp-tramp)) (lsp-register-client - (make-lsp-client :new-connection (lsp-tramp-connection "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/sourcekit-lsp" 'return-true) + (make-lsp-client :new-connection (lsp-tramp-connection-over-ssh-port-forwarding "sourcekit-lsp") :major-modes '(swift-mode) :remote? t - :server-id 'sourcekit-lsp-tramp)) + :server-id 'sourcekit-lsp-ssh-forward)) + + (lsp-register-client + (make-lsp-client :new-connection (lsp-tramp-connection-over-ssh-port-forwarding "bash-language-server") + :major-modes '(shell-mode) + ;;:initialization-options '((omitInitBuild . t) + ;; (cmdRun . t)) + :remote? t + :server-id 'bash-language-ssh-forward)) + ) +END_SRC +*** LSP Bridge +LSP Bridge is meant to be a super fast LSP integration. + +#+BEGIN_SRC emacs-lisp + (use-package lsp-bridge + :straight '(lsp-bridge :type git :host github :repo "manateelazycat/lsp-bridge" + :files (:defaults "*.el" "*.py" "acm" "core" "langserver" "multiserver" "resources") + :build (:not compile)) + :init + ;; Automatically start the lsp_bridge.py process on the remote host (which needs to support bash) when opening a tramp file + (setq lsp-bridge-enable-log t) + (setq lsp-bridge-enable-with-tramp t) + ;;(setq lsp-bridge-remote-start-automatically t) + ;;(setq lsp-bridge-remote-python-command "~/usr/bin/python3") + ;;(setq lsp-bridge-remote-python-file "~/.emacs.d/straight/repos/lsp-bridge/lsp_bridge.py") + (setq lsp-bridge-remote-log "~/.emacs.d/lbr_log.txt") + + (setq acm-enable-capf t) + (setq acm-enable-icon t) + (setq acm-enable-lsp-workspace-symbol t) + (setq acm-backend-search-file-words-enable-fuzzy-match t) + (setq acm-enable-yas t) + (setq lsp-bridge-enable-org-babel t) + (setq acm-enable-doc-markdown-render 'async) + + (global-lsp-bridge-mode) + ) +#+END_SRC ** Edwina Dynamic Tiling Edwina is a dynamic window manager for Emacs. It automatically arranges your Emacs panes (called “windows” in Emacs parlance) into predefined layouts, dwm-style. @@ -1290,6 +1383,30 @@ Allows you to edit files as root via running sudo-edit :ensure t) #+END_SRC ** Eshell +*** Bash-like Completion +#+BEGIN_SRC emacs-lisp + (add-hook + 'eshell-mode-hook + (lambda () + (setq pcomplete-cycle-completions nil))) + + (setq eshell-cmpl-cycle-completions nil) + + (use-package bash-completion + :ensure t + :init + (autoload 'bash-completion-dynamic-complete + "bash-completion" + "BASH completion hook") + (add-hook 'shell-dynamic-complete-functions + 'bash-completion-dynamic-complete) + (add-hook 'eshell-mode-hook + (lambda () + (add-hook 'completion-at-point-functions + 'bash-completion-capf-nonexclusive nil t))) + + ) +#+END_SRC *** Zoxide Zoxide Z like functionality, better cd inside eshell #+BEGIN_SRC emacs-lisp @@ -1310,5 +1427,10 @@ Set the default shell used to run commands. ** TRAMP TRAMP edit files over SSH configuration #+BEGIN_SRC emacs-lisp - (setopt tramp-remote-path '(tramp-own-remote-path)) + (use-package tramp + :ensure t + :config + (add-to-list 'tramp-remote-path 'tramp-own-remote-path) + (when (eq window-system 'w32) + (setq tramp-default-method "plink"))) #+END_SRC diff --git a/init.el b/init.el index dca3e7f..cc6b296 100644 --- a/init.el +++ b/init.el @@ -10,6 +10,20 @@ ;; Packages +;; Straight.el +(defvar bootstrap-version) +(let ((bootstrap-file + (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory)) + (bootstrap-version 5)) + (unless (file-exists-p bootstrap-file) + (with-current-buffer + (url-retrieve-synchronously + "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el" + 'silent 'inhibit-cookies) + (goto-char (point-max)) + (eval-print-last-sexp))) + (load bootstrap-file nil 'nomessage)) + ;; Use-Package (unless (package-installed-p 'use-package)