Shrug
This commit is contained in:
parent
3e1c7b565b
commit
f1a4519507
3 changed files with 498 additions and 6 deletions
|
|
@ -17,9 +17,9 @@
|
||||||
'(comint-prompt-read-only t)
|
'(comint-prompt-read-only t)
|
||||||
'(comint-scroll-to-bottom-on-input t)
|
'(comint-scroll-to-bottom-on-input t)
|
||||||
'(company-backends
|
'(company-backends
|
||||||
'(company-bbdb company-nxml company-css company-semantic company-clang company-cmake company-capf company-files
|
'(company-tasks company-reviewers company-bbdb company-nxml company-css company-capf
|
||||||
(company-dabbrev-code company-gtags company-etags company-keywords)
|
(company-dabbrev-code company-keywords)))
|
||||||
company-oddmuse company-dabbrev company-flow))
|
'(company-minimum-prefix-length 1)
|
||||||
'(css-indent-offset 2)
|
'(css-indent-offset 2)
|
||||||
'(custom-safe-themes
|
'(custom-safe-themes
|
||||||
'("3dbb18bf06f41012d4525e6c64c392d6cfef06a2f8fe1bf7b565c4e020255466" "8db4b03b9ae654d4a57804286eb3e332725c84d7cdab38463cb6b97d5762ad26" default))
|
'("3dbb18bf06f41012d4525e6c64c392d6cfef06a2f8fe1bf7b565c4e020255466" "8db4b03b9ae654d4a57804286eb3e332725c84d7cdab38463cb6b97d5762ad26" default))
|
||||||
|
|
@ -58,7 +58,7 @@
|
||||||
'(org-odd-levels-only t)
|
'(org-odd-levels-only t)
|
||||||
'(org-todo-keywords '((sequence "TODO" "|" "DONE" "ABANDONED" "DEFERRED")))
|
'(org-todo-keywords '((sequence "TODO" "|" "DONE" "ABANDONED" "DEFERRED")))
|
||||||
'(package-selected-packages
|
'(package-selected-packages
|
||||||
'(prettier-js zig-mode modus-operandi-theme esup gnu-elpa-keyring-update lsp-hack hack-mode rust-mode filladapt lsp-ui yaml-mode wgrep fsharp-mode company-lsp cquery mustache-mode clang-format projectile dash-functional mocha add-node-modules-path rjsx-mode xref-js2 js2-refactor company omnisharp geiser cider clojure-mode graphviz-dot-mode multi-term xterm-color thrift markdown-mode tuareg merlin ag use-package flycheck dockerfile-mode js2-mode web-mode tss switch-window python-mode paredit magit lua-mode go-mode go-autocomplete exec-path-from-shell csharp-mode color-theme-monokai auto-complete auto-complete-nxml flymake flyspell json-mode popup ruby-mode company-jedi tide elm-mode monky))
|
'(eglot prettier-js zig-mode modus-operandi-theme esup gnu-elpa-keyring-update lsp-hack hack-mode rust-mode filladapt lsp-ui yaml-mode wgrep fsharp-mode company-lsp cquery mustache-mode clang-format projectile dash-functional mocha add-node-modules-path rjsx-mode xref-js2 js2-refactor company omnisharp geiser cider clojure-mode graphviz-dot-mode multi-term xterm-color thrift markdown-mode tuareg merlin ag use-package flycheck dockerfile-mode js2-mode web-mode tss switch-window python-mode paredit magit lua-mode go-mode go-autocomplete exec-path-from-shell csharp-mode color-theme-monokai auto-complete auto-complete-nxml flymake flyspell json-mode popup ruby-mode company-jedi tide elm-mode monky))
|
||||||
'(reb-re-syntax 'string)
|
'(reb-re-syntax 'string)
|
||||||
'(rmail-mail-new-frame t)
|
'(rmail-mail-new-frame t)
|
||||||
'(safe-local-variable-values
|
'(safe-local-variable-values
|
||||||
|
|
@ -84,8 +84,8 @@
|
||||||
'(tab-width 4)
|
'(tab-width 4)
|
||||||
'(tags-revert-without-query t)
|
'(tags-revert-without-query t)
|
||||||
'(tramp-completion-reread-directory-timeout nil)
|
'(tramp-completion-reread-directory-timeout nil)
|
||||||
'(tramp-default-method "sshx" nil (tramp))
|
'(tramp-default-method "sshx")
|
||||||
'(tramp-use-ssh-controlmaster-options nil nil (tramp))
|
'(tramp-use-ssh-controlmaster-options nil)
|
||||||
'(transient-mark-mode t)
|
'(transient-mark-mode t)
|
||||||
'(truncate-lines t)
|
'(truncate-lines t)
|
||||||
'(typescript-indent-level 2)
|
'(typescript-indent-level 2)
|
||||||
|
|
|
||||||
105
site-lisp/fb-glass.el
Normal file
105
site-lisp/fb-glass.el
Normal file
|
|
@ -0,0 +1,105 @@
|
||||||
|
;;; fb-glass.el --- Emacs integration for the Glass CLI -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
;; Keywords: tools,processes
|
||||||
|
;; Package-Requires: ((emacs "27.1") (f "1.0"))
|
||||||
|
;; Version: 0.1
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
;; Integrates `glass` into Emacs. Improvements welcome!
|
||||||
|
;; Note that Glass is designed more for static/"offline" navigation of code, without needing
|
||||||
|
;; a full LSP to be running.
|
||||||
|
;; This integration will return stale results if you try to use it on files that have been modified.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
(require 'compile)
|
||||||
|
(require 'f)
|
||||||
|
|
||||||
|
(defun glass--call-process-shell-check-success (command)
|
||||||
|
(with-temp-buffer
|
||||||
|
(let ((exit-code (call-process-shell-command command nil (current-buffer))))
|
||||||
|
(unless (equal exit-code 0)
|
||||||
|
(error "Error running shell command"))
|
||||||
|
(buffer-string))))
|
||||||
|
|
||||||
|
(defun glass--root (filename)
|
||||||
|
"Gets the root corresponding to the given filename. If none given, the current buffer's filename is used."
|
||||||
|
(let ((default-directory (file-name-directory (file-truename filename))))
|
||||||
|
(string-trim (glass--call-process-shell-check-success "hg root"))))
|
||||||
|
|
||||||
|
(defun glass--repo (filename)
|
||||||
|
"Gets the Glean repo ID corresponding to the given filename. If none given, the current buffer's filename is used."
|
||||||
|
(let ((default-directory (file-name-directory (file-truename filename))))
|
||||||
|
(string-trim (glass--call-process-shell-check-success "hg config remotefilelog.reponame"))))
|
||||||
|
|
||||||
|
;;; VISIT SYMBOLS
|
||||||
|
|
||||||
|
(defun glass-visit-symbol (symbol)
|
||||||
|
"Given a Glass symbol, visit the file that defines that symbol"
|
||||||
|
(interactive)
|
||||||
|
(let* ((output (glass--call-process-shell-check-success
|
||||||
|
(format "glass --caller=emacs describe -t %s" (shell-quote-argument symbol))))
|
||||||
|
(position (split-string (car (split-string output)) ":"))
|
||||||
|
(filename (car position))
|
||||||
|
(local-filename (concat "~/" filename)))
|
||||||
|
(if (file-exists-p local-filename)
|
||||||
|
(progn
|
||||||
|
(find-file local-filename)
|
||||||
|
(goto-char (point-min))
|
||||||
|
(forward-line (- (string-to-number (cadr position)) 1))
|
||||||
|
(forward-char (- (string-to-number (caddr position)) 1)))
|
||||||
|
(let* ((buffer (generate-new-buffer (concat "glass--" (file-name-nondirectory filename))))
|
||||||
|
(repo (car (split-string filename "/")))
|
||||||
|
(exit-code (call-process "scsc" nil buffer nil
|
||||||
|
"cat"
|
||||||
|
"--repo" (shell-quote-argument repo)
|
||||||
|
"--path" (shell-quote-argument (string-remove-prefix repo filename))
|
||||||
|
"-B" "master")))
|
||||||
|
(if (equal exit-code 0)
|
||||||
|
(progn
|
||||||
|
(with-current-buffer buffer
|
||||||
|
(setq-local buffer-read-only t)
|
||||||
|
(goto-char (point-min))
|
||||||
|
(forward-line (- (string-to-number (cadr position)) 1))
|
||||||
|
(forward-char (- (string-to-number (caddr position)) 1)))
|
||||||
|
(pop-to-buffer buffer))
|
||||||
|
(progn
|
||||||
|
(kill-buffer buffer)
|
||||||
|
(error "Couldn't display source with `scsc`")))))))
|
||||||
|
|
||||||
|
;;; LIST SYMBOLS
|
||||||
|
|
||||||
|
(defun glass-list-symbols (&optional filename)
|
||||||
|
"Lists all symbols within the given filesystem path. If none given, the current buffer's filename is used."
|
||||||
|
(let* ((file (file-truename (or filename (buffer-file-name))))
|
||||||
|
(root (glass--root file))
|
||||||
|
(repo (glass--repo file))
|
||||||
|
(search-path (concat repo "/" (file-relative-name file root))))
|
||||||
|
;; TODO integrate with myles, myles to get a path -> glass to list its symbols
|
||||||
|
(compilation-start
|
||||||
|
(format "glass --caller emacs list-symbols %s | sed -e 's|^|~/|'" search-path))))
|
||||||
|
|
||||||
|
;;; SYMBOL-SEARCH
|
||||||
|
|
||||||
|
(with-eval-after-load "counsel"
|
||||||
|
(defun glass--symbol-search (input)
|
||||||
|
(counsel--async-command
|
||||||
|
(format "glass --caller=emacs symbol-search %s"
|
||||||
|
(shell-quote-argument input)))
|
||||||
|
nil)
|
||||||
|
|
||||||
|
(defun glass-symbol-search-counsel ()
|
||||||
|
"Find a symbol by full symbol ID prefix using `glass symbol-search`"
|
||||||
|
(interactive)
|
||||||
|
(counsel-require-program "glass")
|
||||||
|
(let ((default-directory (myles--root)))
|
||||||
|
;; TODO allow entering "/" to grab the current candidate and restart from there
|
||||||
|
;; similar to how it works for counsel-find-file
|
||||||
|
(ivy-read
|
||||||
|
"symbol prefix: "
|
||||||
|
#'glass--symbol-search
|
||||||
|
:caller 'glass-counsel
|
||||||
|
:dynamic-collection t
|
||||||
|
:action #'glass-visit-symbol))))
|
||||||
|
|
||||||
|
(provide 'fb-glass)
|
||||||
|
;;; fb-glass.el ends here
|
||||||
387
site-lisp/thrift.el
Normal file
387
site-lisp/thrift.el
Normal file
|
|
@ -0,0 +1,387 @@
|
||||||
|
;;; thrift.el --- major mode for fbthrift and Apache Thrift files -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
;; Keywords: languages
|
||||||
|
;; Package-Version: 20180905.1050
|
||||||
|
;; Package-Requires: ((emacs "24"))
|
||||||
|
|
||||||
|
;; Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
;; or more contributor license agreements. See the NOTICE file
|
||||||
|
;; distributed with this work for additional information
|
||||||
|
;; regarding copyright ownership. The ASF licenses this file
|
||||||
|
;; to you under the Apache License, Version 2.0 (the
|
||||||
|
;; "License"); you may not use this file except in compliance
|
||||||
|
;; with the License. You may obtain a copy of the License at
|
||||||
|
;;
|
||||||
|
;; http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
;;
|
||||||
|
;; Unless required by applicable law or agreed to in writing,
|
||||||
|
;; software distributed under the License is distributed on an
|
||||||
|
;; "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
;; KIND, either express or implied. See the License for the
|
||||||
|
;; specific language governing permissions and limitations
|
||||||
|
;; under the License.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
|
||||||
|
;; This is a major mode for syntax highlighting .thrift files.
|
||||||
|
;;
|
||||||
|
;; Features:
|
||||||
|
;;
|
||||||
|
;; * Precise syntax highlighting based on the thrift parser code.
|
||||||
|
;; * Highlighting of method definitions
|
||||||
|
;; * Custom face for struct/argument indexes
|
||||||
|
;; * Highlighting of doxygen keywords
|
||||||
|
;; * Indentation
|
||||||
|
;;
|
||||||
|
;; This mode works for both fbthrift and Apache Thrift files.
|
||||||
|
;;
|
||||||
|
;; Hacked by doty for more modern thrift.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(defvar thrift-mode-syntax-table
|
||||||
|
(let ((table (make-syntax-table)))
|
||||||
|
;; Both " and ' are strings.
|
||||||
|
(modify-syntax-entry ?\" "\"" table)
|
||||||
|
(modify-syntax-entry ?\\ "\\" table)
|
||||||
|
(modify-syntax-entry ?' "\"" table)
|
||||||
|
|
||||||
|
;; Treat < and > as paired delimiters.
|
||||||
|
(modify-syntax-entry ?< "(<" table)
|
||||||
|
(modify-syntax-entry ?> ")>" table)
|
||||||
|
|
||||||
|
;; Comments can start with //, /* or # characters.
|
||||||
|
(modify-syntax-entry ?/ ". 124" table)
|
||||||
|
(modify-syntax-entry ?* ". 23b" table)
|
||||||
|
(modify-syntax-entry ?# "<" table)
|
||||||
|
(modify-syntax-entry ?\n ">" table)
|
||||||
|
|
||||||
|
table))
|
||||||
|
|
||||||
|
(defgroup thrift nil
|
||||||
|
"A major mode for editing .thrift files."
|
||||||
|
:group 'languages)
|
||||||
|
|
||||||
|
(defface thrift-ordinal-face
|
||||||
|
'((t :foreground "orange"))
|
||||||
|
"Face used to highlight Thrift indexes."
|
||||||
|
:group 'thrift)
|
||||||
|
|
||||||
|
(defface thrift-doxygen-key-face
|
||||||
|
'((t :foreground "SlateGray"))
|
||||||
|
"Face used to highlight @foo in doxygen style comments."
|
||||||
|
:group 'thrift)
|
||||||
|
|
||||||
|
(defun thrift--doxygen-search (pattern limit)
|
||||||
|
"Search for PATTERN in /** comments, up to position LIMIT.
|
||||||
|
If we find a match, set match-data and put point on the final
|
||||||
|
location, and return point. Otherwise, return nil and don't move point.
|
||||||
|
|
||||||
|
This is intended to be used with `font-lock-keywords'."
|
||||||
|
(let (res
|
||||||
|
match-data)
|
||||||
|
(save-match-data
|
||||||
|
;; Search forward for the first @foo..
|
||||||
|
(while (and
|
||||||
|
(not res)
|
||||||
|
(re-search-forward pattern limit t))
|
||||||
|
;; Set match data to the @foo we found, before we call `looking-at'.
|
||||||
|
(setq match-data (match-data))
|
||||||
|
|
||||||
|
(let* ((ppss (syntax-ppss))
|
||||||
|
(in-comment-p (nth 4 ppss))
|
||||||
|
(comment-start (nth 8 ppss))
|
||||||
|
in-doxygen-comment-p)
|
||||||
|
;; Go to the start of the comment, and confirm this is a /** comment.
|
||||||
|
(when in-comment-p
|
||||||
|
(save-excursion
|
||||||
|
(goto-char comment-start)
|
||||||
|
(when (looking-at (rx "/**"))
|
||||||
|
(setq in-doxygen-comment-p t))))
|
||||||
|
|
||||||
|
(when in-doxygen-comment-p
|
||||||
|
(setq res (point))))))
|
||||||
|
;; Set match data and return point, so Emacs knows we found something.
|
||||||
|
(when res
|
||||||
|
(set-match-data match-data)
|
||||||
|
res)))
|
||||||
|
|
||||||
|
(defvar thrift-font-lock-keywords
|
||||||
|
`((,(regexp-opt
|
||||||
|
;; Useful keywords in thriftl.ll.
|
||||||
|
'("namespace"
|
||||||
|
"cpp_namespace"
|
||||||
|
"cpp_include"
|
||||||
|
"hs_include"
|
||||||
|
"java_package"
|
||||||
|
"cocoa_prefix"
|
||||||
|
"csharp_namespace"
|
||||||
|
"php_namespace"
|
||||||
|
"py_module"
|
||||||
|
"perl_package"
|
||||||
|
"ruby_namespace"
|
||||||
|
"smalltalk_category"
|
||||||
|
"smalltalk_prefix"
|
||||||
|
"include"
|
||||||
|
"oneway"
|
||||||
|
"typedef"
|
||||||
|
"struct"
|
||||||
|
"union"
|
||||||
|
"exception"
|
||||||
|
"extends"
|
||||||
|
"throws"
|
||||||
|
"service"
|
||||||
|
"enum"
|
||||||
|
"const"
|
||||||
|
"interaction" ;; doty
|
||||||
|
;; Deprecated
|
||||||
|
"cpp_type"
|
||||||
|
"async")
|
||||||
|
'symbols)
|
||||||
|
. font-lock-keyword-face)
|
||||||
|
;; Keywords in thriftl.ll that correspond to types.
|
||||||
|
(,(regexp-opt
|
||||||
|
'("binary"
|
||||||
|
"bool"
|
||||||
|
"byte"
|
||||||
|
"double"
|
||||||
|
"float"
|
||||||
|
"hash_map"
|
||||||
|
"hash_set"
|
||||||
|
"i16"
|
||||||
|
"i32"
|
||||||
|
"i64"
|
||||||
|
"list"
|
||||||
|
"map"
|
||||||
|
"set"
|
||||||
|
"slist"
|
||||||
|
"stream"
|
||||||
|
"string"
|
||||||
|
"void"
|
||||||
|
;; Treat optional/required as type keywords, as they occur in that context.
|
||||||
|
"optional"
|
||||||
|
"required"
|
||||||
|
)
|
||||||
|
'symbols)
|
||||||
|
. font-lock-type-face)
|
||||||
|
;; Reserved words in thirftl.ll that don't currently do anything.
|
||||||
|
(,(regexp-opt
|
||||||
|
'("abstract"
|
||||||
|
"and"
|
||||||
|
"args"
|
||||||
|
"as"
|
||||||
|
"assert"
|
||||||
|
"auto"
|
||||||
|
"break"
|
||||||
|
"case"
|
||||||
|
"char"
|
||||||
|
"class"
|
||||||
|
"continue"
|
||||||
|
"declare"
|
||||||
|
"def"
|
||||||
|
"default"
|
||||||
|
"del"
|
||||||
|
"delete"
|
||||||
|
"do"
|
||||||
|
"elif"
|
||||||
|
"else"
|
||||||
|
"elseif"
|
||||||
|
"except"
|
||||||
|
"exec"
|
||||||
|
"extern"
|
||||||
|
"finally"
|
||||||
|
"for"
|
||||||
|
"foreach"
|
||||||
|
"function"
|
||||||
|
"global"
|
||||||
|
"goto"
|
||||||
|
"if"
|
||||||
|
"implements"
|
||||||
|
"import"
|
||||||
|
"in"
|
||||||
|
"int"
|
||||||
|
"inline"
|
||||||
|
"instanceof"
|
||||||
|
"interface"
|
||||||
|
"is"
|
||||||
|
"lambda"
|
||||||
|
"long"
|
||||||
|
"native"
|
||||||
|
"new"
|
||||||
|
"not"
|
||||||
|
"or"
|
||||||
|
"pass"
|
||||||
|
"public"
|
||||||
|
"print"
|
||||||
|
"private"
|
||||||
|
"protected"
|
||||||
|
"raise"
|
||||||
|
"register"
|
||||||
|
"return"
|
||||||
|
"short"
|
||||||
|
"signed"
|
||||||
|
"sizeof"
|
||||||
|
"static"
|
||||||
|
"switch"
|
||||||
|
"synchronized"
|
||||||
|
"template"
|
||||||
|
"this"
|
||||||
|
"throw"
|
||||||
|
"transient"
|
||||||
|
"try"
|
||||||
|
"unsigned"
|
||||||
|
"var"
|
||||||
|
"virtual"
|
||||||
|
"volatile"
|
||||||
|
"while"
|
||||||
|
"with"
|
||||||
|
"yield"
|
||||||
|
"Object"
|
||||||
|
"Client"
|
||||||
|
"IFace"
|
||||||
|
"Processor")
|
||||||
|
'symbols)
|
||||||
|
. font-lock-type-face)
|
||||||
|
(,(regexp-opt
|
||||||
|
'("true" "false")
|
||||||
|
'symbols)
|
||||||
|
. font-lock-constant-face)
|
||||||
|
;; Constants are all in upper case, and cannot start with a
|
||||||
|
;; digit. We use font-lock-variable-name-face for consistence with
|
||||||
|
;; c-mode.
|
||||||
|
(,(rx symbol-start
|
||||||
|
(any upper "_")
|
||||||
|
(+ (any upper "_" digit))
|
||||||
|
symbol-end)
|
||||||
|
. font-lock-variable-name-face)
|
||||||
|
;; Highlight type declarations.
|
||||||
|
(,(rx symbol-start
|
||||||
|
(or "enum" "service" "struct" "interaction")
|
||||||
|
symbol-end
|
||||||
|
(+ space)
|
||||||
|
symbol-start
|
||||||
|
(*
|
||||||
|
(seq (syntax word) "."))
|
||||||
|
(group (+ (or (syntax word) (syntax symbol))))
|
||||||
|
symbol-end)
|
||||||
|
1 font-lock-type-face)
|
||||||
|
;; Highlight method declarations
|
||||||
|
(,(rx symbol-start
|
||||||
|
(group (+ (or (syntax word) (syntax symbol))))
|
||||||
|
symbol-end
|
||||||
|
"(")
|
||||||
|
1 font-lock-function-name-face)
|
||||||
|
;; Highlight other PascalCase symbols as types.
|
||||||
|
(,(rx symbol-start
|
||||||
|
(group
|
||||||
|
(any upper)
|
||||||
|
(+ (or (syntax word) (syntax symbol))))
|
||||||
|
symbol-end)
|
||||||
|
1 font-lock-type-face)
|
||||||
|
|
||||||
|
;; Highlight struct indexes.
|
||||||
|
(,(rx symbol-start
|
||||||
|
(group (+ digit))
|
||||||
|
symbol-end
|
||||||
|
":")
|
||||||
|
1 'thrift-ordinal-face)
|
||||||
|
;; Highlight doxygen items that are followed by a symbol, such as '@param foo_bar'.
|
||||||
|
(,(lambda (limit)
|
||||||
|
(thrift--doxygen-search
|
||||||
|
(rx (or "@param" "@throws") symbol-end
|
||||||
|
;; Highlight @param even before we've started typing the name of the param.
|
||||||
|
(zero-or-one
|
||||||
|
(1+ space)
|
||||||
|
(1+ (or (syntax word) (syntax symbol) ".")))
|
||||||
|
symbol-end)
|
||||||
|
limit))
|
||||||
|
0 'thrift-doxygen-key-face t)
|
||||||
|
;; Highlight standalone doxygen items.
|
||||||
|
(,(lambda (limit)
|
||||||
|
(thrift--doxygen-search
|
||||||
|
(rx (or "@return" "@see") symbol-end)
|
||||||
|
limit))
|
||||||
|
0 'thrift-doxygen-key-face t)))
|
||||||
|
|
||||||
|
(defvar thrift-indent-level 2
|
||||||
|
"Indentation amount used in Thrift files.")
|
||||||
|
|
||||||
|
(defun thrift-indent-line ()
|
||||||
|
"Indent the current line of Thrift code.
|
||||||
|
Preserves point position in the line where possible."
|
||||||
|
(interactive)
|
||||||
|
(let* ((point-offset (- (current-column) (current-indentation)))
|
||||||
|
(ppss (syntax-ppss (line-beginning-position)))
|
||||||
|
(paren-depth (nth 0 ppss))
|
||||||
|
(current-paren-pos (nth 1 ppss))
|
||||||
|
(text-after-paren
|
||||||
|
(when current-paren-pos
|
||||||
|
(save-excursion
|
||||||
|
(goto-char current-paren-pos)
|
||||||
|
(buffer-substring
|
||||||
|
(1+ current-paren-pos)
|
||||||
|
(line-end-position)))))
|
||||||
|
(in-multiline-comment-p (nth 4 ppss))
|
||||||
|
(current-line (buffer-substring (line-beginning-position) (line-end-position))))
|
||||||
|
;; If the current line is just a closing paren, unindent by one level.
|
||||||
|
(when (and
|
||||||
|
(not in-multiline-comment-p)
|
||||||
|
(string-match-p (rx bol (0+ space) (or ")" "}")) current-line))
|
||||||
|
(setq paren-depth (1- paren-depth)))
|
||||||
|
(cond
|
||||||
|
;; In multiline comments, ensure the leading * is indented by one
|
||||||
|
;; more space. For example:
|
||||||
|
;; /*
|
||||||
|
;; * <- this line
|
||||||
|
;; */
|
||||||
|
(in-multiline-comment-p
|
||||||
|
;; Don't modify lines that don't start with *, to avoid changing the indentation of commented-out code.
|
||||||
|
(when (or (string-match-p (rx bol (0+ space) "*") current-line)
|
||||||
|
(string= "" current-line))
|
||||||
|
(indent-line-to (1+ (* thrift-indent-level paren-depth)))))
|
||||||
|
;; Indent 'throws' lines by one extra level. For example:
|
||||||
|
;; void foo ()
|
||||||
|
;; throws (1: FooError fe)
|
||||||
|
((string-match-p (rx bol (0+ space) "throws" symbol-end) current-line)
|
||||||
|
(indent-line-to (* thrift-indent-level (1+ paren-depth))))
|
||||||
|
;; Indent according to the last paren position, if there is text
|
||||||
|
;; after the paren. For example:
|
||||||
|
;; throws (1: FooError fe,
|
||||||
|
;; 2: BarError be, <- this line
|
||||||
|
((and
|
||||||
|
text-after-paren
|
||||||
|
(not (string-match-p (rx bol (0+ space) eol) text-after-paren)))
|
||||||
|
(let (open-paren-column)
|
||||||
|
(save-excursion
|
||||||
|
(goto-char current-paren-pos)
|
||||||
|
(setq open-paren-column (current-column)))
|
||||||
|
(indent-line-to (1+ open-paren-column))))
|
||||||
|
;; Indent parameters by an extra level, so they're visually distinct from 'throws'.
|
||||||
|
;; void foo(
|
||||||
|
;; 1: int bar) <- this line
|
||||||
|
;; throws (1: FooError fe)
|
||||||
|
((and current-paren-pos
|
||||||
|
(eq (char-after current-paren-pos) ?\())
|
||||||
|
(indent-line-to (* thrift-indent-level (1+ paren-depth))))
|
||||||
|
;; Indent according to the amount of nesting.
|
||||||
|
(t
|
||||||
|
(indent-line-to (* thrift-indent-level paren-depth))))
|
||||||
|
|
||||||
|
;; Point is now at the beginning of indentation, restore it
|
||||||
|
;; to its original position (relative to indentation).
|
||||||
|
(when (>= point-offset 0)
|
||||||
|
(move-to-column (+ (current-indentation) point-offset)))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(add-to-list 'auto-mode-alist '("\\.thrift$" . thrift-mode))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(define-derived-mode thrift-mode prog-mode "Thrift"
|
||||||
|
"Major mode for editing Thrift files."
|
||||||
|
(setq-local font-lock-defaults '(thrift-font-lock-keywords))
|
||||||
|
(setq-local indent-line-function 'thrift-indent-line)
|
||||||
|
|
||||||
|
(setq-local comment-start "// "))
|
||||||
|
|
||||||
|
(provide 'thrift)
|
||||||
|
;;; thrift.el ends here
|
||||||
Loading…
Add table
Add a link
Reference in a new issue