emacs lisp: how to add to link/hyperlink to another file just like that in *H e l p* - emacs

we can get help with "C-h ..." and emacs show a Help buffer,and jump to other place with the link . How can I make something like that with elisp, link to another buffer or show something else?

The builtin Button package provides a convenient way. For example,
(require 'button)
(insert-button "foo" 'action (lambda (x) (find-file user-init-file)))
will insert a button/link labeled "foo" that when activated (by pressing Enter while point is over the label or middle clicking) will bring up the init file.
Here is another example that mimics a www link,
(insert-button "fsf"
'action (lambda (x) (browse-url (button-get x 'url)))
'url "http://www.fsf.org")
See Elisp Reference Manual 38.17 Buttons.

You are looking at "clickable text"
Read this for more explanation.
Or this if you are going to be using org-mode.

Related

Open dialog box (Open File...) in Emacs with keyboard shortcut

In Emacs, I make no use of the default command linked with +. Hence, I would like to use this keyboard shortcut to open the graphical dialog box for "Open File...". How should I proceed to set this ?
Put the following in your .emacs file:
(global-set-key (kbd "+") (lambda ()
(interactive)
(let (last-nonmenu-event)
(menu-find-file-existing))))
Then either type M-x eval-buffer or restart Emacs.
However - are you really absolutely sure that you will never ever need the + for anything else (such as, say, inserting a +)? Perhaps consider using at least something like CTRL + as your keyboard shortcut instead of just +... this could easily be implemented by replacing "+" in the above code snippet with "C-+".
Similar to #Thomas's answer (and I'd pose the same question about using +):
(global-set-key (kbd "+") (lambda ()
(interactive)
(let (use-file-dialog)
(menu-find-file-existing))))
Dunno which is better, or whether it matters. But at least this way you will perhaps have done C-h v use-file-dialog to understand what that variable does and hence why this code does what you want.
(menu-find-file-existing is just the command that menu-bar File > Open File... is bound to. It's what C-h k tells you when you click that menu item.)

emacs tabbar customisation, making unsaved changes visible

i want to mark buffers, that have unsaved changes, in the tabbar tab bar in emacs. Also i want to assign F1 - F12 to the buffer and open them by pressing the according button.
But since i have no programming practice in lisp, i have no idea where to start. Also i got the feeling that learning lisp to know how to configure emacs on a low lwevel is an incredible usefull skill.
So my question is not really how to archieve that, but rather where to start looking. And maybe how to start learning Lisp.
Thanks
This following code works with stock versions of Emacs and tabbar.el -- it creates + sign at the beginning of the modified buffer name in the tab.
;; BUFFER MODIFICATION STATE INDICATOR
(defadvice tabbar-buffer-tab-label (after fixup_tab_label_space_and_flag activate)
(setq ad-return-value
(if (and (buffer-modified-p (tabbar-tab-value tab))
(buffer-file-name (tabbar-tab-value tab)))
(concat " + " (concat ad-return-value " "))
(concat " " (concat ad-return-value " ")))))
(defun ztl-modification-state-change ()
(tabbar-set-template tabbar-current-tabset nil)
(tabbar-display-update))
(defun ztl-on-buffer-modification ()
(set-buffer-modified-p t)
(ztl-modification-state-change))
(add-hook 'after-save-hook 'ztl-modification-state-change)
(add-hook 'first-change-hook 'ztl-on-buffer-modification)
If you want to take it one step further, look at the source code for aquamacs-tabbar.el -- it contains customizable options such as tabbar-unselected-modified and tabbar-selected-modified. You would either need to use Aquamacs for the options mentioned above, or you would need to make a few revisions to the following files so that they work with a stock version of Emacs: aquamacs-tabbar.el, tabbar.el, and tabbar-window.el:
https://github.com/davidswelt/aquamacs-emacs/tree/master/aquamacs/src/site-lisp/tabbar
See also this example of possibilities to further customize the look and feel.
(source: lawlist.com)
As sds mentioned, you'll have to go through the info pages. You could do C-h i m Emacs Lisp RET as mentioned by sds, or you could do M-x info and then find the Emacs Lisp Intro from there.
You raised too many issues in a single question.
I will respond briefly to each, but you should ask a separate question if you are not clear.
i want to mark buffers, that have unsaved changes, in the tabbar tab bar in emacs.
No, you do not want that.
This is already done in the mode line.
i want to assign F1 - F12 to the buffer and open them by pressing the according button
No, you do not want that.
Keys are precious, you do not want to waste them like that.
Use Mouse Buffers menu or list-buffers.
how to start learning Lisp
In Emacs, type C-h i m Emacs Lisp Intro RET and start reading.
Emacs is superbly customizable, and you can make it do exactly what you want.
However, you must realize that it has been used for over 30 years by many smart people, so, whenever your wish is reasonable, chances are this can be done out of the box, and if not, you will have a lot of fun implementing it yourself.
You can also look at tabbar.el to try and figure out where the actual text of the bar is created (i.e. where you'll want to add the "unsaved" indicators). To figure out if a buffer has unsaved changes, you can use the buffer-modified-p function.

Highlight occurrences on click

How to automatically highlight all occurrences of a word, when you click on it?
I don't use mouse often, but would like my editor to be as interactive as it could be.
Like this, but more intelligent:
You can use idle-highlight-mode to get a similar behavior. This highlights all the occurences of the word at point without the need to click.
This mode can be installed from package.el.
I've been using this snippet for selecting the current word: http://emacswiki.org/emacs/MarkCommands#toc5
I had a go at using this to construct something like what you're asking for. Probably not exactly what you want, but hopefully a starting point.
(defun click-select-word (event)
(interactive "e")
(hi-lock-mode 0)
(let ((phrase (concat "\\b" (regexp-quote (thing-at-point 'symbol)) "\\b")))
(highlight-regexp phrase)))
(global-set-key [mouse-1] 'click-select-word)
It appears, it's very ease to highlight JavaScript variables in scope using Tern.
You can bind it to mouse click:
(autoload 'tern-mode "tern" nil t)
(tern-mode t)
(local-set-key [mouse-1] 'tern-highlight-refs)

Org-mode: embed links to info files

I maintain a diary (internal blog containing thoughts to remember) in org-mode, and sometimes, as i study Emacs, i store learned skills and tricks with references to info files.
Currently i do the following. I open the needed info file, press c to copy current node name, press < s TAB - that is an easy template which unwraps into a src-block. Then i add lisp expression and paste node name and finally the link looks like this:
#+begin_src emacs-lisp
(info "(org) Properties and Columns")
#+end_src
When i need to view the info file, i put cursor after lisp sexp and press C-x C-e (eval-last-sexp).
This process is tedious and inelegant. What is the best way to embed links to info files in org-mode?
Edit: I've found how one can add links to info nodes. Org-mode manual on External links describes these equivalent methods using links:
[[info:org#Tags]]
[[elisp:(info "(org) Tags")]]
With the first variant i'm not sure how to automatically transform (org) Tags in org#Tags. How can i further simplify this process?
You do it as in any of the supported link types (see the "Handling
links" section in the manual). In the info file, you say M-x org-store-link,
(bind it to C-c l as suggested in the manual) and then in your org
file, you insert the link with C-c C-l. There you just have to
select the link to your info file from the list of stored links.
org-store-link says "Cannot link to a buffer which is not visiting a file" when visiting an Info page because Info sets the buffer-name to *info* and the buffer-file-name to nil. To work around this, the community contributed example of how to add linking to man pages (http://orgmode.org/manual/Adding-hyperlink-types.html) can be modified slightly:
;; Modified version of contrib/lisp/org-man.el; see
;; (http://orgmode.org/manual/Adding-hyperlink-types.html#Adding-hyperlink-types)
(require 'org)
(org-add-link-type "info" 'org-info-open)
(add-hook 'org-store-link-functions 'org-info-store-link)
(defcustom org-info-command 'info
"The Emacs command to be used to display an info page."
:group 'org-link
:type '(choice (const info)))
(defun org-info-open (path)
"Visit the infopage on PATH.
PATH should be a topic that can be thrown at the info command."
(funcall org-info-command path))
(defun org-info-store-link ()
"Store a link to an info page."
(when (memq major-mode '(Info-mode))
;; This is a info page, we do make this link
(let* ((page (org-info-get-page-name))
(link (concat "info:" page))
(description (format "Infopage for %s" page)))
(org-store-link-props
:type "info"
:link link
:description description))))
(defun org-info-get-page-name ()
"Extract the page name from Info in a hackish way."
;; This works for `Info-mode'.
;; Hackity-hack: copy the node name into the kill ring.
(Info-copy-current-node-name)
;; Just return the kill.
(current-kill 0))
(provide 'org-info)
The important bit is near the end: since the info node name is not directly accessible (not that I could easily find), we can work around it by calling Info-copy-current-node-name to put it in the kill-ring, then return the first entry in the kill-ring (which should be the just inserted node name).
The step that should work
- go to info node you need then press just 'c' (node-name will be
entry to kill ring)
- on your org source-file go to point you need to insert the link
press C-c,C-l
- press Tab then select elisp: from prompted buffer shown (or any kind
of link you need).Now your prompt in mini-buffer say elisp:
- entry this context after that ':' (info "^") ,let ^ be your
node-name yank back by C-y
- press Ret ,then you'll be ask for some description just fill it with
your own. Now you are done with it ,but still don't know what happen
really.
- M-x,visibility-mode,And there how to write that content manually and
we are now came to conclusion that "%20" must be replace every
occurence of space in the context.
eg.==> do it yourself ,see it yourself
- switch back your visibility-mode
GoodLuck

show org-mode outline up to a certain heading level

I'm making an outline for my thesis using org-mode, and I'd like to show all headings up to a certain level (e.g. all level-1 and level-2 headings).
I haven't found anything about that in the org-mode manual. Cycling shows either only level-1 headings, or all headings, which is too much information in my outline right now.
Thanks,
daniel.
Update: I found a workaround for his: set the variable org-cycle-max-level. This is a global setting, though.
Just stumbled on this question. One year later but what the heck.. There are commands for this that allows you to show headings to a certain level.
One command is C-<n> C-c tab will show subheadings up to level <n> (<n>=1,2,3...).
Another command is C-<n> S-tab which will operate on the whole buffer. It shows all headings up to level <n> (<n>=1,2,3...)
I found a solution that suits me: The command org-content shows the folder hierarchy, and giving it a numeric argument does exactly what I want: limit the maximum level shown. In my example, I wanted to show 2 levels, so I can do C-2 M-x org-content <RET>.
I also added my own command to my .emacs init file, binding that command to C-c m
(defun org-show-two-levels ()
(interactive)
(org-content 2))
(add-hook 'org-mode-hook
(lambda ()
(define-key org-mode-map "\C-cm" 'org-show-two-levels)))
If the prefix arguments from M. Kullman's answer take too much mental capacity for you (a limited resource when you are thinking hard about something else at the same time) then you can use the following functions to expand contract headings
(defvar hf-org-depth-point nil)
(defvar hf-org-depth-depth nil)
(defun hf-org-depth-increase ()
(interactive)
(hf-org-depth-incr 1))
(defun hf-org-depth-decrease ()
(interactive)
(hf-org-depth-incr -1))
(defun hf-org-depth-incr (incr)
(when (not (equal (point) hf-org-depth-point))
(setq hf-org-depth-point nil)
(setq hf-org-depth-depth 0))a
(setq hf-org-depth-point (point))
(setq hf-org-depth-depth (max (+ hf-org-depth-depth incr) 0))
(hide-subtree)
(show-children hf-org-depth-depth))
```
I am way late to the party, but let us add a simple way for posterity. Simply use Cycle Global Visibility (<backtab>). If your headings are open, it will close them. However, if you apply it repeatedly with all headings collapsed, they will open to the level you want.
I use it from the keyboard by <SHIFT>+<TAB>. You can also find it in the Org menu (in Emacs) under Show/Hide -> Cycle Global Visibility ()