emacs mode
This commit is contained in:
@@ -0,0 +1,162 @@
|
|||||||
|
(require 'cl-lib)
|
||||||
|
(require 'company)
|
||||||
|
|
||||||
|
|
||||||
|
(defconst slime-built-ins
|
||||||
|
'("=" ">" ">=" "<" "<=" "+" "-" "*" "/" "**" "%"
|
||||||
|
"assert" "define" "define-syntax" "mutate" "if"
|
||||||
|
"quote" "quasiquote" "unquote" "unquote-splicing" "and" "or" "not" "while" "let"
|
||||||
|
"lambda" "special-lambda" "eval" "begin" "list" "pair"
|
||||||
|
"first" "rest" "set-type" "delete-type" "type" "info"
|
||||||
|
"show" "addr-of" "generate-docs" "print" "read" "exit" "break" "memstat" "try"
|
||||||
|
"load" "import" "copy" "error" "symbol->keyword" "string->symbol"
|
||||||
|
"symbol->string" "concat-strings"))
|
||||||
|
|
||||||
|
|
||||||
|
(defun my-slime-eldoc-function ()
|
||||||
|
(let ((symbol (symbol-name (car (read (thing-at-point 'sexp))))))
|
||||||
|
(if (member symbol slime-built-ins)
|
||||||
|
(sample-meta symbol)
|
||||||
|
(concat symbol " ?"))))
|
||||||
|
|
||||||
|
(defun sample-meta (s)
|
||||||
|
(cond
|
||||||
|
((string= s "=") "(= :rest <objects>)")
|
||||||
|
((string= s ">") "(> :rest <numbers>)")
|
||||||
|
((string= s ">=") "(>= :rest <numbers>)")
|
||||||
|
((string= s "<") "(< :rest <numbers>)")
|
||||||
|
((string= s "<=") "(<= :rest <numbers>)")
|
||||||
|
((string= s "+") "(+ :rest <numbers>)")
|
||||||
|
((string= s "-") "(- :rest <numbers>)")
|
||||||
|
((string= s "*") "(* :rest <numbers>)")
|
||||||
|
((string= s "/") "(/ :rest <numbers>)")
|
||||||
|
((string= s "**") "(** <number> <exponent>)")
|
||||||
|
((string= s "assert") "(assert <condition>)")
|
||||||
|
((string= s "define") "(define <name-or-lambda-list> [doc-string] <expression-or-bodx>)")
|
||||||
|
((string= s "define-syntax") "(define-syntax <name-and-lambda-list> [doc-string] <bodx>)")
|
||||||
|
((string= s "mutate") "(mutate <expression> <expression>)")
|
||||||
|
((string= s "if") "(if <test> <consequence> <alternative>)")
|
||||||
|
(t "")))
|
||||||
|
|
||||||
|
|
||||||
|
(add-to-list 'auto-mode-alist '("\\.slime\\'" . slime-mode))
|
||||||
|
|
||||||
|
(put 'lambda 'doc-string-elt 2)
|
||||||
|
(put 'special-lambda 'doc-string-elt 2)
|
||||||
|
(put 'define 'doc-string-elt 2)
|
||||||
|
(put 'define-syntax 'doc-string-elt 2)
|
||||||
|
|
||||||
|
(define-derived-mode slime-mode prog-mode "(slime)"
|
||||||
|
"Major mode for editing slime code."
|
||||||
|
:group 'lisp
|
||||||
|
|
||||||
|
(defvar project-vc-external-roots-function)
|
||||||
|
|
||||||
|
(set-syntax-table lisp-mode-syntax-table)
|
||||||
|
(setq-local lisp-mode-symbol-regexp "\\(?:\\sw\\|\\s_\\|\\\\.\\|?\\)+")
|
||||||
|
(setq-local paragraph-ignore-fill-prefix t)
|
||||||
|
(setq-local fill-paragraph-function 'lisp-fill-paragraph)
|
||||||
|
(setq-local adaptive-fill-function #'lisp-adaptive-fill)
|
||||||
|
;; Adaptive fill mode gets in the way of auto-fill,
|
||||||
|
;; and should make no difference for explicit fill
|
||||||
|
;; because lisp-fill-paragraph should do the job.
|
||||||
|
;; I believe that newcomment's auto-fill code properly deals with it -stef
|
||||||
|
;;(set (make-local-variable 'adaptive-fill-mode) nil)
|
||||||
|
(setq-local indent-line-function 'lisp-indent-line)
|
||||||
|
(setq-local indent-region-function 'lisp-indent-region)
|
||||||
|
(setq-local comment-indent-function #'lisp-comment-indent)
|
||||||
|
;; (setq-local outline-regexp ";;;\\(;* [^ \t\n]\\|###autoload\\)\\|(")
|
||||||
|
(setq-local outline-level 'lisp-outline-level)
|
||||||
|
(setq-local add-log-current-defun-function #'lisp-current-defun-name)
|
||||||
|
(setq-local comment-start ";")
|
||||||
|
(setq-local comment-start-skip ";+ *")
|
||||||
|
(setq-local comment-add 1) ;default to `;;' in comment-region
|
||||||
|
(setq-local comment-column 40)
|
||||||
|
(setq-local comment-use-syntax t)
|
||||||
|
(setq-local imenu-generic-expression lisp-imenu-generic-expression)
|
||||||
|
(setq-local multibyte-syntax-as-symbol t)
|
||||||
|
|
||||||
|
(defconst yess
|
||||||
|
(append
|
||||||
|
`((,(concat "\\(define\\)\\s-*(\\(\\_<[^ )]*\\)")
|
||||||
|
(1 font-lock-keyword-face)
|
||||||
|
(2 font-lock-function-name-face)
|
||||||
|
))
|
||||||
|
`((,(concat "(\\s-*\\_<"
|
||||||
|
(regexp-opt
|
||||||
|
slime-built-ins) "\\_>")
|
||||||
|
(0 font-lock-keyword-face)))
|
||||||
|
`((,(concat "[`‘]\\(\\(?:\\sw\\|\\s_\\|\\\\.\\)"
|
||||||
|
lisp-mode-symbol-regexp "\\)['’]")
|
||||||
|
(1 font-lock-constant-face prepend))
|
||||||
|
;; Constant values.
|
||||||
|
(,(concat "\\_<:" lisp-mode-symbol-regexp "\\_>")
|
||||||
|
(0 font-lock-builtin-face)))
|
||||||
|
|
||||||
|
))
|
||||||
|
|
||||||
|
(setq font-lock-defaults
|
||||||
|
`((yess)
|
||||||
|
nil nil nil nil
|
||||||
|
(font-lock-mark-block-function . mark-defun)
|
||||||
|
(font-lock-extra-managed-props help-echo)
|
||||||
|
(font-lock-syntactic-face-function
|
||||||
|
. lisp-font-lock-syntactic-face-function)))
|
||||||
|
;; (setq font-lock-defaults '((;; ads
|
||||||
|
;; ;; lisp-el-font-lock-keywords-1
|
||||||
|
;; ;; lisp-el-font-lock-keywords-2
|
||||||
|
;; )
|
||||||
|
;; nil nil nil nil
|
||||||
|
;; (font-lock-mark-block-function . mark-defun)
|
||||||
|
;; (font-lock-extra-managed-props help-echo)
|
||||||
|
;; (font-lock-syntactic-face-function
|
||||||
|
;; . lisp-font-lock-syntactic-face-function)))
|
||||||
|
(setq-local prettify-symbols-alist lisp-prettify-symbols-alist)
|
||||||
|
(setq-local electric-pair-skip-whitespace 'chomp)
|
||||||
|
(setq-local electric-pair-open-newline-between-pairs nil)
|
||||||
|
|
||||||
|
(add-hook 'after-load-functions #'elisp--font-lock-flush-elisp-buffers)
|
||||||
|
(unless noninteractive
|
||||||
|
(require 'elec-pair)
|
||||||
|
(defvar electric-pair-text-pairs)
|
||||||
|
(setq-local electric-pair-text-pairs
|
||||||
|
(append '((?\` . ?\') (?‘ . ?’)) electric-pair-text-pairs))
|
||||||
|
(setq-local electric-quote-string t))
|
||||||
|
(setq imenu-case-fold-search nil)
|
||||||
|
(add-function :before-until (local 'eldoc-documentation-function)
|
||||||
|
#'elisp-eldoc-documentation-function)
|
||||||
|
(add-hook 'xref-backend-functions #'elisp--xref-backend nil t)
|
||||||
|
(setq-local project-vc-external-roots-function #'elisp-load-path-roots)
|
||||||
|
(add-hook 'completion-at-point-functions #'elisp-completion-at-point nil 'local)
|
||||||
|
(add-hook 'flymake-diagnostic-functions #'elisp-flymake-checkdoc nil t)
|
||||||
|
(add-hook 'flymake-diagnostic-functions #'elisp-flymake-byte-compile nil t))
|
||||||
|
|
||||||
|
|
||||||
|
(defun company-simple-backend (command &optional arg &rest ignored)
|
||||||
|
(interactive (list 'interactive))
|
||||||
|
(cl-case command
|
||||||
|
(interactive (company-begin-backend 'company-simple-backend))
|
||||||
|
(prefix (when (looking-back "foo\\>")
|
||||||
|
(match-string 0)))
|
||||||
|
(candidates (when (equal arg "foo")
|
||||||
|
(list "foobar" "foobaz" "foobarbaz")))
|
||||||
|
(meta (format "This value is named %s" arg))))
|
||||||
|
|
||||||
|
(defun company-sample-backend (command &optional arg &rest ignored)
|
||||||
|
(interactive (list 'interactive))
|
||||||
|
(cl-case command
|
||||||
|
(interactive (company-begin-backend 'company-sample-backend))
|
||||||
|
(prefix (and (eq major-mode 'slime-mode)
|
||||||
|
(company-grab-symbol)))
|
||||||
|
(candidates
|
||||||
|
(remove-if-not
|
||||||
|
(lambda (c) (string-prefix-p arg c))
|
||||||
|
slime-built-ins))
|
||||||
|
(meta (sample-meta arg))))
|
||||||
|
|
||||||
|
(add-hook 'slime-mode-hook
|
||||||
|
(lambda ()
|
||||||
|
;; (set (make-local-variable 'eldoc-documentation-function) 'my-slime-eldoc-function)
|
||||||
|
(set (make-local-variable 'company-backends) '(company-sample-backend))))
|
||||||
|
|
||||||
|
(provide 'slime-mode)
|
||||||
Reference in New Issue
Block a user