Disabling prefix key binding - shell

In shell mode on emacs, the current key binding for quitting the shell mode ('comint-interrupt-subjob) is "\C-c \C-c", and I want to change it to "\C-c" as in ordinary linux shell. I tried
(add-hook 'shell-mode-hook '(lambda ()
(local-set-key "\C-c" 'comint-interrupt-subjob)
))
But it did not work. Probably I need to disable the prefix assigned to "\C-c". How can I do that?

Try this:
(eval-after-load "shell"
'(define-key shell-mode-map (kbd "C-c") 'comint-interrupt-subjob))
In general, when you define keys you should define them in particular keymaps, as opposed to just hoping the local-set-key does what you want.
Note: I prefer using kbd for describing keys, your "\C-c" would work just fine.

(define-key (current-local-map) "^C" 'comint-interrupt-subjob)
This will do the work without the error checking of local-set-key

Related

emacs + comint-dynamic-complete-filename after '='

Editing a Bash script I want to assign a filename to a variable.
E.g. inputfile=foo.txt
With std. settings I can't complete the filename without first inserting a space after the '='.
Is there any solution to this?
First of all, comint-dynamic-complete has been obsolete since Emacs 24.1. The replacement function is completion-at-point.
Now, if you starting looking at what completion-at-point actually does in a shell script buffer, you'll eventually end up in comint anyway. In particular, the function comint--match-partial-filename looks promising for an explanation of the behavior you described.
If I read that correctly, the problem here is that "=" is considered a valid part of a filename, at least on POSIX-like systems (see variable comint-file-name-chars). So, the completion mechanism is trying to complete the filename "inputfile=/..." which it can obviously not find.
If you never use a "=" in your filenames (or you use it so rarely that the working completion outweighs other downsides), you may want to consider doing something like (setq comint-file-name-chars "[]~/A-Za-z0-9+#:_.$#%,{}-") in the shell script mode hook (if you are on a POSIX system; on Windows it would look slightly different).
Hope that helps.
You can use bash-completion assuming your not on windows. It just requires a slight modification to work in sh-mode since it uses a comint function to determine the current completion candidate.
I like this because, in addition to completing filenames there, it also will give you all the nice readline completion like command line switches, etc. Here is an example setup using company, but you could remove the company stuff, since all you really need is to add the modified completion-at-point function.
;; required packages: company bash-completion
(eval-when-compile
(require cl-lib))
;; locally redefine comint-line-beginning-position so bash-completion
;; can work in sh-mode
(defun sh-bash-completion ()
(cl-letf (((symbol-function 'comint-line-beginning-position)
#'(lambda ()
(save-excursion
(sh-beginning-of-command)
(point)))))
(let ((syntax (syntax-ppss)))
(and (not (or (nth 3 syntax)
(nth 4 syntax)))
(bash-completion-dynamic-complete)))))
;; put this in your sh-mode hook
(defun sh-completion-setup ()
;; add capf function
(add-hook 'completion-at-point-functions
'sh-bash-completion nil 'local)
(company-mode)
(make-local-variable 'company-backends)
;; use company completion-at-point
(delq 'company-capf company-backends)
(cl-pushnew 'company-capf company-backends)
(setq-local company-transformers
'(company-sort-by-backend-importance)))
(add-hook 'sh-mode-hook 'sh-completion-setup)

Emacs: How to enable highlighting breakpoints in a text terminal (emacs -nw)

Emacs doesn't show breakpoints in text mode.
I tried integrating the suggestions here and here, but failed (I am not a lisp programmer).
I tried:
(require 'gdb-mi)
(setq default-text-properties '(foo 1111))
(defun set_breakpt_cmds ()
"set breakpoint and indicate on editor"
(interactive)
(gud-break)
(gdb-put-breakpoint-icon "false" (get-text-property 1 'foo)))
(global-set-key (kbd "<f12>") 'set_breakpt_cmds)
The resulting error is
Wrong number of arguments: (lambda (arg) "Set breakpoint at current line." (interactive "p") (if (not gud-running) (gud-call "dbstop \
at %l in %f" arg))), 0
Note: A similar issue is this (following this). However the solution there doesn't fit me because I would like to be able to call the fix from .emacs file. This way it is easier to duplicate my emacs configuration when I setup a new linux box.
Thanks
The error you get comes from the fact that gud-break expects an argument (which isn't used), so just use (gud-break 1).
The message reads as follow:
the error is of kind wrong number of arguments
when calling (lambda (arg) ...) (where we see that exactly one argument is expected)
and it was called with 0 arguments.

How to go to beginning of command in term mode in Emacs?

I am running bash terminal under Term: line run mode inside Emacs.
Often I want to go to beginning of a command (not beginning of line, which includes the prompt).
i.e. In below line, I 'd like to go to s (not p).
prompt> some command text here
May I know what is the key shortcut in doing so, if any?
C-cC-a (term-bol) is intended to do this. It works by moving to the beginning of the line, and then skipping forward past the prompt, as defined by the buffer-local term-prompt-regexp variable.
However the default value for that regex is just ^ (which therefore has no effect in this situation); so you would need to set it yourself. There are some useful examples in that variable's help text.
Some alternative options are:
Use term-char-mode instead (in which case C-a works).
You can switch to char mode with C-cC-k and back to line mode with C-cC-j.
Copy that same binding for C-a for term-line-mode, so that it does the same thing in both modes:
(define-key term-mode-map (kbd "C-a") 'term-send-raw)
Create a new binding which does the same thing. e.g.:
(define-key term-mode-map (kbd "s-a") (lambda () (interactive) (term-send-raw-string (string 1))))
n.b. Using (string 1) because C-a is ascii value 1. See the definition of term-send-raw.

Why is it that these prog-mode keybindings aren't working in emacs-lisp-mode?

I have a couple lines in my Emacs setup:
;; swap defaults
(define-key prog-mode-map (kbd "RET") 'newline-and-indent)
(define-key prog-mode-map (kbd "C-j") 'newline)
This works as expected in the couple of other programming modes that I tried. But in the Emacs Lisp mode, RET was still bound to newline and C-j was still bound to newline-and-indent. I still observed this confusing behavior even after moving the keybinding code to the very beginning of my Emacs initialization. If I create separate keybinding statements for Emacs Lisp's mode, I don't have any problems.
;; swap defaults for most programming modes
(define-key prog-mode-map (kbd "RET") 'newline-and-indent)
(define-key prog-mode-map (kbd "C-j") 'newline)
;; swap defaults in Emacs Lisp mode too
(define-key emacs-lisp-mode-map (kbd "RET") 'newline-and-indent)
(define-key emacs-lisp-mode-map (kbd "C-j") 'newline)
Why is this? If it matters, I'm using Emacs 24.3 on OS X 10.8.3.
P.S. I recently learned about electric-indent-mode, which probably accomplishes something very similar to these keybindings. However, the mystery still stands.
Look at the definition of emacs-lisp-mode-map in lisp-modes.el:
(defvar emacs-lisp-mode-map
(let ((map (make-sparse-keymap "Emacs-Lisp"))
(menu-map (make-sparse-keymap "Emacs-Lisp"))
(lint-map (make-sparse-keymap))
(prof-map (make-sparse-keymap))
(tracing-map (make-sparse-keymap)))
(set-keymap-parent map lisp-mode-shared-map)
…
map))
The key is the set-keymap-parent call. Though Emacs Lisp Mode inherits from Prog Mode, its keymap does not inherit from prog-mode-map, but from another keymap defined in lisp-modes.el:
(defvar lisp-mode-shared-map
(let ((map (make-sparse-keymap)))
(define-key map "\e\C-q" 'indent-sexp)
(define-key map "\177" 'backward-delete-char-untabify)
map)
"Keymap for commands shared by all sorts of Lisp modes.")
This keymap also does not inherit from prog-mode-map, so bindings in prog-mode-map do indeed not have any effect in Emacs Lisp Mode.
This is arguably a bug in Emacs.
Update: I wrote to the mailing list.
Update 2: The corresponding bug report
Update 3: The bug has been fixed. In a current snapshot build your key bindings should work as expected. As a work around for earlier builds of Emacs you can use the following snippet in your init.el:
(unless (keymap-parent lisp-mode-shared-map)
(set-keymap-parent lisp-mode-shared-map prog-mode-map))
Now lisp-mode-shared-map will inherit from prog-mode-map, effectively replicating the bug fix.

Emacs Key Binding Error

When I try to set the following binding:
(global-set-key "\C-M-v" 'scroll-other-window-up)
I get a "Key Sequence RET - v starts with a non-prefix key RET"
What is that?
The binding you have specified is "Control-M-v". Control-M is the key sequence for the non-printable character 'carriage return' and is equivalent to the RET key. The RET key is already bound so it is not available as a prefix key.
Did you intend the binding to be Control+Meta+v? That would be:
(global-set-key "\C-\M-v" 'scroll-other-window-up)
The key string you used "\C-M-v" is getting translated as C-m - which is also the key RET.
I think the easiest way to do key bindings is to use the kbd macro. When you do C-h k and see a string describing which key you just typed, you can cut/paste that into the argument for kbd:
(global-set-key (kbd "C-M-v") 'scroll-other-window-up)
Try
(global-set-key (kbd "C-M-v") 'scroll-other-window-up)
but be aware that standard emacs does not have a scroll-other-window-up function!

Resources