AUCTeX: insert reference / citation without macro - emacs

Is there a way to add a reference / citation format which inserts the reference / citation label directly into the buffer without enclosing it into a macro?
To be clear: When I hit C-c ) AUCTeX prompts for a reference format, when I hit return it'll insert ~\ref{LABEL} into the buffer [after selecting the appropriate reference in the next buffer]. I would like to add a reference format which is bound to \?s (space) that inserts only the LABEL part.
That is to say: I hit C-c ), then <space>, then select the reference and... tadaa there's LABEL in the buffer.
[Edit:] I have tried
(eval-after-load "latex"
'(progn
(add-to-list
'reftex-ref-style-alist
'("Default" t
(("" ?\s))))))
however this encloses the label in curly braces and prepends ~ if there's a word before point.

I have created a solution by adding an around-advice to reftex-reference, however, it's not a pretty solution. I'll put it up as an answer but I'm still hoping for a better solution.
(eval-after-load "latex"
'(progn
(add-to-list
'reftex-ref-style-alist
'("Default" t
(("LABEL ONLY" ?\s))))
(defadvice reftex-format-special (around reftex-format-special-labely-only activate)
"Advice `reftex-format-special' such that if
REFSTYLE is \"LABEL ONLY\" it will insert
only the reference's label."
(if (string= (ad-get-arg 2) "LABEL ONLY")
(setq ad-return-value (format "%s" (ad-get-arg 0)))
ad-do-it))))

Related

Emacs org-mode: textual reference to a file:line

