1

I'm using "M-x compile" several times a day with the following in my ~/.emacs:

(setq compile-command "cd ~/my-dev/linux_build/ && killall gdb ; ~/my-dev/someStuff/.git/hooks/pre-commit; mv -f ../bin/my-exe /tmp 2>&1; echo ---; make -j$(nproc) APP=my-exe MODE=debug SOMEOPTION=value && date")

The main problem is that sometimes I don't want "SOMEOPTION=value" - other times I want it (I know I can just use the cursor keys to change the command before hitting enter, but I'm looking for an even faster/quicker way). So, the question is:

Is there a way to modify "M-x compile" such that it by default runs without SOMEOPTION=value and using just a single key after "M-x compile", it runs with SOMEOPTION=value? Maybe it would be nice also to be able to switch between 2 makefiles, again - using just a single keypress, e.g. the following 3 tasks should be easy and fast/quick to switch between:

  1. "M-x compile + enter" (default): Runs the usual command without SOMEOPTION=value, i.e. cd ~/my-dev/linux_build/ && killall gdb ; ~/my-dev/someStuff/.git/hooks/pre-commit; mv -f ../bin/my-exe /tmp 2>&1; echo ---; make -j$(nproc) APP=my-exe MODE=debug && date
  2. "M-x compile + S": Runs the usual command WITH SOMEOPTION=value, i.e: cd ~/my-dev/linux_build/ && killall gdb ; ~/my-dev/someStuff/.git/hooks/pre-commit; mv -f ../bin/my-exe /tmp 2>&1; echo ---; make -j$(nproc) APP=my-exe MODE=debug SOMEOPTION=value && date
  3. "M-x compile + M": Runs everything but using a different makefile, i.e: cd ~/my-dev/linux_build/ && killall gdb ; ~/my-dev/someStuff/.git/hooks/pre-commit; mv -f ../bin/my-exe /tmp 2>&1; echo ---; make -j$(nproc) -f makefileAlternative APP=my-exe MODE=debug SOMEOPTION=value && date
  4. (maybe something else here in the future, with a relevant keystroke after "M-x compile")

As I'm not very good at emacs programming I'm asking to learn, so I also highly appreciate a few words for background information, e.g. why a solution is good or why this cannot be achieved (if it cannot, but I'm guessing there's a way to do this). I hope some of you can help, I would appreciate it a lot as I do this many times per day...

EDIT: Based on the answer by lawlist, I've updated the first 3 example cases with i.e: "commandline-to-be-executed" in code-tag, I think this should make the question clearer (and the objective is to be able to run each case, with as few keystrokes as possible)...

Okay Dokey
  • 13
  • 4
  • I think you can use history for that (up arrow to get to last command used). – JeanPierre Aug 06 '19 at 14:47
  • No, the arrow keys (up/down/left/right) can be used to change the compile command. But you have to manually find the right spot to insert e.g. SOMEOPTION=value or to remove it... So I don't really see this as a solution... – Okay Dokey Aug 06 '19 at 15:42
  • @OkayDokey I think JeanPierre's suggestion is better than you give it credit for. You only need to edit the compile command the first time you want to run a different command. After that the modified command will be in the history and you can get at it again going up or down. – Omar Aug 07 '19 at 03:49
  • @JeanPierre and Omar: Sorry, it was a misunderstanding from my side. It was first when Omar wrote that if I change the command, there will be different versions in the history, which can be accessed by the up arrow - and then I need to press up not just to switch line but to go up in the history, that I understood the answer... So thanks both - it was merely a misunderstanding, I didn't knew there was history inside M-x compile, I've misunderstood the answer, thanks both... – Okay Dokey Aug 07 '19 at 07:58

1 Answers1

1

Inasmuch as the function compile can take a command-line string as the argument, the O.P. may wish to consider setting up some custom functions of commonly used options. Here are a few simple examples:

(defun make ()
"Doc-string for `make'."
(interactive)
  (compile "make"))

(defun make-clean ()
"Doc-string for `make-clean'."
(interactive)
  (compile "make clean"))

