Skip to content

Instantly share code, notes, and snippets.

@nimeshneema
Created April 30, 2026 17:31
Show Gist options
  • Select an option

  • Save nimeshneema/5ea958eee6897d39ea4718b497d90a6f to your computer and use it in GitHub Desktop.

Select an option

Save nimeshneema/5ea958eee6897d39ea4718b497d90a6f to your computer and use it in GitHub Desktop.
(define-key global-map [f1] 'find-file)
(define-key global-map [f2] 'save-buffer)
(define-key global-map [f3] 'revert-buffer)
(define-key global-map [f4] 'buffer-menu)
(define-key esc-map [f1] 'view-file)
(define-key esc-map [f2] 'save-all-buffers)
(define-key esc-map [f3] 'kill-current-buffer)
(define-key esc-map [f4] 'goto-line)
(define-key global-map [f5] 'save-compile)
(define-key global-map [f6] 'isearch-forward)
(define-key global-map [f7] 'kill-region) ; cut
(define-key global-map [f8] 'fill-paragraph)
(define-key esc-map [f5] 'set-compile-command)
(define-key esc-map [f6] 'query-replace)
(define-key esc-map [f7] 'kill-ring-save) ; copy
(define-key esc-map [f8] 'yank) ; paste
(define-key global-map [f9] 'delete-other-windows)
(define-key global-map [f10] 'split-window-vertically)
(define-key global-map [f11] 'showvar)
(define-key global-map [f12] 'show-keymap)
(define-key esc-map [f9] 'shell)
(define-key esc-map [f10] 'split-window-horizontally)
(define-key esc-map [f11] 'spell-word)
(define-key esc-map [f12] 'load-emacs-file)
(global-set-key [(button4)] '(lambda()(interactive)(scroll-down 1)))
(global-set-key [(button5)] '(lambda()(interactive)(scroll-up 1)))
(global-set-key "\t" 'tab-to-tab-stop) ; "normal" tab key
(setq tab-stop-list '(2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 36))
(setq-default indent-tabs-mode nil)
(setq-default standard-indent 2)
(setq-default tab-width 2)
;;; init.el --- Russ P. — Scala IDE Configuration -*- lexical-binding: t; -*-
;;;
;;; Merged config: Russ's personal preferences + full Metals/LSP stack
;;; Emacs 30.x + lsp-mode + Metals (official recommendation)
;;; ------------------------------------------------------------------
;;; 1. PACKAGE MANAGEMENT
;;; ------------------------------------------------------------------
(require 'package)
(setq package-archives '(("melpa" . "https://melpa.org/packages/")
("melpa-stable" . "https://stable.melpa.org/packages/")
("gnu" . "https://elpa.gnu.org/packages/")))
(package-initialize)
;; Refresh package list on first run
(unless package-archive-contents
(package-refresh-contents))
;; Install and configure use-package
(unless (package-installed-p 'use-package)
(package-install 'use-package))
(require 'use-package)
(setq use-package-always-ensure t)
;;; ------------------------------------------------------------------
;;; 2. BASIC EDITOR SETTINGS & VISUALS
;;; ------------------------------------------------------------------
(setq inhibit-startup-message t)
(global-display-line-numbers-mode)
(column-number-mode 1)
(show-paren-mode 1)
;; Spaces, not tabs
(setq-default indent-tabs-mode nil)
(setq-default tab-width 2)
;; Disable backup files entirely (Russ's preference)
(setq make-backup-files nil)
;; Redirect auto-save files to /tmp so they don't land in project dirs
;; (Metals is sensitive to stray files in the project tree)
(setq auto-save-file-name-transforms `((".*" ,temporary-file-directory t)))
;; which-key: built into Emacs 30, shows available keybindings after a prefix
(which-key-mode 1)
;; Smoother scrolling
(setq scroll-margin 3)
(setq scroll-conservatively 101)
;; THEME
(use-package doom-themes
:config
(load-theme 'doom-one t))
;;; ------------------------------------------------------------------
;;; 3. PERFORMANCE TUNING FOR LSP
;;; ------------------------------------------------------------------
;; Critical for Metals on large projects. Without these, the editor lags.
;; Increase GC threshold to 100MB (default 800KB causes constant pauses)
(setq gc-cons-threshold 100000000)
;; Increase process read size to 1MB (default 4KB too small for LSP JSON)
(setq read-process-output-max (* 1024 1024))
;;; ------------------------------------------------------------------
;;; 3.5 ENVIRONMENT PATHS (Coursier / SBT)
;;; ------------------------------------------------------------------
;; Expand the path to resolve the '~' to your actual home directory
(let ((coursier-path (expand-file-name "~/.local/share/coursier/bin")))
;; 1. Add to Emacs's internal executable path (so Emacs can find 'cs' and 'sbt')
(add-to-list 'exec-path coursier-path)
;; 2. Add to Emacs's environment PATH (so child processes launched by Emacs can find them)
(setenv "PATH" (concat coursier-path ":" (getenv "PATH"))))
;;; ------------------------------------------------------------------
;;; 4. SCALA LSP SETUP (Metals Integration)
;;; ------------------------------------------------------------------
;; SCALA-MODE: Syntax highlighting, indentation, motion commands
(use-package scala-mode
:interpreter ("scala" . scala-mode)
:mode "\\.s\\(cala\\|bt\\)$")
;; SBT-MODE: Interaction with the build tool from within Emacs
(use-package sbt-mode
:commands sbt-start sbt-command
:config
;; WORKAROUND: allow SPACE in sbt minibuffer prompts
;; Without this, space triggers completion instead of inserting a space
(substitute-key-definition
'minibuffer-complete-word
'self-insert-command
minibuffer-local-completion-map)
;; Disable sbt supershell (it breaks sbt-mode output parsing)
(setq sbt:program-options '("-Dsbt.supershell=false")))
;; FLYCHECK: Real-time error highlighting (red squiggly lines / diagnostics)
(use-package flycheck
:init (global-flycheck-mode))
;; COMPANY: Auto-completion framework (method/function popups)
(use-package company
:hook (scala-mode . company-mode)
:config
(setq company-minimum-prefix-length 1)
(setq company-idle-delay 0.0)
;; Use completion-at-point as the backend (required for lsp-mode integration)
(setq lsp-completion-provider :capf))
;; YASNIPPET: Code snippet expansion (lsp-mode uses it for template completions)
(use-package yasnippet
:hook (scala-mode . yas-minor-mode))
;; POSFRAME: Pop-up framework (required by dap-mode for debugging UI)
(use-package posframe)
;; LSP-MODE: The core Language Server Client
(use-package lsp-mode
:hook
;; Activate LSP when opening a Scala file
(scala-mode . lsp)
;; Enable code lenses (shows implicit params, test run buttons, etc.)
(lsp-mode . lsp-lens-mode)
:init
;; Set prefix for LSP commands (Russ's preference)
(setq lsp-keymap-prefix "C-c l")
:config
;; Use flycheck for diagnostics, not flymake
(setq lsp-prefer-flymake nil)
;; Shut down Metals when all project buffers are closed
(setq lsp-keep-workspace-alive nil)
;; Show breadcrumb navigation (current scope in header line)
(setq lsp-headerline-breadcrumb-enable t)
;; Enable semantic tokens for richer syntax highlighting
(setq lsp-semantic-tokens-enable t)
;; Reduce logging for performance (set to t for debugging)
(setq lsp-log-io nil)
:commands lsp)
;; LSP-METALS: Scala-specific extensions for lsp-mode
(use-package lsp-metals
:ensure t
:custom
;; Server JVM options
(lsp-metals-server-args '(
;; Disable multiline string formatting so scala-mode handles indentation
"-J-Dmetals.allow-multiline-string-formatting=off"
;; Enable unicode icons
"-J-Dmetals.icons=unicode"))
;; Enable semantic highlighting
(lsp-metals-enable-semantic-highlighting t)
:config
;; Explicit path to the Metals binary installed by Coursier
(setq lsp-metals-server-path "~/.local/share/coursier/bin/metals")
;; Show tree view when available
(setq lsp-metals-treeview-show-when-views-received t)
:hook (scala-mode . lsp))
;; LSP-UI: Popups for documentation, inline errors, peek definitions
(use-package lsp-ui
:after lsp-mode
:config
;; Show documentation on hover
(setq lsp-ui-doc-enable t)
(setq lsp-ui-doc-position 'top)
;; Show errors/warnings inline next to the code
(setq lsp-ui-sideline-enable t)
(setq lsp-ui-sideline-show-code-actions t)
(setq lsp-ui-sideline-show-hover nil)
;; Enable peek for references/definitions (M-x lsp-ui-peek-find-references)
(setq lsp-ui-peek-enable t))
;; DAP-MODE: Debugging support (Debug Adapter Protocol)
(use-package dap-mode
:hook
(lsp-mode . dap-mode)
(lsp-mode . dap-ui-mode))
;;; ------------------------------------------------------------------
;;; 5. SCALA KEYBINDINGS
;;; ------------------------------------------------------------------
;; Note: With lsp-keymap-prefix set to "C-c l", all standard LSP commands
;; are available under C-c l (e.g., C-c l g g = go to definition).
;; The bindings below provide additional direct shortcuts for Scala work.
(with-eval-after-load 'scala-mode
(define-key scala-mode-map (kbd "C-c C-t") 'lsp-describe-thing-at-point) ;; Show type info
(define-key scala-mode-map (kbd "C-c C-d") 'lsp-ui-doc-show) ;; Show docs popup
(define-key scala-mode-map (kbd "C-c C-r") 'lsp-rename) ;; Rename symbol
(define-key scala-mode-map (kbd "C-c C-a") 'lsp-execute-code-action) ;; Code actions
(define-key scala-mode-map (kbd "C-c C-f") 'lsp-format-buffer) ;; Format buffer
(define-key scala-mode-map (kbd "C-c C-o") 'lsp-organize-imports) ;; Organize imports
(define-key scala-mode-map (kbd "C-c C-b") 'lsp-metals-build-import)) ;; Import build
;;; ------------------------------------------------------------------
;;; 6. CUSTOM COLOR OVERRIDES
;;; ------------------------------------------------------------------
;; Russ's preferred syntax highlighting colors
(custom-set-faces
;; custom-set-faces was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
'(font-lock-function-name-face ((t (:foreground "red"))))
'(font-lock-keyword-face ((t (:foreground "yellow")))))
;;; ------------------------------------------------------------------
(provide 'init)
;;; init.el ends here
(custom-set-variables
;; custom-set-variables was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
'(package-selected-packages nil))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment