diff options
author | mattkae <mattkae@protonmail.com> | 2022-06-07 08:23:47 -0400 |
---|---|---|
committer | mattkae <mattkae@protonmail.com> | 2022-06-07 08:23:47 -0400 |
commit | bd18a38c2898548a3664a9ddab9f79c84f2caf4a (patch) | |
tree | 95b9933376770381bd8859782ae763be81c2d72b /elpa/irony-20220110.849/irony.el | |
parent | b07628dddf418d4f47b858e6c35fd3520fbaeed2 (diff) | |
parent | ef160dea332af4b4fe5e2717b962936c67e5fe9e (diff) |
Merge conflict
Diffstat (limited to 'elpa/irony-20220110.849/irony.el')
-rw-r--r-- | elpa/irony-20220110.849/irony.el | 917 |
1 files changed, 0 insertions, 917 deletions
diff --git a/elpa/irony-20220110.849/irony.el b/elpa/irony-20220110.849/irony.el deleted file mode 100644 index f70eca3..0000000 --- a/elpa/irony-20220110.849/irony.el +++ /dev/null @@ -1,917 +0,0 @@ -;;; irony.el --- C/C++ minor mode powered by libclang - -;; Copyright (C) 2011-2016 Guillaume Papin - -;; Author: Guillaume Papin <guillaume.papin@epitech.eu> -;; Version: 1.5.0 -;; URL: https://github.com/Sarcasm/irony-mode -;; Compatibility: GNU Emacs 24.x -;; Keywords: c, convenience, tools -;; Package-Requires: ((cl-lib "0.5") (json "1.2")) - -;; This program is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation, either version 3 of the License, or -;; (at your option) any later version. - -;; This program is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with this program. If not, see <http://www.gnu.org/licenses/>. - -;;; Commentary: -;; -;; This file provides `irony-mode', a minor mode for C, C++ and Objective-C. -;; -;; Usage: -;; (add-hook 'c++-mode-hook 'irony-mode) -;; (add-hook 'c-mode-hook 'irony-mode) -;; (add-hook 'objc-mode-hook 'irony-mode) -;; -;; ;; Windows performance tweaks -;; ;; -;; (when (boundp 'w32-pipe-read-delay) -;; (setq w32-pipe-read-delay 0)) -;; ;; Set the buffer size to 64K on Windows (from the original 4K) -;; (when (boundp 'w32-pipe-buffer-size) -;; (setq irony-server-w32-pipe-buffer-size (* 64 1024))) -;; -;; See also: -;; - https://github.com/Sarcasm/company-irony -;; - https://github.com/Sarcasm/flycheck-irony -;; - https://github.com/Sarcasm/ac-irony - -;;; Code: - -(require 'irony-iotask) - -(autoload 'irony-completion--enter "irony-completion") -(autoload 'irony-completion--exit "irony-completion") - -(require 'cl-lib) - -(autoload 'find-library-name "find-func") -(autoload 'lm-version "lisp-mnt") - - -;; -;; Compatibility -;; - -(eval-and-compile - - ;; As seen in flycheck/magit - ;; - ;; Added in Emacs 24.3 (mirrors/emacs@b335efc3). - (unless (fboundp 'setq-local) - (defmacro setq-local (var val) - "Set variable VAR to value VAL in current buffer." - (list 'set (list 'make-local-variable (list 'quote var)) val))) - - ;; Added in Emacs 24.3 (mirrors/emacs@b335efc3). - (unless (fboundp 'defvar-local) - (defmacro defvar-local (var val &optional docstring) - "Define VAR as a buffer-local variable with default value VAL. -Like `defvar' but additionally marks the variable as being -automatically buffer-local wherever it is set." - (declare (debug defvar) (doc-string 3)) - (list 'progn (list 'defvar var val docstring) - (list 'make-variable-buffer-local (list 'quote var))))) - - ) ;; eval-and-compile - - -;; -;; Customizable variables -;; - -(defgroup irony nil - "C/C++ minor mode powered by libclang." - :group 'c) - -(defcustom irony-lighter " Irony" - "Text to display in the mode line when irony mode is on." - :type 'string - :group 'irony) - -(defcustom irony-extra-cmake-args nil - "Extra arguments to CMake when compiling the server." - :type '(repeat string) - :group 'irony) - -(defcustom irony-user-dir (locate-user-emacs-file "irony/") - "Directory containing the Irony generated files. - -The slash is expected at the end." - :type 'directory - :risky t - :group 'irony) - -(defcustom irony-supported-major-modes '(c++-mode - c-mode - objc-mode) - "List of modes known to be compatible with Irony." - :type '(repeat symbol) - :group 'irony) - -;;;###autoload -(defcustom irony-additional-clang-options nil - "Additional command line options to pass down to libclang. - -Please, do NOT use this variable to add header search paths, only -additional warnings or compiler options. - -These compiler options will be prepended to the command line, in -order to not override the value coming from a compilation -database." - :type '(repeat string) - :options '("-Wdocumentation") - :group 'irony) - -(defcustom irony-lang-compile-option-alist - '((c++-mode . "c++") - (c-mode . "c") - (objc-mode . "objective-c")) - "Alist to decide the language option to used based on the `major-mode'." - :type '(alist :key-type symbol :value-type string) - :group 'irony) - -(defcustom irony-cmake-executable "cmake" - "Name or path of the CMake executable." - :type 'string - :group 'irony) - -(defcustom irony-server-source-dir nil - "Points to the irony-server source directory. - -This should point to the directory that contains the top-most -CMakeLists.txt used to build the server. - -By default it will find the directory based on the irony.el directory." - :type 'directory - :group 'irony - :package-version '(irony . "1.2.0")) - -(defcustom irony-server-build-dir nil - "Build directory for irony-server. - -If set to nil the default is to create a build directory in -`temporary-file-directory'/build-irony-server-`(irony-version)'." - :type 'directory - :group 'irony) - -(defcustom irony-server-install-prefix irony-user-dir - "Installation prefix used to install irony-server. - -The irony-server executable is expected to be in -`irony-server-install-prefix'/bin/." - :type 'directory - :group 'irony) - -(defcustom irony-server-w32-pipe-buffer-size nil - "Windows-only setting, -the buffer size to use for the irony-server process pipe on Windows. - -Larger values can improve performances on large buffers. - -If non-nil, `w32-pipe-buffer-size' will be let-bound to this value -during the creation of the irony-server process.") - - -;; -;; Public/API variables -;; -;; Non-customizable variables provided by Irony that can be useful to other -;; packages. -;; -;; Note that they shouldn't be modified directly by external packages, just -;; read. -;; - -;; TODO: make this variable public when the CDB API stabilizes. -(defvar-local irony--compile-options nil - "Compile options for the current file. - -The compile options used by the compiler to build the current -buffer file.") - -;; TODO: make this variable public when the CDB API stabilizes. -(defvar-local irony--working-directory nil - "The working directory to pass to libclang, if any.") - - -;; -;; Internal variables -;; -;; The prefix `irony--' is used when something can completely change (or -;; disappear) from one release to the other. -;; -;; -- https://lists.gnu.org/archive/html/emacs-devel/2013-06/msg01129.html - -(defconst irony--eot "\n;;EOT\n" - "String sent by the server to signal the end of a response.") - - -;; -;; Error conditions -;; - -;; `define-error' breaks backward compatibility with Emacs < 24.4 -(defun irony--define-error (name message &optional parent) - "Define NAME as a new error signal. -MESSAGE is a string that will be output to the echo area if such an error -is signaled without being caught by a `condition-case'. -PARENT is either a signal or a list of signals from which it inherits. -Defaults to `error'." - (unless parent (setq parent 'error)) - (let ((conditions - (if (consp parent) - (apply #'nconc - (mapcar (lambda (parent) - (cons parent - (or (get parent 'error-conditions) - (error "Unknown signal `%s'" parent)))) - parent)) - (cons parent (get parent 'error-conditions))))) - (put name 'error-conditions - (delete-dups (copy-sequence (cons name conditions)))) - (when message (put name 'error-message message)))) - -(irony--define-error 'irony-error "Irony-Mode error") -(irony--define-error 'irony-parse-error "Irony-Mode parsing error" 'irony-error) -(irony--define-error 'irony-server-error "Irony-Mode server error" 'irony-error) - - -;; -;; Utility functions & macros -;; - -;; TODO: remove and use `if-let' when supported version jumps to Emacs 25.1 -(defmacro irony--aif (test if-expr &rest else-body) - (declare (indent 2)) - `(let ((it ,test)) - (if it - ,if-expr - (progn ,@else-body)))) - -;; TODO: remove and use `when-let' when supported version jumps to Emacs 25.1 -(defmacro irony--awhen (test &rest body) - (declare (indent 1)) - `(let ((it ,test)) - (when it - (progn ,@body)))) - -(defun irony--assoc-all (key list) - (delq nil (mapcar (lambda (c) - (when (equal (car c) key) - c)) - list))) - -(defmacro irony--without-narrowing (&rest body) - "Remove the effect of narrowing for the current buffer. - -Note: If `save-excursion' is needed for BODY, it should be used -before calling this macro." - (declare (indent 0) (debug t)) - `(save-restriction - (widen) - (progn ,@body))) - -(defun irony--buffer-size-in-bytes () - "Return the buffer size, in bytes." - (1- (position-bytes (point-max)))) - -(defun irony--read-char-choice (prompt chars) - "Wrapper around `read-char-choice', available since Emacs 24." - (setq prompt (concat prompt " [" chars "]: ")) - (if (fboundp 'read-char-choice) - (read-char-choice prompt chars) - (setq prompt (propertize prompt 'face 'minibuffer-prompt)) - (let ((cursor-in-echo-area t) - k) - (while (not (member k chars)) - (setq k (read-char-exclusive prompt))) - k))) - -(defun irony--shorten-path (path) - "Make PATH as short as possible. - -The given path can be considered understandable by human but not -necessary a valid path string to use in code. Its only purpose is -to be displayed to the user." - (let ((relative (file-relative-name path)) - (abbreviated (abbreviate-file-name path))) - (if (< (string-width relative) (string-width abbreviated)) - relative - abbreviated))) - -(defun irony--split-command-line-1 (quoted-str) - "Remove the escaped quotes and backlash from a QUOTED-STR. - -Return a list of the final characters in the reverse order. - -Only to be consumed by `irony--split-command-line'." - (let ((len (length quoted-str)) - (i 0) - ch next-ch - result) - (while (< i len) - (setq ch (aref quoted-str i)) - (when (eq ch ?\\) - (let ((next-ch (and (< (1+ i) len) - (aref quoted-str (1+ i))))) - (when (member next-ch '(?\\ ?\")) - (setq ch next-ch) - (cl-incf i)))) - (push ch result) - (cl-incf i)) - result)) - -;; TODO: rewrite the function correctly to handle things like the following: -;; -;; "/usr/bin/clang++ -Irelative -DSOMEDEF=\"With spaces, quotes and \\-es.\" <args...>" -(defun irony--split-command-line (cmd-line) - "Split CMD-LINE into a list of arguments. - -Takes care of double quotes as well as backslash. - -Sadly I had to write this because `split-string-and-unquote' -breaks with escaped quotes in compile_commands.json, such as in: - - /usr/bin/c++ -DLLVM_VERSION_INFO=\\\\\\\"3.2svn\\\\\\\" <args>" - ;; everytime I write a function like this one, it makes me feel bad - (let* ((len (length cmd-line)) - (spaces (string-to-list " \f\t\n\r\v")) - (first-not-spaces-re (concat "[^" spaces "]")) - (i 0) - ch - args cur-arg) - (while (< i len) - (setq ch (aref cmd-line i)) - (cond - ((member ch spaces) ;spaces - (when cur-arg - (setq args (cons (apply 'string (nreverse cur-arg)) args) - cur-arg nil)) - ;; move to the next char - (setq i (or (string-match-p first-not-spaces-re cmd-line i) - len))) - ((eq ch ?\") ;quoted string - (let ((endq (string-match-p "[^\\]\"" cmd-line i))) - (unless endq - (signal 'irony-parse-error (list "ill formed command line" cmd-line))) - (let ((quoted-str (substring cmd-line (1+ i) (1+ endq)))) - (setq cur-arg (append (irony--split-command-line-1 quoted-str) - cur-arg) - i (+ endq 2))))) - (t ;a valid char - ;; if it's an escape of: a backslash, a quote or a space push - ;; only the following char. - (when (eq ch ?\\) - (let ((next-ch (and (< (1+ i) len) - (aref cmd-line (1+ i))))) - (when (or (member next-ch '(?\\ ?\")) - (member next-ch spaces)) - (setq ch next-ch) - (cl-incf i)))) - (push ch cur-arg) - (cl-incf i)))) - (when cur-arg - (setq args (cons (apply 'string (nreverse cur-arg)) args))) - (nreverse args))) - -(defun irony--get-buffer-path-for-server (&optional buffer) - "Get the path of the current buffer to send to irony-server. - -If no such file exists on the filesystem the special file '-' is - returned instead." - (let ((file (buffer-file-name buffer))) - (if (and file (file-exists-p file)) - file - "-"))) - - -;; -;; Mode -;; - -(defvar irony-mode-map (make-sparse-keymap) - "Keymap used in `irony-mode' buffers.") - -;;;###autoload -(define-minor-mode irony-mode - "Minor mode for C, C++ and Objective-C, powered by libclang." - nil - irony-lighter - irony-mode-map - :group 'irony - (if irony-mode - (irony--mode-enter) - (irony--mode-exit))) - -(defun irony--mode-enter () - ;; warn the user about modes such as php-mode who inherits c-mode - (when (not (memq major-mode irony-supported-major-modes)) - (display-warning 'irony "Major mode is unknown to Irony,\ - see `irony-supported-major-modes'.")) - ;; warn the user about Windows-specific issues - (when (eq system-type 'windows-nt) - (cond - ((version< emacs-version "24.4") - (display-warning 'irony "Emacs >= 24.4 expected on Windows.")) - ((and (boundp 'w32-pipe-read-delay) (> w32-pipe-read-delay 0)) - (display-warning 'irony "Performance will be bad because a\ - pipe delay is set for this platform (see variable\ - `w32-pipe-read-delay').")))) - (irony-completion--enter)) - -(defun irony--mode-exit () - (irony-completion--exit)) - -;;;###autoload -(defun irony-version (&optional show-version) - "Return the version number of the file irony.el. - -If called interactively display the version in the echo area." - (interactive (list t)) - ;; Shamelessly stolen from `company-mode'. - (with-temp-buffer - (insert-file-contents (find-library-name "irony")) - (let ((v (lm-version))) - (when show-version - (message "irony version: %s" v)) - v))) - - -;; -;; Compile options handling -;; - -(defun irony--lang-compile-option () - (irony--awhen (cdr-safe (assq major-mode irony-lang-compile-option-alist)) - (list "-x" it))) - -(defun irony--extract-working-directory-option (flags) - "Return working directory specified on the command line, if -any." - (catch 'found - (while flags - (let ((flag (car flags))) - (cond - ((string= "-working-directory" flag) - (throw 'found (cadr flags))) - ((string-prefix-p "-working-directory=" flag) - (throw 'found (substring flag (length "-working-directory=")))) - (t - (setq flags (cdr flags)))))))) - -(defun irony--adjust-compile-options () - "The compile options to send to libclang." - ;; TODO: if current buffer has no associated file (will be sent as '-') but is - ;; in an existing directory, we will want to add -I (directory-file-name - ;; buffer-file-name) to find the relative headers - (append - (irony--lang-compile-option) - (irony--awhen irony--working-directory - (unless (irony--extract-working-directory-option irony--compile-options) - (list "-working-directory" it))) - irony-additional-clang-options - irony--compile-options)) - -(defun irony--extract-user-search-paths (compile-options work-dir) - "Retrieve the user search paths present in COMPILE-OPTIONS. - -Relative paths are expanded to be relative to WORK-DIR. - -The returned paths are returned as -directory (`file-name-as-directory'). - -Note: WORK-DIR is not used when the compile option -'-working-directory=<directory>' is detected in COMPILE-OPTIONS." - (setq work-dir (or (irony--extract-working-directory-option compile-options) - work-dir)) - (let (include-dirs opt) - (while (setq opt (car compile-options)) - (cond - ((string= "-I" opt) - (add-to-list 'include-dirs (nth 1 compile-options) t) - (setq compile-options (cddr compile-options))) - ((string-prefix-p "-I" opt) - (add-to-list 'include-dirs (substring opt 2) t) - (setq compile-options (cdr compile-options))) - (t - (setq compile-options (cdr compile-options))))) - (delete-dups (mapcar #'(lambda (path) - (file-name-as-directory - (expand-file-name path work-dir))) - include-dirs)))) - - -;; -;; Irony-Server setup -;; - -(defvar irony--server-install-command-history nil) -(defun irony--install-server-read-command (command) - (read-shell-command - "Install command: " command - (if (equal (car irony--server-install-command-history) command) - '(irony--server-install-command-history . 1) - 'irony--server-install-command-history))) - -(defun irony-install-server (command) - "Install or reinstall the Irony server. - -The installation requires CMake and the libclang development package." - (interactive - (list (let ((command - (format - (concat "%s %s %s %s && %s --build . " - "--use-stderr --config Release --target install") - (shell-quote-argument irony-cmake-executable) - (shell-quote-argument (concat "-DCMAKE_INSTALL_PREFIX=" - (expand-file-name - irony-server-install-prefix))) - (mapconcat 'shell-quote-argument irony-extra-cmake-args " ") - (shell-quote-argument - (or irony-server-source-dir - (expand-file-name "server" - (file-name-directory - (find-library-name "irony"))))) - (shell-quote-argument irony-cmake-executable)))) - (irony--install-server-read-command command)))) - (let ((build-dir (or irony-server-build-dir - (concat - (file-name-as-directory temporary-file-directory) - (file-name-as-directory (format "build-irony-server-%s" - (irony-version))))))) - (make-directory build-dir t) - (let ((default-directory build-dir)) - ;; we need to kill the process to be able to install a new one, - ;; at least on Windows - (irony-server-kill) - (with-current-buffer (compilation-start command nil - #'(lambda (maj-mode) - "*irony-server build*")) - (setq-local compilation-finish-functions - '(irony--server-install-finish-function)))))) - -(defun irony--server-install-finish-function (buffer msg) - (if (string= "finished\n" msg) - (message "irony-server installed successfully!") - (message "Failed to build irony-server, you are on your own buddy!"))) - -(defun irony--find-server-executable () - "Return the path to the irony-server executable. - -Throw an `irony-server-error' if a proper executable cannot be -found." - (let* ((exec-path (cons (expand-file-name "bin" irony-server-install-prefix) - exec-path)) - (exe (executable-find "irony-server"))) - (condition-case err - (let ((version (car (process-lines exe "--version")))) - (if (and (string-match "^irony-server version " version) - (version= (irony-version) - (substring version - (length "irony-server version ")))) - ;; irony-server is working and up-to-date! - exe - (signal 'irony-server-error - (list - (format "irony-server version mismatch: %s" - (substitute-command-keys - "type `\\[irony-install-server]' to reinstall")))))) - (irony-server-error - (signal (car err) (cdr err))) - (error - (signal 'irony-server-error - (if (and exe - (file-executable-p exe)) - ;; failed to execute due to a runtime problem, i.e: - ;; libclang.so isn't in the ld paths - (list (format "irony-server is broken! %s" - (error-message-string err))) - ;; irony-server doesn't exists, first time irony-mode is used? - ;; inform the user about how to build the executable - (list - (format "irony-server not installed! %s" - (substitute-command-keys - "Type `\\[irony-install-server]' to install"))))))))) - - -;; -;; irony-server process management. -;; - -(defvar irony--server-executable nil) -(defvar irony--server-process nil) -(defvar irony--server-buffer " *Irony*" - "The name of the buffer for the irony process to run in. - -When using a leading space, the buffer is hidden from the buffer -list (and undo information is not kept).") - -(defun irony--start-server-process () - (unless irony--server-executable - ;; if not found, an `irony-server-error' error is signaled - (setq irony--server-executable (irony--find-server-executable))) - (let ((process-connection-type nil) - (process-adaptive-read-buffering nil) - (w32-pipe-buffer-size (when (boundp 'w32-pipe-buffer-size) - (or irony-server-w32-pipe-buffer-size - w32-pipe-buffer-size))) - process) - (setq process - (start-process-shell-command - "Irony" ;process name - irony--server-buffer ;buffer - (format "%s -i 2> %s" ;command - (shell-quote-argument irony--server-executable) - (expand-file-name - (format-time-string "irony.%Y-%m-%d_%Hh-%Mm-%Ss.log") - temporary-file-directory)))) - (set-process-query-on-exit-flag process nil) - (irony-iotask-setup-process process) - process)) - -;;;###autoload -(defun irony-server-kill () - "Kill the running irony-server process, if any." - (interactive) - (when (process-live-p irony--server-process) - (kill-process irony--server-process) - (setq irony--server-process nil))) - -(defun irony--get-server-process-create () - (unless (process-live-p irony--server-process) - (setq irony--server-process (irony--start-server-process))) - irony--server-process) - -(defun irony--run-task (task) - (irony-iotask-run (irony--get-server-process-create) task)) - -(defun irony--run-task-asynchronously (task callback) - (irony-iotask-schedule (irony--get-server-process-create) task callback)) - -(defun irony--quote-strings (strings &optional separator) - "Like `combine-and-quote-strings', but when the string is \"\" or nil, -`irony--quote-strings' will convert it to \"\" instead of <SPC>. -That is: - - (irony--quote-strings \'(\"a\" \"\" \"b\")) => \"a \\\"\\\" b\" - (combine-and-quote-strings \'(\"a\" \"\" \"b\")) => \"a b\" -" - (let* ((sep (or separator " ")) - (re (concat "[\\\"]" "\\|" (regexp-quote sep)))) - (mapconcat - (lambda (str) - (cond - ((or (not str) (string= str "")) - "\"\"") - ((string-match re str) - (concat "\"" (replace-regexp-in-string "[\\\"]" "\\\\\\&" str) "\"")) - (t str))) - strings sep))) - -(defun irony--server-send-command (command &rest args) - (let ((command-line (concat (irony--quote-strings - (mapcar (lambda (arg) - (if (numberp arg) - (number-to-string arg) - arg)) - (cons command args))) - "\n"))) - (irony-iotask-send-string command-line))) - -;; XXX: this code can run in very tight very sensitive on big inputs, -;; every change should be measured -(defun irony--server-command-update (&rest _args) - (when (and (>= (buffer-size) (length irony--eot)) - (string-equal (buffer-substring-no-properties - (- (point-max) (length irony--eot)) (point-max)) - irony--eot)) - (condition-case-unless-debug nil - (let ((result (read (current-buffer)))) - (cl-case (car result) - (success - (irony-iotask-set-result (cdr result))) - (error - (apply #'irony-iotask-set-error 'irony-server-error - (cdr result))))) - (error - (throw 'invalid-msg t))))) - -;; FIXME: code duplication with `irony--server-command-update' -;; XXX: this code can run in very tight very sensitive on big inputs, -;; every change should be measured -(defun irony--server-query-update (&rest _args) - (when (and (>= (buffer-size) (length irony--eot)) - (string-equal (buffer-substring-no-properties - (- (point-max) (length irony--eot)) (point-max)) - irony--eot)) - (condition-case-unless-debug nil - (irony-iotask-set-result (read (current-buffer))) - (error - (throw 'invalid-msg t))))) - - -;; -;; Server commands -;; - -(irony-iotask-define-task irony--t-get-compile-options - "`get-compile-options' server command." - :start (lambda (build-dir file) - (irony--server-send-command "get-compile-options" build-dir file)) - :update irony--server-command-update) - -(defun irony--get-compile-options-task (build-dir file) - (irony-iotask-package-task irony--t-get-compile-options build-dir file)) - -(cl-defstruct (irony--buffer-state - (:constructor irony--buffer-state-create-1)) - file - exists - modified - tick) - -(defun irony--buffer-state-create (buffer) - (let ((file (buffer-file-name buffer))) - (irony--buffer-state-create-1 :file file - :exists (and file (file-exists-p file)) - :modified (buffer-modified-p buffer) - :tick (buffer-chars-modified-tick buffer)))) - -(defun irony--buffer-state-compare (old new) - (unless (equal old new) - (cond - ((irony--buffer-state-modified new) 'set-unsaved) - ((null old) nil) ;noop - ((and - (irony--buffer-state-modified old) - (irony--buffer-state-exists old)) 'reset-unsaved)))) - -(irony-iotask-define-task irony--t-set-unsaved - "`set-unsaved' server command." - :start (lambda (process buffer buf-state) - (let ((elem (assq buffer (process-get process :unsaved-buffers))) - temp-file) - (if (eq (cdr elem) buf-state) - ;; early exit if already cached - (irony-iotask-set-result t) - (setq temp-file (make-temp-file "irony-unsaved-")) - (irony-iotask-put :temp-file temp-file) - (irony-iotask-put :buffer-state buf-state) - (process-put process :buffer-state buf-state) - (with-current-buffer buffer - (irony--without-narrowing - (let ((write-region-inhibit-fsync t)) - (write-region nil nil temp-file nil 0))) - (irony--server-send-command "set-unsaved" - (irony--get-buffer-path-for-server) - temp-file))))) - :update irony--server-command-update - :finish (lambda (&rest _args) - (delete-file (irony-iotask-get :temp-file))) - :on-success - (lambda (process buffer &rest _args) - (let* ((unsaved-buffers (process-get process :unsaved-buffers)) - (elem (assq buffer unsaved-buffers)) - (buf-state (irony-iotask-get :buffer-state))) - (if elem - (setcdr elem buf-state) - (process-put process :unsaved-buffers (cons (cons buffer buf-state) - unsaved-buffers)))))) - -(defun irony--set-unsaved-task (process buffer buf-state) - (irony-iotask-package-task irony--t-set-unsaved process buffer buf-state)) - -(irony-iotask-define-task irony--t-reset-unsaved - "`reset-unsaved' server command." - :start (lambda (process buffer) - (if (assq buffer (process-get process :unsaved-buffers)) - (irony--server-send-command "reset-unsaved" - (irony--get-buffer-path-for-server - buffer)) - ;; exit early if already reset - (irony-iotask-set-result t))) - :update irony--server-command-update - :finish (lambda (process buffer) - (process-put - process - :unsaved-buffers - (assq-delete-all buffer (process-get process :unsaved-buffers))))) - -(defun irony--reset-unsaved-task (process buffer) - (irony-iotask-package-task irony--t-reset-unsaved process buffer)) - -(defun irony--list-unsaved-irony-mode-buffers (&optional ignore-list) - (delq nil (mapcar (lambda (buf) - (unless (memq buf ignore-list) - (when (buffer-modified-p buf) - (with-current-buffer buf - (and irony-mode buf))))) - (buffer-list)))) - -(defun irony--get-buffer-change-alist (process) - "Return a list of (buffer . old-state). - -old-state can be nil if the old state isn't known." - (let ((unsaved-list (process-get process :unsaved-buffers))) - (append unsaved-list - (mapcar (lambda (buf) - (cons buf nil)) - (irony--list-unsaved-irony-mode-buffers - (mapcar #'car unsaved-list)))))) - -(defun irony--unsaved-buffers-tasks () - (let ((process (irony--get-server-process-create)) - result) - (dolist (buffer-old-state-cons (irony--get-buffer-change-alist process) - result) - (let* ((buffer (car buffer-old-state-cons)) - (old-state (cdr buffer-old-state-cons)) - (new-state (irony--buffer-state-create buffer)) - (task - (cl-case (irony--buffer-state-compare old-state new-state) - (set-unsaved - (irony--set-unsaved-task process buffer new-state)) - (reset-unsaved - (irony--reset-unsaved-task process buffer))))) - (when task - (setq result (if result - (irony-iotask-chain result task) - task))))))) - -(irony-iotask-define-task irony--t-parse - "`parse' server command." - :start (lambda (file compile-options) - (apply #'irony--server-send-command "parse" file "--" - compile-options)) - :update irony--server-command-update) - -(defun irony--parse-task-1 (&optional buffer) - (with-current-buffer (or buffer (current-buffer)) - (irony-iotask-package-task irony--t-parse - (irony--get-buffer-path-for-server) - (irony--adjust-compile-options)))) - -(defun irony--parse-task (&optional buffer) - (let ((unsaved-tasks (irony--unsaved-buffers-tasks)) - (parse-task (irony--parse-task-1 buffer))) - (if unsaved-tasks - (irony-iotask-chain unsaved-tasks parse-task) - parse-task))) - -(irony-iotask-define-task irony--t-diagnostics - "`parse' server command." - :start (lambda () - (irony--server-send-command "diagnostics")) - :update irony--server-query-update) - -(defun irony--diagnostics-task (&optional buffer) - (irony-iotask-chain - (irony--parse-task buffer) - (irony-iotask-package-task irony--t-diagnostics))) - -(irony-iotask-define-task irony--t-get-type - "`get-type' server command." - :start (lambda (line col) - (irony--server-send-command "get-type" line col)) - :update irony--server-query-update) - -(defun irony--get-type-task (&optional buffer pos) - (let ((line-column (irony--completion-line-column pos))) - (irony-iotask-chain - (irony--parse-task buffer) - (irony-iotask-package-task irony--t-get-type - (car line-column) (cdr line-column))))) - -;;;###autoload -(defun irony-get-type () - "Get the type of symbol under cursor." - (interactive) - (let ((types (irony--run-task (irony--get-type-task)))) - (unless types - (user-error "Type not found")) - (if (and (cdr types) (not (string= (car types) (cadr types)))) - (message "%s (aka '%s')" (car types) (cadr types)) - (message "%s" (car types))))) - -(defun irony-parse-buffer-async (&optional callback) - "Parse the current buffer sending results to an optional - CALLBACK function." - (irony--run-task-asynchronously (irony--parse-task) - (or callback #'ignore))) - -(provide 'irony) - -;; Local Variables: -;; byte-compile-warnings: (not cl-functions) -;; End: - -;;; irony.el ends here |