I have a replace-regexp that I use frequently, so I want to make it into a function. But M-xreplace-regexp either scans the document or uses the selected region; the function I've written seems only to scan the document. How can I get it to work just the same as M-xreplace-regexp when I call my-scripture-links, particularly with respect to selection or no-selection?
(defun my-scripture-links ()
(interactive)
(replace-regexp "^\(.*[0-9]+?:[0-9]+\)" "[[https://www.lds.org/scriptures/search?lang=eng&query=\1&x=0&y=0][\1]]"))
The arguments for replace-regexp are
(replace-regexp REGEXP TO-STRING &optional DELIMITED START END)
To replace only within a region you need to specify the START and END of the region. You can get these from the functions region-beginning and region-end. To change behaviour based on whether the region is active or not, just check region-active-p. This will replace within the region if it is active.
(defun my-scripture-links ()
(interactive)
(if (region-active-p)
(replace-regexp "^\(.*[0-9]+?:[0-9]+\)" "[[https://www.lds.org/scriptures/search?lang=eng&query=\1&x=0&y=0][\1]]"
nil (region-beginning) (region-end))
(replace-regexp "^\(.*[0-9]+?:[0-9]+\)" "[[https://www.lds.org/scriptures/search?lang=eng&query=\1&x=0&y=0][\1]]")
))
Related
The function delete-indentation, usually bound to (M-^), joins the current line to the next one and deletes any indentation.
How do I apply this function to a whole region to join multiple lines in a region?
Or is there another way to achieve the desired result?
Thanks
Try unfill-paragraph, taken from the Emacs wiki.
;;; An unfill-paragraph that works in lisp modes
(defun unfill-paragraph (&optional region)
"Takes a multi-line paragraph and makes it into a single line of text."
(interactive (progn (barf-if-buffer-read-only) '(t)))
(let ((fill-column (point-max))
(emacs-lisp-docstring-fill-column t))
(fill-paragraph nil region)))
If you're willing to give up the prefix argument of the standard M-^, you could bind the following function to that keyboard shortcut like so:
(defun join-line-or-unfill-paragraph (&optional unfill)
(interactive "P")
(if unfill (unfill-paragraph) (delete-indentation)))
(global-set-key (kbd "M-^") 'join-line-or-unfill-paragraph)
This way, whenever you type C-u before M-^ the full paragraph will be joined.
I'm using function like this to replace strings in Emacs.
(defun replace-string-from-top ()
(interactive)
(save-excursion
(beginning-of-buffer)
(call-interactively 'replace-string)))
(global-set-key "\C-r" 'replace-string-from-top)
And I want to use default value of replace-string function by selecting a word.
What I want to do is.
select a word by double clicking it.
call replace-string-from-top function with the selected word by default value.
I've tried to write the function but I couldn't.
How can I do it?
Neither replace-string nor the function that it uses to read its args when you call it interactively, which is query-replace-read-args, has any provision for providing a default programmatically in a dynamic way. The most you can do is set variable query-replace-defaults. You can bind that variable to a value in your command, so that the first element in its list value is the string from the region, i.e.:
(let* ((region-string (buffer-substring (region-beginning) (region-end))))
(query-replace-defaults (cons region-string region-string)))
...)
(The value is a cons. Use whatever other value you like as the cdr. Here I've just used the same region string.)
But you can more easily and more directly do what you want if you use library replace+.el. In that case, just set option search/replace-region-as-default-flag to non-nil to get what you want. You can also toggle that option anytime, using command toggle-search/replace-region-as-default. A description of the library is here.
Here's my setup. You can change it in a few places, like add beginning-of-buffer, if you want.
(defvar qr-beg)
(defun string-dwim ()
(let ((bounds
(if (region-active-p)
(cons (region-beginning)
(region-end))
(ignore-errors
(bounds-of-thing-at-point 'symbol)))))
(setq qr-beg (car bounds))
(when (region-active-p)
(set-mark nil))
(when qr-beg
(kill-new
(buffer-substring-no-properties
qr-beg
(cdr bounds))))))
(defun query-replace-dwim (from)
(interactive
(list
(read-regexp "Query replace" (string-dwim))))
(when qr-beg
(goto-char qr-beg)
(setq qr-beg))
(query-replace
from
(query-replace-read-to from "Query replace" nil)))
As you can see, this is a setup for query-replace.
It auto-suggests the thing to be replaced as the current string.
The current string is either the current region, if it's active, or symbol at point.
Also, the current string is kill-newed, so you can yank it as the replacement,
and then just tweak it a bit.
I defined a function and wanted to ues the
region as optional parameters.
(defun my-grep-select(&optional beg end)
(interactive "r")
(if mark-active
(....)
(....))
I wanted to grep the select chars in the buffer if the mark is active,
or grep the word under the cursor in the buffer if the mark is not active.
But In the situation: I opened the file and haven't select anything, Then run the command my-grep-select, emacs complains:
The mark is not set now, so there is no region
How can I eliminate this complains? Thanks.
The right way to do it might be:
(defun my-grep-select(&optional beg end)
(interactive
(if (use-region-p) (list (region-beginning) (region-end))
(list <wordbegin> <wordend>)))
...)
You don't need to use (interactive "r"). Instead, you could just check if region is active using (region-active-p) or similar then use (region-beginning) and (region-end) else do whatever else.
Perhaps there is choice to be made when region is active and a different set of parameters are passed...
You can also just use M-n or <down> in mini-buffer (after issuing M-x grep command) to insert selected text.
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
is there any way know there is set-mark beginning and where is the start point query in lisp
Use the variable mark-active:
mark-active is a variable defined in `C source code'.
Its value is nil
Local in buffer whole-line-or-region.el; global value is nil
Automatically becomes buffer-local when set in any fashion.
Documentation:
Non-nil means the mark and region are currently active in this buffer.
You might also want to check if mark === point, if it's really a region you're looking for:
(if (and mark-active
(/= (point) (mark)))
If you want to write a function that requires a region be defined, you can use interactive, like so:
(defun my-fn-that-requires-a-region (beg end)
"Some documentation string mentioning BEG and END."
(interactive "r")
(message "%d / %d" beg end))
If called interactively, mark must be set or an error is generated. Called programatically, any two values must be passed in; no validation of the parameters is done.
I'd recommend turning on transient-mark-mode
(setq transient-mark-mode t)
transient-mark-mode will highlight the region between the mark and your current point.
Alternatively, you can press C-x C-x to jump between the current point and the mark to see where the mark is set.