Define a copy-section command in Emacs - emacs

I would like to set up a command that put the content of the lines between two § characters without moving the point (not including the lines containg the §).
Here is my current attempt
(defun copy-section ()
"Copy current section, that is lines between two §."
(interactive)
(save-excursion
(when (not (search-backward-regexp "§" nil t))
(goto-char (point-min)) )
(forward-line 1)
(when (not (search-forward-regexp "§" nil t))
(goto-char (point-max)) )
(move-beginning-of-line nil)
(kill-ring-save (mark) (point)) ) )
It works well but the remarks in the documentation about moving around the mark being bad style make me think taht there is a better way to achieve the same result.
Does saving position into variable (which I do not know how to do it) allows for a cleaner function.
Part of the code above comes from ergoemacs.

No "regexp" form needed as only a char is looked for
(defun copy-section ()
"Copy current section, that is lines between two §."
(interactive)
(save-excursion
(let* ((start (and (search-backward "§" nil t)
(forward-line 1)
(point)))
(end (progn (and start (search-forward "§" nil t))
(forward-line -1)
(end-of-line)
(point))))
(and start end (kill-new (buffer-substring-no-properties start end))))))

This version saves the beginning and end of your section in temporary local variables, and doesn't use the mark at all:
(defun copy-section ()
"Copy current page as defined by form feed characters."
(interactive)
(let (start end)
(save-excursion
(when (not (search-backward-regexp "§" nil t))
(goto-char (point-min)) )
(forward-line 1)
(setq start (point))
(when (not (search-forward-regexp "§" nil t))
(goto-char (point-max)) )
(move-beginning-of-line nil)
(setq end (point))
(kill-ring-save start end))))

Related

Forward sentence by comma by partial sentence in org

Strike M-e in org which invokes org-forward-sentence and thus move point to end of the sentence.
I desire to move by comma. When refer to org-forward-sentence, notice the last two lines of
(let ((sentence-end (concat (sentence-end) "\\|^\\*+ .*$")))
(call-interactively #'forward-sentence)))))))
From the completed definition.
(defun org-forward-sentence (&optional _arg)
"Go to end of sentence, or end of table field.
This will call `forward-sentence' or `org-table-end-of-field',
depending on context."
(interactive)
(if (and (org-at-heading-p)
(save-restriction (skip-chars-forward " \t") (not (eolp))))
(save-restriction
(narrow-to-region (line-beginning-position) (line-end-position))
(call-interactively #'forward-sentence))
(let* ((element (org-element-at-point))
(contents-end (org-element-property :contents-end element))
(table (org-element-lineage element '(table) t)))
(if (and table
(>= (point) (org-element-property :contents-begin table))
(< (point) contents-end))
(call-interactively #'org-table-end-of-field)
(save-restriction
(when (and contents-end
(> (point-max) contents-end)
;; Skip blank lines between elements.
(< (org-element-property :end element)
(save-excursion (goto-char contents-end)
(skip-chars-forward " \r\t\n"))))
(narrow-to-region (org-element-property :contents-begin element)
contents-end))
;; End of heading is considered as the end of a sentence.
(let ((sentence-end (concat (sentence-end) "\\|^\\*+ .*$")))
(call-interactively #'forward-sentence)))))))
Then changed dot to comma
(let ((sentence-end (concat (sentence-end) "\\|^\\*+ ,*$"))) ;;changee . to ,
(call-interactively #'forward-sentence)))))))
However, it proved wrong.
Where should I change within the original function.
Define it as
(def org-forward-partial-sentence (&optional arg)
and (global-set-key "\C-m"
That . has special meaning in a regex context, see (emacs)Regexps in the manual.
A very simplistic modification could be,
(concat (sentence-end) "\\|^\\*+ .*$\\|,")
to move to , as well.
Instead of changing the entire function, you could just let bind sentence-end around org-forward-sentence, eg.
(defun my-org-forward-sentence ()
(interactive)
(let ((sentence-end (concat (sentence-end) "\\|,")))
(call-interactively #'org-forward-sentence)))

Emacs -- modify `dired-mark` to prevent moving cursor to an empty line at eob

I have a custom function that gets dired marked file names (i.e., the names of every marked file) if more than one has been marked, or if only one, it gets the file name at point. A problem occurs whenever the cursor is in no-man's-land because dired-mark (or me, because I'm the pilot) got overzealous on repetition and moves the cursor to a blank line at the end of the buffer where there is no file. In that situation, the error is as follows:
Debugger entered--Lisp error: (error "No file on this line")
signal(error ("No file on this line"))
error("No file on this line")
dired-get-file-for-visit()
(file-directory-p (dired-get-file-for-visit))
(if (file-directory-p (dired-get-file-for-visit)) nil (let ((lawlist-filename (if (or (re-search-backward "^*" nil t) (re-search-forward "^*" nil t)) (dired-get-marked-files) (dired-get-file-for-visit)))) (wl-draft-mailto) (attach-multiple-files lawlist-filename)))
(lambda nil (interactive) (if (file-directory-p (dired-get-file-for-visit)) nil (let ((lawlist-filename (if (or (re-search-backward "^*" nil t) (re-search-forward "^*" nil t)) (dired-get-marked-files) (dired-get-file-for-visit)))) (wl-draft-mailto) (attach-multiple-files lawlist-filename))))()
funcall-interactively((lambda nil (interactive) (if (file-directory-p (dired-get-file-for-visit)) nil (let ((lawlist-filename (if (or (re-search-backward "^*" nil t) (re-search-forward "^*" nil t)) (dired-get-marked-files) (dired-get-file-for-visit)))) (wl-draft-mailto) (attach-multiple-files lawlist-filename)))))
call-interactively((lambda nil (interactive) (if (file-directory-p (dired-get-file-for-visit)) nil (let ((lawlist-filename (if (or (re-search-backward "^*" nil t) (re-search-forward "^*" nil t)) (dired-get-marked-files) (dired-get-file-for-visit)))) (wl-draft-mailto) (attach-multiple-files lawlist-filename)))) nil nil)
command-execute((lambda nil (interactive) (if (file-directory-p (dired-get-file-for-visit)) nil (let ((lawlist-filename (if (or (re-search-backward "^*" nil t) (re-search-forward "^*" nil t)) (dired-get-marked-files) (dired-get-file-for-visit)))) (wl-draft-mailto) (attach-multiple-files lawlist-filename)))))
I like the ability to hold the dired-mark key down for repetition, but I would like it to stop at the last line with a file in the dired-mode buffer. Any ideas on how to accomplish that goal would be greatly appreciated. Moving past that point, performing a test, and then returning to the previous point seems to not be a very efficient means of handling it. It might be better to terminate the dired buffer at the end of the last line with a file, so that there is no blank line -- i.e., if there is no blank line at the end of the dired-mode buffer, then dired-mark can't go there (so that would be good?).
EDIT:  The debugger message has been updated with a complete backtrace. The following is the custom function that may be, as #Drew suggests, the root cause of the error message that I am receiving:
;; E-mail attachments using Wanderlust.
(define-key dired-mode-map (kbd "C-c e") (lambda () (interactive)
;; if hovering over a directory, then do nothing
(unless (file-directory-p (dired-get-file-for-visit))
(let ((lawlist-filename
(if (or (re-search-backward "^*" nil t)
(re-search-forward "^*" nil t))
(dired-get-marked-files)
(dired-get-file-for-visit))))
(wl-draft-mailto)
(attach-multiple-files lawlist-filename)))))
(defun attach-multiple-files (&optional lawlist-filename)
"Either (dired-get-marked-files) or (dired-get-file-for-visit) when exiting recursive edit."
(interactive)
(let* (
new-dir
(beg (point))
(dir "/Users/HOME/.0.data"))
(goto-char (point-min))
(when (and (re-search-forward "username#hostname.com" nil t) (not (re-search-forward "username#hostname.com\n" nil t)))
(goto-char (point-max))
(newline 2))
(catch 'done
(while t
(goto-char (point-max))
(let* (
(multi-attach-variable t)
(next-file
(if lawlist-filename
lawlist-filename
(dired-read-file-name
(if new-dir
new-dir
dir)))) )
(setq new-dir
(cond
((and next-file (stringp next-file))
(file-name-directory next-file))
((and next-file (listp next-file))
(file-name-directory (car next-file)))))
(cond
((stringp next-file)
(mime-edit-insert-file next-file t))
((listp next-file)
(mapcar (lambda (x) (mime-edit-insert-file x t)) next-file)))
(setq lawlist-filename nil)
(if (not (lawlist-y-or-n-p "Attach another? "))
(progn
(goto-char beg)
(throw 'done nil))))))))
Try defadvice on dired-mark to avoid landing in no-man's-land:
(defadvice dired-mark (after stop-at-last-file activate)
(when (eobp)
(previous-line 1)))
The "move forward after marking" functionality is baked into dired-mark (actually, if you want to get into the guts of it, into dired-repeat-over-lines), so this advice checks if it put you on that blank line and moves you back if so. Your last paragraph suggests you might not be super-keen on this option, but it strikes me as less troublesome than altering the dired internals.
Previous Answer (October 17, 2014):  The following 3 lines of code will halt the function if the cursor is not on a file or directory and if nothing has been marked:
(when (null (dired-get-marked-files))
(let ((debug-on-quit nil))
(signal 'quit `("You are not on a line containing a valid file or directory."))))
Revised Answer (January 20, 2015):  The function dired-insert-directory may be modified to delete trailing new lines and/or whitespace at the end of the buffer as follows:
(goto-char (point-max))
(let ((trailing-whitespace+newlines (abs (skip-chars-backward "\s\r\n\t"))))
(when (> trailing-whitespace+newlines 0)
(delete-char trailing-whitespace+newlines)))

Emacs -- calculating new window-start/end without redisplay

Is it possible to calculate a new window-start/end without a redisplay occurring? If so, then an example would be greatly appreciated. If not, then what is the best way to approximate it?
Example:  We want to move to a new area of the buffer somewhere off screen, and place overlays when we get there. We might be using page-down or scroll-down or paragraph-down or end-of-buffer. When we get to that new point, we want to calculate the new window-start and the new window-end. However, we want to avoid a momentary naked looking buffer without any overlays. Ideally, the redisplay would occur once those overlays are added. I want to restrict new overlays to the new region based upon the new window-start/end.
Point-Min:  point = 1
Old Window Start:  point = 1000
Old Window End:  point = 1500
New Window Start:  point = 3500
New Window End: point = 4000
Point-Max:  point = 6000
Problem: When using the post-command-hook to try and calculate the new window-start and new window-end, the previous display positions are being used instead -- i.e., the old window-start and the old window-end.
Here is a sample of the project I am working on. Absent fixing the window-start \ window-end problem, I get the following error:
Error in post-command-hook (my-eol-ruler-function):
(error "Invalid search bound (wrong side of point)")`.
The error happens when going from (point-min) to the end of the buffer with the interactive function end-of-buffer. In the context of this error, (point-max) is beyond the old window-end.
EDIT:  Updated code to include a message: (message "point: %s | window-start: %s | window-end: %s | point-max: %s" (point) (window-start) (window-end) (point-max) ). The message is used to demonstrate that the new window-start and new window-end are not calculated within the post-command-hook because a redisplay has not yet occurred. However, I am trying to avoid a redisplay until after the new overlays have been placed -- otherwise, a naked buffer without overlays is visible for a split second.
(defvar my-eol-ruler nil
"A horizontal ruler stretching from eol (end of line) to the window edge.")
(make-variable-buffer-local 'my-eol-ruler)
(defvar my-eol-pilcrow nil
"A pilcrow symbol placed at the end of every line except the current line.")
(make-variable-buffer-local 'my-eol-pilcrow)
(defun my-eol-ruler-function ()
(let* (
(opoint (point))
(window-width (window-width))
(window-start (window-start))
(window-end (window-end))
(col-eovl
(save-excursion
(vertical-motion 1)
(skip-chars-backward " \r\n" (- (point) 1))
(- (current-column) (progn (vertical-motion 0) (current-column)))))
(my-current-line-length (- (- window-width col-eovl) 3))
(pilcrow
(propertize (char-to-string ?\u00B6)
'face '(:foreground "white")
'cursor t))
(pilcrow-underlined
(propertize (char-to-string ?\u00B6)
'face '(:foreground "white" :underline "yellow")
'cursor t))
(underline (propertize (char-to-string ?\u2009)
'display `(space :width ,my-current-line-length)
'face '(:underline "yellow")
'cursor t)))
(when (or my-eol-ruler my-eol-pilcrow)
(dolist (description `(
,my-eol-ruler
,my-eol-pilcrow ))
(remove-overlays (point-min) (point-max)
'after-string description)) )
(setq my-eol-ruler (concat pilcrow-underlined underline))
(setq my-eol-pilcrow pilcrow)
(save-excursion
(end-of-line)
(overlay-put (make-overlay (point) (point))
'after-string my-eol-ruler ) )
(message "point: %s | window-start: %s | window-end: %s | point-max: %s"
(point)
(window-start)
(window-end)
(point-max) )
(save-excursion
(goto-char window-end)
(while (re-search-backward "\n" window-start t)
(let* (
(pbol (point-at-bol))
(pbovl (save-excursion (vertical-motion 0) (point)))
(peol (point))
(peol-pbol-region-p
(if (region-active-p)
(= peol pbol)))
(eol-inside-region-p
(if (region-active-p)
(and
(<= reg-beg peol)
(> reg-end peol))))
(col-eovl
(save-excursion
(vertical-motion 1)
(skip-chars-backward " \r\n" (- (point) 1))
(- (current-column) (progn (vertical-motion 0) (current-column)))))
(my-last-column (current-column))
(window-width-bug-p (= my-last-column (- window-width 1)))
(shazbot-pbol
(save-excursion
(end-of-line)
(re-search-backward "\s\\|\t" pbol t) (+ (point) 1)))
(wrapped-window-width-bug-p (= col-eovl (- window-width 1))) )
(when
(or
(< opoint pbol)
(> opoint peol))
(overlay-put (make-overlay peol peol) 'after-string my-eol-pilcrow))))) ))
(add-hook 'post-command-hook 'my-eol-ruler-function)
Beginning of the buffer, before the error occurs.
End of the buffer -- the error occurs when executing the interactive function end-of-buffer from a point at the beginning of the buffer.
Error in post-command-hook (my-eol-ruler-function):
(error "Invalid search bound (wrong side of point)")
See also Emacs bug tracker feature request #22404 (which has not yet been implemented, but the mailing archive contains a rough draft rudimentary patch that creates a new hook for this specific issue): https://debbugs.gnu.org/cgi/bugreport.cgi?bug=22404
Minor-mode for testing window-start and window-end BEFORE visual redisplay.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; test-mode
;; A minor-mode for testing `window-start` / `window-end` BEFORE visual redisplay.
(defvar test-this-command nil
"This local variable is set within the `post-command-hook`; and,
is also used by the `window-scroll-functions` hook.")
(make-variable-buffer-local 'test-this-command)
(defun test-post-command-hook-fn ()
"A function attached to the `post-command-hook`."
(setq test-this-command this-command)
(test-demo-fn))
(defun test-window-scroll-functions-fn (win _start)
"A function attached to the `window-scroll-functions` hook."
(test-demo-fn))
(defun test-demo-fn ()
"This is a test-mode demonstration function."
(when
(and
test-mode
test-this-command
(window-live-p (get-buffer-window (current-buffer)))
(not (minibufferp))
(pos-visible-in-window-p (point)
(get-buffer-window (current-buffer) (selected-frame)) t))
(let* (
(selected-window (selected-window))
(window-start (window-start selected-window))
(window-end (window-end selected-window t)) )
(message "window-start: %s | window-end: %s" window-start window-end)
(setq test-this-command nil) )))
(define-minor-mode test-mode
"A minor-mode for testing `window-start` / `window-end` BEFORE visual redisplay."
:init-value nil
:lighter " TEST"
:keymap nil
:global nil
:group nil
(cond
(test-mode
(set (make-local-variable 'scroll-conservatively) 101)
(add-hook 'post-command-hook 'test-post-command-hook-fn nil t)
(add-hook 'window-scroll-functions 'test-window-scroll-functions-fn nil t)
(when (called-interactively-p 'any)
(message "Turned ON `test-mode`.")))
(t
(kill-local-variable 'scroll-conservatively)
(kill-local-variable 'test-this-command)
(remove-hook 'post-command-hook 'test-post-command-hook-fn t)
(remove-hook 'window-scroll-functions 'test-window-scroll-functions-fn t)
(when (called-interactively-p 'any)
(message "Turned OFF `test-mode`.") ))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Offhand, I'd say that the error is raised because you pass a BOUND arg to a search function. For example:
(re-search-backward "\n" window-start t)
(re-search-backward "\s\\|\t" pbol t)
Check your values of window-start and pbol. Remember that when you search backward the bound must not be greater than the current position (point).
I think you want to use jit-lock-register instead of post-command-hook. This way, the redisplay code will call you back once it has decided of a window-start and you'll be able to add the overlays you want before the buffer's content is displayed.

Sorting lines with multiline expressions under Emacs

I'm looking for a variant of M-x sort-lines that can handle multiline expressions properly. For instance:
this is the first line
this is the second lien
this is the (third
line
spanning multiple lines because of parens)
Any ideas?
Here is a similar question solved in a similar way
(defun end-of-chunk ()
"forward line or to ends of mid-expression."
(interactive)
(goto-char (point-at-eol))
(let ((limit (point-at-bol))
temp
expr-beg)
(while (and (setq temp (nth 1 (syntax-ppss)))
(<= limit temp))
(goto-char temp)
(setq expr-beg (point)))
(when expr-beg
(goto-char expr-beg)
(forward-sexp))))
(defun sort-lines-as-exprs (reverse beg end)
"sort lines, or whole expression if line ends mid-expression."
(interactive "P\nr")
(save-excursion
(save-restriction
(narrow-to-region beg end)
(goto-char (point-min))
(sort-subr reverse
'forward-line
'end-of-chunk))))

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)