Collapse/expand parts of .emacs file with org-mode - emacs

I recently learned the basics of emacs' org-mode and couldn't help but imagine applying the collapse/expand concept to parts of a source file. I would like to be able to divide my .emacs file in subparts and only display headers on load, somewhat like the following:
; ERC config...
; DIRED config...
; MISC config...
Each of these would of course be headers to many lines of codes once expanded, like this:
; ERC config
(defun start-irc ()
(interactive)
(erc-tls :server "irc.freenode.net" :port 6697 :nick "foo"))
; DIRED config...
; MISC config...
So is this possible? How could I accomplish something like this with emacs 24.2?
Thanks!

As nice as org-mode is, it does require some structure, which I don't believe can be maintained the way you want in your .emacs file.
What does work well is folding-mode. Check out the information for it on the wiki page, but basically what you do is set up comments around the chunks of code you want to put in a fold, like so:
;;{{{ some folder of some kind
(a few lines)
(of lisp)
(this "code" is just filler)
;;}}}
;;{{{ a different folder
(some more elisp code)
;;}}}
And when it is folded, it will look like:
;;{{{ some folder of some kind...
;;{{{ a different folder...

Babel enables you to achieve exactly this (i.e. managing your init file in org-mode). Specifically, see: http://orgmode.org/worg/org-contrib/babel/intro.html#emacs-initialization
Myself, I make use of outline-minor-mode in my init file for vaguely similar purposes. Various things are treated as outline headings, but you can set outline-regexp as a file local variable to restrict that behaviour, and then you toggle things open and closed with outline-toggle-children (which you would bind to some convenient key). The toggle command works from anywhere in the section, not just on the heading.
I start the headings I want to be collapsed by default with ;;;; * and end my init file with:
;;; Local Variables:
;;; outline-regexp: ";;;; "
;;; eval:(progn (outline-minor-mode 1) (while (re-search-forward "^;;;; \\* " nil t) (outline-toggle-children)))
;;; End:
In your instance you could use:
;;; Local Variables:
;;; outline-regexp: "; "
;;; eval:(progn (outline-minor-mode 1) (hide-body))
;;; End:
Pretty similar in effect to Trey's suggestion, although I expect with folding you can trivially nest sections which I'm not accounting for (having no need to do so). I feel the outline approach leaves the file looking slightly cleaner, if that matters to you.

You can also take a look at the new Outshine package which works together with outline-minor-mode to make it feel more like org-mode. In (e)lisp files outshine interprets sequences of semicolons as headers so all existing code which follows standard conventions for comments becomes foldable without any changes. Many org-mode-like key bindings (like TAB to fold/unfold heading, etc) work too.

Related

How to use the same file extension with different modes?

I have files with a .new extension that contain LaTeX code (they are the output of a program that does things on the original .tex source).
In order to check them I need that they have the LaTeX syntax highlighted and that they can be opened in read-only mode to avoid introducing errors. So I put these lines in my .emacs:
(setq auto-mode-alist
(append '(("\\.new\\'" . read-only-mode)
("\\.new\\'" . latex-mode))
auto-mode-alist))
But it does not work as expected because only the first mode is applied. How can I force emacs to apply both read-only-mode and latex-mode to the same file extension?
An easy solution is to associate your file extension with a custom derived major mode:
(define-derived-mode read-only-latex-mode latex-mode "LaTeX"
"Major mode for viewing files of input for LaTeX."
(read-only-mode 1))
(add-to-list 'auto-mode-alist '("\\.new\\'" . read-only-latex-mode))
The new read-only-latex-mode does everything that latex-mode does (including running latex-mode-hook if you're already using that), but it additionally enables read-only-mode after all of the parent mode's actions have taken place.
Any other code which cares about the major mode being latex-mode should already be testing that using the standard approach of (derived-mode-p 'latex-mode) which is still true for this new mode; so in principle this approach should Just Work.
Not sure I can really provide an answer, but here's some things to consider:
read-only-mode is a minor mode, while
auto-mode-alist is meant to turn on major modes. For major modes, it makes sense that you can have only one.
You can put something like -*- buffer-read-only: t; -*- on your first line in the file (possibly behind some comments or shebangs, depending on the file type) which would turn on read-only-mode. Maybe automate this using auto-insert-alist and match the .new filename pattern.
There's some good suggestions over at https://www.reddit.com/r/emacs/comments/jqxgiz/how_can_i_make_some_files_automatically_readonly/ , namely try file local variables and use find-file-hook
Hope some of that helps.

emacs > org mode > agenda - always use current buffer

I am using many different org mode files for various projects, and I rev them by adding the date to the filename eg filename-2020-09-17.org. I realize I could use version control but in this case that is not possible, due to needing to share the file with others who are not using VC.
I would like the Agenda to always show just the items for the current file/buffer.
When I save eg the file with filename-2020-09-16.org to filename-2020-09-17.org, then the agenda still shows the old file name unless I remove it from the agenda file list and add the new file.
I realize that I can use C-c a < a but I am lazy and would rather not have to type S-, each time to get the <.
I looked at
Agenda view of the current buffer
And the OP says the solution was simple but he/she/they did not provide the solution - at least I don't see it and I tried the posted code but it no works.
I also found https://www.reddit.com/r/orgmode/comments/bxwovd/agenda_for_current_buffer/ but that did not seem to meet my need.
Specifically I would like to put something in .emacs so that this would apply to all files all the time.
I also looked into a keystroke macro programs but this does not seem ideal.
Any help is appreciated.
Thanks ahead of time.
Here's a simple function to do what you want, but there is no error checking to make sure e.g. that you are invoking it from a buffer that is visiting an Org mode file. The idea is that you set the org-agenda-files list to contain just the file which the buffer is visiting and then you call the regular org-agenda function. Binding the modified function to the C-c a key may or may not be what you want to do, but you can try and decide for yourself:
(defun org-agenda-current-buffer ()
(interactive)
(let ((org-agenda-files (list (buffer-file-name (current-buffer)))))
(org-agenda)))
(define-key global-map (kbd "C-c a") #'org-agenda-current-buffer)

Emacs - How to wrap selection in org-mode source code block?

I have a bunch of elisp and other code with some notes i wanted to reformat to be more organized, and i found that having to type
#+BEGIN_SRC emacs-lisp ... #+END_SRC
all the time around what i want, is taking a bit longer than expected...
So what i wanted to do instead is to wrap/or put the selected content (with C-space) and put it in a template source code block for org-mode (in my case it's mostly elisp code, but i plan to use it for other things maybe)
How could i do this in emacs or in elisp?
There is a new templating mechanism in recent Org mode (>= 9.0 IIRC) that allows you tor wrap a region in a block: after selecting the region in the usual manner, you say C-c C-, s. You still have to type the emacs-lisp part though. That's the disadvantage. The advantage is that it is general enough to allow you to wrap a region in any kind of block. In your case, I think the disadvantage outweighs the advantage, so I would go with the wrap-region method in the other answer, but this one is good to know as well.
You can try wrap-region. It will allow you to define what type of string you want to wrap around a selection.
Put this in your init.el and evaluate it.
(wrap-region-global-mode t)
(wrap-region-add-wrapper "#+BEGIN_SRC emacs-lisp\n" "#+END_SRC" "#" 'org-mode)
Then, while you are editing your org files, you can select a block of text and type #, which will wrap it with your string. You can change the # to another character that will do the wrapping.
There is a feature in org-mode to do exactly that. It's like a snippet of some sort where you enter <eland hit TAB, the < char is here to say we're gonna use a template and the el part tells which template to use. But of course, you have to configure it first.
For that, you can just add this to an org-mode file or to your init.el file :
#+begin_src emacs-lisp
;; This is needed as of Org 9.2
(require 'org-tempo)
(add-to-list `org-structure-template-alist `("sh" . "src shell"))
(add-to-list `org-structure-template-alist `("el" . "src emacs-lisp"))
(add-to-list `org-structure-template-alist `("py" . "src python"))
#+end_src
There a bunch of way to use this, it's actually more useful than just use it as a template, you can go check the documentation here.

Set emacs comment style based on file extension

There are multiple questions along these lines but I haven't been able to find what I need from start to finish. I have been using emacs for a few years but am not used to its customization.
I have a unique file type, identified by its extension, which emacs is not configured for. Its comment style is
<!-- text -->
and I would like to set the variables comment-start and comment-end to the relevant values (which I am assuming will allow me to use comment-region). I don't know the correct way to do this so that it will always be configured when I open this file type but won't affect the default behavior of emacs.
Do I need to make a new major mode for this file type, and then set the variables, or is there an easier way of doing it? An example of the complete requirements for my .emacs file would be much appreciated!
See here. I think this will work:
(add-to-list 'auto-mode-alist
'("\\.extension\\'" . (lambda ()
(setq-local comment-start "<!--")
(setq-local comment-end "-->"))))
Alternatively, if this file extension is well known (or if these files are close enough to a well known syntax), you may be able to just find a major-mode online that does what you want. For example, NXML Mode may just give you the comment syntax you want along with some other useful features.

Emacs: what are good tactics for navigating directories and opening files?

Last week, infuriated (again) by having to cope with different IDEs for R and Perl, neither of which I like or use enough to get really comfortable in, I decided to try Emacs. This decision was not made without a certain trepidation on my part. My main use is for Perl with cperl and for R with ESS. My environment is Windows 7 Ultimate 64-bit and I am running v23.4.1, which I think is what the ESS package installed on my behalf.
Nearly a week in and so far it has been surprisingly painless, no more involved than any other significant piece of software. I have remapped my ctrl key to caps-lock, changed default folders, messed around with .emacs and made some additions such as auto-install, yasnippet, color-theme, icicles and a few others. Clearly there is some very sophisticated stuff out there. In addition of course certain features of base Emacs are immediately very powerful and useful, such as isearching up and down. On the whole I have been pleasantly surprised and reassured.
One thing that is cruder than I was expecting is the process of finding and opening files. After a cursory read of various tutorials I had this image of quasi-magical file location and filename auto-completion. The main directories in my setup have paths like g:/roaming/code/perl or g:/roaming/code/R/ but I often need to branch into completely different paths like g:/pricedata/support files/sector/project01/ and so on.
Currently I laboriously delete the file path when I need to take a different fork, then use auto-complete to move deeper into that branch of the filesystem. It kinda takes me back to running a bash shell on the Amiga twenty years ago.
What had I expected? Something like (using the above example) typing 'project01' to skip immediately into the folder at the bottom of the path. For some reason I had got the idea in my head that Emacs would preload directories. So maybe this wasn't realistic.
My guess is that my difficulties probably stem from my own lack of familiarity rather than a structural shortcoming in Emacs and leads on to my questions. I can't complain that there is not enough documentation; rather there is abundant information that it is scattered around rather haphazardly. Icicles has a similar problem - if anything there's too much.
1) What is the best tactic for moving around different branches of the file tree when trying to open files in the minibuffer or using some other method? Are there aliases that can be used to shortcut from one place to another or can one specify directories to be preloaded? Do people just cd around a lot? Or am I coming at this from completely the wrong angle and need to adopt a different strategy?
2) With additional setup, can auto-complete be used to find files in (say) the project01 directly above by prefixing with wildcards etc? What should I focus on to become more efficient here? Am I not tapping the power of add-ons like icicles, anything etc?
I realise these questions veer dangerously close the deprecated category of not having clear answers. My defence is that some tips/guidance at this stage before I commit myself to bad habits or a poor long-term solution would be welcome and I suspect the answers will benefit others who might be considering the switch. I am happy to withdraw or rephrase if there are problems.
helm (formerly known as anything) might suit you. You can install it manually, or using a auto-install extension.
For the auto-install way: download it, put in Your load-path, then add to .emacs:
(add-to-list 'load-path "~/.emacs.d/site-lisp/auto-install")
(require 'auto-install)
(setq auto-install-directory "~/.emacs.d/site-lisp/auto-install/")
Then do M-x auto-install-batch anything. After that is done, put in .emacs:
(require 'anything)
(require 'anything-match-plugin)
(require 'anything-config)
(require 'anything-show-completion)
Then do M-x anything for anything.
Also give a try to ECB (stands for Emacs Code Browser). If you're on Linux, you probably have it available in a standard repository.
You could benefit from using ido-mode, which greatly enhances autocompletion nearly everywhere in emacs (especially when finding files or buffers)
(setq ido-enable-flex-matching t
ido-auto-merge-work-directories-length -1
ido-create-new-buffer 'always
ido-use-filename-at-point 'guess
ido-everywhere t
ido-default-buffer-method 'selected-window)
(ido-mode 1)
(put 'ido-exit-minibuffer 'disabled nil)
(when (require 'ido-ubiquitous nil t)
(ido-ubiquitous-mode 1))
While this might help you quickly finding files "not far away", it probably won't help you much finding files in entirely different locations.
If find that one way to begin tackling this problem is using recentf-mode to quickly jump to recent locations (if you have only a small number of usual project directories, this might do the trick). recentf can be coupled with ido using something like this (I'm not sure where I got this snippet from):
(recentf-mode 1)
(setq recentf-max-saved-items 50)
(defun ido-recentf-open ()
"Use `ido-completing-read' to \\[find-file] a recent file"
(interactive)
(if (find-file (ido-completing-read "Find recent file: " recentf-list))
(message "Opening file...")
(message "Aborting")))
(global-set-key (kbd "C-x C-r") 'ido-recentf-open)
With this, you can use C-x C-f (ido-find-file) to look for files near you current location, and C-x C-r (ido-recentf-open) to look for recently opened files (hoping one of them is not too far away from where you want to go).
There are various approaches. File name cache is a built in solution. Opening files from recent files is also very effective, especially if you set the stored files to a high number (e.g. 1000). There are also packages for opening files from anywhere on the file system. And there are meta solutions like anything.el which can show you file completions from multiple sources (history, project files, etc.) in a common interface.
You should investigate the different options to find out which is the most suitable for you.
In addition to IDO and recetf you can use the following methods:
Open the directory recursively.
(defun op-i:dired (rec)
"customized dired: will display directory recursively when called with an argument"
(interactive "P")
(let ((dir (car (find-file-read-args "Dired: " nil)))
(opts (if rec (read-string "options: " "-lhAR") "-lhA")))
(if (file-directory-p dir) (dired dir opts))))
(define-key (current-global-map) (kbd "C-x C-d") 'op-i:dired)
Then you can navigate in the directory buffer as in any other buffer using a (wildcard) search.
Use Emacs registers to point to often used directories. You can initialize them in your .emacs
(set-register ?0 (cons 'file "c:/path/to/my-project0"))
(set-register ?1 (cons 'file "c:/path/to/my-project1"))
Then jump to register using C-x r j
Other people have already mentioned anything, suffice it to say, I believe it solves all your problems. :)
Calling out one specific feature of anything is anything-locate. On *nix systems, this uses the DB created by the locate command to quickly find files. On Windows, I believe it works with "Everything", which should give you near instantaneous search results across all your files. I mean all.
Tom has mentioned file-cache. Anything works with that.
Just as a side note, Dired is an absolute monster once you get used to it. You should read the emacswiki pages related to it. In particular dired-x, which comes with Emacs binds C-x C-j, jumps to current buffer in Dired was a revelation for me. Also dired-find, wdired.
Edit: some details on why C-x C-j is awesome.
When you pop the current buffer in a Dired buffer, you can modify it, i.e. rename, delete, etc. And Emacs is aware of what you've done, and adjusts accordingly.
Other possibilities:
Bookmarks. If you use Bookmark+ then you can also:
Bookmark Dired buffers, which remembers their inserted subdirs, their markings, and their file omissions. You can have a bookmark that opens Dired to a specific set of files that need not be in the same directory or even the same directory tree.
From Dired you can hit a key to create a separate bookmark to each marked file or subdir.
Bookmark files automatically (autofiles).
Tag bookmarks and files (autofile bookmarks) with arbitrary-text tags. (Tags can even be non-text Lisp objects). Use tags to organize, search, etc. different categories of bookmarks.
Bookmark sets of bookmarks or bookmark files or Emacs desktops. Jump to such a bookmark to restore a given project state/context.
Icicles.
Define temporary or persistent sets of files on the fly, even from different directories. Operate on the files in a set in various ways. (Use Emacs filesets, less powerful, the same way.)
Complete against file names from such saved sets during any completion command, not just file-finding.
Act in different ways on candidate files during completion.
Search bookmarked objects or saved sets of files or buffers.
Dired+.
Additional navigation, including i bouncing between a subdirectory listing and the subdirectory's line in the parent listing.
Refs:
http://www.emacswiki.org/cgi-bin/wiki/BookmarkPlus
http://www.emacswiki.org/emacs/Icicles_-_Support_for_Projects
http://www.emacswiki.org/emacs/Icicles_-_File-Name_Input
http://www.emacswiki.org/cgi-bin/wiki/DiredPlus