How to restrict a function to a subtree in emacs org-mode? - emacs

I am using org-mode and org-attach extensively which means that
there can be many attachment directories associated with one org file.
On worg I found a function from Matt Lundi which allows to see all
attachments that belong to the whole file and browse them with ido.
I would like to restrict this function to a subtree which would make it
much more useful for my use case.
Since I am not new to emacs but almost completely elisp illiterate I am
asking here.
This is the function:
(defun my-ido-find-org-attach ()
"Find files in org-attachment directory"
(interactive)
(let* ((enable-recursive-minibuffers t)
(files (find-lisp-find-files org-attach-directory "."))
(file-assoc-list
(mapcar (lambda (x)
(cons (file-name-nondirectory x)
x))
files))
(filename-list
(remove-duplicates (mapcar #'car file-assoc-list)
:test #'string=))
(filename (ido-completing-read "Org attachments: " filename-list nil t))
(longname (cdr (assoc filename file-assoc-list))))
(ido-set-current-directory
(if (file-directory-p longname)
longname
(file-name-directory longname)))
(setq ido-exit 'refresh
ido-text-init ido-text
ido-rotate-temp t)
(exit-minibuffer)))

Maybe I'm missing something, but calling org-narrow-to-subtree first should do what you want (call widen afterwards to revert that).

I thought this would be pretty darned useful myself so, inspired by your question, I wrote a version that does what you want plus a couple other bells and whistles. To invoke it you have to type C-c o. NOTE: This is NOT on the usual org-attach key prefix because that function is oddly written without a keymap so it is difficult to add the functionality onto the key prefix.
(autoload 'org-attach-dir "org-attach")
(autoload 'find-lisp-find-files "find-lisp")
(defcustom ido-locate-org-attach-all-files nil
"Non-nil means `ido-locate-org-attach' returns all files.
Otherwise the default behavior only returns files attached to the
current entry."
:group 'ido
:type 'boolean)
(defun ido-locate-org-attach (&optional find-all)
"Find files in org-attachment directory for current entry.
When called with a prefix argument, include all files in
`org-attach-directory'. With a double `C-u' prefix arg the value
of `ido-locate-org-attach-all-files' will be toggled for the
session. If you want to save it permanently for future session
then customize the variable `ido-locate-org-attach-all-files'."
(interactive "P")
(when (org-attach-dir nil)
(when (equal find-all '(16))
(setq ido-locate-org-attach-all-files
(not ido-locate-org-attach-all-files)))
(let* ((enable-recursive-minibuffers t)
(dir (if (org-xor ido-locate-org-attach-all-files
(equal find-all '(4)))
org-attach-directory
(org-attach-dir nil)))
(files (find-lisp-find-files dir "."))
(file-assoc-list
(mapcar (lambda (x)
(cons (file-name-nondirectory x)
x))
files))
(filename-list
(remove-duplicates (mapcar #'car file-assoc-list)
:test #'string=))
(filename (ido-completing-read "Org attachments: " filename-list nil t))
(longname (cdr (assoc filename file-assoc-list))))
(ido-set-current-directory
(if (file-directory-p longname)
longname
(file-name-directory longname)))
(setq ido-exit 'refresh
ido-text-init ido-text
ido-rotate-temp t)
(exit-minibuffer))))
;; Run ido-locate-org-attach when using org-open-at-point (C-c C-o) in
;; the current entry (except if you're on the header line itself it
;; will use the default behavior to open/close the entry.
(add-hook 'org-open-at-point-functions 'ido-locate-org-attach)
;; C-c o will locate files for the current entry
;; C-u C-c o will locate files for the whole file
;; C-u C-u C-c o will toggle the default current entry / whole file
(define-key org-mode-map "\C-co" 'ido-locate-org-attach)
I'll look into submitting this to be an official part of org-attach.el.
As an aside, the '(4) and '(16) are magic numbers that mean prefix arg once C-u and prefix arg twice C-u C-u before the key sequence that invoked the command interactively.

Related

Emacs AucTeX; How to set C-c C-c default command?

I have set this in my .emacs file:
(add-hook 'TeX-mode-hook
(lambda ()
(setq TeX-command-default "LaTeX"))
(add-hook 'LaTeX-mode-hook
(lambda ()
(setq TeX-command-default "LaTeX"))
I see that C-c C-c is bound to TeX-command-master, which calls TeX-command-query. But since my (TeX-master-file) is "<none>", I expect the default command to be called, but keeps wanting to invoke "View" instead of "LaTeX".
If you check the source for TeX-command-query you'll find that it checks the modification date of the tex (lines 4-9) and bbl (lines 10-19) files involved in your document. Unless those files are more recent than the output file and there is no known next command to be performed (lines 20-22) it will use the "View" command as default (line 23).
This behaviour is of course sensible because normally you don't want to recompile unless there are changes (modified tex files). Apart from "patching" the command [posted below, would not really recommend to use because it will not receive automatic updates ;-) ] there isn't really anything you can do.
If you decide to use the patched command, just put is somewhere in your init file after the original command has been loaded. You could for example wrap it into (replace ;; BODY by code)
(eval-after-load "tex-buf"
'(progn
;; BODY
))
Here comes the patched command:
(defun TeX-command-query (name)
"Query the user for what TeX command to use."
(let* ((default
(cond ((if (string-equal name TeX-region)
(TeX-check-files (concat name "." (TeX-output-extension))
(list name)
TeX-file-extensions)
(TeX-save-document (TeX-master-file)))
TeX-command-default)
((and (memq major-mode '(doctex-mode latex-mode))
;; Want to know if bib file is newer than .bbl
;; We don't care whether the bib files are open in emacs
(TeX-check-files (concat name ".bbl")
(mapcar 'car
(LaTeX-bibliography-list))
(append BibTeX-file-extensions
TeX-Biber-file-extensions)))
;; We should check for bst files here as well.
(if LaTeX-using-Biber TeX-command-Biber TeX-command-BibTeX))
((TeX-process-get-variable name
'TeX-command-next
;; HERE COMES THE PATCH
;; was TeX-command-View
TeX-command-default))
;; END OF PATCH
(TeX-command-Show)))
(completion-ignore-case t)
(answer (or TeX-command-force
(completing-read
(concat "Command: (default " default ") ")
(TeX-mode-specific-command-list major-mode) nil t
nil 'TeX-command-history))))
;; If the answer is "latex" it will not be expanded to "LaTeX"
(setq answer (car-safe (TeX-assoc answer TeX-command-list)))
(if (and answer
(not (string-equal answer "")))
answer
default)))

Lisp location in emacs

Where can I find the all Emacs' elisp scripts? I don't mean scripts users developed or installed themselves, but the common elisp script already there.
For example,
if I have a function like describe-char or insert-file, how can I find the file contained these functions?
Ctrl-h f will tell a function's explanation and where it is contained.
And if you want a function to do this automaticlly, here's a draft:
(defun my-find-lisp-object-file-name (function)
"Display the lisp file name of FUNCTION (a symbol)."
(interactive
(let ((fn (function-called-at-point))
(enable-recursive-minibuffers t)
val)
(setq val (completing-read (if fn
(format "Describe function (default %s): " fn)
"Describe function: ")
obarray 'fboundp t nil nil
(and fn (symbol-name fn))))
(list (if (equal val "")
fn (intern val)))))
(if (null function)
(message "You didn't specify a function")
(setq object-file-name (find-lisp-object-file-name function (symbol-function function)))
(if (eq object-file-name 'C-source)
(message "%s is in %s" function "C source code")
(setq buff (find-function-search-for-symbol function nil object-file-name))
(setq buf-name (buffer-name(car buff)))
(setq buf-pos (cdr buff))
(switch-to-buffer (car buff))
(message "%s is in %s(%s, %d)" function object-file-name buf-name buf-pos))))
I guess M-x locate-library RET <libname> RET could be an answer tho it needs the library name rather than the function name. Else, M-x find-function-other-window will not just tell you where the file is, but instead will open the file, after which you can use M-x pwd to know where you are.
One more thing: you can do C-h v load-path RET to see the directories that Emacs uses to find its libraries, so that should give you a good idea of where all the bundled Elisp files reside.
INITIAL DRAFT (March 25, 2014):  First rough draft.
EDIT (March 26, 2014):  Added a global-set-key. Added one more car to the final message in order to fully extract the path of the file name from the list of button text properties. Added some colorization to the initial and final messages. Added return cursor to beginning of buffer at the end of the function. Added options for find-variable-other-window and find-function-other-window. Added conditions so that no messages are generated if there is no file name.
Here is a fun little function that I whipped up -- it displays a message with a file path if an *.el file is displayed in the *Help* buffer.
(global-set-key (kbd "C-h z") 'lawlist-describe-find-function-variable)
(defun lawlist-describe-find-function-variable ()
"Describe or find a function / variable. Displays the path of filename."
(interactive)
(message (concat
(propertize "Describe" 'face 'font-lock-keyword-face)
" ["
(propertize "f" 'face 'font-lock-warning-face)
"]unction / ["
(propertize "v" 'face 'font-lock-warning-face)
"]ariable | "
(propertize "Find" 'face 'font-lock-keyword-face)
" ["
(propertize "F" 'face 'font-lock-warning-face)
"]unction / ["
(propertize "V" 'face 'font-lock-warning-face)
"]ariable"))
(let* (
(select-f-or-v (read-char-exclusive))
function
variable)
(cond
((eq select-f-or-v ?f)
(setq function (read (read-string "Please enter a function name: ")))
(describe-function function)
(select-window (get-buffer-window "*Help*")))
((eq select-f-or-v ?v)
(setq variable (read (read-string "Please enter a variable name: ")))
(describe-variable variable)
(select-window (get-buffer-window "*Help*")))
((eq select-f-or-v ?F)
(setq function (read (read-string "Please enter a function name: ")))
(find-function-other-window function)
(when buffer-file-name
(message (propertize buffer-file-name 'face 'font-lock-warning-face))))
((eq select-f-or-v ?V)
(setq variable (read (read-string "Please enter a variable name: ")))
(find-variable-other-window variable)
(when buffer-file-name
(message (propertize buffer-file-name 'face 'font-lock-warning-face))))
(t
(message "Thanks and come again!")))
(when (and
(equal (buffer-name) "*Help*")
(save-excursion
(goto-char (point-max))
(re-search-backward "\\(`*[.]el'\\)" nil t)))
(goto-char (point-max))
(re-search-backward "\\(`*[.]el'\\)" nil t)
(message
(propertize
(car (cdr (car (nthcdr 1 (text-properties-at (point))))))
'face 'font-lock-warning-face) )
(goto-char (point-min))) ))
If you use lispy minor mode:
You can open the definition of current function by positioning the point
on the open paren of that function and pressing F.
You can open the definition of current variable by marking it and
pressing F.
You can find all definitions in current directory with g.
You get a helm completion interface for all tags in all Elisp files.
Each line will have the tag in the first column and the file in the second.
My installation's base Elisp directory has 19838 tags, and the completion is fast enough.
You can find all definitions in current directory and its sub-directories
with lispy-goto-recursive. It takes minutes to parse and seconds to bring
up the completion interface. But it allows to interactively search through
all the files in the Emacs source - that's 89675 tags.
A sample search: there are 55 top-level tags that contain insert-file spread
around about 20 files.
Most of them are functions, but the top-level tag (define-key ctl-x-map "i" 'insert-file)
is also matched and can be viewed without opening the file.
You can grab the source of Emacs (if you installed Emacs you probably have .elc files - which are compiled elisp files), and search for the function, if you're on Unix like system you can use ack or find/grep all lisp files are in lisp directory
cd Emacs-24.4/lisp
ack 'defun some-function'
find . -name '*.el' | xargs grep 'defun some-function'

Emacs quicker bookmark-jump?

I have most of my bookmarks prefixed by a letter in a way that
the first letter almost always uniquely determines the bookmark.
This way I can, for instance,
jump to my source folder (bookmarked as "s: source") with M-x bookmark-jump RET s RET.
I have it on a shortcut, so it's actually ~ s RET.
I'd like to get rid of RET in the end,
i.e. get M-x bookmark-quick-jump RET s or ~ s
to do the aforementioned job.
I'd also like it to fall back to the default behavior: to show me all bookmarks
that start with the given letter, in case there's not just one variant.
So far, I've got:
(defun bookmark-do-quick-jump (str)
(let ((completions (all-completions str bookmark-alist)))
(bookmark-jump
(if (eq 1 (length completions))
(car completions)
(completing-read "Jump to bookmark: " bookmark-alist nil t str)))))
There's still two hiccups:
Firstly, I need to jump into minibuffer somehow and stick in there this map (don't know how to do this):
(setq bookmark-quick-jump-map
(let ((map (make-sparse-keymap)))
(mapcar (lambda (key)
(define-key map key
(lambda()
(interactive)
(bookmark-do-quick-jump key))))
(loop for c from ?a to ?z
collect (string c)))
map))
Secondly, when I do a call
(bookmark-do-quick-jump "o")
It comes back with 3 variants (org-capture-last-stored, org-capture-last-stored-marker...).
I'm in minibuffer now, but I still need to press RET RET
to see these 3 variants. I'd like this to be done automatically.
I'd appreciate any responses that either directly answer my two sub-problems,
or an altogether different approach, as long as I can get the behavior and usability
that I described.
UPD:
I've solved the second thing by switching from completing-read to ido-completing-read:
(defun bookmark-do-quick-jump (str)
(let ((completions (all-completions str bookmark-alist)))
(bookmark-jump
(if (eq 1 (length completions))
(car completions)
(ido-completing-read "Jump to bookmark: " completions nil t str)))))
Btw, I forgot to mention that I use bookmark+. I'm not sure if jumping to dired
is supported by the default bookmark-jump.
We can remap self-insert-command during the completing-read to trigger the auto-completion and auto-acceptance behaviour.
I originally used (or (minibuffer-complete-and-exit) (minibuffer-completion-help)) which at first glance worked very nicely but, as noted in the comments, is less than ideal when one bookmark's name is the prefix of another, as it will immediately accept the shorter name, hence making the longer one inaccessible.
Calling minibuffer-complete and minibuffer-completion-help together breaks the completion functionality, however, so instead I've copied the relevant part of minibuffer-complete-and-exit to a new function. Using this resolves all of the earlier problems.
(require 'bookmark)
(defvar bookmark-do-quick-jump-map (copy-keymap minibuffer-local-must-match-map)
"Keymap for `bookmark-do-quick-jump'.
`minibuffer-local-must-match-map' is used by `completing-read' when its
REQUIRE-MATCH argument is t.
In `bookmark-do-quick-jump' we bind this modified copy to use in its place.")
(define-key bookmark-do-quick-jump-map
[remap self-insert-command] 'my-self-insert-complete-and-exit)
(defun bookmark-do-quick-jump ()
"Jump to specified bookmark with auto-completion and auto-acceptance."
(interactive)
(bookmark-maybe-load-default-file)
(let ((minibuffer-local-must-match-map bookmark-do-quick-jump-map))
(bookmark-jump
(completing-read "Jump to bookmark: " bookmark-alist nil t))))
(defun my-self-insert-complete-and-exit (n)
"Insert the character, then attempt to complete the current string,
automatically exiting when only one option remains, and displaying the
completion options otherwise."
(interactive "p")
(self-insert-command n)
(my-minibuffer-complete)
(let ((my-completions (completion-all-sorted-completions)))
(if (and my-completions (eq 0 (cdr my-completions)))
(exit-minibuffer)
(minibuffer-completion-help))))
(defun my-minibuffer-complete ()
"Copied from `minibuffer-complete-and-exit'."
(interactive)
(condition-case nil
(completion--do-completion nil 'expect-exact)
(error 1)))
Edit:
I took another stab at this using ido. It's a little unfortunate that you don't get the next 'important character' highlighted the way that you do with the regular minibuffer completion (as that was a nice indicator of what to type next), but this seems to work nicely in other respects.
(require 'bookmark)
(require 'ido)
(defvar bookmark-ido-quick-jump-map (copy-keymap minibuffer-local-map)
"Keymap for `bookmark-ido-quick-jump'.
Every time `ido-completing-read' is called it re-initializes
`ido-common-completion-map' and sets its parent to be `minibuffer-local-map'.
In `bookmark-ido-quick-jump' we provide this modified copy as a replacement
parent.")
(define-key bookmark-ido-quick-jump-map
[remap self-insert-command] 'my-self-insert-and-ido-complete)
(defun bookmark-ido-quick-jump ()
"Jump to selected bookmark, using auto-completion and auto-acceptance."
(interactive)
(bookmark-maybe-load-default-file)
(let ((minibuffer-local-map bookmark-ido-quick-jump-map)
(ido-enable-prefix t))
(bookmark-jump
(ido-completing-read "Jump to bookmark: "
(loop for b in bookmark-alist collect (car b))))))
(defun my-self-insert-and-ido-complete (n)
"Insert the character, then attempt to complete the current string,
automatically exiting when only one option remains."
(interactive "p")
(self-insert-command n)
;; ido uses buffer-local pre- and post-command hooks, so we need to
;; co-operate with those. We append our post-command function so that
;; it executes after ido has finished processing our self-insert.
(add-hook 'post-command-hook
'my-self-insert-and-ido-complete-post-command t t))
(defun my-self-insert-and-ido-complete-post-command ()
(remove-hook 'post-command-hook
'my-self-insert-and-ido-complete-post-command t)
;; Now that ido has finished its normal processing for the current
;; command, we simulate a subsequent `ido-complete' command.
(ido-tidy) ;; pre-command-hook
(ido-complete)
(ido-exhibit)) ;; post-command-hook
Here's another take:
(defun bookmark-do-quick-jump (str)
(let ((completions (all-completions str bookmark-alist)))
(if (null (cdr completions))
(bookmark-jump (car completions))
(minibuffer-with-setup-hook
(lambda () (insert str)
(minibuffer-completion-help))
(call-interactively 'bookmark-jump)))))
Or yet another (even more guaranteed untested):
(defadvice bookmark-jump (around quick-bookmarks activate)
(minibuffer-with-setup-hook
(lambda ()
(add-hook 'post-self-insert-hook
(lambda ()
(let ((completions
(all-completions (minibuffer-contents)
bookmark-alist)))
(if (cdr completions)
(minibuffer-completion-help)
(minibuffer-complete-and-exit))))
nil t))
ad-do-it))
Sounds like you're doing a lot of extra work. Just use Icicles.
User option icicle-incremental-completion non-nil and non-t means show all matches as soon as you type input.
Option icicle-top-level-when-sole-completion-flag non-nil means accept a solitary match without your needing to hit a key (e.g. RET).
Instead of customizing the options to have these values in general, you can just bind them to the values in your own command.

How to find the files in TAGS file in emacs

I have generated the TAGS file using ctags for the *.h and *.cpp file in a directory.
How to find the files in TAGS file.
Assuming i have generated the TAGS file for the files one.h two.h three.h. What is the command to find the file one.h, two.h, three.h not the tags in those files.
Assuming that you simply want to know how to use the TAGS file...
Load the TAGS file with:
M-x visit-tags-table RET TAGS file or parent directory RET
Then you can use it with:
M-. (i.e. find-tag)
M-x tags-search RET pattern RET
(with M-, to move to each successive match)
M-x tags-apropos RET pattern RET
M-x tags-query-replace RET pattern RET replacement RET
Those are the defaults. Naturally there are enhancements available:
http://www.emacswiki.org/emacs/EmacsTags
Personally I use etags-select (which you can obtain via ELPA), and I have M-. bound to etags-select-find-tag.
I wrote this a couple of years ago, I haven't gotten around to releasing it yet, though... Enjoy!
The function tags-extra-find-file will let you visit a file in the current tags table, complete with file-name completion. This is perfect if you have many source files spread out over a large number of directories. (Honestly, I use this at least one hundred times every day...)
(defun tags-extra-get-all-tags-files ()
"Return all, fully qualified, file names."
(save-excursion
(let ((first-time t))
(while (visit-tags-table-buffer (not first-time))
(setq first-time nil)
(setq res
(append res (mapcar 'expand-file-name (tags-table-files)))))))
res))
(defun tags-extra-find-file (name)
"Edit file named NAME that is part of the current tags table.
The file name should not include parts of the path."
(interactive
(list
(completing-read "Name of file: "
;; Make an a-list of all files without path.
(mapcar
(lambda (file)
(cons (file-name-nondirectory file) nil))
(tags-extra-get-all-tags-files)))))
(let ((files (tags-extra-get-all-tags-files))
(done nil)
(name-re (concat "^" (regexp-quote name) "$")))
(while (and (not done)
files)
(let ((case-fold-search t))
(if (string-match name-re (file-name-nondirectory (car files)))
(setq done t)
(setq files (cdr files)))))
(if files
(find-file (car files))
(error "File not found in the tags table."))))
This correction works in emacs 26.3. With an old etags, M-. would accept a file name, such as Setup.cpp, and visit the file wherever etags found it. Very handy with lots of files in many directories. No need to remember what directory the file was in to visit it. I'm surprised that's not an out-of-the-box feature!
(defun tags-extra-get-all-tags-files ()
"Return all, fully qualified, file names."
(setq res nil)
(save-excursion
(let ((first-time t))
(while (visit-tags-table-buffer (not first-time))
(setq first-time nil)
(setq res
(append res (mapcar 'expand-file-name (tags-table-files)))))))
res)
Something like this? It might not be entirely robust.
(defun visit-tags-table-and-files (file)
"Run `visit-tags-table FILE', then visit all the referenced files."
(interactive "fTags file: ")
(visit-tags-table file)
(save-excursion
(set-buffer (get-file-buffer tags-file-name))
(mapc #'find-file (tags-table-files)) ) )
Thanks #Lindydancer's answer and emacswiki ido. The emacswiki version only support one tag file. Combining them which allows me jumping to any file in all TAG files. Petty close to the sublime text's goto anything.
Here is the code.
;;; using ido find file in tag files
(defun tags-extra-get-all-tags-files ()
"Return all, fully qualified, file names."
(save-excursion
(let ((first-time t)
(res nil))
(while (visit-tags-table-buffer (not first-time))
(setq first-time nil)
(setq res
(append res (mapcar 'expand-file-name (tags-table-files)))))
res)))
(defun ido-find-file-in-tag-files ()
(interactive)
(find-file
(expand-file-name
(ido-completing-read
"Files: " (tags-extra-get-all-tags-files) nil t))))

How to display autocomplete choices in emacs?

I'm working on autocompletion implementation in emacs for haxe programming language.
I already figured out how to obtain list of autocompletions which I wants to present. The list is in format:
'((name1 type1 desc1)
(name2 type2 desc2) ...
I want to display to user list containing text in format "name1 type1" after cursor position (like in autocomplete-mode) and desc for currently selected item in minibuffer. User should be able to select completion or give up like in auto-complete mode.
When user select something, name1 should be inserted at cursor position.
What is the best/easiest way to do this? Is there some standard emacs way to do this, or I should code something on my own?
EDIT: I have functions to get the list of autocomplete candidates based on buffer. Now I'm struggling how to integrate that to autocomplete-mode. Since get-completes is heavy operation, I would like to trigger it only if cursor is on "." character.
Here's the code I have.
(defun get-completes-from-haxe (hxml-file file pos)
(let* ((completion-buffer (get-buffer-create "*haxe-completions*"))
(cmd (concat "cd " (file-name-directory hxml-file) "; haxe " hxml-file " --display " file "#" (number-to-string pos))))
(ignore-errors
(shell-command cmd completion-buffer)
(let ((clist (xml-parse-region 1 (buffer-size completion-buffer) completion-buffer))
(completes nil))
(dolist (s (cddar clist))
(when (listp s)
(let* ((item (cdr s))
(name (cdaar item))
(type (car (cddadr item)))
(desc (cdddr item)))
(setf completes (cons name completes)))))
completes))))
(defun file-find-upwards (buffer file-name)
;; Chase links in the source file and search in the dir where it points.
(setq dir-name (or (and (buffer-file-name buffer)
(file-name-directory (file-chase-links
(buffer-file-name buffer))))
default-directory))
;; Chase links before visiting the file. This makes it easier to
;; use a single file for several related directories.
(setq dir-name (file-chase-links dir-name))
(setq dir-name (expand-file-name dir-name))
;; Move up in the dir hierarchy till we find a change log file.
(let ((file1 (concat dir-name file-name))
parent-dir)
(while (and (not (file-exists-p file1))
(progn (setq parent-dir
(file-name-directory
(directory-file-name
(file-name-directory file1))))
;; Give up if we are already at the root dir.
(not (string= (file-name-directory file1)
parent-dir))))
;; Move up to the parent dir and try again.
(setq file1 (expand-file-name file-name parent-dir)))
;; If we found the file in a parent dir, use that. Otherwise,
;; return nil
(if (or (get-file-buffer file1) (file-exists-p file1))
file1
nil)))
(defun get-candidate-list (buffer pos)
(get-completes-from-haxe
(file-find-upwards buffer "compile.hxml")
(buffer-file-name buffer)
pos))
I'd suggest the excellent package AutoComplete: http://www.emacswiki.org/emacs/AutoComplete
You can define custom sources for autocomplete and it seems fairly straight forward.
Why keep reinventing wheels? company-mode has support for a few languages
The ido-completing-read from ido.el is another way to do it.
An useful feature of it is that you can use regular expressions to filter out the candidates, and you can toggle this feature on and off on the fly. See ido.el for more details.
ido package has convenient completion functionality called 'ido-completing-read'. For example, here's a simple tweak to make it show lists in a line-by-line basis:
(defun x-ido-completing-read
(prompt choices &optional predicate require-match initial-input hist def)
(let* ((indent (concat "\n" (make-string (length prompt) ? )))
(ido-decorations
`("" "" ,indent ,(concat indent "...")
"[" "]" " [No match]" " [Matched]" " [Not readable]" " [Too big]")))
(ido-completing-read prompt choices predicate require-match initial-input hist def)))
Inside the yasnippet code, available from google code, they use 'dropdown-list.el' by Jaeyoun Chung to display the possible snippets that could be used at point. This gives a popup (tooltip-like) menu at the cursor position you can select with the arrow keys and enter or you can select by number.
http://www.emacswiki.org/emacs/dropdown-list.el