How to maintain an emacs-based knowledge base? - emacs

I've been using org-mode for a little while, I've kept it really simple for now, with only two files :
one to act as an inbox, with remember-mode
another where I stick just about anything that's been processed from the inbox
This is great for managing somewhat 'actionable' items, but I keep adding things of a more general nature, that I won't be needing on a day-to-day basis (how-tos, reading notes etc), so it's getting slow and hard to manage.
The material I'm concerning myself with doesn't fit the /projects/tasks/sub-tasks paradigms, they are more like little knowledge nuggets on selected topics, which are inherently more complex to classify and manage.
I've been wondering what kind of structure could be used to handle that kind of information (classification and retrieval), and if there are maybe other modes that could help with the job ?
I guess there is no pre-made answer to this question, since everyone may have different needs.
Noufal gave good conceptual tips that I'll keep in mind, but overall, the accepted answer provided more pragmatic views on this, the linked resource was a GREAT read.

I think this excellent document on how to use org-mode to it's fullest potential will be very helpful to you: "Org Mode: Organize Your Life In Plain Text". It is lengthy reading, but trust me, completely worth the effort.
UPDATE:
You can use the remember-mode section mentioned in the document for your use-case. (I use it for the same use-case) Remember-mode is extremely handy to make quick notes. I use it when I have to store random observations or information that won't go anywhere else. I use the following templates for remember:
(setq org-default-notes-file (concat org-directory "/remember-notes.org"))
(setq org-remember-templates
`(("Todo" ?t "* TODO %?\n %i\n" ,(concat org-directory "/remember-notes.org") bottom)
("Misc" ?m "* %?\n %i\n" ,(concat org-directory "/Notes.org") "Misc")
("iNfo" ?n "* %?\n %i\n" ,(concat org-directory "/Notes.org") "Information")
("Idea" ?i "* %?\n %i\n" ,(concat org-directory "/Notes.org") "Ideas")
("Journal" ?j "* %T %?\n\n %i\n" ,(concat org-directory "/journal.org") bottom)
("Blog" ?b "* %T %? :BLOG:\n\n %i\n" ,(concat org-directory "/journal.org") bottom)
))
As you can see, misc notes and other information goes in the notes.org file under the headings Misc and Information. If the note I'm making doesn't fall in any of the categories defined above, it gets filed in the default file (remember-notes.org) and I can always refile it to another location at a convenient time. This makes my note-taking, jotting down random ideas, and such things extremely simple, without taking away the focus from the job I'm currently doing.

[org-mode] is great for managing somewhat 'actionable' items, but I keep adding things of a more general nature, that I won't be needing on a day-to-day basis (how-tos, reading notes etc), so it's getting slow and hard to manage.
I'm a follower of David Allen and his Getting Things Done methodology. I'm using Emacs for three of the lists he recommends:
Next Actions
Project Resources
The Someday/Maybe list
The material I'm concerning myself with doesn't fit the /projects/tasks/sub-tasks paradigms, they are more like little knowledge nuggets on selected topics, which are inherently more complex to classify and manage.
I've been wondering what kind of structure could be used to handle that kind of information (classification and retrieval), and if there are maybe other modes that could help with the job ?
For this kind of information I've migrated away from emacs. Instead I keep a directory ~/etc/howto, and in that directory I put files that contain "little knowledge nuggets on selected topics", where the key criterion is that the information has long-term value.
I could search this directory with Emacs, but my Emacs Lisp is not so hot, so I wrote a howto shell script instead (some error checking omitted for clarity):
case $# in
1) ;;
*) echo "Usage: $0 <topic>" 1>&2; exit 2 ;;
esac
topic="$1"
# Note the ordering: first exact matches, then beginning matches, then any matches
set xxx `find $HOME/etc/howto/. -name "$topic" -not -type d -print` \
`find $HOME/etc/howto/. -name "${topic}?*" -not -type d -not -name '*~' -print` \
`find $HOME/etc/howto/. -name "?*$topic*" -not -type d -not -name '*~' -print`
shift
case $# in
0) echo "No file found matching *$topic*" 1>&2 ; exit 1 ;;
*) for i
do
less "$i"
done
;;
esac
Examples include:
howto football brings up three nuggets, in this order:
Instructions to give to my wife on how to record a football game on the computer
Instructions for me as exactly what to take and how to dress when I have tickets to a football game
Instructions for transcoding a football game so it can be transmitted over the net and viewed away from home
howto filesystem brings up instructions on how to copy a filesystem
howto batteries brings up a list of recommended rechargeable batteries
One reason I don't use Emacs is that my real script is a little more complicated than what you see above: it also handles PDF and djvu files, so for example howto razor brings up a djvu document of the manual which came with my electric razor.
I have over 500 items in the main directory or in subdirectories, and even at this scale the system works quite well for me. I hope you may find it helpful too.

I personally keep a list of project directories with somewhat similar structure. Each has a tasklist.org, a tracking subdirectory (where I do project estimates and time tracking and always maintain a diary which is the main thing for the project - it will have links to other files for the project), a docs subdirectory which usually consist of stuff I'm going to publish (docs for the project, proposals etc.). I get my agenda-files to the tasklist.org in each of the subdirectories so that my agenda works fine.
I think the organisation of the data would change a little in your case (perhaps topics like "functional programming" etc.). I'm sceptical of how much a hierarchical structure would help since that would confine you into one way of looking at things (tags vs. folders again). Here are some things that come to mind.
Keep a 'master' org file that has links to all the 'interesting' top level pieces of the other content (similar to the diary I mentioned above).
Tag all your material properly (you'll settle on a set of useful tags after a while) and then use the Tag search feature to search through the files quickly. This assumes that all the files are in your agenda-files though.
Finally, if your data is too exotic to put into a structure, you can consider using a full text indexer (like xapian) and integrate that into your Emacs. There was some discussion of this over here.
Update : 26/Nov/2019
I recently came across the hyperbole package which claims to be a information organiser. I haven't used it but I'm quite tempted to and will update this when I do.

I have tried several ways to manage a knowledge base in the past. I have a bunch of "knowledge nuggets" (btw, thanks, I like that term a lot) on all sorts of diverse topics ranging from how to set up apache tomcat ssl cert, to checklists for doing a monthly family budget, to keeping a list of weights and reps completed on workouts.
I've tried keeping these in a wordpress blog, on a personal wiki, using pen and paper, etc.
In the end, emacs and org-mode is the clear winner for me. I love to have the ability to start simple, and build more complex functionality as I need it. I've used a lot of the tips described by Sacha Chua.
In my case, I always end up with a bunch of notes (more formal and organized) mixed in with action items (less formal). In general I maintain one master "action item" list and then create a separate file for notes on each topic. So far, grep has worked well for me to quickly find the file containing notes. I'll often create a emacs bookmark C-x r m to quickly navigate to notes files as well.
Simple Blogs, CMS, and wikis (like Drupal and Wordpress) are good at classification and retrieval. Maybe you could export org files to html and publish them to a blog, cms or wiki? It might not be too difficult to hook into the blog/wiki/cms tagging capability.

At work, we use a wiki (actually, several - a global wiki plus a wiki per project) for this. It's ideal for non-hierarchical data, but can also be used for hierarchical data. It's formattable, hypertextual, linkable-to, searchable, shareable but also ownable, it maintains history, and other good stuff.
Personally, i used to also use a wiki for this. But these days, i generally just forget things instead. Far easier.

You can speed up org-mode by keeping your notes in a separate file (or one for each broad topic) which is not included in the usual list of agenda files. Customise org-agenda-files to see the list.
Use org-remember to enter notes quickly without interrupting your flow. Either tag them at the time, or save them somewhere to be refiled later. You can use a tag in the remember template (customise org-remember-templates) to mark notes for refiling, and use a custom agenda search (org-agenda-custom-commands) to list them.
Tag each note with relevant topics, and use the agenda view's search facilities to find them. You can define a custom search which knows to look in the right files, or you can visit the file and restrict the agenda search to just that file.
I keep a file of notes, and your question has just inspired me to go back and start tagging them all. Works a treat!

I hold tips in .rst (reStructuredText) files in single directory. Each file have own topic.
For search I use M-x occur, or M-x lgrep, or M-x ack.
Web hosted example: http://tips.defun.work/frame.html and it is easy to turn that pages into blog like solution.
Original sources with build script: http://hg.defun.work/tips/
Main advantage of reStructuredText format:
TOC support.
include syntax.
Ability to build JavaScript based full text offline search index in HTML site with TOC, index, reference by Sphinx!!
Remember Markdown suck at extensibility, RST have regular syntax for marking data by your tokens and include any plain text format as inline into your document. Thinks about graphs with dot, prog lang syntax highlighting, etc.

The material I'm concerning myself with doesn't fit the /projects/tasks/sub-tasks paradigms, they are more like little knowledge nuggets on selected topics, which are inherently more complex to classify and manage.
Use bookmarks and Bookmark+. You can create bookmarks for sets of files and directories, in addition to individual files, and you can tag bookmarks or files, a la delicious, for organization and search purposes.

Related

Customizing Org Mode variables--where is the documentation?

I've been using Org-mode a few months, and as I customize Emacs, I'm having a lot of difficulty finding documentation on how to specifically customize various variables.
Example: I've successfully set up archiving, but want to customize the org-archive-save-context-info variable to reduce the info that's archived along with the task. I do not want to do this per-file, but in my config file. Despite my best efforts, I don't see documentation on syntax and parameters for customizing this.
I do see some documentation when I customize the variable in the Emacs UI--but I'm looking for documentation so I can see syntax and parameters for customizing this myself via a config file. I can learn it backwards this way (via 'easy customization'): customize a variable, see what Emacs wrote to the config, try tweaking that, etc.
[EDIT] I'm talking about info below the task that appears after archiving, like this:
:PROPERTIES:
:ARCHIVE_TIME: 2018-09-10 Mon 11:24
:ARCHIVE_FILE: ~/Dropbox/logs/capture.org
:ARCHIVE_OLPATH: Tasks
:ARCHIVE_CATEGORY: capture
:ARCHIVE_TODO: DONE
:END:
Is this intentional? Do I just need to 'know ELisp' first? Is the intention that you use the Emacs point-and-click UI to customize things like this? Happy to RTFM if I could find the FM.
Is the intention that you use the Emacs point-and-click UI to customize things like this?
It's certainly intended that you would use the customize interface if you don't know elisp (and you might well choose to use it even if you do).
Do I just need to 'know ELisp' first?
Yes, you'll need at least some familiarity with elisp in order to understand the documentation and be able to write your own config changes. This is because elisp is the configuration language for Emacs, and so the documentation is written in that context. (It wouldn't make sense for basic lisp concepts to be explained and repeated in every piece of documentation which used them.)
That said, many people get by just copying and pasting from config examples -- and you're likely to pick up the basics this way, even if you don't fully understand them. If you're serious about Emacs, though, spending some time to learn about elisp will be hugely beneficial to you in future.
I can learn it backwards this way (via 'easy customization'): customize a variable, see what Emacs wrote to the config, try tweaking that, etc.
That's an entirely reasonable thing to do.
FWIW C-hv org-archive-save-context-info is actually very clear if you have the background understanding.
This variable can be a list of any of the following symbols:
time The time of archiving.
file The file where the entry originates.
ltags The local tags, in the headline of the subtree.
itags The tags the subtree inherits from further up the hierarchy.
todo The pre-archive TODO state.
category The category, taken from file name or #+CATEGORY lines.
olpath The outline path to the item. These are all headlines above
the current item, separated by /, like a file path.
That tells you that you might use the following in your config file:
(setq org-archive-save-context-info '(time file todo))
Happy to RTFM if I could find the FM.
You can start learning about elisp in the "Emacs Lisp Intro" manual, which you should find near the top of the Info directory, or jump to directly with C-hig (eintr) RET. Type h from there if you need to learn how to use the Info reader.

How to maintain notes organized with org-mode?

I have a bunch of papers to read and taking notes. The problem is I don't have much time to spend looking for a way to organize my note taking system. For me emacs org-mode seems to be a quite powerfull solution, and pretty straightforward.
I encounter another problem, how can I keep my notes organized with a single file, in a way that I can rapidly access all the notes?
Since you're short time, you might do well to start with a simple system in which you can capture the notes you need to take, and worry later about organization. Consider the following:
* Title of a paper
** First section name
- A note
- Another note
** Second section name
- Yet another note
- A fourth note
- A fifth note
* Title of another paper
** First section name
- Yet more notes
** Second section name
- &c., &c.
Using paper titles as top-level section headings makes it easy to navigate among papers with isearch; C-s Title of a paper RET brings you to the section containing all your notes on that paper. From there, you can search for a section title, or just use TAB on headings to fold and unfold until you're looking at what you want.
Unless I've misunderstood your requirement, that should give you a pretty quick and straightforward way to dive in and start taking your notes, without losing navigability. That'll also give you an opportunity for some initial, shallow exploration of the problem domain; then, once you've gotten past the current glut of work and have time to think about how you want your note-taking system to work, you can explore the problem more deeply, using org-mode's quick outline rearrangement tools at need to turn the scheme you've got into the scheme you need.

Emacs plugin for storing written code as template

For example, standard libraries in C/C++ are used very often, and it's very inefficient to go to the web browser, search for the code example how to use a library component, copy the source code and modify to suit your need; a few month later, you need to use that library component again but forgot how to use it, and you have to repeat the whole process again!
This process is not very productive for me because after we learn something the first time, we do not need to fully study the same thing again; just part of it can help us recall how to use it. I want my written code or example code copied from the web site to be stored for later reference and modification.
Emacs macro is an option, but I think you have to type the whole source code to make a desired template. What if I found a well written code, and I want to store that code segment for future reference? Macro won't be productive because I have to type the whole thing.
Is there Emacs plugin for doing this?
I wouldn't recommend snippets for the task that you described.
Snippets are meant to be repeated often. You can't have a lot of them.
What you need is something that you use rarely, but can have a lot of.
I'm using org-mode for this task. With org-mode you can:
Organize your knowledge by language/library etc.
Include small code snippets directly via babel.
Attach any number of files to any heading.
This way you get the overview/description via the headings,
and the actual code via code blocks / attachments.
Another advantage is that you can easily grep your org-file / your attachments.
Other advantages are timestamps, TODOs and all kinds of export that org-mode provides.
UPD
Just to give you a sample of what it can do (open in in emacs, otherwise it looks ugly):
https://gist.github.com/abo-abo/6040382/raw/1be55e30a9ed8d81cc1b2b752b7d498d05e72978/hyper.org
There is quite a list on the EmacsWiki: Templates.
Personally I know TempoMode and Yasnippets. I prefer Yasnippets. The snippets are very easy to write and have support for variable fields which you enter on snippet insertion.
This should provide a command inserting the last item of current kill-ring.
(defun my-code ()
(interactive "*")
(insert "(defun ")
(save-excursion (insert (concat "()
(interactive \"*\")
(insert \"" (car kill-ring) "\"))"))))
Remains to specify the name of the command when done - and installing it.
In the past I have used Else-Mode to do just that sort of thing, especially when the project I was working on had a very rigid and long, required function header comments.
You can look to SRecode from CEDET package. Besides standard templates, like yasnippet, etc., it also provides support for content-aware templating, like some templates could be expanded only inside the classes, some only as top-level declaration, etc.

Banish unmatched top-level trees when performing tag search in Emacs Org Mode

For the past year and a half, I've maintained a monolithic buffer in Org Mode for my engineering notes with my current employer. Despite containing mostly pointers to other documents, this file has become quite large by human standards (48,290 lines of text), while remaining trivially searchable and editable through programmatic means (read: grep and Org Mode tag search).
One thing bothers me, though. When I perform a tag search using Org Mode 6.33x, Org's sparse tree view retains the folded representation of unmatched trees within the buffer (that is, content preceded by a single asterisk, *). This is generally useful for smaller buffers or those better organized into a single tree with multiple branches. However, this doesn't work especially well for documentation where each new tree is generated chronologically, one for each day, as I've been doing.
.
Before I continue, I'll note that my workaround is inherent in what I've just asked, as are the obvious alterations in my documentation habits with this buffer. However, the following questions remain:
1) Why does Org Mode organize trees in this manner when performing sparse tag searching? The technical details are self-evident, the UX decisions less so.
2) If I wished to correct this issue with a script written in Emacs Lisp, what hooks and commands should I explore in more detail to restructure the document view? Writing overrides for the standard commands (for example, org-match-sparse-tree) is already self-evident.
.
Thank you in advance.
As you already noticed the problem only affects the top level headings. The good thing is that in org-mode you can demote easily all headings with simple keystrokes. This way you can avoid the problem. Also cleaning up afterwards are just some simple keystrokes.
Step-by-step instructions:
Mark the full buffer
Call M-right (for outline-demote)
Input * root\n at the beginning of the file
Now, build up your subtree and do what you want with it.
When done you can remove * root\n at the beginning of the file and promote the headings again with M-left
I have got the impression that you can even leave the overall-heading where it is for your application.

Emacs recursive project search

I am switching to Emacs from TextMate. One feature of TextMate that I would really like to have in Emacs is the "Find in Project" search box that uses fuzzy matching. Emacs sort of has this with ido, but ido does not search recursively through child directories. It searches only within one directory.
Is there a way to give ido a root directory and to search everything under it?
Update:
The questions below pertain to find-file-in-project.el from MichaƂ Marczyk's answer.
If anything in this message sounds obvious it's because I have used Emacs for less than one week. :-)
As I understand it, project-local-variables lets me define things in a .emacs-project file that I keep in my project root.
How do I point find-file-in-project to my project root?
I am not familiar with regex syntax in Emacs Lisp. The default value for ffip-regexp is:
".*\\.\\(rb\\|js\\|css\\|yml\\|yaml\\|rhtml\\|erb\\|html\\|el\\)"
I presume that I can just switch the extensions to the ones appropriate for my project.
Could you explain the ffip-find-options? From the file:
(defvar ffip-find-options
""
"Extra options to pass to `find' when using find-file-in-project.
Use this to exclude portions of your project: \"-not -regex \\".vendor.\\"\"")
What does this mean exactly and how do I use it to exclude files/directories?
Could you share an example .emacs-project file?
I use M-x rgrep for this. It automatically skips a lot of things you don't want, like .svn directories.
(Updated primarily in order to include actual setup instructions for use with the below mentioned find-file-in-project.el from the RINARI distribution. Original answer left intact; the new bits come after the second horizontal rule.)
Have a look at the TextMate page of the EmacsWiki. The most promising thing they mention is probably this Emacs Lisp script, which provides recursive search under a "project directory" guided by some variables. That file begins with an extensive comments section describing how to use it.
What makes it particularly promising is the following bit:
;; If `ido-mode' is enabled, the menu will use `ido-completing-read'
;; instead of `completing-read'.
Note I haven't used it myself... Though I may very well give it a try now that I've found it! :-)
HTH.
(BTW, that script is part of -- to quote the description from GitHub -- "Rinari Is Not A Rails IDE (it is an Emacs minor mode for Rails)". If you're doing any Rails development, you might want to check out the whole thing.)
Before proceeding any further, configure ido.el. Seriously, it's a must-have on its own and it will improve your experience with find-file-in-project. See this screencast by Stuart Halloway (which I've already mentioned in a comment on this answer) to learn why you need to use it. Also, Stu demonstrates how flexible ido is by emulating TextMate's project-scoped file-finding facility in his own way; if his function suits your needs, read no further.
Ok, so here's how to set up RINARI's find-file-in-project.el:
Obtain find-file-in-project.el and project-local-variables.el from the RINARI distribution and put someplace where Emacs can find them (which means in one of the directories in the load-path variable; you can use (add-to-list 'load-path "/path/to/some/directory") to add new directories to it).
Add (require 'find-file-in-project) to your .emacs file. Also add the following to have the C-x C-M-f sequence bring up the find-file-in-project prompt: (global-set-key (kbd "C-x C-M-f") 'find-file-in-project).
Create a file called .emacs-project in your projects root directory. At a minimum it should contain something like this: (setl ffip-regexp ".*\\.\\(clj\\|py\\)$"). This will make it so that only files whose names and in clj or py will be searched for; please adjust the regex to match your needs. (Note that this regular expression will be passed to the Unix find utility and should use find's preferred regular expression syntax. You still have to double every backslash in regexes as is usual in Emacs; whether you also have to put backslashes before parens / pipes (|) if you want to use their 'magic' regex meaning depends on your find's expectations. The example given above works for me on an Ubuntu box. Look up additional info on regexes in case of doubt.) (Note: this paragraph has been revised in the last edit to fix some confusion w.r.t. regular expression syntax.)
C-x C-M-f away.
There's a number of possible customisations; in particular, you can use (setl ffip-find-options "...") to pass additional options to the Unix find command, which is what find-file-in-project.el calls out to under the hood.
If things appear not to work, please check and double check your spelling -- I did something like (setl ffip-regex ...) once (note the lack of the final 'p' in the variable name) and were initially quite puzzled to discover that no files were being found.
Surprised nobody mentioned https://github.com/defunkt/textmate.el (now gotta make it work on Windows...)
eproject has eproject-grep, which does exactly what you want.
With the right project definition, it will only search project files; it will ignore version control, build artifacts, generated files, whatever. The only downside is that it requires a grep command on your system; this dependency will be eliminated soon.
You can get the effect you want by using GNU Global or IDUtils. They are not Emacs specific, but they has Emacs scripts that integrate that effect. (I don't know too much about them myself.)
You could also opt to use CEDET and the EDE project system. EDE is probably a bit heavy weight, but it has a way to just mark the top of a project. If you also keep GNU Global or IDUtils index files with your project, EDE can use it to find a file by name anywhere, or you can use `semantic-symref' to find references to symbols in your source files. CEDET is at http://cedet.sf.net
For pure, unadulterated speed, I highly recommend a combination of the command-line tool The Silver Searcher (a.k.a. 'ag') with ag.el. The ag-project interactive function will make an educated guess of your project root if you are using git, hg or svn and search the entire project.
FileCache may also be an option. However you would need to add your project directory manually with file-cache-add-directory-recursively.
See these links for info about how Icicles can help here:
find files anywhere, matching any parts of their name (including directory parts)
projects: create, organize, manage, search them
Icicles completion matching can be substring, regexp, fuzzy (various kinds), or combinations of these. You can also combine simple patterns, intersecting the matches or complementing (subtracting) a subset of them