New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
lisp function to run compilation? #1553
Comments
I think that's a good idea and it should pretty easy to implement it. |
How would you advise implementing it? I thought if the function set using Thoughts? |
This seems to be working for me: @@ -3843,8 +3843,11 @@
((not command) nil)
((stringp command) command)
((functionp command)
- (if (fboundp command)
- (funcall (symbol-function command))))
+ (when (fboundp command)
+ (if (commandp command)
+ (prog1 nil
+ (funcall-interactively command))
+ (funcall (symbol-function command)))))
(t
(error "The value for: %s in project-type: %s was neither a function nor a string" command-type project-type))))) alongside: (defmacro assoc-pop! (key alist)
`(let ((result (assoc ,key ,alist)))
(setq ,alist (delete result ,alist))
result))
(assoc-pop! 'rust-cargo projectile-project-types)
(projectile-register-project-type 'rust-cargo '("Cargo.toml")
:compile #'rustic-compile
:test #'rustic-cargo-test
:run #'rustic-cargo-run) on a slight tangent, does projectile have a function to reassign fields in |
Kay, my earlier fix doesn't seem to be working. Now I'm getting the following stacktrace when debug-on-error is true, which I can only presume is because projectile expects commands to be strings and returning nil to skip evaluating isn't valid. Debugger entered--Lisp error: (wrong-type-argument stringp nil)
string-match("\\`\\s *cd\\(?:\\s +\\(\\S +?\\|'[^']*'\\|\"\\(?:[^\"`$\\]\\|\\\\..." nil)
#f(compiled-function (command &optional mode name-function highlight-regexp) "Run compilation command COMMAND (low level interface).\nIf COMMAND starts with a cd command, that becomes the `default-directory'.\nThe rest of the arguments are optional; for them, nil means use the default.\n\nMODE is the major mode to set in the compilation buffer. Mode\nmay also be t meaning use `compilation-shell-minor-mode' under `comint-mode'.\n\nIf NAME-FUNCTION is non-nil, call it with one argument (the mode name)\nto determine the buffer name. Otherwise, the default is to\nreuses the current buffer if it has the proper major mode,\nelse use or create a buffer with name based on the major mode.\n\nIf HIGHLIGHT-REGEXP is non-nil, `next-error' will temporarily highlight\nthe matching section of the visited source line; the default is to use the\nglobal value of `compilation-highlight-regexp'.\n\nReturns the compilation buffer created." #<bytecode 0x15616979e699>)(nil nil)
apply(#f(compiled-function (command &optional mode name-function highlight-regexp) "Run compilation command COMMAND (low level interface).\nIf COMMAND starts with a cd command, that becomes the `default-directory'.\nThe rest of the arguments are optional; for them, nil means use the default.\n\nMODE is the major mode to set in the compilation buffer. Mode\nmay also be t meaning use `compilation-shell-minor-mode' under `comint-mode'.\n\nIf NAME-FUNCTION is non-nil, call it with one argument (the mode name)\nto determine the buffer name. Otherwise, the default is to\nreuses the current buffer if it has the proper major mode,\nelse use or create a buffer with name based on the major mode.\n\nIf HIGHLIGHT-REGEXP is non-nil, `next-error' will temporarily highlight\nthe matching section of the visited source line; the default is to use the\nglobal value of `compilation-highlight-regexp'.\n\nReturns the compilation buffer created." #<bytecode 0x15616979e699>) (nil nil))
compilation-start(nil nil)
compile(nil)
(if (functionp cmd) (funcall cmd) (compile cmd))
projectile-run-compilation(nil)
(let* ((project-root (projectile-project-root)) (default-directory (projectile-compilation-dir)) (command (projectile-maybe-read-command show-prompt command prompt-prefix))) (if command-map (progn (puthash default-directory command command-map) (ring-insert (projectile--get-command-history project-root) command))) (if save-buffers (progn (save-some-buffers (not compilation-ask-about-save) #'(lambda nil (projectile-project-buffer-p (current-buffer) project-root))))) (if (file-directory-p default-directory) nil (mkdir default-directory)) (projectile-run-compilation command) command)
(progn (let ((--cl-keys-- --cl-rest--)) (while --cl-keys-- (cond ((memq (car --cl-keys--) '(:show-prompt :prompt-prefix :save-buffers :allow-other-keys)) (setq --cl-keys-- (cdr (cdr --cl-keys--)))) ((car (cdr (memq ... --cl-rest--))) (setq --cl-keys-- nil)) (t (error "Keyword argument %s not one of (:show-prompt :prom..." (car --cl-keys--)))))) (let* ((project-root (projectile-project-root)) (default-directory (projectile-compilation-dir)) (command (projectile-maybe-read-command show-prompt command prompt-prefix))) (if command-map (progn (puthash default-directory command command-map) (ring-insert (projectile--get-command-history project-root) command))) (if save-buffers (progn (save-some-buffers (not compilation-ask-about-save) #'(lambda nil (projectile-project-buffer-p ... project-root))))) (if (file-directory-p default-directory) nil (mkdir default-directory)) (projectile-run-compilation command) command))
(let* ((show-prompt (car (cdr (plist-member --cl-rest-- ':show-prompt)))) (prompt-prefix (car (cdr (plist-member --cl-rest-- ':prompt-prefix)))) (save-buffers (car (cdr (plist-member --cl-rest-- ':save-buffers))))) (progn (let ((--cl-keys-- --cl-rest--)) (while --cl-keys-- (cond ((memq (car --cl-keys--) '...) (setq --cl-keys-- (cdr ...))) ((car (cdr ...)) (setq --cl-keys-- nil)) (t (error "Keyword argument %s not one of (:show-prompt :prom..." (car --cl-keys--)))))) (let* ((project-root (projectile-project-root)) (default-directory (projectile-compilation-dir)) (command (projectile-maybe-read-command show-prompt command prompt-prefix))) (if command-map (progn (puthash default-directory command command-map) (ring-insert (projectile--get-command-history project-root) command))) (if save-buffers (progn (save-some-buffers (not compilation-ask-about-save) #'(lambda nil ...)))) (if (file-directory-p default-directory) nil (mkdir default-directory)) (projectile-run-compilation command) command)))
projectile--run-project-cmd(nil #<hash-table equal 1/65 0x156169a00e9d> :show-prompt nil :prompt-prefix "Compile command: " :save-buffers t)
(let ((command (projectile-compilation-command (projectile-compilation-dir)))) (projectile--run-project-cmd command projectile-compilation-cmd-map :show-prompt arg :prompt-prefix "Compile command: " :save-buffers t))
(closure (projectile-grep-find-unignored-patterns projectile-grep-find-ignored-patterns projectile-grep-find-unignored-paths projectile-grep-find-ignored-paths t) (arg) "Run project compilation command.\n\nNormally you'll ..." (interactive "P") (let ((command (projectile-compilation-command (projectile-compilation-dir)))) (projectile--run-project-cmd command projectile-compilation-cmd-map :show-prompt arg :prompt-prefix "Compile command: " :save-buffers t)))(nil)
funcall((closure (projectile-grep-find-unignored-patterns projectile-grep-find-ignored-patterns projectile-grep-find-unignored-paths projectile-grep-find-ignored-paths t) (arg) "Run project compilation command.\n\nNormally you'll ..." (interactive "P") (let ((command (projectile-compilation-command (projectile-compilation-dir)))) (projectile--run-project-cmd command projectile-compilation-cmd-map :show-prompt arg :prompt-prefix "Compile command: " :save-buffers t))) nil)
(if (and (consp prefix) (setq prefix (car prefix)) (>= prefix 16)) (let* ((vnew (symbol-function 'compile)) (old (symbol-function 'actual-compile))) (unwind-protect (progn (fset 'actual-compile vnew) (let* ((vnew #'...) (old (symbol-function ...))) (unwind-protect (progn (fset ... vnew) (funcall func ...)) (fset 'compile old)))) (fset 'actual-compile old))) (funcall func prefix))
(let ((prefix current-prefix-arg)) (if (and (consp prefix) (setq prefix (car prefix)) (>= prefix 16)) (let* ((vnew (symbol-function 'compile)) (old (symbol-function 'actual-compile))) (unwind-protect (progn (fset 'actual-compile vnew) (let* ((vnew ...) (old ...)) (unwind-protect (progn ... ...) (fset ... old)))) (fset 'actual-compile old))) (funcall func prefix)))
projectile-compile--double-prefix-means-run-comint((closure (projectile-grep-find-unignored-patterns projectile-grep-find-ignored-patterns projectile-grep-find-unignored-paths projectile-grep-find-ignored-paths t) (arg) "Run project compilation command.\n\nNormally you'll ..." (interactive "P") (let ((command (projectile-compilation-command (projectile-compilation-dir)))) (projectile--run-project-cmd command projectile-compilation-cmd-map :show-prompt arg :prompt-prefix "Compile command: " :save-buffers t))) nil)
apply(projectile-compile--double-prefix-means-run-comint (closure (projectile-grep-find-unignored-patterns projectile-grep-find-ignored-patterns projectile-grep-find-unignored-paths projectile-grep-find-ignored-paths t) (arg) "Run project compilation command.\n\nNormally you'll ..." (interactive "P") (let ((command (projectile-compilation-command (projectile-compilation-dir)))) (projectile--run-project-cmd command projectile-compilation-cmd-map :show-prompt arg :prompt-prefix "Compile command: " :save-buffers t))) nil)
projectile-compile-project(nil)
funcall-interactively(projectile-compile-project nil)
call-interactively(projectile-compile-project nil nil)
command-execute(projectile-compile-project) checking whether a command is nil before trying to run it seems to work, @@ -4039,10 +4039,11 @@
with a prefix ARG."
(interactive "P")
(let ((command (projectile-compilation-command (projectile-compilation-dir))))
- (projectile--run-project-cmd command projectile-compilation-cmd-map
- :show-prompt arg
- :prompt-prefix "Compile command: "
- :save-buffers t)))
+ (when command
+ (projectile--run-project-cmd command projectile-compilation-cmd-map
+ :show-prompt arg
+ :prompt-prefix "Compile command: "
+ :save-buffers t))))
;;;###autoload
(defun projectile-test-project (arg)
@@ -4053,10 +4054,11 @@
with a prefix ARG."
(interactive "P")
(let ((command (projectile-test-command (projectile-compilation-dir))))
- (projectile--run-project-cmd command projectile-test-cmd-map
- :show-prompt arg
- :prompt-prefix "Test command: "
- :save-buffers t)))
+ (when command
+ (projectile--run-project-cmd command projectile-test-cmd-map
+ :show-prompt arg
+ :prompt-prefix "Test command: "
+ :save-buffers t))))
;;;###autoload
(defun projectile-run-project (arg)
@@ -4067,9 +4069,10 @@
with a prefix ARG."
(interactive "P")
(let ((command (projectile-run-command (projectile-compilation-dir))))
- (projectile--run-project-cmd command projectile-run-cmd-map
- :show-prompt arg
- :prompt-prefix "Run command: ")))
+ (when command
+ (projectile--run-project-cmd command projectile-run-cmd-map
+ :show-prompt arg
+ :prompt-prefix "Run command: "))))
;;;###autoload
(defun projectile-repeat-last-command (show-prompt) but I don't think this is a good way to do this. maybe if |
Have you had more time to consider how this should be approached? I was getting round to implementing it only to find that projectile has a caching mechanism in place for compilation commands and I'm not sure how this would interact with that? |
@bbatsov Do you have any feedback on this? I'm interested on it and, if my Elisp abilities are good enough to tackle it, I'd like to take a stab at it. |
@pataquets You may be interested in https://github.com/mohkale/projection. It's a WIP projectile replacement for myself where I'm also experimenting with some more IDE like features. It supports compilation commands as functions out of the box (specifically for rustic mode). Not really public facing yet since some of the extensions aren't on MELPA but I've been using it on and off for a bit. |
Thank you very much, @mohkale. I wasn't aware of projection, and I've read the rationale behind it and learnt a lot. Specially, I'll take a look at multi-compile packages. EDIT: Replied to wrong user initially, my apologies for the noise. Time to go to sleep. |
FYI - Projectile's development is just as active as ever. (at least from my perspective) |
Sorry, @bbatsov. Wrongly replied to you initially. Apologies for the noise. |
Just a little "beep here!. I'd love to be able to specifx run or compile as elisp functions. I dont think its currently possible, but am hoping to be corrected : primarily I want to run the new "eat" terminal and exec a posix script. |
Type
Feature Request
Description
Allow users to specify a compilation function which takes care of compiling a project.
At the moment registering a function to any of
:test
,:run
or:compile
inprojectile-register-project-type
seems to call the function to generate a command string which is then run to do the appropriate task. I'd like to register a function which performs the compilation itself.eg.
with the added benefit that the function approach can dynamically build a command line to compile your project.
My issue here is that I'm using
rustic
mode for rust programming and it provides it's own excellent commands for running compilations, testing etc. I'd like projectile to use those lisp-functions to compile, build and test my project but I can't register them because projectile only seems to accept command lines or functions that return command lines.This isn't valid:
Environment & Version information
Projectile version information
Emacs version
GNU Emacs 27.0.91 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.20, cairo version 1.17.3) of 2020-06-05
Operating system
Linux mk-desktop 5.7.3-arch1-1 #1 SMP PREEMPT Wed, 17 Jun 2020 19:42:12 +0000 x86_64 GNU/Linux
The text was updated successfully, but these errors were encountered: