Disable '\C-x\C-s" in multi-term mode - emacs

There is no need to use C-x C-s to save buffer in term mode. So I want to disable it. I tried to define a new binding in term mode to replace it, but failed.
(add-hook 'term-mode-hook
#'(lambda ()
(define-key term-mode-map "\C-x\C-s"
#'(lambda ()
(interactive)
(message "NO!")))))
Any help is appreciated. Thanks
Update: I use multi-term which based on term mode.

As wvxvw said, I tried this and it works. Add below to term-bind-key-alist. Thanks everyone.
("\C-x\C-s" . (lambda ()
(interactive)
(message "NO!")))

Take off the #' from your code. It should work. But you will still be able to save the buffer with "M-x save-buffer"
UPDATE:
This code is working for me
(add-hook 'term-mode-hook
(lambda ()
(define-key term-mode-map (kbd "C-x C-s")
(lambda ()
(interactive)
(message "hello world")))))
You will need to reload your term buffer after you setup the hook. It will not work for existing buffers

Related

emacs ow can I helm-find with default directory pre-specified?

I use emacs for notes mainly. All my notes are in:
~/Dropbox/Uni/Notes
I want to tie a keyboard shortcut (e.g C-f12) to do a helm-find that always starts in the above dir irrelevant of the source buffer.
I have tried:
(global-set-key (kbd "C-<f2>") (lambda () (interactive) (helm-find "~/Dropbox/Uni/Notes/")))
But when I run it, it still prompts me for 'DefaultDirectory' which is usually the same as the current buffer.
?
[edit]
I made a hack-around:
(global-set-key (kbd "<C-f2>")
(lambda ()
(interactive)
(find-file "~/Dropbox/Uni/Notes/leo.org")
(helm-find nil)))
That opens a file and then when I do a helm-find, it's relative to leo.org's location. But a better solution would be preferred.
[edit]
Below solution works perfectly.
Here you go:
(defmacro helm-find-note (dir)
`(defun ,(intern (format "helm-find-note-%s" dir)) ()
(interactive)
(let ((default-directory ,dir))
(helm-find nil))))
(global-set-key (kbd "C-M-3") (helm-find-note "~/Downloads"))

wrong type argument commandp with a custom function in emacs

I know this type of question have been asked by many people,
but I have read many similar posts and still have no idea
what to do. So here is the elisp code in .emacs:
;; send line to python console
(require 'python-mode)
(defun py-execute-line-down ()
"execute python line and move cursor down"
(progn
(py-execute-line)
(evil-next-line)))
(add-hook 'python-mode-hook
(lambda () (define-key python-mode-map (kbd "C-c C-j") 'py-execute-line-down)))
I also tried to add (interactive) into the function, it didn't work.
Just to keep the record here, this seemed to do the trick, not sure if it's optimal though:
;; send line to python console
(require 'python-mode)
(defun py-execute-line-down ()
"execute python line and move cursor down"
(interactive)
(py-execute-line)
(evil-next-line 1))
(defun kaiyin-pykeys ()
"python mode custome keys"
(local-set-key (kbd "C-c j") 'py-execute-line-down)
)
(add-hook 'python-mode-hook 'kaiyin-pykeys)
Taking Dan's advice, I changed the above into:
;; send line to python console
(require 'python-mode)
(defun py-execute-line-down ()
"execute python line and move cursor down"
(interactive)
(py-execute-line)
(forward-line 1))
(define-key python-mode-map (kbd "C-c j") 'py-execute-line-down)

In emacs, how do I save without running save hooks?

I have various things set up in my 'before-save-hook. For example, I run 'delete-trailing-whitespace. This is what I want in almost all occasions.
But sometimes, I'm working on files that are shared with other people, and the file already has a bunch of trailing whitespace. If I save the file, I'll get a big diff that's pretty confusing, as my change is buried in dozens or hundreds of meaningless changes. Yes, everyone could just tell their diff tool to not show whitespace changes, but that's something that everyone has to do every time they look at the diff. I'd rather not even have the whitespace change.
Is there anything I can do to save the file without the whitespace changes, short of starting a new instance of Emacs with no init.el file, or with a modified init.el that doesn't have the hook?
Here is how I save without triggering delete-trailing-whitespace:
C-x C-q C-x C-s C-x C-q: read-only, save, revert read-only
A simpler solution I came up with is that my fundamental-mode has no hooks installed, because I want it to be as plain as possible. Thus if I want to save a file without running hooks, I temporarily switch to fundamental-mode.
Based on a comment discussion with #Stefan, here are two possible (untested) solutions:
Use let:
(defun save-buffer-without-dtw ()
(interactive)
(let ((b (current-buffer))) ; memorize the buffer
(with-temp-buffer ; new temp buffer to bind the global value of before-save-hook
(let ((before-save-hook (remove 'delete-trailing-whitespace before-save-hook)))
(with-current-buffer b ; go back to the current buffer, before-save-hook is now buffer-local
(let ((before-save-hook (remove 'delete-trailing-whitespace before-save-hook)))
(save-buffer)))))))
Use unwind-protect:
(defun save-buffer-without-dtw ()
(interactive)
(let ((restore-global
(memq 'delete-trailing-whitespace (default-value before-save-hook)))
(restore-local
(and (local-variable-p 'before-save-hook)
(memq 'delete-trailing-whitespace before-save-hook))))
(unwind-protect
(progn
(when restore-global
(remove-hook 'before-save-hook 'delete-trailing-whitespace))
(when restore-local
(remove-hook 'before-save-hook 'delete-trailing-whitespace t))
(save-buffer))
(when restore-global
(add-hook 'before-save-hook 'delete-trailing-whitespace))
(when restore-local
(add-hook 'before-save-hook 'delete-trailing-whitespace nil t)))))
The problem with the second solution is that the order of functions in the before-save-hook may change.
Here's another solution:
(defvar my-inhibit-dtw nil)
(defun my-delete-trailing-whitespace ()
(unless my-inhibit-dtw (delete-trailing-whitespace)))
(add-hook 'before-save-hook 'my-delete-trailing-whitespace)
and then
(defun my-inhibit-dtw ()
(interactive)
(set (make-local-variable 'my-inhibit-dtw) t))
so you can M-x my-inhibit-dtw RET in the buffers where you don't want to trim whitespace.
I wrote a command inspired by Nicholas Douma's solution.
(defun olav-save-buffer-as-is ()
"Save file \"as is\", that is in read-only-mode."
(interactive)
(if buffer-read-only
(save-buffer)
(read-only-mode 1)
(save-buffer)
(read-only-mode 0)))
What we need to do is remove 'delete-trailing-whitespace from before-save-hook, save the buffer, then add it back.
This code will do that, but only remove and add it if it's there to begin with.
;; save the buffer, removing and readding the 'delete-trailing-whitespace function
;; to 'before-save-hook if it's there
(defun save-buffer-no-delete-trailing-whitespace ()
(interactive)
(let ((normally-should-delete-trailing-whitespace (memq 'delete-trailing-whitespace before-save-hook)))
(when normally-should-delete-trailing-whitespace
(remove-hook 'before-save-hook 'delete-trailing-whitespace))
(save-buffer)
(when normally-should-delete-trailing-whitespace
(add-hook 'before-save-hook 'delete-trailing-whitespace))))
(global-set-key (kbd "C-c C-s") 'save-buffer-no-delete-trailing-whitespace)
It also binds the command to (kbd C-c C-s), for convenience.

Emacs run forward char in a hook

I wrote this below to get to search for the next period in tex mode. It works fine except trying to get it to move forward a char after it finds the period. I am not sure how to do this but here was my attempt.
(add-hook 'text-mode-hook (lambda ()
(local-set-key (kbd "s-p")
(lambda () (interactive) ((search-backward "." nil t) (forward-char))))))
Final solution I combined the functions from ajk solution. I couldn't get the other one working without the add-hook. Someone might know how to get the second one working. The below completely works and searches backward for the previous period unless it is currently at a period.
(add-hook 'text-mode-hook
(lambda ()
(local-set-key (kbd "s-p")
(lambda ()
(interactive)
(if (looking-back "\.")
(backward-char))
(search-backward "." nil t)
(forward-char)))))
Thanks for the help.
You have parentheses around the last two function calls in the anonymous function you're assigning to the key, causing Emacs Lisp to think you want to call a function named (search-backward "." nil t). Try
(add-hook 'text-mode-hook
(lambda ()
(local-set-key (kbd "s-p")
(lambda ()
(interactive)
(search-backward "." nil t)
(forward-char)))))
The problem I would have with this binding is it's not repeatable. If you run it a second time, it finds the same period you just found. You might want to check to see if the previous character is a period and if so, skip it. Also, you can simplify it a bit by using define-key to add the binding explicitly to the text-mode keymap:
(define-key text-mode-map (kbd "s-p")
(lambda ()
(interactive)
(if (looking-back "\.")
(backward-char))
(search-backward "." nil t)
(forward-char)))

Redefining ENTER key in Emacs

I don't know elisp, but I'm trying to do something like the following:
(add-hook
'scala-mode-hook
(lambda ()
(define-key scala-mode-map (kbd "RET") (lambda ()
(scala-newline)
(scala-indent-line)))))
Goal is to call the two functions each time I hit the ENTER key. How do I actually do this?
I do essentially this in so many modes that I've squashed them all together:
(mapcar (lambda (hooksym)
(add-hook hooksym
(lambda ()
(local-set-key (kbd "C-m") 'newline-and-indent)
)))
'(
clojure-mode-hook
emacs-lisp-mode-hook
erlang-mode-hook
java-mode-hook
js-mode-hook
lisp-interaction-mode-hook
lisp-mode-hook
makefile-mode-hook
nxml-mode-hook
python-mode-hook
ruby-mode-hook
scheme-mode-hook
sh-mode-hook
))
Just stick scala-mode-hook in there somewhere and it'll work for you too :)
You need an (interactive) form after the lambda in your define-key.
EDIT:
To be clear, the inner form should look like:
(lambda ()
(interactive)
(scala-newline)
(scala-indent-line))
In hook you can use local-set-key, for example
(add-hook 'scala-mode-hook
(lambda ()
(local-set-key [return]
(lambda ()
(scala-newline)
(scala-indent-line)))))
although, maybe it will be easier to use something like standard newline-and-indent?
(add-hook 'scala-mode-hook
(lambda ()
(local-set-key [return] 'newline-and-indent)))
Just type C-j it will call the newline-and-indent command and do exactly what you ask.