emacs24 backtab is undefined , how to define this shortcut-key - emacs

How to define <backtab> short key in emacs24 ?
I had found some solution,
like:
http://stuff.mit.edu/afs/sipb/user/daveg/Info/backtab-howto.txt
Emacs Shift-Tab to left shift the block
but it isn't work for me.
In the end:
(global-set-key (kbd "<backtab>") 'un-indent-by-removing-4-spaces)
(defun un-indent-by-removing-4-spaces ()
"remove 4 spaces from beginning of of line"
(interactive)
(save-excursion
(save-match-data
(beginning-of-line)
;; get rid of tabs at beginning of line
(when (looking-at "^\\s-+")
(untabify (match-beginning 0) (match-end 0)))
(when (looking-at "^ ")
(replace-match "")))))
worked for me !!!
thanks #Drew and #lawlist.

Related

Emacs. Specific formatting autopair for "{"

I have found many ways to automatically insert "}" after typing "{" but never found the following implementation:
After typing "{" it moved on the next line (with indented if necessary), next is an empty string with the cursor, and "}" on the next line:
if (i == 0)*here we typing "{"*
and get the following:
if (i == 0)
{
|
}
and for nested brackets:
if (i == 0)
{
if (j == 0)
{
|
}
}
How to do this?
Note: I already use yasnipped but it does not work for functions.
If you are using electric-pair-mode, you can supply your own function:
(defun my-electric-pair-open-newline-between-pairs()
"Indent paired char and empty line"
(when (and (eq last-command-event ?\n)
(< (1+ (point-min)) (point) (point-max))
(eq (save-excursion
(skip-chars-backward "\t\s")
(char-before (1- (point))))
(matching-paren (char-after))))
(save-excursion
(insert "\n")
(indent-according-to-mode))
(indent-according-to-mode))
nil)
(setq-default electric-pair-open-newline-between-pairs 'my-electric-pair-open-newline-between-pairs)
(electric-pair-mode 1)
It will do what you describe only if you hit return between empty brackets.
I did something similar to this to try to emulate Eclipse's newline functionality.
(defun my-newline ()
(interactive)
(let ((s (buffer-substring (point-at-bol) (point))))
(cond
((string-match ".*{$" s) ; matching a line ending with {
(move-end-of-line nil)
(insert "}") ; insert }. Can be removed if already being inserted
(backward-char 2)
(newline-and-indent)
(forward-char)
(newline-and-indent)
(move-beginning-of-line nil)
(backward-char 1)
(newline-and-indent))
(t (newline-and-indent)))))
You can then attach it to whatever keybinding you like. I overrode C-j as that was what I was used to.
(defun my-newline-hook ()
(local-set-key (kbd "C-j") 'my-newline))
(add-hook 'java-mode-hook 'my-java-hook)
The regex and steps taken can be adjusted to fit your needs.

emacs isearch-forward default search string

I have a question about Emacs Lisp, I want to achieve this functionality: ‘highlight a word under cursor, then when I push C-s C-s, I can jump to the next highlighted word’.
So after I highlight a word, I hope the isearch-string can be set as the same as the word I have high lightened, i.e. the default ** search string for command **isearch-forward or isearch-backward can be my highlighted word.
My code is like:
(defun highlight-current-word()
"highlight the word under cursor"
(interactive)
(let (head-point tail-point word)
(skip-chars-forward "-_A-Za-z0-9")
(setq tail-point (point))
(skip-chars-backward "-_A-Za-z0-9")
(setq head-point (point))
(setq word (buffer-substring-no-properties head-point tail-point))
(setq isearch-string word) ; no use
(isearch-search-and-update) ; no use
(highlight-regexp word 'hi-yellow)))
But it always prompts: [No previous search string]
Can you help me? Thank you!
I think you need add hook to isearch-mode, then your function will be work.
(defun highlight-current-word()
"highlight the word under cursor"
(interactive)
(let (head-point tail-point word)
(skip-chars-forward "-_A-Za-z0-9")
(setq tail-point (point))
(skip-chars-backward "-_A-Za-z0-9")
(setq head-point (point))
(setq word (buffer-substring-no-properties head-point tail-point))
(setq isearch-string word)
(isearch-search-and-update)))
(add-hook 'isearch-mode-hook 'highlight-current-word)
Is this all you are looking for (not too clear to me)?
(defun foo ()
(interactive)
(skip-chars-backward "-_A-Za-z0-9")
(isearch-yank-internal (lambda () (forward-word 1) (point))))
(define-key isearch-mode-map (kbd "C-o") 'foo)
That does what C-w does, except that it picks up the whole word at the cursor, not just the text from the cursor to word end.

How to avoid line breaks within |...| in Emacs

In Emacs, how can I avoid line breaks within |...| when using M-q (fill-paragraph)?
In https://groups.google.com/forum/?fromgroups#!searchin/gnu.emacs.help/fill-nobreak-predicate/gnu.emacs.help/qNuZZjQnsww/99oJ1fb4OSUJ I found the following solution for [[...]], but it doesn't work when the open and close delimiters are the same:
(defun fill-open-link-nobreak-p ()
"Don't break a line after an unclosed \"[[link \"."
(save-excursion
(skip-chars-backward " ")
(let ((opoint (point))
spoint inside)
(save-excursion
(beginning-of-line)
(setq spoint (point)))
(when (re-search-backward "\\[\\[" spoint t)
;; (message "found") (sit-for 2)
(unless (re-search-forward "\\]\\]" opoint t)
(setq inside t)))
inside)))
(add-to-list 'fill-nobreak-predicate 'fill-open-link-nobreak-p)
This seems to do the trick:
(defun odd-number-of-pipes-this-paragraph-so-far ()
(oddp (how-many "|" (save-excursion (backward-paragraph) (point)) (point))))
(add-to-list 'fill-nobreak-predicate 'odd-number-of-pipes-this-paragraph-so-far)

Intelligent auto closing matching characters

In some of the modes I'm using, emacs helps me by auto closing some elements such as quotes, parenthesis.
However some times, out of habit I type the closing element my self and end up with ()) or """.
How can I set up emacs to ignore the extra key?
While it is fun to roll your own, autopair has emerged as the canonical solution to this problem. It does everything you ask, and a few things, you didn't know you wanted. Emacs wiki entry.
Emacs 24 (currently in pretest) will be prepackaged with an electric pairing package. Autopair is still much more sophisticated than the builtin one.
EDIT: I had had the following in my .emacs for a while, and it worked fine so I didn't think too much about it. As event_jr points out in his answer, the same features (and apparently a bit more) can be had with the autopairs.el package, linked from the same page that I got this code from.
I have the following code in my .emacs to do this, taken from the emacs wiki:
(setq skeleton-pair t)
(setq skeleton-pair-alist
'((?\( _ ?\))
(?[ _ ?])
(?{ _ ?})
(?\" _ ?\")))
(defun autopair-insert (arg)
(interactive "P")
(let (pair)
(cond
((assq last-command-char skeleton-pair-alist)
(autopair-open arg))
(t
(autopair-close arg)))))
(defun autopair-open (arg)
(interactive "P")
(let ((pair (assq last-command-char
skeleton-pair-alist)))
(cond
((and (not mark-active)
(eq (car pair) (car (last pair)))
(eq (car pair) (char-after)))
(autopair-close arg))
(t
(skeleton-pair-insert-maybe arg)))))
(defun autopair-close (arg)
(interactive "P")
(cond
(mark-active
(let (pair open)
(dolist (pair skeleton-pair-alist)
(when (eq last-command-char (car (last pair)))
(setq open (car pair))))
(setq last-command-char open)
(skeleton-pair-insert-maybe arg)))
((looking-at
(concat "[ \t\n]*"
(regexp-quote (string last-command-char))))
(replace-match (string last-command-char))
(indent-according-to-mode))
(t
(self-insert-command (prefix-numeric-value arg))
(indent-according-to-mode))))
(defun autopair-backspace (arg)
(interactive "p")
(if (eq (char-after)
(car (last (assq (char-before) skeleton-pair-alist))))
(and (char-after) (delete-char 1)))
(delete-backward-char arg))
(global-set-key [backspace] 'autopair-backspace)
(define-key isearch-mode-map [backspace] 'isearch-delete-char) ;; required to fix behaviour in isearch
(global-set-key "(" 'autopair-insert)
(global-set-key ")" 'autopair-insert)
(global-set-key "[" 'autopair-insert)
(global-set-key "]" 'autopair-insert)
(global-set-key "{" 'autopair-insert)
(global-set-key "}" 'autopair-insert)
(global-set-key "\"" 'autopair-insert)
I'm not sure if it's Emacs 24 feature only, but electric-pair-mode seems to do what you want.

Emacs: how to write a defun which acts on region, but acts on point if there's no region?

I write a simple defun for a region, and I want to apply it even if there's no region – i.e. call it with no selection at all. I thought I could do something like the following:
(defun region-study (strt end)
(interactive "r")
(if (= strt end)
(progn ....) ;; then
(progn ....))) ;; else
But it doesn't work. As it turns out, when you call (interactive "r") with no region it doesn't just set boundaries to be equal. Try this:
(defun region-study (strt end)
(interactive "r")
(message "strt=%d; end=%d" strt end))
So my question is that: "how to write a defun which acts on region, but acts on point if there's no region?"
Edit:
So I wanted to put selection in brackets or just to insert brackets and (backward-char 1). Here's a solution:
(defun put-in-lft-rit (lft rit)
(interactive "k")
(if (use-region-p) ;; act on region
(progn
(setq pP (point))
(setq strt (region-beginning))
(setq end (region-end))
(setq meat (buffer-substring-no-properties strt end))
(setq news (concat lft meat rit))
(delete-region strt end)
(goto-char strt)
(insert news)
(if (= pP strt)
(goto-char strt) ; then
(goto-char (+ end 1)))) ; else
(progn ;; act on point
(insert lft rit)
(backward-char 1))))
(defun bk-put-in-braces ()
(interactive)
(put-in-lft-rit "(" ")"))
(defun bk-put-in-curly-braces ()
(interactive)
(put-in-lft-rit "{" "}"))
(defun bk-put-in-quotes ()
(interactive)
(put-in-lft-rit "'" "'"))
(defun bk-put-in-double-quotes ()
(interactive)
(put-in-lft-rit "\"" "\""))
(defun bk-put-in-square-brackes ()
(interactive)
(put-in-lft-rit "[" "]"))
And then you bind in .emacs:
(global-set-key (kbd "C-<f9>") 'bk-put-in-square-brackes)
(global-set-key (kbd "<f9>") 'bk-put-in-curly-braces)
(global-set-key (kbd "S-<f7>") 'bk-put-in-quotes)
(global-set-key (kbd "S-<f8>") 'bk-put-in-double-quotes)
(global-set-key (kbd "S-<f9>") 'bk-put-in-braces)
That's it! Should be working in all modes.
Edit2:
#phils
Thanks. You are definetely right. One thing though - my code had an additional feature of leaving the point at the beginning or end of the region - depending on where it was in the selection. Here's Your code with this feature added:
(defun put-in-lft-rit (lft rit)
(interactive "k")
(if (use-region-p) ;; act on region
(let ((strt (region-beginning))
(end (region-end))
(pP (point)))
(save-excursion
(goto-char end)
(insert rit)
(goto-char strt)
(insert lft))
(if (= pP strt)
(goto-char strt) ; then
(goto-char (+ end 1)))) ; else
(progn ;; act on point
(insert lft rit)
(backward-char 1))))
A few notes on your solution...
It's good practice to avoid unnecessary global-scope setqs. Use (let) instead to define a temporary scope for your variables.
You are doing a lot more work than required. Instead of copying the region, concatenating that copy and the delimiters into a 'news' variable, deleting the region, and then inserting 'news', all you need to do is insert the delimiter characters at the beginning and end of the region.
(In general, if you try to "think like an editor" when writing elisp, and focus on manipulating buffers rather than variables, you'll generally wind up with more efficient code.)
save-excursion is very useful (along with several other save- and with- forms).
 
(defun put-in-lft-rit (lft rit)
(interactive "k")
(if (use-region-p) ;; act on region
(let ((strt (region-beginning))
(end (region-end)))
(save-excursion
(goto-char end)
(insert rit)
(goto-char strt)
(insert lft)))
(progn ;; act on point
(insert lft rit)
(backward-char 1))))
use-region-p should return t if your function should act on the region instead of at a point.
You may like to use the function region-or-word-at-point defined in thingatpt+.el