I am using org-mode in Emacs to document my development activities. One of the tasks which I must continuously do by hand is to describe areas of code. Emacs has a very nice Bookmark List: create a bookmark with CTRL-x r m, list them with CTRL-x r l. This is very useful, but is not quite what I need.
Org-mode has the concept of link, and the command org-store-link will record a link to the current position in any file, which can be pasted to the org-file. The problem with this is two-fold:
It is stored as an org-link, and the linked position is not directly visible (just the description).
It is stored in the format file/search, which is not what I want.
I need to have the bookmark in textual form, so that I can copy paste it into org-mode, end edit it if needed, with a simple format like this:
absolute-file-path:line
And this must be obtained from the current point position. The workflow would be as simple as:
Go to the position which I want to record
Call a function: position-to-kill-ring (I would bind this to a keyboard shortcut)
Go to the org-mode buffer.
Yank the position.
Edit if needed (sometimes I need to change absolute paths by relative paths, since my code is in a different location in different machines)
Unfortunately my lisp is non-existent, so I do not know how to do this. Is there a simple solution to my problem?
(defun position-to-kill-ring ()
"Copy to the kill ring a string in the format \"file-name:line-number\"
for the current buffer's file name, and the line number at point."
(interactive)
(kill-new
(format "%s:%d" (buffer-file-name) (save-restriction
(widen) (line-number-at-pos)))))
You want to use the org-create-file-search-functions and org-execute-file-search-functions hooks.
For example, if you need the search you describe for text-mode files, use this:
(add-hook 'org-create-file-search-functions
'(lambda ()
(when (eq major-mode 'text-mode)
(number-to-string (line-number-at-pos)))))
(add-hook 'org-execute-file-search-functions
'(lambda (search-string)
(when (eq major-mode 'text-mode)
(goto-line (string-to-number search-string)))))
Then M-x org-store-link RET will do the right thing (store a line number as the search string) and C-c C-o (i.e. M-x org-open-at-point RET) will open the file and go to this line number.
You can of course check for other modes and/or conditions.
An elisp beginner myself I though of it as a good exercise et voila:
Edit: Rewrote it using the format methode, but I still think not storing it to the kill-ring is less intrusive in my workflow (don't know about you). Also I have added the capability to add column position.
(defvar current-file-reference "" "Global variable to store the current file reference")
(defun store-file-line-and-col ()
"Stores the current file, line and column point is at in a string in format \"file-name:line-number-column-number\". Insert the string using \"insert-file-reference\"."
(interactive)
(setq current-file-reference (format "%s:%d:%d" (buffer-file-name) (line-number-at-pos) (current-column))))
(defun store-file-and-line ()
"Stores the current file and line oint is at in a string in format \"file-name:line-number\". Insert the string using \"insert-file-reference\"."
(interactive)
(setq current-file-reference (format "%s:%d" (buffer-file-name) (line-number-at-pos))))
(defun insert-file-reference ()
"Inserts the value stored for current-file-reference at point."
(interactive)
(if (string= "" current-file-reference)
(message "No current file/line/column set!")
(insert current-file-reference)))
Not tested extensively but working for me. Just hit store-file-and-line or store-file-line-and-col to store current location and insert-file-reference to insert the stored value at point.
BTW, if you want something better than FILE:LINE, you can try to use add-log-current-defun (in add-log.el) which should return the name of the current function.
;; Insert a org link to the function in the next window
(defun insert-org-link-to-func ()
(interactive)
(insert (with-current-buffer (window-buffer (next-window))
(org-make-link-string
(concat "file:" (buffer-file-name)
"::" (number-to-string (line-number-at-pos)))
(which-function)
))))
This func generates link with the function name as the description.
Open two windows, one is the org file and the other is src code.
Then M-x insert-org-link-to-func RET

Change the definition of paragraph (e.g. in org-mode)

I'd like to use mark-paragraph (also for movement with forward/backward-paragraph) in org-mode buffers in the same way as in other major modes, i.e. to mark a continuous region delimited by empty lines. This should apply also to headings, list items, lines starting with '#' etc. – i.e. I'd like for the purposes of paragraph editing to everything be treated as regular text.
Is this possible?
See the variables paragraph-start and paragraph-separate, and possibly also the use-hard-newlines function which is related (but probably not actually relevant in this case).
(defun use-default-paragraph-delimiters ()
(setq paragraph-start (default-value 'paragraph-start)
paragraph-separate (default-value 'paragraph-separate)))
(add-hook 'org-mode-hook 'use-default-paragraph-delimiters)
Edit: Admittedly, org-mode might depend upon its paragraph definitions for more than just interactive marking and moving, so here is a more targeted approach for customising the paragraph definitions for those commands only when called interactively using their key bindings.
(defmacro with-default-paragraph-definition (&rest body)
"Evaluate body forms using the default definition of a paragraph."
`(let ((paragraph-start (default-value 'paragraph-start))
(paragraph-separate (default-value 'paragraph-separate)))
,#body))
(defalias 'my-org-mark-paragraph 'mark-paragraph)
(defadvice my-org-mark-paragraph
(around my-org-mark-paragraph-advice activate)
(with-default-paragraph-definition ad-do-it))
(defalias 'my-org-forward-paragraph 'forward-paragraph)
(defadvice my-org-forward-paragraph
(around my-org-forward-paragraph-advice activate)
(with-default-paragraph-definition ad-do-it))
(defalias 'my-org-backward-paragraph 'backward-paragraph)
(defadvice my-org-backward-paragraph
(around my-org-backward-paragraph-advice activate)
(with-default-paragraph-definition ad-do-it))
(defun my-org-paragraph-overrides ()
"Use the default paragraph definitions in org-mode
when marking or moving by paragraph."
(local-set-key [remap mark-paragraph] 'my-org-mark-paragraph)
(local-set-key [remap forward-paragraph] 'my-org-forward-paragraph)
(local-set-key [remap backward-paragraph] 'my-org-backward-paragraph))
(add-hook 'org-mode-hook 'my-org-paragraph-overrides)
You can try customising the paragraph-start variable. I'm not sure
what would be appropriate here, org sets it to something quite elaborate
as you see in the quoted docstring below. Setting it to the default
might work, or you could try use-hard-newlines as mentioned in the quote below.
paragraph-start is a variable defined in `paragraphs.el'.
Its value is
"\f\|[ ]$\|\+ \|[ ]#\|\([ ]\([-+]\|\(\([0-9]+\)[.)]\)\)\|[ ]+\*\)\([ ]+\|$\)\|[ ]*[:|]\|\$\$\|\\\(begin\|end\|[][]\)"
Original value was "\f\|[ ]*$"
Local in buffer coding.org; global value is "\f\|[ ]*$"
This variable is safe as a file local variable if its value
satisfies the predicate `stringp'.
Documentation:
Regexp for beginning of a line that starts OR separates paragraphs.
This regexp should match lines that separate paragraphs
and should also match lines that start a paragraph
(and are part of that paragraph).
This is matched against the text at the left margin, which is not necessarily
the beginning of the line, so it should never use "^" as an anchor. This
ensures that the paragraph functions will work equally well within a region
of text indented by a margin setting.
The variable `paragraph-separate' specifies how to distinguish
lines that start paragraphs from lines that separate them.
If the variable `use-hard-newlines' is non-nil, then only lines following a
hard newline are considered to match.

Emacs: Insert word at point into replace string query

Is there an analogue to inserting the word after point into the isearch query by hitting C-w after C-s but for the replace string (and replace regexp) queries?
I also enjoy Sacha Chua's modification of C-x inserting whole word around point into isearch:
http://sachachua.com/blog/2008/07/emacs-keyboard-shortcuts-for-navigating-code/
This too would be really useful in some cases if it could be used in replace string.
I'd be very thankful for any tips!
Thank you!
This will do it, although it isn't as fancy as C-w in isearch because you can't keep hitting that key to extend the selection:
(defun my-minibuffer-insert-word-at-point ()
"Get word at point in original buffer and insert it to minibuffer."
(interactive)
(let (word beg)
(with-current-buffer (window-buffer (minibuffer-selected-window))
(save-excursion
(skip-syntax-backward "w_")
(setq beg (point))
(skip-syntax-forward "w_")
(setq word (buffer-substring-no-properties beg (point)))))
(when word
(insert word))))
(defun my-minibuffer-setup-hook ()
(local-set-key (kbd "C-w") 'my-minibuffer-insert-word-at-point))
(add-hook 'minibuffer-setup-hook 'my-minibuffer-setup-hook)
EDIT:
Note that this is in the standard minibuffer, so you can use it use it anywhere you have a minibuffer prompt, for example in grep, occur, etc.
Two answers:
Replace+ automatically picks up text at point as the default value when you invoke replace commands.
More generally, Icicles does something similar to what scottfrazer's code (above) does, but it is more general. At any time, in any minibuffer, you can hit M-. (by default) to pick up text ("things") at point and insert it in the minibuffer. You can repeat this, to either (a) pick up successive things (e.g. words) of the same kind, accumulating them like C-w does for Isearch, or (b) pick up alternative, different things at point. More explanation here.
I think this exists in Emacs already - you just start replace with M-S-% and then press M-n (while the minibuffer is empty), this fills in the word under cursor, there are more useful things you can do with this, check http://endlessparentheses.com/predicting-the-future-with-the-m-n-key.html?source=rss#disqus_thread.

Emacs - select text by regexp (and idealy with option to select text only if regexp match is surrounding caret

I need to select text in Emacs with regexp. And it would be for the best if I had an option to match only if match is surrounding caret.
Example:
text.....
<start oftext I want to select> text.....
text....
text.... <caret> text....
text....
text.... <end of text I want to select>
some other text
Edit: I am sorry that I obviously didn't state my question clearly, so here is a clarification:
Caret was meant as the place where cursor is currently placed, not literal text to be matched
Start and end of text to be selected is just all the text that is in the document without any empty line.
It's not hard to find something around point in elisp. Just use two searches, forward and backward.
(defun set-selection-around-parens()
(interactive)
(let ( (right-paren (save-excursion ; using save-excursion because
; we don't want to move the
; point.
(re-search-forward ")" nil t))) ; bound nil
; no-error t
(left-paren (save-excursion (re-search-backward "(" nil t))))
(when (and right-paren left-paren)
;; this is actually a way to activate a mark
;; you have to move your point to one side
(push-mark right-paren)
(goto-char left-paren)
(activate-mark))))
When you use primary selection to select something around, you can't save the position of your current point(you named it caret). To save current position and have some selection, you can use secondary selection.
(require 'second-sel)
(global-set-key [(control meta ?y)] 'secondary-dwim)
(define-key esc-map "y" 'yank-pop-commands)
(define-key isearch-mode-map "\C-\M-y" 'isearch-yank-secondary)
(defun secondary-selection-deactivate()
(interactive)
(x-set-selection 'SECONDARY nil)
(move-overlay mouse-secondary-overlay (point-min) (point-min) (current-buffer)))
(defun secondary-selection-in-this-buffer-p()
(and (x-get-selection 'SECONDARY) (overlayp mouse-secondary-overlay) (eq (current-buffer) (overlay-buffer mouse-secondary-overlay))))
(defun set-secondary-selection-around-parens()
(interactive)
(let ( (right-paren (save-excursion (re-search-forward ")" nil t)))
(left-paren (save-excursion (re-search-backward "(" nil t))))
(when (and right-paren left-paren)
(primary-to-secondary left-paren right-paren)
)))
You do not say how the start and end of the text to be selected are defined. In fact, your question is not clear at all. If you just want to highlight all text that contains the literal text <carat>, then do this:
Use M-s h r to highlight a regexp. It prompts you for the regexp.
Type this regexp to match all text that contains the string <carat>:
\(.\|C-qC-j\)*<carat>\(.\|C-qC-j\)*
(If you meant the carat character, ^, instead of the literal text <carat>, then replace that text above by \^.)
C-q C-j inserts a newline character. The regexp . matches any character except newline, so the regexp \(.\|C-qC-j\) matches any character, including newline.
I know this doesn't directly answer your question, but depending on what you are actually selecting it may be best to use mark-defun or mark-paragraph. There may even be something like LaTeX-mark-environment for the specific mode you are in. If it's a new mode for a new type of file you can customize paragraph-start, beginning-of-defun or similar to get the desired results. Of course if the regular expressions are input by the user this won't be a good option.

How to use vimpulse together with autopair.el

It seems that when vimpulse is running, autopair only works partially in the sense that pressing backspace in empty bracket pairs will no longer remove the closing bracket but only the opening one (which means backspace functions as normal backspace now). An example:
(When Vimpulse and autopair are both active, and current mode is INSERT mode, "|" denotes the cursor)
begin: (|)
Now press "backspace"
expected result: | (both opening and closing brackets are removed)
actual result: |) (only the opening bracket is removed)
I know this has to do with the fact that vimpulse (or rather viper-mode) remapped [backspace] from delete-backward-char to something else (viper-delete-backward-char I think). But I could not find a fix to it.
Could anybody find a solution to this? (so that backspace key will remove both opening and closing bracket when the bracket is empty and cursor is in between).
Thanks!
i think something like this in your init file would work:
(add-hook 'autopair-mode-hook
'(lambda ()
(define-key autopair-emulation-alist [remap viper-delete-backward-char] 'autopair-backspace)))
I will answer this question myself.
I could not figure out an "orthodoxy" way to solve the problem and I came up with a hack.
The function that is bound to in viper insert mode (viper-del-backward-char-in-insert) is adviced to check whether cursor is currently in a matched pair, if so, the character after the cursor is deleted before the actual function is called. This also takes into account possible problem caused by prefix character (backslash).
Just copy the code below into your .emacs file after viper-mode or vimpulse is loaded.
(defun not-escaped (escape-char)
"Character immediately before cursor is not prefixed by escape-char"
(let ((count 0))
(save-excursion
(if (char-before)
(backward-char))
(while (and (char-before)
(= (char-before) escape-char))
(setq count (+ count 1))
(backward-char))
(if (= 0
(% count 2))
t
nil))))
(defun in-matched-empty-pair (pair-list)
"tell if cursor is in an empty pair in pair-list"
(let ((next-char (char-after))
(prev-char (char-before))
(matched nil)
(pair)
(pair-left)
(pair-right))
(if (and next-char
prev-char)
(while (and (setq pair
(pop pair-list))
(not matched))
(setq pair-left (pop pair)
pair-right (pop pair))
(if (= next-char pair-right)
(if (and
(= prev-char pair-left)
(not-escaped ?\\))
(setq matched t)))))
(if matched
t
nil)))
(defvar viper-workaround-pairs
'(
(?\" ?\")
(?\' ?\')
(?\` ?\`)
(?\( ?\))
(?\[ ?\])
(?\{ ?\})
))
;; Workaround for integration problem with autopair
(defadvice viper-del-backward-char-in-insert (before viper-auto-delete-pair-backward())
(if (in-matched-empty-pair viper-workaround-pairs)
(delete-char 1)))
;; Activate advice
(ad-activate 'viper-del-backward-char-in-insert)
This is a hack but it is probably the best I could do now.
Here is my updated solution. Put the following in your .emacs file after the code that loads autopair and vimpulse:
(add-to-ordered-list 'emulation-mode-map-alists (car (last emulation-mode-map-alists)) 400)
It moves autopair's keymap in front of viper's one, giving it higher priority.
Maybe you have to adept the order number (here 400), depending on whether you are using additional emulation-modes.
The result can be checked with C-x v emulation-mode-map-alists. In my case:
(viper--intercept-key-maps cua--keymap-alist autopair-emulation-alist viper--key-maps)
Now, autopair-emulation-alist should be listed before viper--key-maps.
baumichel found the trick. I just add a quick snippet to help :
First, as autopair-mode simply appends autopair-emulation-alist, evaluate:
(defadvice viper-change-state-to-insert (after autopair nil activate)
(add-to-ordered-list 'emulation-mode-map-alists 'autopair-emulation-alist 300))
Then, remember that vimpulse-normalize-minor-mode-map-alist removes all viper keymaps in front of the alist, so execute:
(defadvice vimpulse-normalize-minor-mode-map-alist (after order-viper--key-maps nil activate)
(add-to-ordered-list 'emulation-mode-map-alists 'viper--key-maps 500))
That works for me! I evaluate these snippets in an embedded eval-after-load for both vimpulse and autopair.
My idea is that Emacs dev should rethink the emulation-mode-map-alists and use a property list indexing priority order like this: ((:name viper--key-maps :after (cua--keymap-alist autopair-emulation-alist)) (:name viper--intercept-key-maps :before (cua--keymap-alist autopair-emulation-alist))). Old packages like viper, CUA and so on should be better maintained because our setup becomes ugly after years with Emacs.