;;; .emacs --- Config ;;; Commentary: ;;; Code: ;; support local packages (add-to-list 'load-path "~/.emacs.d/site-lisp/") (require 'package) (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/")) (package-initialize) (setq package-selected-packages '(meson-mode groovy-mode gradle-mode kotlin-mode go-mode flycheck flycheck-go java-imports ido-vertical-mode rg)) ;; use (package-install-selected-packages) to install the ones above ;; show matching parentheses (and other characters) (show-paren-mode t) ;; hide toolbar (tool-bar-mode -1) ;; hide tooltips (tooltip-mode -1) (setq ;; skip startup message inhibit-startup-message t ;; show line and column number in mode-line line-number-mode t column-number-mode t ;; increase undo undo-limit 200000 undo-strong-limit 300000 ;; enable visible bell visible-bell t ;; enable font lockmode global-font-lock-mode t font-lock-mode t font-lock-maximum-decoration t) ;; Force more unique buffer names (require 'uniquify) (setq uniquify-buffer-name-style 'post-forward-angle-brackets) ;; Clean the buffer list at midnight (require 'midnight) ;; Set clean-buffer-list delay to 3 days (setq clean-buffer-list-delay-general 3) (if (not (boundp 'clean-buffer-list-kill-regexps)) (setq clean-buffer-list-kill-regexps '())) ;; Add preprocessed buffers to the list (add-to-list 'clean-buffer-list-kill-regexps '("\\`\\*.*-preprocessed\\*\\'")) (defun rename-current-buffer-file () "Renames current buffer and file it is visiting." (interactive) (let* ((name (buffer-name)) (filename (buffer-file-name)) (basename (file-name-nondirectory filename))) (if (not (and filename (file-exists-p filename))) (error "Buffer '%s' is not visiting a file!" name) (let ((new-name (read-file-name "New name: " (file-name-directory filename) basename nil basename))) (if (get-buffer new-name) (error "A buffer named '%s' already exists!" new-name) (rename-file filename new-name 1) (rename-buffer new-name) (set-visited-file-name new-name) (set-buffer-modified-p nil) (message "File '%s' successfully renamed to '%s'" name (file-name-nondirectory new-name))))))) ;; load rg (require 'rg) (setq rg-custom-type-aliases nil) (setq rg-ignore-case (quote smart)) (setq rg-ignore-ripgreprc nil) (setq ;; create backups make-backup-files t ;; don't ask to delete backup versions delete-old-versions t ;; use version control version-control t) ;; put all backup files in their own directory (let ((backup-dir "~/.emacs.d/backups/")) (make-directory backup-dir :parents) (setq backup-directory-alist `((".*" . ,backup-dir)))) ;; show buffer in frame title (setq frame-title-format "%b %* emacs") ;; frame parameters ;; frame size (add-to-list 'default-frame-alist '(width . 80)) (add-to-list 'default-frame-alist '(height . 36)) ;; tell WM that we really want those sizes (add-to-list 'default-frame-alist '(user-size . t)) ;; frame font and color (add-to-list 'default-frame-alist '(font . "-windows-proggycleancp-medium-r-normal-sans-13-80-96-96-c-70-iso8859-1")) (add-to-list 'default-frame-alist '(cursor-color . "green")) (add-to-list 'default-frame-alist '(foreground-color . "grey")) (add-to-list 'default-frame-alist '(background-color . "black")) (add-to-list 'default-frame-alist '(background-mode . "dark")) ;; Make man open in full frame instead of always creating half a frame (set-variable 'Man-notify-method (quote pushy)) ;; Toggle frame width (defun toggle-frame-width (frame) "Toggle FRAME width between 100 and 80." (when window-system (let ((width (frame-width frame))) (cond ((eq width 80) (set-frame-width frame 100)) (t (set-frame-width frame 80)))))) (defun toggle-selected-frame-width () "Toggle selected frame width between 100 and 80." (interactive) (toggle-frame-width (selected-frame))) ;; default styles (setq-default ;; no tabs in indentation indent-tabs-mode nil ;; tab-width 4 tab-width 4 ;; c-basic-offset c-basic-offset 4 ;; show trailing whitespace show-trailing-whitespace t) ;; enable c warnings (global-cwarn-mode t) ;; auto inserts (eval-after-load 'autoinsert '(define-auto-insert '("\\.\\(hh\\|hxx\\|hpp\\)\\'" . "C++ header") '((upcase (mapconcat 'identity (split-string (file-name-nondirectory buffer-file-name) "[^a-zA-Z0-9]+") "_")) "#ifndef " str \n "#define " str \n \n _ \n \n "#endif // " str \n))) (eval-after-load 'autoinsert '(define-auto-insert '("\\.\\(CC?\\|cc\\|cxx\\|cpp\\|c++\\)\\'" . "C++ source") '(nil "// -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-" \n "//" \n "// Copyright (C) 2020 Opera Norway AS. All rights reserved." \n "//" \n "// This file is an original work developed by Opera." \n \n (let ((base (file-name-sans-extension buffer-file-name))) (cond ((file-exists-p (concat base ".hh")) (concat "#include \"" (file-name-nondirectory (concat base ".hh")) "\"\n\n")))) > _ \n))) (eval-after-load 'autoinsert '(define-auto-insert '("\\.\\([Hh]\\)\\'" . "C++ header") '((upcase (mapconcat 'identity (split-string (file-name-nondirectory buffer-file-name) "[^a-zA-Z0-9]+") "_")) "// -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-" \n "//" \n "// Copyright (C) 2020 Opera Norway AS. All rights reserved." \n "//" \n "// This file is an original work developed by Opera." \n \n "#ifndef " str \n "#define " str \n \n _ \n \n "#endif // " str \n))) (eval-after-load 'autoinsert '(define-auto-insert '("\\.\\([Cc]\\)\\'" . "C source") '(nil "#include \"common.h\"" \n \n (let ((base (file-name-sans-extension buffer-file-name))) (cond ((file-exists-p (concat base ".h")) (concat "#include \"" (file-name-nondirectory (concat base ".h")) "\"\n\n")))) > _ \n))) (eval-after-load 'autoinsert '(define-auto-insert '("[Mm]akefile\\'" . "Makefile") '(nil ".PHONY: all clean" \n \n "all: " _ \n \n "clean:" \n \n))) (eval-after-load 'autoinsert '(define-auto-insert '("\\.\\(py\\)\\'" . "Python source") '(nil "#!/usr/bin/env python" \n \n _ \n))) (eval-after-load 'autoinsert '(define-auto-insert '("\\.\\(java\\)\\'" . "Java source") '((file-name-base buffer-file-name) "// -*- Mode: java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-" \n "//" \n "// Copyright (C) 2020 Opera Norway AS. All rights reserved." \n "//" \n "// This file is an original work developed by Opera." \n \n "package " (mapconcat 'identity (member "com" (split-string (file-name-directory buffer-file-name) "/" t)) ".") ";" \n \n "class " str " {" \n str "() {" \n > _ ?\n " }" ?\n "}" \n))) (eval-after-load 'autoinsert '(define-auto-insert '("\\.\\(kt\\)\\'" . "Kotlin source") '((file-name-base buffer-file-name) "// -*- Mode: kotlin; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-" \n "//" \n "// Copyright (C) 2020 Opera Norway AS. All rights reserved." \n "//" \n "// This file is an original work developed by Opera." \n \n "package " (mapconcat 'identity (member "com" (split-string (file-name-directory buffer-file-name) "/" t)) ".") \n \n "class " str "() {" \n > _ ?\n "}" \n))) (eval-after-load 'autoinsert '(define-auto-insert '("\\.\\(groovy\\|gradle\\)\\'" . "Groovy source") '((file-name-base buffer-file-name) "// -*- Mode: groovy; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-" \n "//" \n "// Copyright (C) 2020 Opera Norway AS. All rights reserved." \n "//" \n "// This file is an original work developed by Opera." \n \n _ \n))) (auto-insert-mode t) ;; don't ask before using auto-insert (setq-default auto-insert-query nil) ;; gpg (require 'epa-file) (epa-file-enable) ;; keys (global-set-key (kbd "C-c o") 'ff-find-other-file) (global-set-key [?\C-x ?\t] 'toggle-selected-frame-width) (define-key java-mode-map (kbd "M-I") 'java-imports-add-import-dwim) (global-set-key (kbd "C-x f") 'find-file-in-repository) ;; java-imports (require 'java-imports) (setq java-imports-find-block-function 'java-imports-find-place-sorted-block) (add-hook 'java-mode-hook 'java-imports-scan-file) ;; stop grep from asking to save buffers (setq grep-save-buffers nil) ;; ido (require 'ido) (require 'ido-vertical-mode) (ido-mode) (ido-vertical-mode) (setq ido-vertical-define-keys 'C-n-C-p-up-and-down) ;; stop ido from switching to another frame where the same buffer is already open (setq ido-default-buffer-method 'selected-window) (setq ido-ignore-directories (quote ("\\`CVS/" "\\`\\.\\./" "\\`\\./" "\\`\\.git/"))) (setq ido-max-dir-file-cache 1000) (setq ido-max-work-directory-list 500) (setq ido-max-work-file-list 100) ;; find-file-in-repo (require 'find-file-in-repository) ;; flycheck (require 'flycheck) (global-flycheck-mode) (setq flycheck-check-syntax-automatically '(save new-line)) (setq flycheck-python-pylint-executable "/usr/bin/python3") ;; replace ch alias fro grep with cchh alias, ie if starting with a ".h" file ;; you might still want to search in cc files (eval-after-load "grep" '(setf (cdr (assoc "ch" grep-files-aliases)) (cdr (assoc "cchh" grep-files-aliases)))) ;; make sure grep skips unimportant things (eval-after-load "grep" '(progn (add-to-list 'grep-find-ignored-directories "out_gradle") (add-to-list 'grep-find-ignored-directories "bin"))) (c-add-style "common c" '("gnu" (c-basic-offset . 4) (c-offsets-alist . ((substatement-open . 0) (arglist-intro . ++) (innamespace . 0))))) (add-hook 'c-mode-common-hook (lambda() (c-set-style "common c"))) (c-add-style "default c++" '("common c" (c-basic-offset . 2))) (defun get-base-dir (path needle) "Get base directory for PATH using NEEDLE to cut." (let ((parts (split-string path "/" t))) (let ((index (cl-position needle parts :from-end t :test 'equal))) (if index (concat "/" (mapconcat 'identity (seq-take parts (+ index 1)) "/")) path)))) (make-variable-buffer-local 'flycheck-clang-definitions) (make-variable-buffer-local 'flycheck-clang-include-path) (make-variable-buffer-local 'flycheck-clang-language-standard) (make-variable-buffer-local 'flycheck-clang-warnings) (add-hook 'c++-mode-hook (lambda() (setq flycheck-clang-language-standard "c++14") (c-set-style "default c++") ;; Chromium hook (when (and buffer-file-name (string-match "/chromium/src/" buffer-file-name)) (let ((base (get-base-dir (file-name-directory buffer-file-name) "src"))) (setq flycheck-clang-language-standard "c++14" flycheck-clang-definitions (list "OS_ANDROID") flycheck-clang-warnings (list "no-unused-parameter") flycheck-clang-include-path (list base (concat base "/out_gradle/BetaArm7Debug/gen") (concat base "/out_gradle/BetaArm7Release/gen")))) (require 'google-c-style) (c-add-style "Google" google-c-style t)) ;; ofa hook (when (and buffer-file-name (string-match "/mobile/mobile/" buffer-file-name)) (let ((base (get-base-dir (file-name-directory buffer-file-name) "mobile"))) (setq flycheck-clang-language-standard "c++14" flycheck-clang-definitions (list "OS_ANDROID") flycheck-clang-warnings (list "no-unused-parameter") flycheck-clang-include-path (list base (concat base "/../../chromium/src") (concat base "/../../chromium/src/third_party/re2/src") (concat base "/../../chromium/src/google/re2/src") (concat base "../../chromium/src/third_party/googlemock/src/googlemock/include") (concat base "../../chromium/src/third_party/googletest/src/googletest/include") (concat base "/../../chromium/src/out_gradle/BetaArm7Debug/gen") (concat base "/../../chromium/src/out_gradle/BetaArm7Release/gen")))) (require 'google-c-style) (c-add-style "Google" google-c-style t)))) (make-variable-buffer-local 'flycheck-android-java-checkstyle-jar) ;; Opera Java hook (add-hook 'java-mode-hook (lambda() (require 'google-c-style) (google-set-c-style) (setq c-file-style "Google") (c-set-offset 'arglist-intro '++) (c-set-offset 'arglist-cont nil) (c-set-offset 'arglist-cont-nonempty '++) (setq indent-tabs-mode nil) (setq c-basic-offset 4) (setq flycheck-android-java-checkstyle-path "tools/checkstyle" flycheck-android-java-checkstyle-config "checkstyle-config-android.xml" flycheck-android-java-checkstyle-properties "checkstyle.properties") ;; ofa hook (when (and buffer-file-name (string-match "/mobile/mobile/" buffer-file-name)) (require 'flycheck-android-experimental) (setq flycheck-android-java-checkstyle-jar "tools/checkstyle/custom/custom-checkstyle-checks-8.35.jar:../../chromium/src/third_party/checkstyle/checkstyle-all.jar" flycheck-android-java-variant "betaArm7Debug" flycheck-android-java-skip-gen t)) ;; mini hook (when (and buffer-file-name (string-match "/mobile/android/" buffer-file-name)) (require 'flycheck-android-experimental) (setq flycheck-android-java-checkstyle-jar "../../chromium/src/third_party/checkstyle/checkstyle-6.5-all.jar")))) ;;;