(defun make-install ()
"Doc-string for `make-install'."
(interactive)
  (compile "make install"))

(defun hello-world ()
"Doc-string for `hello-world'."
(interactive)
  (compile "while :; do echo \"Hello-World\"; sleep 1; done"))

Here is another example where the function prompts the user to specify a string that is incorporated into the command line:

(defun echo-string ()
"Doc-string for `echo-string'."
(interactive)
  (let* ((string (read-string "STRING:  "))
         (command (concat "while :; do echo \""
                          string
                          "\"; sleep 1; done")))
    (compile command)))

Here is another example giving the user 3 choices to select; i.e., a, b or c:

(defun echo-choices ()
"Doc-string for `echo-choices'."
(interactive)
  (let* ((choice (read-char-exclusive "[a]pple | [b]eet | [c]arrot)"))
         (command (concat "while :; do echo \""
                          (cond
                            ((eq choice ?a)
                             "apple")
                            ((eq choice ?b)
                             "beet")
                            ((eq choice ?c)
                             "carrot")
                            (t
                              (user-error "Try again ...")))
                         "\"; sleep 1; done")))
    (compile command)))
lawlist
  • 19,106
  • 5
  • 38
  • 120
  • I can see I haven't been completely clear - therefore I felt I had to update the original question. After the first 3 example cases, I've added "i.e: THE-LINES-TO-BE-EXECUTED"... I think what you've shown here doesn't really solve the problem, with as few as possible keystrokes, to run the mentioned commands... Please see the updated question and sorry if I wasn't clear enough... – Okay Dokey Aug 06 '19 at 16:43
  • 3
    I do not believe that trying to modify how M-x compile works is the best solution, sorry. I think that a custom function is the best choice, as it can be tailored to your precise needs. You can have it present options such as (a), (b), (c) -- where the user selects the desired option. You can have it accept universal arguments such that '(4) [C-u] does one thing, and '(16) [C-u C-u] does something else. The sky is the limit if you use your imagination. The answer contains some general examples, including, seeking input from the user with the function read-string. – lawlist Aug 06 '19 at 16:50
  • I added another example function (echo-choices) that presents the user with three choices; i.e., (a), (b) and (c) -- each option will modify the command line string accordingly. The function can be bound to just one keyboard shortcut such as (global-set-key [f5] 'echo-choices) – lawlist Aug 06 '19 at 17:36
  • The "echo-choices" function is really really nice, thank you very much. I agree, I wasn't particularly looking for a way to modify "M-x compile", if this isn't easily obtainable - but something similar as you presented is also really good. I'll mark as answered, but is it possible to modify the "echo-choices" function so it has a default, e.g. "[b]eet" if the user just presses enter without typing in a/b/c? I suppose that is possible, although I'm not experienced enough (if I press enter it just says "Try again ...")... Thanks for your great valuable help! – Okay Dokey Aug 07 '19 at 01:53
  • Sure, just replace (user-error "Try again ...") with "beet" and that will be the default/catchall if you press something other than a, b or c. Or, add a new condition that looks for enter/RET -- ((eq choice ?\C-m) "beet") before the catchall that begins with (t ...) – lawlist Aug 07 '19 at 02:24
  • @OkayDokey Re: "I wasn't particularly looking for a way to modify M-x compile, if this isn't easily obtainable". It is easily obtainable, what lawlist is saying is that it's a bad idea. – Omar Aug 07 '19 at 03:53
  • @lawlist : Oh, thanks a lot. I works very nicely, both with the added condition: '((eq choice ?\C-m) "beet")' - and then it it took a while for me to understand I needed '(t "beet")' instead of the user-error-line... I think I've learned enough now to customize this to my liking... – Okay Dokey Aug 07 '19 at 08:50
  • @Omar : Ok, thanks, I agree, he wrote "a custom function is the best choice, as it can be tailored". And I'm happy with the help you've provided... I've put the stuff into my ~/.emacs file and assigned to the F5-key - and it works very nicely. I think I tailor this to my needs now, thanks a lot all! – Okay Dokey Aug 07 '19 at 09:02