Binding a key to elisp find-file function - elisp

I tried the below elisp expression to bind the "F5" key to load a file in a buffer.
(global-set-key (kbd "<f5>") '(find-file "/etc/fstab"))
which throws error
Wrong type argument: commandp, (find-file "/etc/fstab")
in the mini buffer.
What is the error in the elisp expression.

What the error says: It's not a command. An command is a function with a interactive form.
Try:
(global-set-key (kbd "<f5>") (lambda () (interactive) (find-file "/etc/fstab")))

Related

Shell script: how to pass arguments into racket that is interpreted in the racket session?

I am trying build a shell script to 1. Open the racket language interactive session using racket and 2. adding the appropriate language and version in the racket session via require (planet dyoo/simply-scheme:2:2)).
Rather than typing racket, waiting for it to load, then typing require (planet dyoo/simply-scheme:2:2)), I'd like to build a shell script to automate this.
How would I do this?
The command line to achieve this is racket -i -p dyoo/simply-scheme:2:2 (or alternatively with -e flag). It is then trivial to build in sh/bash:
#!/bin/sh
racket -i -p dyoo/simply-scheme:2:2
You can even write a script in Racket like this, which accept an argument to require any package:
;; repl.rkt
#! /usr/bin/env racket
(require racket/cmdline)
(require racket/system)
(define package (make-parameter ""))
(define parser
(command-line
#:usage-help
"Start a racket REPL and require an initial package."
#:once-each
[("-p" "--package") PACKAGE
"Add an initial package to require."
(package PACKAGE)]
#:args () (void)))
(define (run (package-name))
(system (~a (printf "racket -i -p ~a" package-name))))
(run package)
And run repl.rkt -p dyoo/simply-scheme:2:2.
Alternative command is racket -i -e '(require (planet "dyoo/simply-scheme:2:2"))'
UPDATE: The shebang has been corrected per the comments.

Can I use bash autocomplete when editing shell scripts in emacs?

In my environment, I have bash autocomplete set up to do lots of amazing things.
However, when I'm editing a shell script in emacs, all of that autocomplete magic goes away.
Is there any way to get emacs to do bash command line autocompletion when I'm editing shell scripts?
I would accept an answer that requires me to use a different editor, if that editor were available on Linux systems. I would also accept an answer that tells me that I need to use a different shell's autocomplete.
bash-completion.el provides an interface to normal bash completion, which can also be extended to work in normal sh-modes with an addition to your completion-at-point-functions. Here is how that could work, just using the command sh-beginning-of-command from sh-script to determine the current completion candidate (this could be extended to handle more complicated shell commands if necessary).
(require 'sh-script) ;sh-beginning-of-command
(require 'bash-completion)
(defun my-sh-completion-at-point ()
(let ((end (point))
(beg (save-excursion (sh-beginning-of-command))))
(when (and beg (> end beg))
(bash-completion-dynamic-complete-nocomint beg end t))))
(defun my-sh-hook ()
(add-hook 'completion-at-point-functions #'my-sh-completion-at-point nil t))
(add-hook 'sh-mode-hook #'my-sh-hook)

Silently send command to comint without printing prompt

I want to send a command to a comint shell-mode without it printing an additional prompt. I'm trying to use the comint-redirect-* API, but I am still getting an additional prompt. What would be an easy way to either avoid the prompt printing altogether, or to track back and delete it?
My redirect,
(defun my-comint-redirect-silently (proc string)
(let (comint-redirect-perform-sanity-check)
(with-temp-buffer
;; possible to have shell not print prompt?
(comint-redirect-send-command-to-process
string (current-buffer) proc nil 'no-display)))
(with-current-buffer (process-buffer proc)
;; necessary to track back and delete here?
(comint-redirect-cleanup)))
Example of a call in a shell-hook,
(add-hook 'shell-mode-hook
(lambda ()
(my-comint-redirect-silently
(get-buffer-process (current-buffer)) "TERM=xterm-256color")))
But, the comint shell then prints the following (notice the double prompt)
me#me-M51AC: ~
$ me#me-M51AC: ~
$
Not directly relevant, but to show it is printing twice, the prompt here is set as
$ echo $PS1
${debian_chroot:+($debian_chroot)}\[\e[32m\]\u#\h: \[\e[33m\]\w\[\e[0m\]\n\$
I took at look at how comint-redirect-results-list-from-process worked and bodged this.
(defun comint-run-thing-process (process command)
"Send COMMAND to PROCESS."
(let ((output-buffer " *Comint Redirect Work Buffer*"))
(with-current-buffer (get-buffer-create output-buffer)
(erase-buffer)
(comint-redirect-send-command-to-process command
output-buffer process nil t)
;; Wait for the process to complete
(set-buffer (process-buffer process))
(while (and (null comint-redirect-completed)
(accept-process-output process)))
;; Collect the output
(set-buffer output-buffer)
(goto-char (point-min))
;; Skip past the command, if it was echoed
(and (looking-at command)
(forward-line))
;; Grab the rest of the buffer
(buffer-substring-no-properties (point) (- (point-max) 1)))))
Hope it helps

Emacs how to run command in Interactive command line mode in elisp

I am newbie to Emacs.
I want to define a function in elisp to run a command in interactive command line mode (Asynchronously if possible).
my current code is:
(defun ma () ;run maxima batch on the current file
(interactive)
(let*
((fn (buffer-file-name)) (cmd (concat "maxima -b " fn)))
(message "cmd:%s" cmd)
(shell-command cmd)
)
)
this works fine when I do not have break points in the maxima code. When I have break points "break()", I have to interact with the program. The current shell-command function does not work.
I also like the mechanism of "shell-command" function that the screen will automatically split into two and show the programming running info in a second window. If possible, I still want this feature in the code that you can help me with.
Any help would be appreciated.
I want to define a function in elisp to run a command in interactive
command line mode (Asynchronously if possible).
Maybe async-shell-command is what you are looking for do C-h f async-shell-command RET for help on the function.
Use the built in compile function in commint mode.
(defun ma (&optional filename)
(interactive)
(compile (format "maxima -b %s" (or filename (buffer-file-name))) t))
This will open up a new window and will show you the output of the program running. Commint mode means that the compilation process is interactive, you will be able to send input to the program from the compilation buffer.

How to trigger or instrument with edebug programmatically?

C-u C-M-x evaluates a defun form with edebug instrumented. Can I do that programmatically? I want to do that because I want to write an elisp file of the following form:
;;; define a function with edebug instrumented.
...
;;; do something that invokes the function with particular arguments.
...
then I can run emacs -q --load on that elisp file, step through code, get an idea on further investigation on the bug, edit the elisp file in my original emacs session, run emacs -q --load on it again, and repeat.
In ~/test.el:
(defun square (x)
(* x x))
In ~/testtest.el:
(with-current-buffer (find-file-noselect "~/test.el")
(re-search-forward "square")
(edebug-defun))
(square 5)
In bash:
emacs -q -l ~/testtest.el

Resources