Skip to content

Commit b91064f

Browse files
committed
add section Questions and Answers - PR #1
- Is there a way to make clickable noweb references <<link>> in source blocks in order to jump to its block definition? - How are speed keys different from/better than evil-mode? Does speed keys can be use along with evil-mode? - Is there a good reason for the entry point to be a variable switch, and for the bindings to be managed by a list, instead of having a minor mode layering its keymap onto standard org-mode bindings? - How do you count 5000 examples?
1 parent 6be849f commit b91064f

File tree

1 file changed

+306
-0
lines changed

1 file changed

+306
-0
lines changed

posts.org

Lines changed: 306 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1332,6 +1332,7 @@ Here are the parts of [[org-mode:lisp/org.el::(defun org-open-file (path][org-op
13321332

13331333
WE ARE DONE!!!
13341334

1335+
** [[#/questions-and-answers/#2022-04-04-search-options-link-abbreviations-and-org-open-at-point][Q&A]]
13351336
* [2022-03-22 Tue] Org Speed Keys! BOOM! Great org-mode's feature! And a good OPPORTUNITY to talk about self-insert-command
13361337
:PROPERTIES:
13371338
:CUSTOM_ID: /2022-03-22-org-speed-keys-and-self-insert-command/
@@ -1887,6 +1888,7 @@ a non-nil value for the inserted character. At the end, it runs
18871888

18881889
WE ARE DONE!!!
18891890

1891+
** [[#/questions-and-answers/#2022-03-22-org-speed-keys-and-self-insert-command][Q&A]]
18901892
* [2022-03-11 Fri] Did you know that org-mode's source code contains more than 5000 examples?
18911893
:PROPERTIES:
18921894
:CUSTOM_ID: /2022-03-11-org-mode-source-code-5000-examples/
@@ -2349,6 +2351,7 @@ part of THE ORG-MODE TRUTH lives.
23492351

23502352
WE ARE DONE!
23512353

2354+
** [[#/questions-and-answers/#2022-03-11-org-mode-source-code-5000-examples][Q&A]]
23522355
* [2022-03-05 Sat] I bet you use hl-line-mode... Do you know how it works? Overlays, post-command-hook and only 5 functions!!!
23532356
:PROPERTIES:
23542357
:CUSTOM_ID: /2022-03-05-i-bet-you-use-hl-line-mode/
@@ -3902,3 +3905,306 @@ prints out the following into the message buffer:
39023905
:type-of-f lambda
39033906
:env-of-f nil)
39043907
#+END_SRC
3908+
3909+
* Questions and Answers
3910+
:PROPERTIES:
3911+
:CUSTOM_ID: /questions-and-answers/
3912+
:END:
3913+
** [[#/2022-04-04-search-options-link-abbreviations-and-org-open-at-point/][Search options in file links | link abbreviations | COME WITH ME on this JOURNEY into the heart of the command org-open-at-point]]
3914+
:PROPERTIES:
3915+
:CUSTOM_ID: /questions-and-answers/#2022-04-04-search-options-link-abbreviations-and-org-open-at-point
3916+
:END:
3917+
*** Is there a way to make clickable noweb references ~<<link>>~ in source blocks in order to jump to its block definition?
3918+
3919+
What we want to accomplish here is to jump to the definition of a
3920+
noweb block, let's say ~my-noweb~, by calling a command (maybe
3921+
~org-open-at-point~) when the point is on a reference ~<<my-noweb>>~ of
3922+
that block, for instance in an org buffer with the following content:
3923+
3924+
#+BEGIN_SRC org
3925+
,#+NAME: my-noweb
3926+
,#+BEGIN_SRC emacs-lisp
3927+
(setq sentence '(foo bar baz))
3928+
,#+END_SRC
3929+
3930+
,#+BEGIN_SRC emacs-lisp :noweb yes :results value verbatim
3931+
<<my-noweb>>
3932+
(reverse sentence)
3933+
,#+END_SRC
3934+
3935+
,#+RESULTS:
3936+
: (baz bar foo)
3937+
#+END_SRC
3938+
3939+
This can be done in at least two ways.
3940+
3941+
**** Using the built-in command ~org-babel-goto-named-src-block~
3942+
3943+
First, we can use the built-in command ~org-babel-goto-named-src-block~
3944+
(bound to ~C-c C-v g~ by default).
3945+
3946+
After calling ~org-babel-goto-named-src-block~ with the point on top of
3947+
the reference ~<<my-noweb>>~:
3948+
3949+
1) we're asked in the minibuffer to choose a name,
3950+
2) we pick the noweb ref ~my-noweb~, press ~RET~,
3951+
3) we jump to the source block named ~my-noweb~.
3952+
3953+
**** Using the hook ~org-open-at-point-functions~
3954+
3955+
Second possibility, we can define a command that jump to a noweb
3956+
block definition when we call it with the point on top of a noweb
3957+
reference without prompting anything in the minibuffer.
3958+
3959+
Then we can call it directly or better (if it's the behavior we
3960+
want) we can add this command to the variable
3961+
~org-open-at-point-functions~.
3962+
3963+
And, now in a source block with the point on top of a noweb reference,
3964+
we can call ~org-open-at-point~ (~C-c C-o~ by default) which will call
3965+
this new command and jump to the noweb block definition at point
3966+
(instead of running ~org-babel-open-src-block-result~).
3967+
3968+
Here an implementation of such a command that we call ~org-goto-noweb~.
3969+
3970+
#+BEGIN_SRC emacs-lisp
3971+
(require 'org)
3972+
3973+
(defun org-noweb-ref-p ()
3974+
"Return the noweb reference at point if any.
3975+
If not return `nil'."
3976+
(interactive)
3977+
(let* ((context (org-element-context))
3978+
(type (org-element-type context))
3979+
(noweb-ref
3980+
(and (memq type '(inline-src-block src-block))
3981+
(org-in-regexp (org-babel-noweb-wrap)))))
3982+
(when noweb-ref
3983+
(buffer-substring
3984+
(+ (car noweb-ref) (length org-babel-noweb-wrap-start))
3985+
(- (cdr noweb-ref) (length org-babel-noweb-wrap-end))))))
3986+
3987+
(defun org-goto-noweb ()
3988+
"Go to the noweb ref at point."
3989+
(interactive)
3990+
(when-let ((ref (org-noweb-ref-p)))
3991+
(let ((point (org-babel-find-named-block ref)))
3992+
(if point
3993+
;; Taken from `org-open-at-point'.
3994+
(progn
3995+
(org-mark-ring-push)
3996+
(goto-char point)
3997+
(org-show-context)
3998+
;; return non-nil, in order to use it in
3999+
;; the variable `org-open-at-point-functions'
4000+
'noweb-found)
4001+
(message "source-code block `%s' not found in this buffer" name)))))
4002+
4003+
(add-to-list 'org-open-at-point-functions #'org-goto-noweb)
4004+
#+END_SRC
4005+
4006+
And here the ~ert~ test for the command ~org-goto-noweb~:
4007+
4008+
#+BEGIN_SRC emacs-lisp
4009+
;; from org-mode: testing/org-test.el
4010+
(defmacro org-test-with-temp-text (text &rest body)
4011+
"Run body in a temporary buffer with Org mode as the active
4012+
mode holding TEXT. If the string \"<point>\" appears in TEXT
4013+
then remove it and place the point there before running BODY,
4014+
otherwise place the point at the beginning of the inserted text."
4015+
(declare (indent 1))
4016+
`(let ((inside-text (if (stringp ,text) ,text (eval ,text)))
4017+
(org-mode-hook nil))
4018+
(with-temp-buffer
4019+
(org-mode)
4020+
(let ((point (string-match "<point>" inside-text)))
4021+
(if point
4022+
(progn
4023+
(insert (replace-match "" nil nil inside-text))
4024+
(goto-char (1+ (match-beginning 0))))
4025+
(insert inside-text)
4026+
(goto-char (point-min))))
4027+
(font-lock-ensure (point-min) (point-max))
4028+
,@body)))
4029+
4030+
(ert-deftest org-goto-noweb-test ()
4031+
(should
4032+
(org-test-with-temp-text
4033+
"#+BEGIN_SRC emacs-lisp :noweb yes
4034+
<point><<my-noweb>>
4035+
(reverse sentence)
4036+
,#+END_SRC"
4037+
(org-noweb-ref-p)))
4038+
(should-not
4039+
(org-test-with-temp-text
4040+
"#+BEGIN_SRC emacs-lisp :noweb yes
4041+
<<my-noweb>>
4042+
(reverse sentence)
4043+
,#+END_SRC"
4044+
(org-noweb-ref-p)))
4045+
4046+
;; source blocks
4047+
(should
4048+
(org-test-with-temp-text
4049+
"#+NAME: my-noweb
4050+
,#+BEGIN_SRC emacs-lisp
4051+
(setq sentence '(foo bar baz))
4052+
,#+END_SRC
4053+
4054+
,#+BEGIN_SRC emacs-lisp :noweb yes
4055+
<point><<my-noweb>>
4056+
(reverse sentence)
4057+
,#+END_SRC"
4058+
(org-goto-noweb)
4059+
(forward-line)
4060+
(looking-at "\(setq")))
4061+
(should-not
4062+
(org-test-with-temp-text
4063+
"#+NAME: my-noweb
4064+
,#+BEGIN_SRC emacs-lisp
4065+
(setq sentence '(foo bar baz))
4066+
,#+END_SRC
4067+
4068+
,#+BEGIN_SRC emacs-lisp :noweb yes
4069+
<<my-noweb>>
4070+
(reverse sentence)
4071+
,#+END_SRC"
4072+
(org-goto-noweb)))
4073+
4074+
;; inline source blocks
4075+
(should
4076+
(org-test-with-temp-text
4077+
"#+NAME: my-noweb
4078+
,#+BEGIN_SRC emacs-lisp
4079+
(setq sentence '(foo bar baz))
4080+
,#+END_SRC
4081+
4082+
src_emacs-lisp{<point><<my-noweb>>}"
4083+
(org-goto-noweb)
4084+
(forward-line)
4085+
(looking-at "\(setq"))))
4086+
#+END_SRC
4087+
4088+
** [[#/2022-03-22-org-speed-keys-and-self-insert-command/][Org Speed Keys! BOOM! Great org-mode's feature! And a good OPPORTUNITY to talk about self-insert-command]]
4089+
:PROPERTIES:
4090+
:CUSTOM_ID: /questions-and-answers/#2022-03-22-org-speed-keys-and-self-insert-command
4091+
:END:
4092+
*** How are speed keys different from/better than ~evil-mode~? Does speed keys can be use along with ~evil-mode~?
4093+
**** Quick answer
4094+
4095+
1) If we are in evil normal state ~<N>~, Org speed keys won't work
4096+
(because most of the printing keys are used for something else,
4097+
specifically they are bound in ~evil-normal-state-map~),
4098+
2) if we are in evil insert state ~<I>~ or in evil emacs state ~<E>~, Org
4099+
speed keys works (because the printing keys are not bound by
4100+
~evil-mode~ in ~evil-insert-state-map~ nor in ~evil-emacs-state-map~).
4101+
4102+
**** Answer with more details
4103+
4104+
Org speed keys are not better than ~evil-mode~ nor the other way, they
4105+
are really differents.
4106+
4107+
***** Org speed keys
4108+
4109+
Org speed keys are a kind of a "hack" that hijack the "inserting emacs
4110+
process".
4111+
4112+
It can be seen as: when we try to insert a character, do not use
4113+
the standard command for inserting, use another one that checks for the
4114+
position of the cursor in the buffer, if it is at a specific location,
4115+
performs a lookup for the command to call, if we find one, call it, if
4116+
none, insert the character. It is all about one command
4117+
~self-insert-command~ and one remapping ~self-insert-command~ to
4118+
~org-self-insert-command~.
4119+
4120+
***** ~evil-mode~
4121+
4122+
~evil-mode~ manipulates the hierarchy of all the keymaps that are
4123+
active, making the current evil "state" map to win over the others.
4124+
4125+
We can check this by inspecting the list of the current active
4126+
keymaps with the function ~current-active-maps~. If the same key
4127+
sequence is bound several times to different commands in the list
4128+
returned by ~current-active-maps~, the first binding in the list wins
4129+
over the others.
4130+
4131+
For instance, when we are in evil normal state ~<N>~, the bindings in
4132+
the keymap ~evil-normal-state-map~ takes precedence (over almost all)
4133+
the other binding in the current active maps, and will appear at the
4134+
beginning of the list returned by ~current-active-maps~.
4135+
4136+
Assuming we are in evil normal state ~<N>~, to check this previous
4137+
assertion, we can run:
4138+
4139+
: M-x pp-eval-expression RET (current-active-maps)
4140+
4141+
Now, if we switch to the evil insert state ~<I>~, the bindings in
4142+
the keymap ~evil-insert-state-map~ takes precedence (over almost all)
4143+
the other binding in the current active maps, and will appear at the
4144+
beginning of the list returned by ~current-active-maps~.
4145+
4146+
Assuming we are in evil normal state ~<I>~, to check this previous
4147+
assertion, we can run:
4148+
4149+
: M-x pp-eval-expression RET (current-active-maps)
4150+
4151+
Now, what's interesting, is that evil insert state ~<I>~ doesn't bind the
4152+
printing keys nor remap the command ~self-insert-command~. So, when
4153+
we are in evil insert state ~<I>~, and we press the key ~n~ for
4154+
instance, the "command loop editor", when perfoming the key lookup in
4155+
the current active maps, won't find the binding coming from the
4156+
keymaps ~evil-insert-state-map~ but the binding coming form the current
4157+
global map which resolves (by default) to the command
4158+
~self-insert-command~. And, if we've remapped ~self-insert-command~ to
4159+
~org-self-insert-command~, (which is the case in org-mode with
4160+
~org-use-speed-commands~ set to ~t~), the "command loop editor" will call
4161+
~org-self-insert-command~.
4162+
4163+
*** Is there a good reason for the entry point to be a variable switch, and for the bindings to be managed by a list, instead of having a minor mode layering its keymap onto standard org-mode bindings?
4164+
4165+
I think that the benefit of this approach (remapping
4166+
~self-insert-command~ to ~org-self-insert-command~) over having a minor
4167+
mode layering its keymap onto standard ~org-mode~ is that we don't have
4168+
to switch between keymaps or minor modes to get the feature.
4169+
4170+
Let's say we define a minor mode ~X-mode~ with the keymap ~X-mode-map~
4171+
that binds the key ~n~ to ~org-next-visible-heading~.
4172+
4173+
Now, when ~X-mode~ is turned on, ~X-mode-map~ "wins" over ~org-mode-map~ and
4174+
typing ~n~ will get us (from anywhere in the buffer) to the next
4175+
heading.
4176+
4177+
Now, what should we do to insert the character ~n~ in the buffer? We
4178+
should turn off ~X-mode~ to remove the binding from ~X-mode-map~.
4179+
4180+
With the remapping method we don't have to switch between minor modes
4181+
before moving to the next heading by typing ~n~. The only restriction
4182+
is to be at the beginning of a heading. There is always a trade off.
4183+
4184+
I don't know if it is a good reason but this the only one that I see.
4185+
4186+
** [[#/2022-03-11-org-mode-source-code-5000-examples/][Did you know that org-mode's source code contains more than 5000 examples?]]
4187+
:PROPERTIES:
4188+
:CUSTOM_ID: /questions-and-answers/#2022-03-11-org-mode-source-code-5000-examples
4189+
:END:
4190+
*** How do you count 5000 examples?
4191+
4192+
Any ~should~, ~should-not~ and ~should-error~ used in a ~ert~ test in the
4193+
repository [[org-mode:testing]] is counted as an example.
4194+
4195+
So now, to count all the examples, we have to count all those form and
4196+
this can be done by searching recursively in the [[org-mode:testing]] for
4197+
the string ~(should~.
4198+
4199+
This can be done using ~grep~ to match recursively the string ~(should~ in
4200+
the directory [[org-mode:testing]] and counting the number of line with ~wc~
4201+
utility:
4202+
4203+
#+BEGIN_SRC bash
4204+
# org-mode at commit cbe3f2d69
4205+
cd org-mode/testing/
4206+
grep -r '(should' | wc -l
4207+
#+END_SRC
4208+
4209+
#+RESULTS:
4210+
: 5235

0 commit comments

Comments
 (0)