Jump to the first occurrence of symbol in Emacs - emacs

I use the excellent highlight-symbol.el to move between different occurrences of the same symbol.
In this screenshot, foo_bar is highlighted, and I can call highlight-symbol-prev to jump to it. Note that this is syntax-aware, so it's smart enough to know that foo_bar_baz is different (something isearch doesn't understand).
I'd really like to be able to jump to the first occurrence of a symbol. This would be brilliant for finding where symbols were imported. How would I go about this?

Something along these lines should do what you want.
(defun goto-first-reference ()
(interactive)
(eval
`(progn
(goto-char (point-min))
(search-forward-regexp
(rx symbol-start ,(thing-at-point 'symbol) symbol-end))
(beginning-of-thing 'symbol))))

(eval-when-compile (require 'cl))
(require 'highlight-symbol)
(defmacro save-mark-ring (&rest body)
"Save mark-ring; execute BODY; restore the old mark-ring."
`(let ((old-mark-ring mark-ring))
,#body
(setq mark-ring old-mark-ring)))
(defun highlight-symbol-jump-to-first ()
"Jump to the first occurrence of the symbol at point."
(interactive)
(push-mark)
(save-mark-ring
(let (earliest-symbol-pos)
(loop do
(highlight-symbol-jump -1)
(setq earliest-symbol-pos (point))
while (< (point) earliest-symbol-pos)))))

Related

How to change the behaviour of org-agenda-goto to open org-file in a new frame?

When pressing TAB (org-agenda-goto) in org-agenda I want to open the related org-file in a new frame instead of splitting the existing frame.
I could create a modified function of org-agenda-goto replacing switch-to-buffer-other-window with switch-to-buffer-other-frame and rebinding the TAB-key but I assume there is a more elegant way to do so?
The quick solution would be as below modifying line 8:
(defun sk/org-agenda-goto (&optional highlight)
"Go to the entry at point in the corresponding Org file."
(interactive)
(let* ((marker (or (org-get-at-bol 'org-marker)
(org-agenda-error)))
(buffer (marker-buffer marker))
(pos (marker-position marker)))
(switch-to-buffer-other-frame buffer)
(widen)
(push-mark)
(goto-char pos)
(when (derived-mode-p 'org-mode)
(org-show-context 'agenda)
(recenter (/ (window-height) 2))
(org-back-to-heading t)
(let ((case-fold-search nil))
(when (re-search-forward org-complex-heading-regexp nil t)
(goto-char (match-beginning 4)))))
(run-hooks 'org-agenda-after-show-hook)
(and highlight (org-highlight (point-at-bol) (point-at-eol)))))
I assume it may be done more elegantly with advice but I'm not so experienced in emacs-lisp and would not know how exactly this could be achived or if using advice would be the right approach.
I found out in override prefered method are hints for using advice-add like this in order to replace the original function with my own:
(advice-add 'org-agenda-goto :override #'sk/org-agenda-goto)
You can use advice to temporarily redefine switch-to-buffer-other-window using cl-letf. Assuming your on at least emacs 25.1 you can use define-advice, eg.
(define-advice org-agenda-goto (:around (orig-fn &rest args) "new-frame")
(cl-letf (((symbol-function 'switch-to-buffer-other-window)
(symbol-function 'switch-to-buffer-other-frame)))
(apply orig-fn args)))
In the advice orig-fn is a placeholder to org-agenda-goto. Alternatively, you could temporarily override display-buffer's function (there are a number of options you could use here -- see help for display-buffer), eg.
(define-advice org-agenda-goto (:around (orig-fn &rest args) "new-frame")
(let ((display-buffer-overriding-action '(display-buffer-pop-up-frame)))
(apply orig-fn args)))

A Simple 'copy-form Command

I want a command that copies a form to the kill ring. In emacs-live, the closest thing I could find was this command / key-binding
(global-set-key (kbd "M-]") 'kill-ring-save)
However kill-ring-save has some wonky behaviour. Ii copies more than 1 form, past the cursor. Ultimately, I want a simple function along the lines of what's below (this doesn't quite work).
(defun copy-form ()
(kill-ring-save (line-beginning-position) (live-paredit-forward)))
(global-set-key (kbd "M-]") 'copy-form)
I've searched high and low ( SO question and Google search), but can't seem to find a simple, working command to copy a balanced expression. Has someone already done this?
Thanks
Tim
Function sexp-at-point gives you the sexp ("form") at the cursor. Just copy that to the kill-ring, using kill-ring-save. E.g.:
(defun copy-sexp-at-point ()
(interactive)
(let ((bnds (bounds-of-thing-at-point 'sexp)))
(kill-ring-save (car bnds) (cdr bnds))))
Alternatively, just use kill-new:
(defun copy-sexp-at-point ()
(interactive)
(kill-new (thing-at-point 'sexp)))
The reason your copy-form cannot be bound to a key is that it is a function, not a command - it is missing an interactive form.
However, in your case you don't even need to write a new function.
Try a combination of
mark-sexp is an interactive compiled Lisp function in `lisp.el'.
It is bound to C-M-#, C-M-SPC.
and
M-w runs the command kill-ring-save, which is an interactive compiled
Lisp function in `simple.el'.
It is bound to <C-insertchar>, M-w, <menu-bar> <edit> <copy>.
I'm not sure I understand the question, but when I need to do what I consider as "copy a balanced form", I do: M-C-SPC M-w. If I want to cut it instead, I do M-C-SPC C-w.
Here's what I generally use. Somehow it's more useful for me
to kill the balanced expression instead of copying. If I want a
copy instead, I first kill, then undo.
This function kills a string, if the point is inside string,
otherwise the balanced expression, i.e. (),[],{},<>
or whatever is defined by the syntax.
(defun kill-at-point ()
"Kill the quoted string or the list that includes the point"
(interactive)
(let ((p (nth 8 (syntax-ppss))))
(cond
;; string
((eq (char-after p) ?\")
(goto-char p)
(kill-sexp))
;; list
((ignore-errors (when (eq (char-after) ?\()
(forward-char))
(up-list)
t)
(let ((beg (point)))
(backward-list)
(kill-region beg (point)))))))
I've also tried to add a special case for when the point is
inside the comment, but I couldn't find a generic
way to determine bounds of comment at point. If anyone knows,
please tell me.
This other function can be relevant as well. It marks instead
of killing, like the previous one. The nice thing that it
extends the region each time it's called.
I bind the first one to C-, and the second to
C-M-,.
(defun mark-at-point ()
"Mark the quoted string or the list that includes the point"
(interactive)
(let ((p (nth 8 (syntax-ppss))))
(if (eq (char-after p) ?\")
(progn
(goto-char p)
(set-mark (point))
(forward-sexp))
(progn
(when (eq (char-after) 40)
(forward-char))
(condition-case nil
(progn
(up-list)
(set-mark (point))
(let ((beg (point)))
(backward-list)
(exchange-point-and-mark)))
(error
(when (looking-back "}")
(exchange-point-and-mark)
;; assumes functions are separated by one empty line
(re-search-backward "^[^A-Z-a-z]" nil t)
(forward-char))))))))

emacs 23.2.1: character-by-character copying from the previous line seems broken

After upgrading to emacs 23.2.1 with Fedora 15 one of my emacs functions is broken and I just can't seem to find the problem. Something has to have changed, but I sure can't find it in the elisp documentation.
I'd really appreciate any suggestions!
What it should do: Pressing Ctl-hyphen should copy the character above the cursor and move the point ahead by 1.
What it does: Keeps copying the character above without advancing the point. HOWEVER, calling it with "M-x insert-char-from-previous-line" or pressing RightArrow between Ctl-hypens works as it should. Adding (forward-char 1) to the end of the script doesn't help.
(defun insert-char-from-previous-line ()
"Copy previous line character by character"
(interactive)
(previous-line 1)
(let ((char-above (following-char) ))
(next-line 1)
(if (not (char-equal char-above ?\n ))
(insert char-above))))
(global-set-key [?\C--] 'insert-char-from-previous-line) ;copy char above
I think your getting caught in a goal column issue. You probably should not use next-line/previous-line for this, rather try this:
(defun insert-char-from-previous-line ()
"Copy previous line character by character"
(interactive)
(let ((curpoint (point))
(curcolumn (current-column)))
(forward-line -1)
(forward-char curcolumn)
(let ((char-above (following-char) ))
(goto-char curpoint)
(if (not (char-equal char-above ?\n ))
(insert char-above)))))
From the docs on pervious-line:
If you are thinking of using this in a Lisp program, consider using
`forward-line' with a negative argument instead. It is usually easier
to use and more reliable (no dependence on goal column, etc.).
(describe-function 'previous-line)
don't move the point for something like this:
(defun i-char (arg)
(interactive "*p")
(let ((start (+ (point-at-bol 0)
(current-column)))))
(insert (buffer-substring-no-properties start (+ start arg))))

Disable auto-fill-mode locally (or un fill-paragraph) with emacs

I use M-q for fill-paragraph, can I do the un-fill-paragraph in auto-fill-mode?
With org mode, I sometimes enter [[Very long HTML][Name with spaces]], and for the 'Name with spaces' the auto-fill mode break the whole line based on the inserted space, which makes it very ugly.
Is there a command something like un-fill-paragraph? Or, is there a way disable auto-fill-mode temporarily/locally?
Emacs does not record what was your line before calling fill-paragraph. So the only thing you can do is C-_ which runs the command undo. It can undo your fill-paragraph command but only if it is the preceding command call.
If you want to put a multi-line paragraph on one line you could do like this :
Select the region
C-M-% C-q C-j RET SPACE RET !
Xah Lee has updated his code since monotux's answer, and I refactored it somewhat for readability:
(defun my-toggle-fill-paragraph ()
;; Based on http://xahlee.org/emacs/modernization_fill-paragraph.html
"Fill or unfill the current paragraph, depending upon the current line length.
When there is a text selection, act on the region.
See `fill-paragraph' and `fill-region'."
(interactive)
;; We set a property 'currently-filled-p on this command's symbol
;; (i.e. on 'my-toggle-fill-paragraph), thus avoiding the need to
;; create a variable for remembering the current fill state.
(save-excursion
(let* ((deactivate-mark nil)
(line-length (- (line-end-position) (line-beginning-position)))
(currently-filled (if (eq last-command this-command)
(get this-command 'currently-filled-p)
(< line-length fill-column)))
(fill-column (if currently-filled
most-positive-fixnum
fill-column)))
(if (region-active-p)
(fill-region (region-beginning) (region-end))
(fill-paragraph))
(put this-command 'currently-filled-p (not currently-filled)))))
To remake a long line out of a paragraph in Org mode, I gave myself a new command. Here is the associated Emacs Lisp code:
(defun fp-unfill-paragraph (&optional justify region)
(interactive (progn
(barf-if-buffer-read-only)
(list (if current-prefix-arg 'full) t)))
(interactive)
(let ((fill-column 100000))
(fill-paragraph justify region)))
(global-set-key "\C-ceu" 'fp-unfill-paragraph)
Of course, you adjust the command keybinding as you see fit!
I use the following snippet to fill and un-fill paragraphs (using only M-q), it is really, really handy. I borrowed it from Xah Lee, but removed some comments and whitespace in order to make it fit in here. The link in the first comment goes to his original code.
;; http://xahlee.org/emacs/modernization_fill-paragraph.html
(defun compact-uncompact-block ()
"Remove or add line endings on the current block of text.
This is similar to a toggle for fill-paragraph and unfill-paragraph
When there is a text selection, act on the region.
When in text mode, a paragraph is considered a block. When in programing
language mode, the block defined by between empty lines.
Todo: The programing language behavior is currently not done.
Right now, the code uses fill* functions, so does not work or work well
in programing lang modes. A proper implementation to compact is replacing
newline chars by space when the newline char is not inside string.
"
(interactive)
(let (bds currentLineCharCount currentStateIsCompact
(bigFillColumnVal 4333999) (deactivate-mark nil))
(save-excursion
(setq currentLineCharCount
(progn
(setq bds (bounds-of-thing-at-point 'line))
(length (buffer-substring-no-properties (car bds) (cdr bds)))))
(setq currentStateIsCompact
(if (eq last-command this-command)
(get this-command 'stateIsCompact-p)
(if (> currentLineCharCount fill-column) t nil)))
(if (and transient-mark-mode mark-active)
(if currentStateIsCompact
(fill-region (region-beginning) (region-end))
(let ((fill-column bigFillColumnVal))
(fill-region (region-beginning) (region-end)))
)
(if currentStateIsCompact
(fill-paragraph nil)
(let ((fill-column bigFillColumnVal))
(fill-paragraph nil))))
(put this-command 'stateIsCompact-p
(if currentStateIsCompact
nil t)))))
(global-set-key (kbd "M-q") 'compact-uncompact-block)

How to write an Emacs function to wrap the marked region with specified text

I'm not too familiar with elisp, and am trying to learn. In emacs, I'd like to be able to do the following:
Mark via C-space
Go to where I want the the marking to end, so I have a region that is highlighted, suppose it is "highlighted text"
Hit a key-sequence
Have emacs ask me to input some text, say "plot", and
Have that highlighted text change to be "plot(highlighted text)". That is, I'd like to wrap the highlited text with parentheses and precede it with the text I input.
(defun wrap-text ()
)
I suppose the input of the function would be the highlighted text, but I don't know where to start looking. The other hard part would be the input text part. Could someone guide me? Thanks.
For your case, this should work:
(defun wrap-text (b e txt)
"simple wrapper"
(interactive "r\nMEnter text to wrap with: ")
(save-restriction
(narrow-to-region b e)
(goto-char (point-min))
(insert txt)
(insert "(")
(goto-char (point-max))
(insert ")")))
(global-set-key (kbd "C-x M-w") 'wrap-text)
Something a bit closer to your version, but with some changes :
you can use 'let' to create a local-variable
region-beginning and region-end gives you the equivalent of what trey did with
Here is an example :
(defun wrap-in-function ()
"Wrap marked region with a specified PREFIX and closing parentheses."
(interactive)
(let ((prefix (read-from-minibuffer "function: ")))
(save-excursion
(goto-char (region-beginning))
(insert (concat prefix "(")))
(save-excursion
(goto-char (region-end))
(insert ")"))))
Another difference between the two versions is the position of the point after you called the function ; trey version might be better to use (matter of taste).
EDIT : edited following vinh remarks.
this requires 'cl but is otherwise pretty tiny. been using it for a few years.
(require 'cl) ;;if you haven't elsewhere
(defun decorate-region( beg end prefix suffix )
(interactive "r\nMPrefix: \nMSuffix: ")
(cl-set-buffer-substring beg end (concat prefix
(buffer-substring beg end)
suffix)))
thanks trey jackson. i didn't know u posted a solution so i went to #emacs on the freenode for help. after some research, i came up with the following:
(defun ess-R-wrap-content-vqn ()
"Wrap marked region with a specified PREFIX and closing parentheses."
(interactive)
(set (make-local-variable 'prefix) (read-from-minibuffer "function: "))
(set (make-local-variable 'prefix) (concat prefix "("))
(save-excursion (goto-char (region-beginning)) (insert prefix))
(save-excursion (goto-char (region-end)) (insert ")"))
)
(define-key ess-mode-map "\C-c\M-w" 'ess-R-wrap-content-vqn) ;; w is for wrap
i thought stackoverflow was going to notify me when a solution is posted. again, thanks. learning a little more of elisp from this.