3 Source code files are hard to manage. They can get unwieldly quickly and making the
4 wrong assumption about your whereabouts in the code tree can have unintended
7 There are many ways to solve this problem to different degrees. We'll be talking about
8 one strategy in particular which I use and recommend for any software project.
10 Looking through the source code in the NAS-T repository you'll find some common
13 - every file start with at least one comment line for example:
15 ;;; file-name.lisp --- file description
18 - Before you see any code in a file, you'll likely encounter this line:
25 What's the deal here? To be clear, I'm of the mind that comments should be
26 significant. They should express to the reader something that is of a non-trivial nature
27 and 'where the code starts' doesn't quite qualify. Indeed, these comments don't fit that
30 The deal is that these comments aren't for the reader, they're for the developer. More
31 specifically, for the developer to treat as a special meta-language to describe the
32 structure of a source code file.
35 Like all my good ideas, this one is credited entirely to Emacs. In this case, the
36 excellent
[[https://www.gnu.org/software/emacs/manual/html_node/emacs/Outline-Mode.html][Outline mode]]. If you are an Emacs user you've probably already used it without
37 knowing -- Org mode, for example, is
[[https://git.savannah.gnu.org/cgit/emacs/org-mode.git/tree/lisp/org.el?h=release_9.6.9#n4789][derived from outline-mode]].
39 I've grown quite fond of it. Here's the summary:
42 Outline mode is a major mode derived from Text mode, which is specialized for editing
43 outlines. It provides commands to navigate between entries in the outline structure, and
44 commands to make parts of a buffer temporarily invisible, so that the outline structure
45 may be more easily viewed.
47 --
[[https://www.gnu.org/software/emacs/manual/html_node/emacs/Outline-Mode.html][GNU]] 50 If you want to jump in right away, I recommend using these keybinds in Emacs:
52 #+tblname: outline-keys
53 | <backtab> | outline-cycle-buffer | 54 | M-TAB | outline-cycle | 55 | M-n | outline-next-visible-heading | 56 | M-p | outline-previous-visible-heading | 58 Here's a snippet which will enable the keybinds I use:
60 #+name: enable-outline-keys
61 #+begin_src emacs-lisp 63 '(("<backtab>" #'outline-cycle-buffer)
64 ("M-TAB" #'outline-cycle)
65 ("M-n" #'outline-next-visible-heading)
66 ("M-p" #'outline-previous-visible-heading))))
67 (cl-loop for (k fn) in keys
68 do (keymap-set outline-minor-mode-map k fn)))
71 Now open a file in the
[[../../src/][src]] directory, like
[[../../src/fs/btrfs/btrfs.lisp][this]] one, enable
=outline-minor-mode= and
72 move around the file with the new keybinds above.
75 Not all programming modes have outline support built-in. The good news is that it's easy
78 You only need to modify one variable:
=outline-regexp= and enable a minor-mode:
82 The way it's done in the NAS-T codebase is with a
[[../../.dir-locals.el][.dir-locals.el]] file.
84 You just need to add this form for the mode of your choice, replacing the string
85 with a regular expression which matches on a
/heading/. In this case we treat lines
86 starting with three comment chars or more as a new heading.
88 (makefile-mode . ((outline-regexp . "###+")))
91 =outline-regexp= is declared as a safe local var, so no prompts will appear asking if
92 you trust these values. You will need to configure your keybinds and enable the
93 minor-mode separately though. For project-level support, that's all there is to it.
96 You may also modify your config to enable
=outline-minor-mode= for select major-modes at
97 startup. Here's a quick example from my config:
99 #+begin_src emacs-lisp 101 (require 'default 'rw/fu)
103 (defun outline-hook (rx)
104 "Enable `outline-minor-mode' and set `outline-regexp'."
105 (setq-local outline-regexp rx)
106 (outline-minor-mode t))
108 (defun add-outline-hook (mode rx)
109 (let ((sym (symb mode "-hook")))
110 (add-hook sym (lambda () (outline-hook rx)))))
112 (defmacro outline-hooks (&rest pairs)
113 `(mapc (lambda (x) (add-outline-hook (car x) (cadr x))) ',pairs))
115 (outline-hooks (asm-mode ";;;+")
117 (rust-mode "\\(//!\\|////+\\)")
119 (sh-script-mode "###+")
120 (makefile-mode "###+"))
122 (provide 'outline-cfg)
123 ;;; outline-cfg.el ends here
126 Our default sections should look familiar - they're just Emacs Lisp defaults, with a few
129 First line of every source code file.
131 Here is the prototype in lisp:
133 ;;; filename --- description -*- vars -*-
138 //! filename --- description -*- vars -*-
142 **** Metadata :optional: 143 Some files may insert a blank line and start the
=Code= heading, while others will
144 include some additional information about the file such as a long-description, version,
145 list of exports, etc.
146 *** Commentary :optional: 147 An optional programmer commentary included in source code files after the
=Source 148 Header= but before the
=Code=. The contents are unpredictable but may include notes,
149 todos, diagrams, stack notations, test results, links, tips, etc.
151 The
=Code= heading should be the final toplevel heading of any source code file. You
152 may see a number of sub-headings, starting with four or more comment chars.