Install some packages

This commit is contained in:
Gergely Polonkai 2016-09-23 13:54:30 +02:00
parent 802b4584ed
commit 6fa0b51045
22 changed files with 8185 additions and 0 deletions

View File

@ -0,0 +1,75 @@
;;; hydra-autoloads.el --- automatically extracted autoloads
;;
;;; Code:
(add-to-list 'load-path (or (file-name-directory #$) (car load-path)))
;;;### (autoloads nil "hydra" "hydra.el" (22501 5659 447421 78000))
;;; Generated autoloads from hydra.el
(autoload 'defhydra "hydra" "\
Create a Hydra - a family of functions with prefix NAME.
NAME should be a symbol, it will be the prefix of all functions
defined here.
BODY has the format:
(BODY-MAP BODY-KEY &rest BODY-PLIST)
DOCSTRING will be displayed in the echo area to identify the
Hydra. When DOCSTRING starts with a newline, special Ruby-style
substitution will be performed by `hydra--format'.
Functions are created on basis of HEADS, each of which has the
format:
(KEY CMD &optional HINT &rest PLIST)
BODY-MAP is a keymap; `global-map' is used quite often. Each
function generated from HEADS will be bound in BODY-MAP to
BODY-KEY + KEY (both are strings passed to `kbd'), and will set
the transient map so that all following heads can be called
though KEY only. BODY-KEY can be an empty string.
CMD is a callable expression: either an interactive function
name, or an interactive lambda, or a single sexp (it will be
wrapped in an interactive lambda).
HINT is a short string that identifies its head. It will be
printed beside KEY in the echo erea if `hydra-is-helpful' is not
nil. If you don't even want the KEY to be printed, set HINT
explicitly to nil.
The heads inherit their PLIST from BODY-PLIST and are allowed to
override some keys. The keys recognized are :exit and :bind.
:exit can be:
- nil (default): this head will continue the Hydra state.
- t: this head will stop the Hydra state.
:bind can be:
- nil: this head will not be bound in BODY-MAP.
- a lambda taking KEY and CMD used to bind a head.
It is possible to omit both BODY-MAP and BODY-KEY if you don't
want to bind anything. In that case, typically you will bind the
generated NAME/body command. This command is also the return
result of `defhydra'.
\(fn NAME BODY &optional DOCSTRING &rest HEADS)" nil t)
(put 'defhydra 'lisp-indent-function 'defun)
;;;***
;;;### (autoloads nil nil ("hydra-examples.el" "hydra-ox.el" "hydra-pkg.el"
;;;;;; "lv.el") (22501 5659 473131 612000))
;;;***
;; Local Variables:
;; version-control: never
;; no-byte-compile: t
;; no-update-autoloads: t
;; End:
;;; hydra-autoloads.el ends here

View File

@ -0,0 +1,386 @@
;;; hydra-examples.el --- Some applications for Hydra
;; Copyright (C) 2015 Free Software Foundation, Inc.
;; Author: Oleh Krehel
;; This file is part of GNU Emacs.
;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;;
;; These are the sample Hydras.
;;
;; If you want to use them plainly, set `hydra-examples-verbatim' to t
;; before requiring this file. But it's probably better to only look
;; at them and use them as templates for building your own.
;;; Code:
(require 'hydra)
;;* Examples
;;** Example 1: text scale
(when (bound-and-true-p hydra-examples-verbatim)
(defhydra hydra-zoom (global-map "<f2>")
"zoom"
("g" text-scale-increase "in")
("l" text-scale-decrease "out")))
;; This example generates three commands:
;;
;; `hydra-zoom/text-scale-increase'
;; `hydra-zoom/text-scale-decrease'
;; `hydra-zoom/body'
;;
;; In addition, two of them are bound like this:
;;
;; (global-set-key (kbd "<f2> g") 'hydra-zoom/text-scale-increase)
;; (global-set-key (kbd "<f2> l") 'hydra-zoom/text-scale-decrease)
;;
;; Note that you can substitute `global-map' with e.g. `emacs-lisp-mode-map' if you need.
;; The functions generated will be the same, except the binding code will change to:
;;
;; (define-key emacs-lisp-mode-map [f2 103]
;; (function hydra-zoom/text-scale-increase))
;; (define-key emacs-lisp-mode-map [f2 108]
;; (function hydra-zoom/text-scale-decrease))
;;** Example 2: move window splitter
(when (bound-and-true-p hydra-examples-verbatim)
(defhydra hydra-splitter (global-map "C-M-s")
"splitter"
("h" hydra-move-splitter-left)
("j" hydra-move-splitter-down)
("k" hydra-move-splitter-up)
("l" hydra-move-splitter-right)))
;;** Example 3: jump to error
(when (bound-and-true-p hydra-examples-verbatim)
(defhydra hydra-error (global-map "M-g")
"goto-error"
("h" first-error "first")
("j" next-error "next")
("k" previous-error "prev")
("v" recenter-top-bottom "recenter")
("q" nil "quit")))
;; This example introduces only one new thing: since the command
;; passed to the "q" head is nil, it will quit the Hydra without doing
;; anything. Heads that quit the Hydra instead of continuing are
;; referred to as having blue :color. All the other heads have red
;; :color, unless other is specified.
;;** Example 4: toggle rarely used modes
(when (bound-and-true-p hydra-examples-verbatim)
(defvar whitespace-mode nil)
(global-set-key
(kbd "C-c C-v")
(defhydra hydra-toggle-simple (:color blue)
"toggle"
("a" abbrev-mode "abbrev")
("d" toggle-debug-on-error "debug")
("f" auto-fill-mode "fill")
("t" toggle-truncate-lines "truncate")
("w" whitespace-mode "whitespace")
("q" nil "cancel"))))
;; Note that in this case, `defhydra' returns the `hydra-toggle-simple/body'
;; symbol, which is then passed to `global-set-key'.
;;
;; Another new thing is that both the keymap and the body prefix are
;; skipped. This means that `defhydra' will bind nothing - that's why
;; `global-set-key' is necessary.
;;
;; One more new thing is that you can assign a :color to the body. All
;; heads will inherit this color. The code above is very much equivalent to:
;;
;; (global-set-key (kbd "C-c C-v a") 'abbrev-mode)
;; (global-set-key (kbd "C-c C-v d") 'toggle-debug-on-error)
;;
;; The differences are:
;;
;; * You get a hint immediately after "C-c C-v"
;; * You can cancel and call a command immediately, e.g. "C-c C-v C-n"
;; is equivalent to "C-n" with Hydra approach, while it will error
;; that "C-c C-v C-n" isn't bound with the usual approach.
;;** Example 5: mini-vi
(defun hydra-vi/pre ()
(set-cursor-color "#e52b50"))
(defun hydra-vi/post ()
(set-cursor-color "#ffffff"))
(when (bound-and-true-p hydra-examples-verbatim)
(global-set-key
(kbd "C-z")
(defhydra hydra-vi (:pre hydra-vi/pre :post hydra-vi/post :color amaranth)
"vi"
("l" forward-char)
("h" backward-char)
("j" next-line)
("k" previous-line)
("m" set-mark-command "mark")
("a" move-beginning-of-line "beg")
("e" move-end-of-line "end")
("d" delete-region "del" :color blue)
("y" kill-ring-save "yank" :color blue)
("q" nil "quit")))
(hydra-set-property 'hydra-vi :verbosity 1))
;; This example introduces :color amaranth. It's similar to red,
;; except while you can quit red with any binding which isn't a Hydra
;; head, you can quit amaranth only with a blue head. So you can quit
;; this mode only with "d", "y", "q" or "C-g".
;;
;; Another novelty are the :pre and :post handlers. :pre will be
;; called before each command, while :post will be called when the
;; Hydra quits. In this case, they're used to override the cursor
;; color while Hydra is active.
;;** Example 6: selective global bind
(when (bound-and-true-p hydra-examples-verbatim)
(defhydra hydra-next-error (global-map "C-x")
"next-error"
("`" next-error "next")
("j" next-error "next" :bind nil)
("k" previous-error "previous" :bind nil)))
;; This example will bind "C-x `" in `global-map', but it will not
;; bind "C-x j" and "C-x k".
;; You can still "C-x `jjk" though.
;;** Example 7: toggle with Ruby-style docstring
(defvar whitespace-mode nil)
(defhydra hydra-toggle (:color pink)
"
_a_ abbrev-mode: %`abbrev-mode
_d_ debug-on-error: %`debug-on-error
_f_ auto-fill-mode: %`auto-fill-function
_t_ truncate-lines: %`truncate-lines
_w_ whitespace-mode: %`whitespace-mode
"
("a" abbrev-mode nil)
("d" toggle-debug-on-error nil)
("f" auto-fill-mode nil)
("t" toggle-truncate-lines nil)
("w" whitespace-mode nil)
("q" nil "quit"))
;; Recommended binding:
;; (global-set-key (kbd "C-c C-v") 'hydra-toggle/body)
;; Here, using e.g. "_a_" translates to "a" with proper face.
;; More interestingly:
;;
;; "foobar %`abbrev-mode" means roughly (format "foobar %S" abbrev-mode)
;;
;; This means that you actually see the state of the mode that you're changing.
;;** Example 8: the whole menu for `Buffer-menu-mode'
(defhydra hydra-buffer-menu (:color pink
:hint nil)
"
^Mark^ ^Unmark^ ^Actions^ ^Search
^^^^^^^^----------------------------------------------------------------- (__)
_m_: mark _u_: unmark _x_: execute _R_: re-isearch (oo)
_s_: save _U_: unmark up _b_: bury _I_: isearch /------\\/
_d_: delete ^ ^ _g_: refresh _O_: multi-occur / | ||
_D_: delete up ^ ^ _T_: files only: % -28`Buffer-menu-files-only^^ * /\\---/\\
_~_: modified ^ ^ ^ ^ ^^ ~~ ~~
"
("m" Buffer-menu-mark)
("u" Buffer-menu-unmark)
("U" Buffer-menu-backup-unmark)
("d" Buffer-menu-delete)
("D" Buffer-menu-delete-backwards)
("s" Buffer-menu-save)
("~" Buffer-menu-not-modified)
("x" Buffer-menu-execute)
("b" Buffer-menu-bury)
("g" revert-buffer)
("T" Buffer-menu-toggle-files-only)
("O" Buffer-menu-multi-occur :color blue)
("I" Buffer-menu-isearch-buffers :color blue)
("R" Buffer-menu-isearch-buffers-regexp :color blue)
("c" nil "cancel")
("v" Buffer-menu-select "select" :color blue)
("o" Buffer-menu-other-window "other-window" :color blue)
("q" quit-window "quit" :color blue))
;; Recommended binding:
;; (define-key Buffer-menu-mode-map "." 'hydra-buffer-menu/body)
;;** Example 9: s-expressions in the docstring
;; You can inline s-expresssions into the docstring like this:
(defvar dired-mode-map)
(declare-function dired-mark "dired")
(when (bound-and-true-p hydra-examples-verbatim)
(require 'dired)
(defhydra hydra-marked-items (dired-mode-map "")
"
Number of marked items: %(length (dired-get-marked-files))
"
("m" dired-mark "mark")))
;; This results in the following dynamic docstring:
;;
;; (format "Number of marked items: %S\n"
;; (length (dired-get-marked-files)))
;;
;; You can use `format'-style width specs, e.g. % 10(length nil).
;;** Example 10: apropos family
(defhydra hydra-apropos (:color blue
:hint nil)
"
_a_propos _c_ommand
_d_ocumentation _l_ibrary
_v_ariable _u_ser-option
^ ^ valu_e_"
("a" apropos)
("d" apropos-documentation)
("v" apropos-variable)
("c" apropos-command)
("l" apropos-library)
("u" apropos-user-option)
("e" apropos-value))
;; Recommended binding:
;; (global-set-key (kbd "C-c h") 'hydra-apropos/body)
;;** Example 11: rectangle-mark-mode
(require 'rect)
(defhydra hydra-rectangle (:body-pre (rectangle-mark-mode 1)
:color pink
:post (deactivate-mark))
"
^_k_^ _d_elete _s_tring
_h_ _l_ _o_k _y_ank
^_j_^ _n_ew-copy _r_eset
^^^^ _e_xchange _u_ndo
^^^^ ^ ^ _p_aste
"
("h" rectangle-backward-char nil)
("l" rectangle-forward-char nil)
("k" rectangle-previous-line nil)
("j" rectangle-next-line nil)
("e" hydra-ex-point-mark nil)
("n" copy-rectangle-as-kill nil)
("d" delete-rectangle nil)
("r" (if (region-active-p)
(deactivate-mark)
(rectangle-mark-mode 1)) nil)
("y" yank-rectangle nil)
("u" undo nil)
("s" string-rectangle nil)
("p" kill-rectangle nil)
("o" nil nil))
;; Recommended binding:
;; (global-set-key (kbd "C-x SPC") 'hydra-rectangle/body)
;;** Example 12: org-agenda-view
(defun org-agenda-cts ()
(and (eq major-mode 'org-agenda-mode)
(let ((args (get-text-property
(min (1- (point-max)) (point))
'org-last-args)))
(nth 2 args))))
(defhydra hydra-org-agenda-view (:hint none)
"
_d_: ?d? day _g_: time grid=?g? _a_: arch-trees
_w_: ?w? week _[_: inactive _A_: arch-files
_t_: ?t? fortnight _f_: follow=?f? _r_: clock report=?r?
_m_: ?m? month _e_: entry text=?e? _D_: include diary=?D?
_y_: ?y? year _q_: quit _L__l__c_: log = ?l?"
("SPC" org-agenda-reset-view)
("d" org-agenda-day-view (if (eq 'day (org-agenda-cts)) "[x]" "[ ]"))
("w" org-agenda-week-view (if (eq 'week (org-agenda-cts)) "[x]" "[ ]"))
("t" org-agenda-fortnight-view (if (eq 'fortnight (org-agenda-cts)) "[x]" "[ ]"))
("m" org-agenda-month-view (if (eq 'month (org-agenda-cts)) "[x]" "[ ]"))
("y" org-agenda-year-view (if (eq 'year (org-agenda-cts)) "[x]" "[ ]"))
("l" org-agenda-log-mode (format "% -3S" org-agenda-show-log))
("L" (org-agenda-log-mode '(4)))
("c" (org-agenda-log-mode 'clockcheck))
("f" org-agenda-follow-mode (format "% -3S" org-agenda-follow-mode))
("a" org-agenda-archives-mode)
("A" (org-agenda-archives-mode 'files))
("r" org-agenda-clockreport-mode (format "% -3S" org-agenda-clockreport-mode))
("e" org-agenda-entry-text-mode (format "% -3S" org-agenda-entry-text-mode))
("g" org-agenda-toggle-time-grid (format "% -3S" org-agenda-use-time-grid))
("D" org-agenda-toggle-diary (format "% -3S" org-agenda-include-diary))
("!" org-agenda-toggle-deadlines)
("[" (let ((org-agenda-include-inactive-timestamps t))
(org-agenda-check-type t 'timeline 'agenda)
(org-agenda-redo)
(message "Display now includes inactive timestamps as well")))
("q" (message "Abort") :exit t)
("v" nil))
;; Recommended binding:
;; (define-key org-agenda-mode-map "v" 'hydra-org-agenda-view/body)
;;* Helpers
(require 'windmove)
(defun hydra-move-splitter-left (arg)
"Move window splitter left."
(interactive "p")
(if (let ((windmove-wrap-around))
(windmove-find-other-window 'right))
(shrink-window-horizontally arg)
(enlarge-window-horizontally arg)))
(defun hydra-move-splitter-right (arg)
"Move window splitter right."
(interactive "p")
(if (let ((windmove-wrap-around))
(windmove-find-other-window 'right))
(enlarge-window-horizontally arg)
(shrink-window-horizontally arg)))
(defun hydra-move-splitter-up (arg)
"Move window splitter up."
(interactive "p")
(if (let ((windmove-wrap-around))
(windmove-find-other-window 'up))
(enlarge-window arg)
(shrink-window arg)))
(defun hydra-move-splitter-down (arg)
"Move window splitter down."
(interactive "p")
(if (let ((windmove-wrap-around))
(windmove-find-other-window 'up))
(shrink-window arg)
(enlarge-window arg)))
(defvar rectangle-mark-mode)
(defun hydra-ex-point-mark ()
"Exchange point and mark."
(interactive)
(if rectangle-mark-mode
(rectangle-exchange-point-and-mark)
(let ((mk (mark)))
(rectangle-mark-mode 1)
(goto-char mk))))
(provide 'hydra-examples)
;; Local Variables:
;; no-byte-compile: t
;; End:
;;; hydra-examples.el ends here

View File

@ -0,0 +1,127 @@
;;; hydra-ox.el --- Org mode export widget implemented in Hydra
;; Copyright (C) 2015 Free Software Foundation, Inc.
;; Author: Oleh Krehel
;; This file is part of GNU Emacs.
;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;;
;; This shows how a complex dispatch menu can be built with Hydra.
;;; Code:
(require 'hydra)
(require 'org)
(declare-function org-html-export-as-html 'ox-html)
(declare-function org-html-export-to-html 'ox-html)
(declare-function org-latex-export-as-latex 'ox-latex)
(declare-function org-latex-export-to-latex 'ox-latex)
(declare-function org-latex-export-to-pdf 'ox-latex)
(declare-function org-ascii-export-as-ascii 'ox-ascii)
(declare-function org-ascii-export-to-ascii 'ox-ascii)
(defhydradio hydra-ox ()
(body-only "Export only the body.")
(export-scope "Export scope." [buffer subtree])
(async-export "When non-nil, export async.")
(visible-only "When non-nil, export visible only")
(force-publishing "Toggle force publishing"))
(defhydra hydra-ox-html (:color blue)
"ox-html"
("H" (org-html-export-as-html
hydra-ox/async-export
(eq hydra-ox/export-scope 'subtree)
hydra-ox/visible-only
hydra-ox/body-only)
"As HTML buffer")
("h" (org-html-export-to-html
hydra-ox/async-export
(eq hydra-ox/export-scope 'subtree)
hydra-ox/visible-only
hydra-ox/body-only) "As HTML file")
("o" (org-open-file
(org-html-export-to-html
hydra-ox/async-export
(eq hydra-ox/export-scope 'subtree)
hydra-ox/visible-only
hydra-ox/body-only)) "As HTML file and open")
("b" hydra-ox/body "back")
("q" nil "quit"))
(defhydra hydra-ox-latex (:color blue)
"ox-latex"
("L" org-latex-export-as-latex "As LaTeX buffer")
("l" org-latex-export-to-latex "As LaTeX file")
("p" org-latex-export-to-pdf "As PDF file")
("o" (org-open-file (org-latex-export-to-pdf)) "As PDF file and open")
("b" hydra-ox/body "back")
("q" nil "quit"))
(defhydra hydra-ox-text (:color blue)
"ox-text"
("A" (org-ascii-export-as-ascii
nil nil nil nil
'(:ascii-charset ascii))
"As ASCII buffer")
("a" (org-ascii-export-to-ascii
nil nil nil nil
'(:ascii-charset ascii))
"As ASCII file")
("L" (org-ascii-export-as-ascii
nil nil nil nil
'(:ascii-charset latin1))
"As Latin1 buffer")
("l" (org-ascii-export-to-ascii
nil nil nil nil
'(:ascii-charset latin1))
"As Latin1 file")
("U" (org-ascii-export-as-ascii
nil nil nil nil
'(:ascii-charset utf-8))
"As UTF-8 buffer")
("u" (org-ascii-export-to-ascii
nil nil nil nil
'(:ascii-charset utf-8))
"As UTF-8 file")
("b" hydra-ox/body "back")
("q" nil "quit"))
(defhydra hydra-ox ()
"
_C-b_ Body only: % -15`hydra-ox/body-only^^^ _C-v_ Visible only: %`hydra-ox/visible-only
_C-s_ Export scope: % -15`hydra-ox/export-scope _C-f_ Force publishing: %`hydra-ox/force-publishing
_C-a_ Async export: %`hydra-ox/async-export
"
("C-b" (hydra-ox/body-only) nil)
("C-v" (hydra-ox/visible-only) nil)
("C-s" (hydra-ox/export-scope) nil)
("C-f" (hydra-ox/force-publishing) nil)
("C-a" (hydra-ox/async-export) nil)
("h" hydra-ox-html/body "Export to HTML" :exit t)
("l" hydra-ox-latex/body "Export to LaTeX" :exit t)
("t" hydra-ox-text/body "Export to Plain Text" :exit t)
("q" nil "quit"))
(define-key org-mode-map (kbd "C-c C-,") 'hydra-ox/body)
(provide 'hydra-ox)
;;; hydra-ox.el ends here

View File

@ -0,0 +1,7 @@
(define-package "hydra" "20160913.216" "Make bindings that stick around."
'((cl-lib "0.5"))
:url "https://github.com/abo-abo/hydra" :keywords
'("bindings"))
;; Local Variables:
;; no-byte-compile: t
;; End:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,117 @@
;;; lv.el --- Other echo area
;; Copyright (C) 2015 Free Software Foundation, Inc.
;; Author: Oleh Krehel
;; This file is part of GNU Emacs.
;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;;
;; This package provides `lv-message' intended to be used in place of
;; `message' when semi-permanent hints are needed, in order to not
;; interfere with Echo Area.
;;
;; "Я тихо-тихо пiдглядаю,
;; І тiшуся собi, як бачу то,
;; Шо страшить i не пiдпускає,
;; А iншi п’ють тебе, як воду пiсок."
;; -- Андрій Кузьменко, L.V.
;;; Code:
(defgroup lv nil
"The other echo area."
:group 'minibuffer
:group 'hydra)
(defcustom lv-use-separator nil
"Whether to draw a line between the LV window and the Echo Area."
:group 'lv
:type 'boolean)
(defface lv-separator
'((((class color) (background light)) :background "grey80")
(((class color) (background dark)) :background "grey30"))
"Face used to draw line between the lv window and the echo area.
This is only used if option `lv-use-separator' is non-nil.
Only the background color is significant."
:group 'lv)
(defvar lv-wnd nil
"Holds the current LV window.")
(defun lv-window ()
"Ensure that LV window is live and return it."
(if (window-live-p lv-wnd)
lv-wnd
(let ((ori (selected-window))
buf)
(prog1 (setq lv-wnd
(select-window
(let ((ignore-window-parameters t))
(split-window
(frame-root-window) -1 'below))))
(if (setq buf (get-buffer " *LV*"))
(switch-to-buffer buf)
(switch-to-buffer " *LV*")
(set-window-hscroll lv-wnd 0)
(setq window-size-fixed t)
(setq mode-line-format nil)
(setq cursor-type nil)
(set-window-dedicated-p lv-wnd t)
(set-window-parameter lv-wnd 'no-other-window t))
(select-window ori)))))
(defvar golden-ratio-mode)
(defvar lv-force-update nil
"When non-nil, `lv-message' will refresh even for the same string.")
(defun lv-message (format-string &rest args)
"Set LV window contents to (`format' FORMAT-STRING ARGS)."
(let* ((str (apply #'format format-string args))
(n-lines (cl-count ?\n str))
deactivate-mark
golden-ratio-mode)
(with-selected-window (lv-window)
(unless (and (string= (buffer-string) str)
(null lv-force-update))
(delete-region (point-min) (point-max))
(insert str)
(when (and (window-system) lv-use-separator)
(unless (looking-back "\n" nil)
(insert "\n"))
(insert
(propertize "__" 'face 'lv-separator 'display '(space :height (1)))
(propertize "\n" 'face 'lv-separator 'line-height t)))
(set (make-local-variable 'window-min-height) n-lines)
(setq truncate-lines (> n-lines 1))
(let ((window-resize-pixelwise t)
(window-size-fixed nil))
(fit-window-to-buffer nil nil 1)))
(goto-char (point-min)))))
(defun lv-delete-window ()
"Delete LV window and kill its buffer."
(when (window-live-p lv-wnd)
(let ((buf (window-buffer lv-wnd)))
(delete-window lv-wnd)
(kill-buffer buf))))
(provide 'lv)
;;; lv.el ends here

View File

@ -0,0 +1,27 @@
;;; id-manager-autoloads.el --- automatically extracted autoloads
;;
;;; Code:
(add-to-list 'load-path (or (file-name-directory #$) (car load-path)))
;;;### (autoloads nil "id-manager" "id-manager.el" (22501 4892 376900
;;;;;; 628000))
;;; Generated autoloads from id-manager.el
(autoload 'idm-open-list-command "id-manager" "\
Load the id-password DB and open a list buffer.
\(fn &optional DB)" t nil)
(autoload 'idm-helm-command "id-manager" "\
Helm interface for id-manager.
\(fn)" t nil)
;;;***
;; Local Variables:
;; version-control: never
;; no-byte-compile: t
;; no-update-autoloads: t
;; End:
;;; id-manager-autoloads.el ends here

View File

@ -0,0 +1 @@
(define-package "id-manager" "20160425.216" "id-password management" 'nil :keywords '("password" "convenience"))

View File

@ -0,0 +1,831 @@
;;; id-manager.el --- id-password management
;; Copyright (C) 2009, 2010, 2011, 2013 SAKURAI Masashi
;; Time-stamp: <2015-06-06 12:38:31 sakurai>
;; Author: SAKURAI Masashi <m.sakurai atmark kiwanami.net>
;; Keywords: password, convenience
;; Package-Version: 20160425.216
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; ID-password management utility.
;; This utility manages ID-password list and generates passwords.
;; The ID-password DB is saved in the tab-separated file. The default
;; file name of the DB `idm-database-file' is "~/.idm-db.gpg".
;; The file format is following:
;; (name)^t(ID)^t(password)^t(Update date "YYYY/MM/DD")[^t(memo)]
;; . One can prepare an initial data or modify the data by hand or
;; the Excel.
;;
;; Implicitly, this elisp program expects that the DB file is
;; encrypted by the some GPG encryption elisp, such as EasyPG or
;; alpaca.
;;
;; Excuting the command `idm-open-list-command', you can open the
;; ID-password list buffer. Check the function `describe-bindings'.
;;; Installation:
;; To use this program, locate this file to load-path directory,
;; and add the following code to your .emacs.
;; ------------------------------
;; (require 'id-manager)
;; ------------------------------
;; If you have helm.el, bind `id-manager' to key,
;; like (global-set-key (kbd "M-7") 'id-manager).
;;; Setting example:
;; For EasyPG users:
;;
;; (autoload 'id-manager "id-manager" nil t)
;; (global-set-key (kbd "M-7") 'id-manager) ; helm UI
;; (setq epa-file-cache-passphrase-for-symmetric-encryption t) ; saving password
;; (setenv "GPG_AGENT_INFO" nil) ; non-GUI password dialog.
;; For alpaca users:
;;
;; (autoload 'id-manager "id-manager" nil t)
;; (global-set-key (kbd "M-7") 'id-manager) ; helm UI
;; (setq idm-db-buffer-save-function ; adjustment for alpaca.el
;; (lambda (file)
;; (set-visited-file-name file)
;; (alpaca-save-buffer))
;; idm-db-buffer-password-var ; if you are using `alpaca-cache-passphrase'.
;; 'alpaca-passphrase)
;;; Current implementation:
;; This program generates passwords by using external command:
;; `idm-gen-password-cmd'. If you have some better idea, please let me
;; know.
;;
;; I think that this program makes lazy password management more
;; securely. But I'm not sure that this program is secure enough.
;; I'd like many people to check and advice me.
;;; Code:
(eval-when-compile (require 'cl))
(require 'widget)
(eval-when-compile (require 'wid-edit))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Setting
(defvar idm-database-file "~/.idm-db.gpg"
"Encripted id-password database file. The file name may
end with '.gpg' for encryption by the GnuPG.")
(defvar idm-gen-password-cmd
"head -c 10 < /dev/random | uuencode -m - | tail -n 2 |head -n 1 | head -c10"
"[String] Password generation command. If a function symbol or
lambda whose receive no parameter is set to this variable,
id-manager calls the function to generate the password.")
;; "openssl rand 32 | uuencode -m - | tail -n 2 |head -n 1 | head -c10"
;; ...any other password generation ?
(defvar idm-copy-action
(lambda (text) (x-select-text text))
"Action for copying a password text into clipboard.")
(defvar idm-db-buffer-load-function
'find-file-noselect
"File loading function. This function has one argument FILENAME and returns a buffer,
like `find-file-noselect'. Some decryption should work at this
function.")
(defvar idm-db-buffer-save-function
'write-file
"File saving function. This function has one arguments FILENAME,
like `write-file'. Some encryption should work at this
function.")
(defvar idm-db-buffer-password-var nil
"Password variable. See the text of settings for alpaca.el. ")
(defvar idm-clipboard-expire-time-sec 5
"Expire time for the clipboard content.")
(defvar idm-clipboard-expire-timer nil
"The timer object that will expire the clipboard content.")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Macros
(defmacro idm--aif (test-form then-form &rest else-forms)
`(let ((it ,test-form))
(if it ,then-form ,@else-forms)))
(put 'idm--aif 'lisp-indent-function 2)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Management API
(defun idm-gen-password ()
"Generate a password."
(cond
((functionp idm-gen-password-cmd)
(funcall idm-gen-password-cmd))
((stringp idm-gen-password-cmd)
(let ((buf (get-buffer-create " *idm-work*")) ret)
(call-process-shell-command
idm-gen-password-cmd
nil buf nil)
(with-current-buffer buf
(setq ret (buffer-string)))
(kill-buffer buf)
ret))
(t (error "idm-gen-password-cmd is set to wrong value. [%S]"
idm-gen-password-cmd))))
;; record struct
(defstruct (idm-record
(:constructor make-idm-record-bylist
(name account-id password update-time
&optional memo)))
name account-id password update-time memo)
(defun idm-load-db ()
"Load the DB file `idm-database-file' and make a DB object."
(let* ((coding-system-for-read 'utf-8)
(tmpbuf
(funcall idm-db-buffer-load-function
(expand-file-name idm-database-file)))
db-object)
(unwind-protect
(let ((db (idm--make-db tmpbuf)))
(when idm-db-buffer-password-var
(with-current-buffer tmpbuf
(funcall db 'file-password
(symbol-value idm-db-buffer-password-var))))
db)
(kill-buffer tmpbuf))))
(defun idm--save-db (records file-vars &optional password)
"Save RECORDS into the DB file `idm-database-file'. This
function is called by a DB object."
(let ((coding-system-for-write 'utf-8)
(tmpbuf (get-buffer-create " *idm-tmp*")))
(with-current-buffer tmpbuf
(erase-buffer)
(goto-char (point-min))
(loop for (sym . v) in file-vars do
(set (make-local-variable sym) v))
(insert (format
";; -*- %s -*-"
(loop for (n . v) in file-vars concat
(format "%s: %S; " n v))) "\n")
(dolist (i records)
(insert (concat (idm-record-name i) "\t"
(idm-record-account-id i) "\t"
(idm-record-password i) "\t"
(idm-record-update-time i)
(idm--aif (idm-record-memo i)
(concat "\t" it))
"\n")))
(when password
(set idm-db-buffer-password-var password))
(funcall idm-db-buffer-save-function idm-database-file)
(kill-buffer tmpbuf))))
(defun idm--make-db (tmpbuf)
"Build a database management object from the given buffer text.
The object is a dispatch function. One can access the methods
`funcall' with the method name symbol and some method arguments."
(lexical-let (records
(db-modified nil)
file-vars ; file variables
file-password) ; password for alpaca
(setq file-vars (buffer-local-value 'file-local-variables-alist tmpbuf))
(idm--each-line
tmpbuf
(lambda (line)
(cond
((string-match "^;; " line) ; file variables
) ; ignore
(t ; entry lines
(let ((cols (split-string line "\t")))
(if (or (= 4 (length cols))
(= 5 (length cols)))
(push (apply 'make-idm-record-bylist cols)
records)))))))
(lambda (method &rest args)
(cond
((eq method 'get) ; get record object by name
(lexical-let ((name (car args)) ret)
(mapc (lambda (i)
(if (equal name (idm-record-name i))
(setq ret i)))
records)
ret))
((eq method 'get-all-records) records) ; get-all-records
((eq method 'add-record) ; add-record
(progn
(lexical-let* ((record (car args))
(name (idm-record-name record)))
(setf records (loop for i in records
unless (equal (idm-record-name i) name)
collect i))
(push record records)
(setq db-modified t))))
((eq method 'delete-record-by-name) ; delete-record-by-name
(lexical-let ((name (car args)))
(setf records (loop for i in records
unless (equal (idm-record-name i) name)
collect i))
(setq db-modified t)))
((eq method 'set-modified) ; set-modified
(setq db-modified t))
((eq method 'save) ; save
(when db-modified
(idm--save-db records file-vars file-password)
(setq db-modified nil)))
((eq method 'file-password) ; file-password
(setq file-password (car args)) nil)
(t (error "Unknown method [%s]" method))))))
(defun idm--each-line (buf task)
"Execute the function TASK with each lines in the buffer
`buf'. This function is called by `idm--make-db'."
(with-current-buffer buf
(goto-char (point-min))
(unless (eobp)
(while
(let ((line
(buffer-substring-no-properties
(line-beginning-position)
(line-end-position))))
(funcall task line)
(forward-line 1)
(not (eobp)))))))
(defun idm--strtime (time)
"Translate emacs time to formatted string."
(format-time-string "%Y/%m/%d" time))
(defun idm--parsetime (str)
"Translate formatted string to emacs time."
(when (string-match "\\([0-9]+\\)\\/\\([0-9]+\\)\\/\\([0-9]+\\)" str)
(apply 'encode-time
(let (ret)
(dotimes (i 6)
(push (string-to-number (match-string (+ i 1) str)) ret))
ret))))
(defun idm--message (&rest args)
"Show private text in the echo area without message buffer
recording."
(let (message-log-max)
(apply 'message args)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; GUI
(defvar idm-show-password nil
"Display passwords switch. If this variable is non-nil, some
functions show the password as plain text.")
(defun idm-toggle-show-password ()
"Toggle the switch for display passwords. This function does not update views."
(interactive)
(setq idm-show-password (not idm-show-password)))
(defun idm-add-record-dialog (db on-ok-func)
"Make an account record interactively and register it with DB."
(lexical-let ((db db) (on-ok-func on-ok-func))
(idm-edit-record-dialog
(make-idm-record)
(lambda (r)
(cond
((funcall db 'get (idm-record-name r))
(idm-edit-record-dialog r on-ok-func nil "Record [%s] exists!"))
(t (funcall on-ok-func r)))))))
(defun idm-edit-record-dialog (record on-ok-func &optional password-show error-msg)
"Pop up the edit buffer for the given record.
If the user pushes the `ok' button, the function
`idm-edit-record-dialog-commit' is called."
(let ((before-win-num (length (window-list)))
(main-buf (current-buffer))
(edit-buf (idm--edit-record-dialog-buffer record on-ok-func password-show error-msg)))
(with-current-buffer edit-buf
(set (make-local-variable 'idm-before-win-num) before-win-num)
(set (make-local-variable 'idm-main-buf) main-buf))
(pop-to-buffer edit-buf)))
(defun idm--edit-record-dialog-buffer (record on-ok-func &optional password-show error-msg)
"Return the editing buffer for the given record."
(let ((buf (get-buffer-create "*idm-record-dialog*")))
(with-current-buffer buf
(let ((inhibit-read-only t)) (erase-buffer))
(kill-all-local-variables)
(remove-overlays)
(widget-insert
(format "Record: %s\n\n"
(idm--aif (idm-record-name record) it "(new record)")))
(when error-msg
(widget-insert
(let ((text (substring-no-properties error-msg)))
(put-text-property 0 (length text) 'face 'font-lock-warning-face text)
text))
(widget-insert "\n\n"))
(lexical-let
((record record) (on-ok-func on-ok-func) (error-msg error-msg)
fname fid fpassword fmemo cbshow bgenerate fields)
;; create dialog fields
(setq fname (widget-create
'editable-field
:size 20 :format " Account Name: %v \n"
:value (or (idm-record-name record) ""))
fid (widget-create
'editable-field
:size 20 :format " Account ID : %v \n"
:value (or (idm-record-account-id record) ""))
fpassword (widget-create
'editable-field
:size 20 :format " Password: %v \n"
:secret (and (not password-show) ?*)
:value (or (idm-record-password record) "")))
(widget-insert " (show password ")
(setq cbshow
(widget-create 'checkbox :value password-show))
(widget-insert " ) ")
(setq bgenerate
(widget-create 'push-button "Generate"))
(widget-insert "\n")
(setq fmemo (widget-create
'editable-field
:size 20
:format " Memo : %v \n"
:value (or (idm-record-memo record) "")))
(setq fields
(list 'name fname 'id fid 'password fpassword 'memo fmemo 'password-show cbshow))
;; OK / Cancel
(widget-insert "\n")
(widget-create
'push-button
:notify (lambda (&rest ignore)
(idm-edit-record-dialog-commit record fields on-ok-func))
"Ok")
(widget-insert " ")
(widget-create
'push-button
:notify (lambda (&rest ignore)
(idm-edit-record-kill-buffer))
"Cancel")
(widget-insert "\n")
;; add event actions
(widget-put cbshow
:notify
(lambda (&rest ignore)
(let ((current-record
(make-idm-record
:name (widget-value fname)
:account-id (widget-value fid)
:password (widget-value fpassword)
:memo (widget-value fmemo)))
(password-show (widget-value cbshow)))
(message "CLICK : %s" password-show)
(idm-edit-record-kill-buffer)
(idm-edit-record-dialog
current-record on-ok-func password-show error-msg)
(widget-forward 3))))
(widget-put bgenerate
:notify
(lambda (&rest ignore)
(widget-value-set fpassword (idm-gen-password))
(widget-setup)))
;; setup widgets
(use-local-map widget-keymap)
(widget-setup)
(goto-char (point-min))
(widget-forward 1)))
buf))
(defun idm-edit-record-dialog-commit (record fields on-ok-func)
"edit-record-dialog-commit"
(let ((name-value (widget-value (plist-get fields 'name))))
(cond
((or (null name-value)
(string-equal "" name-value))
(idm-edit-record-kill-buffer)
(idm-edit-record-dialog
record on-ok-func
(widget-value (plist-get fields 'password-show))
"Should not be empty!"))
(t
(setf (idm-record-name record) name-value
(idm-record-account-id record)
(widget-value (plist-get fields 'id))
(idm-record-password record)
(widget-value (plist-get fields 'password))
(idm-record-memo record)
(widget-value (plist-get fields 'memo))
(idm-record-update-time record) (idm--strtime (current-time)))
(idm-edit-record-kill-buffer)
(funcall on-ok-func record)))))
(defun idm-edit-record-kill-buffer ()
"edit-record-kill-buffer"
(interactive)
(let ((cbuf (current-buffer))
(win-num (length (window-list)))
(next-win (get-buffer-window idm-main-buf)))
(when (and (not (one-window-p))
(> win-num idm-before-win-num))
(delete-window))
(kill-buffer cbuf)
(when next-win (select-window next-win))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; id-password list buffer
(defun idm-open-list (db)
"Open id-password list buffer."
(lexical-let ((buf (get-buffer-create "ID-Password List"))
(db db))
(with-current-buffer buf
(idm--layout-list db)
(idm--set-list-mode db)
)
(set-buffer buf)))
(defun idm--put-text-property (text attr val)
"Put a text property on the whole text."
(put-text-property 0 (length text) attr val text) text)
(defun idm--put-record-id (text id)
"Put the record id with the text property `idm-record-id'."
(idm--put-text-property text 'idm-record-id id))
(defun idm--get-record-id ()
"Get the record id on the current point."
(get-text-property (point) 'idm-record-id))
(defun idm--layout-list (db &optional order)
"Erase the content in the current buffer and insert record
lines. ORDER is sort key, which can be `time', `name' and `id'."
(unless order
(setq order 'name))
(let* ((name-max (length "Account Name"))
(id-max (length "ID"))
(pw-max (length "Password"))
(pw-mask "********")
(pw-getter (lambda (record)
(if idm-show-password
(idm-record-password record)
pw-mask)))
(cut (lambda (str) (substring str 0 (min (length str) 20))))
numcolm (count 1)
(line-format "%%-%ds|%%-10s | %%-%ds | %%-%ds : %%-%ds : %%s\n")
(records (funcall db 'get-all-records)))
(when records
(setq numcolm (fceiling (log10 (length records))))
(dolist (i records)
(setq name-max (min 20 (max name-max (length (idm-record-name i))))
id-max (min 20 (max id-max (length (idm-record-account-id i))))
pw-max (max pw-max (length (funcall pw-getter i)))))
(setq line-format (format line-format numcolm name-max id-max pw-max))
(let ((buffer-read-only nil) (prev-line (line-number-at-pos)))
(erase-buffer)
(goto-char (point-min))
(insert (format line-format
" " "Time" "Name" "ID" "Password" "Memo"))
(insert (make-string (- (window-width) 1) ?-) "\n")
(dolist (i (idm--sort-records records order))
(insert
(idm--put-record-id
(format line-format
count
(idm-record-update-time i)
(funcall cut (idm-record-name i))
(funcall cut (idm-record-account-id i))
(funcall pw-getter i)
(idm-record-memo i))
(idm-record-name i)))
(incf count))
(goto-char (point-min))
(when (< 1 prev-line)
(ignore-errors
(forward-line (1- prev-line))))))))
(defun idm--sort-records (records order)
"Sort records by the key ORDER, which can be `time', `name',
`memo' and `id'."
(let*
((comparator
(lambda (ref)
(lexical-let ((ref ref))
(lambda (i j)
(let ((ii (funcall ref i))
(jj (funcall ref j)))
(cond
((string= ii jj) 0)
((string< ii jj) -1)
(t 1)))))))
(to-bool
(lambda (f)
(lexical-let ((f f))
(lambda (i j)
(< (funcall f i j) 0)))))
(cmp-id (funcall comparator 'idm-record-account-id))
(cmp-name (funcall comparator 'idm-record-name))
(cmp-time (funcall comparator 'idm-record-update-time))
(cmp-memo (funcall comparator 'idm-record-memo))
(chain
(lambda (a b)
(lexical-let ((a a) (b b))
(lambda (i j)
(let ((v (funcall a i j)))
(if (= 0 v)
(funcall b i j)
v)))))))
(sort
(loop for i in records collect i) ; copy-list
(cond
((eq order 'id) ; id -> id, name
(funcall to-bool (funcall chain cmp-id cmp-name)))
((eq order 'name) ; name -> name
(funcall to-bool cmp-name))
((eq order 'time) ; time -> time, name
(funcall to-bool (funcall chain cmp-time cmp-name)))
((eq order 'memo) ; memo -> time, name
(funcall to-bool (funcall chain cmp-memo cmp-name)))
(t ; default
(funcall to-bool cmp-name))))))
(defvar idm-list-mode-map nil
"Keymap for `idm-list-mode'.")
(setq idm-list-mode-map nil) ; for debug
(unless idm-list-mode-map
(setq idm-list-mode-map (make-sparse-keymap))
(mapc (lambda (i)
(define-key idm-list-mode-map (car i) (cdr i)))
`(("q" . idm-list-mode-quit)
("Q" . idm-list-mode-quit-without-save)
("n" . next-line)
("p" . previous-line)
("j" . next-line)
("k" . previous-line)
("d" . idm-list-mode-delete)
("-" . idm-list-mode-delete)
("e" . idm-list-mode-edit-dialog)
("m" . idm-list-mode-edit-dialog)
("a" . idm-list-mode-add)
("+" . idm-list-mode-add)
("u" . idm-list-mode-reload)
("r" . idm-list-mode-reload)
("T" . idm-list-mode-sortby-time)
("N" . idm-list-mode-sortby-name)
("I" . idm-list-mode-sortby-id)
("M" . idm-list-mode-sortby-memo)
("S" . idm-list-mode-toggle-show-password)
("s" . idm-list-mode-show-password)
([return] . idm-list-mode-copy)
)))
(defun idm-list-mode-copy ()
(interactive)
(idm--aif (idm--get-record-id)
(let ((record (funcall idm-db 'get it)))
(when record
(idm--copy-password-action record)))))
(defun idm--copy-password-action (record)
(interactive)
(message (concat "Copied the password for the account ID: "
(idm-record-account-id record)))
(funcall idm-copy-action (idm-record-password record))
(idm-set-clipboard-expiry))
(defun idm--copy-id-action (record)
(interactive)
(message (concat "Copied account ID: "
(idm-record-account-id record)))
(funcall idm-copy-action (idm-record-account-id record))
(idm-set-clipboard-expiry))
(defun idm-set-clipboard-expiry ()
(when idm-clipboard-expire-timer
(cancel-timer idm-clipboard-expire-timer))
(when idm-clipboard-expire-time-sec
(setq idm-clipboard-expire-timer
(run-at-time idm-clipboard-expire-time-sec nil 'idm-expire-clipboard))))
(defun idm-expire-clipboard ()
"Clear clipboard"
(funcall idm-copy-action "")
(idm--message "ID Manager: expired."))
(defun idm-list-mode-sortby-id ()
(interactive)
(idm--layout-list idm-db 'id))
(defun idm-list-mode-sortby-name ()
(interactive)
(idm--layout-list idm-db 'name))
(defun idm-list-mode-sortby-time ()
(interactive)
(idm--layout-list idm-db 'time))
(defun idm-list-mode-sortby-memo ()
(interactive)
(idm--layout-list idm-db 'memo))
(defun idm-list-mode-reload ()
"Reload the id-password database file."
(interactive)
(setq idm-db (idm-load-db))
(idm--layout-list idm-db))
(defun idm-list-mode-toggle-show-password ()
"Toggle whether to show passwords."
(interactive)
(idm-toggle-show-password)
(idm--layout-list idm-db))
(defun idm-list-mode-show-password ()
"Show password of the selected record."
(interactive)
(idm--aif (idm--get-record-id)
(let ((record (funcall idm-db 'get it)))
(if record
(idm--message
(concat
"ID: " (idm-record-account-id record)
" / PW: "(idm-record-password record)))))))
(defun idm--set-list-mode (db)
"Set up major mode for id-password list mode."
(kill-all-local-variables)
(make-local-variable 'idm-db)
(setq idm-db db)
(setq truncate-lines t)
(use-local-map idm-list-mode-map)
(setq major-mode 'idm-list-mode
mode-name "ID-Password List")
(hl-line-mode 1))
(defun idm-list-mode-quit ()
"Save the DB and kill buffer."
(interactive)
(funcall idm-db 'save)
(kill-buffer (current-buffer)))
(defun idm-list-mode-quit-without-save ()
"Kill buffer without saving the DB."
(interactive)
(kill-buffer (current-buffer)))
(defun idm-list-mode-delete ()
"Delete a selected record from the DB. After deleting, update
the list buffer."
(interactive)
(idm--aif (idm--get-record-id)
(progn
(when (y-or-n-p (format "Delete this record[%s] ?" it))
(funcall idm-db 'delete-record-by-name it)
(idm--layout-list idm-db)))))
(defun idm-list-mode-add ()
"Add a new record. After adding, update the list buffer."
(interactive)
(lexical-let ((db idm-db)
(curbuf (current-buffer)))
(idm-add-record-dialog db
(lambda (r)
(with-current-buffer curbuf
(funcall db 'add-record r)
(idm--layout-list db))))))
(defun idm-list-mode-edit-dialog ()
"Edit the selected record. After editting, update the list
buffer."
(interactive)
(idm--aif (idm--get-record-id)
(let ((record (funcall idm-db 'get it)))
(if record
(lexical-let ((db idm-db) (prev record)
(curbuf (current-buffer)))
(idm-edit-record-dialog
record
(lambda (r)
(with-current-buffer curbuf
(funcall db 'delete-record-by-name (idm-record-name prev))
(funcall db 'add-record r)
(idm--layout-list db)))))))))
;;;###autoload
(defun idm-open-list-command (&optional db)
"Load the id-password DB and open a list buffer."
(interactive)
(unless db
(setq db (idm-load-db)))
(switch-to-buffer (idm-open-list db)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Helm UI
(defun idm--helm-add-dialog (db)
"Add a new record by the helm interface."
(interactive)
(lexical-let ((db db))
(idm-add-record-dialog db
(lambda (r)
(funcall db 'add-record r)
(funcall db 'save)
(when (eq major-mode 'idm-list-mode)
(idm--layout-list db))))))
(defun idm--helm-edit-dialog (db record)
"Edit a record selected by the helm interface."
(interactive)
(lexical-let ((db db) (prev record))
(idm-edit-record-dialog
record
(lambda (r)
(funcall db 'delete-record-by-name (idm-record-name prev))
(funcall db 'add-record r)
(funcall db 'save)
(when (eq major-mode 'idm-list-mode)
(idm--layout-list db))))))
;;;###autoload
(defun idm-helm-command ()
"Helm interface for id-manager."
(interactive)
(let* ((db (idm-load-db))
(source-commands
(helm-build-sync-source "id-manager-global-command"
:name "Global Command : "
:candidates '(("Add a record" . (lambda ()
(idm--helm-add-dialog db)))
("Show all records" . (lambda ()
(idm-open-list-command db))))
:action (helm-make-actions "Execute" (lambda (i) (funcall i)))))
(souce-records
(helm-build-sync-source "id-manager-source-commands"
:name "Accounts : "
:candidates (lambda ()
(mapcar
(lambda (record)
(cons (concat
(idm-record-name record)
" (" (idm-record-account-id record) ") "
" " (idm-record-memo record))
record))
(funcall db 'get-all-records)))
:action (helm-make-actions "Copy password" (lambda (record)
(idm--copy-password-action record))
"Copy id" (lambda (record)
(idm--copy-id-action record))
"Show ID / Password" (lambda (record)
(idm--message
(concat
"ID: " (idm-record-account-id record)
" / PW: "(idm-record-password record))))
"Edit fields" (lambda (record)
(idm--helm-edit-dialog db record)))
:migemo t)))
(helm
:sources '(source-commands souce-records)
:buffer "ID-Password Management : ")))
(defalias 'id-manager 'idm-open-list-command)
(eval-after-load "helm"
'(defalias 'id-manager 'idm-helm-command))
(provide 'id-manager)
;;; id-manager.el ends here

View File

@ -0,0 +1,381 @@
;;; bbdb-identica.el ---
;;
;; Filename: bbdb-identica.el
;; Description:
;; Author: Christian
;; Maintainer:
;; Created: dom oct 2 22:15:13 2011 (-0300)
;; Version:
;; Last-Updated:
;; By:
;; Update #: 0
;; URL:
;; Keywords:
;; Compatibility:
;;
;; Features that might be required by this library:
;;
;; BBDB
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Commentary:
;;
;; This should work in BBDB V.3.x for now...
;; It is in heavy, really heavy, development.
;;
;; As far I tried, I couldn't make it work in the way proposed by BBDB.
;; I couldn't find any documentation of how to use the MUA API.
;; For now, I will use every possible command despite it is not desirable
;; for BBDB developers(I think :-S ).
;;
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Change Log:
;;
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as
;; published by the Free Software Foundation; either version 3, or
;; (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
;; General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program; see the file COPYING. If not, write to
;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
;; Floor, Boston, MA 02110-1301, USA.
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Code:
(require 'bbdb)
(require 'bbdb-com)
(require 'bbdb-mua)
(require 'identica-mode)
(require 'identica-friends)
; Identica-friends-buffer
;; Identica friends buffer must have a way to introduce people into BBDB.
;; There's need of creating a new field into a record. This field will be called "identica".
;; We'll define a ':' key for introducing a new record into BBDB or updating a record.
(defcustom bbdb/identica-update-records-p
(lambda ()
(let ((bbdb-update-records-p 'query ))
(bbdb-select-message)))
"How `bbdb-mua-update-records' processes mail addresses in Identica and Identica-friends.
Allowed values are:
nil Do nothing.
search Search for existing records.
query Update existing records or query for creating new ones.
create or t Update existing records or create new ones.
A function which returns one of the above values."
:group 'bbdb-mua-identica
:type '(choice (const :tag "do nothing" nil)
(const :tag "search for existing records"
(lambda () (let ((bbdb-update-records-p 'search))
(bbdb-select-message))))
(const :tag "query annotation of all messages"
(lambda () (let ((bbdb-update-records-p 'query))
(bbdb-select-message))))
;; (const :tag "annotate (query) only new messages"
;; (lambda ()
;; (let ((bbdb-update-records-p
;; (if (bbdb/rmail-new-flag) 'query 'search)))
;; (bbdb-select-message))))
(const :tag "annotate all messages"
(lambda () (let ((bbdb-update-records-p 'create))
(bbdb-select-message))))
(const :tag "accept messages" bbdb-accept-message)
(const :tag "ignore messages" bbdb-ignore-message)
(const :tag "select messages" bbdb-select-message)
(sexp :tag "user defined function")))
;; (defun bbdb/identica-header (header)
;; ""
;; )
; --------------------
; Insinuation
; --------------------
;; It doesn't work :-( Is still under development.
;;
;; ;;;###autoload
;; (defun bbdb-insinuate-identica ()
;; "Add every keymap and hooks necesary for using BBDB into `identica-friends-mode'.
;; You shouldn't call this in your init file, instead use `bbdb-initialize'"
;; (define-key identica-friends-mode-map ":" 'bbdb-mua-display-sender)
;; (define-key identica-friends-mode-map ";" 'bbdb-mua-edit-notes-sender)
;; )
;; ;; We have to make bbdb-mua recognice identica-friends-mode, if not it will fall-back with error.
;; (defadvice bbdb-mua (before identica-bbdb-mua ())
;; "This advice add into `bbdb-mua' the necessary for BBDB to recognice identica-friends-mode, and identica-mode."
;; (if (member major-mode '(identica-mode identica-friends-mode))
;; 'identica)
;; )
;; Activate identica-bbdb-mua advice
;; (ad-activate 'bbdb-mua)
;; (ad-deactivate 'bbdb-mua)
; ____________________
(defun bbdb-identica-friends-next-usr ()
"This function is supposed to be used as a hook to the function `identica-friends-next-user'.
Check if the actual user is in BBDB. If not, add it *without query the user*.
Remember:
Adding into the BBDB means:
1) to create a new BBDB record with the same name of the identica user name(NOT NICK!)
2) Add the nick into a new field called \"identica\"."
(setq usr (identica-friends-get-current-user))
;; Our idea is to show the user if founded...
;; Search for the *first mach* in the BBDB:
(setq record
(let ((usr-name (nth 1 usr)))
(car (bbdb-search (bbdb-records) usr-name))
)
)
;; check if exist, if not add it(or query to add it).
(if record
(progn
(bbdb-display-records (cons record '()))
(unless (bbdb-identica-check-record record usr)
;; It has to be updated!
(bbdb-identica-query-update-record record usr)
(bbdb-display-records (cons record '()))
)
)
(progn
;; No record available... query to add it..
(bbdb-identica-query-add-record record usr)
;; Show new record...
(setq record
(let ((usr-name (nth 1 usr)))
(car (bbdb-search (bbdb-records) usr-name))
)
)
(when record
(bbdb-display-records (cons record '()))
)
)
)
)
(defun bbdb-identica-query-update-record (record usr)
"Query the user if she/he wants to update the BBDB record.
If she/he answer \"yes\", update it.
If she/he answer \"no\", do nothing."
(when (bbdb-identica-prompt-yepnop "Do you want to update this record?(y/n)")
(bbdb-identica-update-record record usr)
)
)
(defun bbdb-identica-update-record (record usr)
"Update the record usr with new values:
1) Update the \"identica\" field.
2) No need to update anything else..."
(bbdb-record-set-note record 'identica (nth 0 usr))
)
(defun bbdb-identica-prompt-yepnop (prompt)
"Ask a question to the user for a yes-no answer.
Return t when user answer yes.
Return nil when user answer no."
(let (
(yepnop (read-char prompt)))
(cond
((eq ?y yepnop)
t)
((eq ?n yepnop)
nil)
(t
(message "Please, answer 'y' or 'n'.")
(bbdb-identica-prompt-yepnop prompt))
)
)
)
(defun bbdb-identica-query-add-record (record usr)
"Query the user if she/he wants to add this identica user into BBDB.
If she/he answer \"yes\", add it.
If she/he answer \"no\", don't add it of course."
(when (bbdb-identica-prompt-yepnop "Do you want to add this user and identica nick?(y/n)")
(bbdb-identica-add-record usr)
)
)
(defun bbdb-identica-add-record (usr)
"Add friend/follower into BBDB."
(bbdb-create-internal
(nth 1 usr) ;;name
nil ;; affix
nil ;; aka
nil ;; organizations
nil ;; mail
nil ;; phones
nil ;; addresses
(cons
(cons 'identica (nth 0 usr))
'()
) ;; notes
)
)
(defun bbdb-identica-check-record (record usr)
"Check if the record has the same value in the \"identica\" field and the name field.
If it is the same return t.
If it is different return nil.
If the \"identica\" field does not exists return nil(it means it has different value).
"
;; Get if exists the field
(if (and
record
usr)
(string=
(bbdb-record-note record 'identica)
(car usr)
)
nil
)
)
(defun bbdb-identica-ask-for-save ()
"This is intended when the user wants to quit identica.
As soon he/she wants to quit, is necessary to ask if she/he wants to update BBDB database."
(bbdb-save t t)
)
(eval-and-compile
(add-hook 'identica-friends-good-bye-hooks 'bbdb-identica-ask-for-save)
(add-hook 'identica-friends-next-user-hooks 'bbdb-identica-friends-next-usr)
(add-hook 'identica-friends-prev-user-hooks 'bbdb-identica-friends-next-usr)
)
(defun bbdb-identica-next-usr ()
"Go to next identica user in the identica buffer, find its BBDB record and show it if exists."
(interactive)
(save-excursion
(goto-char (bbdb-identica-find-next-usr-pos))
;; Get user nick
(save-excursion
(search-forward-regexp "[^[:blank:]]+" nil t)
(setq usrnick (match-string-no-properties 0))
)
;; Remove the '@'
(when (string= "@" (substring usrnick 0 1))
;;Has a '@', take it out.
(setq usrnick (substring usrnick 0 1))
)
;; Remove the ','
(when (string= "," (substring usrnick -1))
(setq usrnick (substring usrnick 0 -1))
)
;; Find usrnick in the BBDB
(bbdb-search-notes "identica" usrnick)
)
)
(defun bbdb-identica-find-next-usr-1-pos ()
"Find the next identica nick starting with '@'."
(with-current-buffer identica-buffer
(save-excursion
(search-forward-regexp "@[^[:blank:]]*" nil t)
(match-beginning 0)
)
)
)
(defun bbdb-identica-find-next-usr-2-pos ()
"Find the next identica nick as the first element that appear of a status. For example:
_
rms, 10:26 septiembre 26, 2011:
hola, esto es un estado // from web [algúnlado] in reply to someone
in this case the return value is 'rms'."
(with-current-buffer identica-buffer
(identica-get-next-username-face-pos (point))
)
)
(defun bbdb-identica-find-next-usr-pos ()
"Return the position of the first identica nick after the current point, no matters if it is a '@user' form or just
the name of the status's remitent."
(let ((usr1 (bbdb-identica-find-next-usr-1-pos))
(usr2 (bbdb-identica-find-next-usr-2-pos))
)
;; Look wich one is first, and return that one
(if (< usr1 usr2)
usr1
usr2
)
)
)
(defun bbdb-identica-down-key ()
"Go to down, and then show the next possible nick BBDB record."
(interactive)
(next-line)
(bbdb-identica-next-usr)
)
(defun bbdb-identica-up-key ()
"Go to up and then show the next possible nick BBDB record."
(interactive)
(previous-line)
(bbdb-identica-next-usr)
)
;; I see that this could be a bit destructive.
;; If down or up key are setted to other functions, this will make identica to ignore them!
(eval-and-compile
;; If you want, at every position, to search for BBDB uncomment this:
;;(define-key identica-mode-map [down] 'bbdb-identica-down-key)
;;(define-key identica-mode-map [up] 'bbdb-identica-up-key)
)
;; This is better: at each j and k key(identica-goto-next-status) search for its BBDB record.
(defadvice identica-goto-next-status (after bbdb-identica-next-status)
"Search for BBDB record of the next nearest nick."
(save-excursion
(backward-char)
(bbdb-identica-next-usr)
)
)
(defadvice identica-goto-previous-status (after bbdb-identica-next-status)
"Search for BBDB record of the next nearest nick."
(save-excursion
(backward-char)
(bbdb-identica-next-usr)
)
)
(eval-and-compile
(ad-activate 'identica-goto-next-status)
(ad-activate 'identica-goto-previous-status)
)
(provide 'bbdb-identica)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; bbdb-identica.el ends here

View File

@ -0,0 +1,19 @@
This is the file .../info/dir, which contains the
topmost node of the Info hierarchy, called (dir)Top.
The first time you invoke Info you start off looking at this node.

File: dir, Node: Top This is the top of the INFO tree
This (the Directory node) gives a menu of major topics.
Typing "q" exits, "?" lists all Info commands, "d" returns here,
"h" gives a primer for first-timers,
"mEmacs<Return>" visits the Emacs manual, etc.
In Emacs, you can click mouse button 2 on a menu item or cross reference
to select it.
* Menu:
Emacs
* Identica mode: (identica-mode).
Emacs mode for microblogging services.

View File

@ -0,0 +1,430 @@
This is fdl.info, produced by makeinfo version 5.2 from fdl.texi.
Version 1.2, November 2002
Copyright (C) 2000,2001,2002 Free Software Foundation, Inc.
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
0. PREAMBLE
The purpose of this License is to make a manual, textbook, or other
functional and useful document "free" in the sense of freedom: to
assure everyone the effective freedom to copy and redistribute it,
with or without modifying it, either commercially or
noncommercially. Secondarily, this License preserves for the
author and publisher a way to get credit for their work, while not
being considered responsible for modifications made by others.
This License is a kind of "copyleft", which means that derivative
works of the document must themselves be free in the same sense.
It complements the GNU General Public License, which is a copyleft
license designed for free software.
We have designed this License in order to use it for manuals for
free software, because free software needs free documentation: a
free program should come with manuals providing the same freedoms
that the software does. But this License is not limited to
software manuals; it can be used for any textual work, regardless
of subject matter or whether it is published as a printed book. We
recommend this License principally for works whose purpose is
instruction or reference.
1. APPLICABILITY AND DEFINITIONS
This License applies to any manual or other work, in any medium,
that contains a notice placed by the copyright holder saying it can
be distributed under the terms of this License. Such a notice
grants a world-wide, royalty-free license, unlimited in duration,
to use that work under the conditions stated herein. The
"Document", below, refers to any such manual or work. Any member
of the public is a licensee, and is addressed as "you". You accept
the license if you copy, modify or distribute the work in a way
requiring permission under copyright law.
A "Modified Version" of the Document means any work containing the
Document or a portion of it, either copied verbatim, or with
modifications and/or translated into another language.
A "Secondary Section" is a named appendix or a front-matter section
of the Document that deals exclusively with the relationship of the
publishers or authors of the Document to the Document's overall
subject (or to related matters) and contains nothing that could
fall directly within that overall subject. (Thus, if the Document
is in part a textbook of mathematics, a Secondary Section may not
explain any mathematics.) The relationship could be a matter of
historical connection with the subject or with related matters, or
of legal, commercial, philosophical, ethical or political position
regarding them.
The "Invariant Sections" are certain Secondary Sections whose
titles are designated, as being those of Invariant Sections, in the
notice that says that the Document is released under this License.
If a section does not fit the above definition of Secondary then it
is not allowed to be designated as Invariant. The Document may
contain zero Invariant Sections. If the Document does not identify
any Invariant Sections then there are none.
The "Cover Texts" are certain short passages of text that are
listed, as Front-Cover Texts or Back-Cover Texts, in the notice
that says that the Document is released under this License. A
Front-Cover Text may be at most 5 words, and a Back-Cover Text may
be at most 25 words.
A "Transparent" copy of the Document means a machine-readable copy,
represented in a format whose specification is available to the
general public, that is suitable for revising the document
straightforwardly with generic text editors or (for images composed
of pixels) generic paint programs or (for drawings) some widely
available drawing editor, and that is suitable for input to text
formatters or for automatic translation to a variety of formats
suitable for input to text formatters. A copy made in an otherwise
Transparent file format whose markup, or absence of markup, has
been arranged to thwart or discourage subsequent modification by
readers is not Transparent. An image format is not Transparent if
used for any substantial amount of text. A copy that is not
"Transparent" is called "Opaque".
Examples of suitable formats for Transparent copies include plain
ASCII without markup, Texinfo input format, LaTeX input format,
SGML or XML using a publicly available DTD, and standard-conforming
simple HTML, PostScript or PDF designed for human modification.
Examples of transparent image formats include PNG, XCF and JPG.
Opaque formats include proprietary formats that can be read and
edited only by proprietary word processors, SGML or XML for which
the DTD and/or processing tools are not generally available, and
the machine-generated HTML, PostScript or PDF produced by some word
processors for output purposes only.
The "Title Page" means, for a printed book, the title page itself,
plus such following pages as are needed to hold, legibly, the
material this License requires to appear in the title page. For
works in formats which do not have any title page as such, "Title
Page" means the text near the most prominent appearance of the
work's title, preceding the beginning of the body of the text.
A section "Entitled XYZ" means a named subunit of the Document
whose title either is precisely XYZ or contains XYZ in parentheses
following text that translates XYZ in another language. (Here XYZ
stands for a specific section name mentioned below, such as
"Acknowledgements", "Dedications", "Endorsements", or "History".)
To "Preserve the Title" of such a section when you modify the
Document means that it remains a section "Entitled XYZ" according
to this definition.
The Document may include Warranty Disclaimers next to the notice
which states that this License applies to the Document. These
Warranty Disclaimers are considered to be included by reference in
this License, but only as regards disclaiming warranties: any other
implication that these Warranty Disclaimers may have is void and
has no effect on the meaning of this License.
2. VERBATIM COPYING
You may copy and distribute the Document in any medium, either
commercially or noncommercially, provided that this License, the
copyright notices, and the license notice saying this License
applies to the Document are reproduced in all copies, and that you
add no other conditions whatsoever to those of this License. You
may not use technical measures to obstruct or control the reading
or further copying of the copies you make or distribute. However,
you may accept compensation in exchange for copies. If you
distribute a large enough number of copies you must also follow the
conditions in section 3.
You may also lend copies, under the same conditions stated above,
and you may publicly display copies.
3. COPYING IN QUANTITY
If you publish printed copies (or copies in media that commonly
have printed covers) of the Document, numbering more than 100, and
the Document's license notice requires Cover Texts, you must
enclose the copies in covers that carry, clearly and legibly, all
these Cover Texts: Front-Cover Texts on the front cover, and
Back-Cover Texts on the back cover. Both covers must also clearly
and legibly identify you as the publisher of these copies. The
front cover must present the full title with all words of the title
equally prominent and visible. You may add other material on the
covers in addition. Copying with changes limited to the covers, as
long as they preserve the title of the Document and satisfy these
conditions, can be treated as verbatim copying in other respects.
If the required texts for either cover are too voluminous to fit
legibly, you should put the first ones listed (as many as fit
reasonably) on the actual cover, and continue the rest onto
adjacent pages.
If you publish or distribute Opaque copies of the Document
numbering more than 100, you must either include a machine-readable
Transparent copy along with each Opaque copy, or state in or with
each Opaque copy a computer-network location from which the general
network-using public has access to download using public-standard
network protocols a complete Transparent copy of the Document, free
of added material. If you use the latter option, you must take
reasonably prudent steps, when you begin distribution of Opaque
copies in quantity, to ensure that this Transparent copy will
remain thus accessible at the stated location until at least one
year after the last time you distribute an Opaque copy (directly or
through your agents or retailers) of that edition to the public.
It is requested, but not required, that you contact the authors of
the Document well before redistributing any large number of copies,
to give them a chance to provide you with an updated version of the
Document.
4. MODIFICATIONS
You may copy and distribute a Modified Version of the Document
under the conditions of sections 2 and 3 above, provided that you
release the Modified Version under precisely this License, with the
Modified Version filling the role of the Document, thus licensing
distribution and modification of the Modified Version to whoever
possesses a copy of it. In addition, you must do these things in
the Modified Version:
A. Use in the Title Page (and on the covers, if any) a title
distinct from that of the Document, and from those of previous
versions (which should, if there were any, be listed in the
History section of the Document). You may use the same title
as a previous version if the original publisher of that
version gives permission.
B. List on the Title Page, as authors, one or more persons or
entities responsible for authorship of the modifications in
the Modified Version, together with at least five of the
principal authors of the Document (all of its principal
authors, if it has fewer than five), unless they release you
from this requirement.
C. State on the Title page the name of the publisher of the
Modified Version, as the publisher.
D. Preserve all the copyright notices of the Document.
E. Add an appropriate copyright notice for your modifications
adjacent to the other copyright notices.
F. Include, immediately after the copyright notices, a license
notice giving the public permission to use the Modified
Version under the terms of this License, in the form shown in
the Addendum below.
G. Preserve in that license notice the full lists of Invariant
Sections and required Cover Texts given in the Document's
license notice.
H. Include an unaltered copy of this License.
I. Preserve the section Entitled "History", Preserve its Title,
and add to it an item stating at least the title, year, new
authors, and publisher of the Modified Version as given on the
Title Page. If there is no section Entitled "History" in the
Document, create one stating the title, year, authors, and
publisher of the Document as given on its Title Page, then add
an item describing the Modified Version as stated in the
previous sentence.
J. Preserve the network location, if any, given in the Document
for public access to a Transparent copy of the Document, and
likewise the network locations given in the Document for
previous versions it was based on. These may be placed in the
"History" section. You may omit a network location for a work
that was published at least four years before the Document
itself, or if the original publisher of the version it refers
to gives permission.
K. For any section Entitled "Acknowledgements" or "Dedications",
Preserve the Title of the section, and preserve in the section
all the substance and tone of each of the contributor
acknowledgements and/or dedications given therein.
L. Preserve all the Invariant Sections of the Document, unaltered
in their text and in their titles. Section numbers or the
equivalent are not considered part of the section titles.
M. Delete any section Entitled "Endorsements". Such a section
may not be included in the Modified Version.
N. Do not retitle any existing section to be Entitled
"Endorsements" or to conflict in title with any Invariant
Section.
O. Preserve any Warranty Disclaimers.
If the Modified Version includes new front-matter sections or
appendices that qualify as Secondary Sections and contain no
material copied from the Document, you may at your option designate
some or all of these sections as invariant. To do this, add their
titles to the list of Invariant Sections in the Modified Version's
license notice. These titles must be distinct from any other
section titles.
You may add a section Entitled "Endorsements", provided it contains
nothing but endorsements of your Modified Version by various
parties--for example, statements of peer review or that the text
has been approved by an organization as the authoritative
definition of a standard.
You may add a passage of up to five words as a Front-Cover Text,
and a passage of up to 25 words as a Back-Cover Text, to the end of
the list of Cover Texts in the Modified Version. Only one passage
of Front-Cover Text and one of Back-Cover Text may be added by (or
through arrangements made by) any one entity. If the Document
already includes a cover text for the same cover, previously added
by you or by arrangement made by the same entity you are acting on
behalf of, you may not add another; but you may replace the old
one, on explicit permission from the previous publisher that added
the old one.
The author(s) and publisher(s) of the Document do not by this
License give permission to use their names for publicity for or to
assert or imply endorsement of any Modified Version.
5. COMBINING DOCUMENTS
You may combine the Document with other documents released under
this License, under the terms defined in section 4 above for
modified versions, provided that you include in the combination all
of the Invariant Sections of all of the original documents,
unmodified, and list them all as Invariant Sections of your
combined work in its license notice, and that you preserve all
their Warranty Disclaimers.
The combined work need only contain one copy of this License, and
multiple identical Invariant Sections may be replaced with a single
copy. If there are multiple Invariant Sections with the same name
but different contents, make the title of each such section unique
by adding at the end of it, in parentheses, the name of the
original author or publisher of that section if known, or else a
unique number. Make the same adjustment to the section titles in
the list of Invariant Sections in the license notice of the
combined work.
In the combination, you must combine any sections Entitled
"History" in the various original documents, forming one section
Entitled "History"; likewise combine any sections Entitled
"Acknowledgements", and any sections Entitled "Dedications". You
must delete all sections Entitled "Endorsements."
6. COLLECTIONS OF DOCUMENTS
You may make a collection consisting of the Document and other
documents released under this License, and replace the individual
copies of this License in the various documents with a single copy
that is included in the collection, provided that you follow the
rules of this License for verbatim copying of each of the documents
in all other respects.
You may extract a single document from such a collection, and
distribute it individually under this License, provided you insert
a copy of this License into the extracted document, and follow this
License in all other respects regarding verbatim copying of that
document.
7. AGGREGATION WITH INDEPENDENT WORKS
A compilation of the Document or its derivatives with other
separate and independent documents or works, in or on a volume of a
storage or distribution medium, is called an "aggregate" if the
copyright resulting from the compilation is not used to limit the
legal rights of the compilation's users beyond what the individual
works permit. When the Document is included in an aggregate, this
License does not apply to the other works in the aggregate which
are not themselves derivative works of the Document.
If the Cover Text requirement of section 3 is applicable to these
copies of the Document, then if the Document is less than one half
of the entire aggregate, the Document's Cover Texts may be placed
on covers that bracket the Document within the aggregate, or the
electronic equivalent of covers if the Document is in electronic
form. Otherwise they must appear on printed covers that bracket
the whole aggregate.
8. TRANSLATION
Translation is considered a kind of modification, so you may
distribute translations of the Document under the terms of section
4. Replacing Invariant Sections with translations requires special
permission from their copyright holders, but you may include
translations of some or all Invariant Sections in addition to the
original versions of these Invariant Sections. You may include a
translation of this License, and all the license notices in the
Document, and any Warranty Disclaimers, provided that you also
include the original English version of this License and the
original versions of those notices and disclaimers. In case of a
disagreement between the translation and the original version of
this License or a notice or disclaimer, the original version will
prevail.
If a section in the Document is Entitled "Acknowledgements",
"Dedications", or "History", the requirement (section 4) to
Preserve its Title (section 1) will typically require changing the
actual title.
9. TERMINATION
You may not copy, modify, sublicense, or distribute the Document
except as expressly provided for under this License. Any other
attempt to copy, modify, sublicense or distribute the Document is
void, and will automatically terminate your rights under this
License. However, parties who have received copies, or rights,
from you under this License will not have their licenses terminated
so long as such parties remain in full compliance.
10. FUTURE REVISIONS OF THIS LICENSE
The Free Software Foundation may publish new, revised versions of
the GNU Free Documentation License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns. See
<http://www.gnu.org/copyleft/>.
Each version of the License is given a distinguishing version
number. If the Document specifies that a particular numbered
version of this License "or any later version" applies to it, you
have the option of following the terms and conditions either of
that specified version or of any later version that has been
published (not as a draft) by the Free Software Foundation. If the
Document does not specify a version number of this License, you may
choose any version ever published (not as a draft) by the Free
Software Foundation.
ADDENDUM: How to use this License for your documents
====================================================
To use this License in a document you have written, include a copy of
the License in the document and put the following copyright and license
notices just after the title page:
Copyright (C) YEAR YOUR NAME.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.2
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
Texts. A copy of the license is included in the section entitled ``GNU
Free Documentation License''.
If you have Invariant Sections, Front-Cover Texts and Back-Cover
Texts, replace the "with...Texts." line with this:
with the Invariant Sections being LIST THEIR TITLES, with
the Front-Cover Texts being LIST, and with the Back-Cover Texts
being LIST.
If you have Invariant Sections without Cover Texts, or some other
combination of the three, merge those two alternatives to suit the
situation.
If your document contains nontrivial examples of program code, we
recommend releasing these examples in parallel under your choice of free
software license, such as the GNU General Public License, to permit
their use in free software.

Tag Table:

End Tag Table

View File

@ -0,0 +1,793 @@
;;; identica-friends.el ---
;;
;; Filename: identica-friends.el
;; Description: A library that provides some functions to look who are your friends in your identi.ca account.
;; Author: Christian Giménez
;; Maintainer:
;; Created: dom sep 25 17:58:40 2011 (-0300)
;; Version:
;; Last-Updated:
;; By:
;; Update #: 0
;; URL:
;; Keywords:
;; Compatibility:
;;
;; Features that might be required by this library:
;;
;; None
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Commentary:
;;
;; Use M-x identica first, if you are not connected, this library
;; will not work.
;; You can check who are your friends on Identi.ca using the function
;; M-x identica-show-friends
;; If you want to check who are following you, type:
;; M-x identica-show-followers
;;
;; I divided the code into sections. This sections are tabbed asside
;; and commented by an only one ";". Also are overlined and underlined
;; so, they are very visible.
;;
;; Convention:
;; All functions and variables in this modules has the prefix
;; "identica-friends" so you can identify easyly.
;; The main functions may not have this prefix so users don't get
;; confused.
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Change Log:
;;
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as
;; published by the Free Software Foundation; either version 3, or
;; (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
;; General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program; see the file COPYING. If not, write to
;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
;; Floor, Boston, MA 02110-1301, USA.
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Code:
(require 'xml)
(require 'identica-mode)
; ____________________
;
; Variables
; ____________________
(defvar identica-friends-buffer nil
"Friend's Buffer. Internal use of identica-friends.el."
)
(defvar identica-friends-buffer-name "*identica-friends*"
"Friends buffer's name. Changing this variable will effect after you
recall identica-friends functions.
Be aware of no function or actual buffers exists. Reboot all identica-friends functions."
)
(defvar identica-friends-buffer-type nil
"If the buffer contains a list of users, the this is setted into 'users.
If the buffer contains a list of groups, this is setted into 'groups.
Nil means, no buffer or just the programmer forgot to set it! :-S ."
)
; ----
; Hooks Variables
; ----
(defcustom identica-friends-good-bye-hooks
'nil
"These functions are called as soon as the `identica-friends-good-bye' functions finnish."
:type '(hook)
)
(defcustom identica-friends-mode-hooks
'nil
"These functions are called as soon as the `identica-friends-mode' functions finnish."
:type '(hook)
)
(defcustom identica-friends-show-friends-hooks
'nil
"These functions are called as soon as the `identica-show-friends' functions finnish."
:type '(hook)
)
(defcustom identica-friends-show-followers-hooks
'nil
"These functions are called as soon as the `identica-show-followers' functions finnish."
:type '(hook)
)
(defcustom identica-friends-next-user-hooks
'nil
"These functions are called as soon as the `identica-friends-next-user' functions finnish."
:type '(hook)
)
(defcustom identica-friends-prev-user-hooks
'nil
"These functions are called as soon as the `identica-friends-prev-user' functions finnish."
:type '(hook)
)
; ____________________
;
; Faces and font-lock
; ____________________
(defface identica-friends-mode-id
'(
; If there's dark background...
(((class color) (background dark))
:foreground "yellow"
)
; If there's light background...
(((class color) (background light))
:foreground "red"
)
(t :background "white"
:foreground "blue")
)
""
)
(defface identica-friends-mode-bar
'(
; If there's dark background...
(((class color) (background dark))
:bold t
)
; If there's light background...
(((class color) (background light))
:bold t
)
(t :background "white"
:foreground "blue"
:bold t)
)
""
)
(defvar identica-friends-mode-font-lock
'(
;; font-lock-keywords
(
("^Id: .*$" . 'identica-friends-mode-id)
("^Nick: .*$" . 'identica-username-face)
("^--------------------$" . 'identica-friends-mode-bar)
)
;; Otros...
)
;;
"Font lock for `identica-friends--mode'"
)
; ____________________
;
; Keymaps
; ____________________
;; Keymaps calls functions from the "Interactive API Commands" sections(see below).
(defvar identica-friends-mode-map
(let ((map (make-sparse-keymap)))
(define-key map "q" 'identica-friends-good-bye)
(define-key map "n" 'identica-friends-next-user)
(define-key map "p" 'identica-friends-prev-user)
(define-key map [down] 'identica-friends-next-user)
(define-key map [up] 'identica-friends-prev-user)
(define-key map [left] 'identica-friends-prev-user)
(define-key map [right] 'identica-friends-next-user)
(define-key map [return] 'identica-friends-goto-timeline-at-point)
map)
"Keymap for `identica-friends-mode'."
)
; ____________________
;
; Major Mode
; ____________________
(define-derived-mode identica-friends-mode nil "Identica-friends-mode"
"Major mode for identica-friends buffer.
Use `identica-show-friends' to call this buffer."
;; font lock para ej-mode
(set (make-local-variable 'font-lock-defaults)
identica-friends-mode-font-lock)
(set (make-local-variable 'buffer-read-only) t)
(make-local-variable 'inhibit-read-only)
(run-hooks 'identica-friends-mode-hooks)
)
; ________________________________________
;
; Interactive API Commands
; ________________________________________
(defun identica-friends-good-bye ()
"Bury the *identica-friends* buffer"
(interactive)
(with-current-buffer identica-friends-buffer
(bury-buffer)
(run-hooks 'identica-friends-good-bye-hooks)
)
)
(defun identica-friends-next-user ()
"Put the pointer in the next friend or follower in the identica-friend buffer."
(interactive)
(with-current-buffer identica-friends-buffer
(goto-char (identica-friends-find-next-user-position))
)
(run-hooks 'identica-friends-next-user-hooks)
)
(defun identica-friends-prev-user ()
"Put the pointer in the previous friend or follower in the identica-friend buffer."
(interactive)
(with-current-buffer identica-friends-buffer
(goto-char (identica-friends-find-prev-user-position))
)
(run-hooks 'identica-friends-prev-user-hooks)
)
(defun identica-friends-goto-timeline-at-point ()
"Check whenever we are in user-list or group-list. If we are listing user, call `identica-friends-goto-user-timeline-at-point',
if not call `identica-friends-goto-group-timeline-at-point'."
(interactive)
(cond
((eq identica-friends-buffer-type 'users)
(identica-friends-goto-user-timeline-at-point)
)
((eq identica-friends-buffer-type 'groups)
(identica-friends-goto-group-timeline-at-point)
)
)
)
(defun identica-friends-goto-user-timeline-at-point ()
"Search for the username and go to his timeline."
(interactive)
(let ((username (identica-friends-find-username))
)
(identica-user-timeline username)
(switch-to-buffer identica-buffer)
)
)
(defun identica-friends-goto-group-timeline-at-point ()
"Search for the group name and go to his timeline."
(interactive)
;; Look that `identica-friends-find-username' can be used for getting anything that starts with the "Nick: " string,
;; so is usefull here as well!
(let ((groupname (identica-friends-find-username))
)
(identica-group-timeline groupname)
(switch-to-buffer identica-buffer)
)
)
;
; Main function:
; Followers Commands
;
(defun identica-show-followers()
(interactive)
(setq identica-friends-buffer-type 'users)
(identica-http-get (sn-account-server sn-current-account)
(sn-account-auth-mode sn-current-account)
"statuses" "followers" nil 'identica-friends-show-user-sentinel '("follower"))
(run-hooks 'identica-friends-show-followers-hooks)
)
;
; Main function:
; Friends Commands
;
(defun identica-show-friends ()
(interactive)
; (setq identica-method-class "statuses")
; (setq identica-method "friends")
; (identica-http-get identica-method-class identica-method identica-show-friend-sentinel)
(setq identica-friends-buffer-type 'users)
(identica-http-get (sn-account-server sn-current-account) ;; server
(sn-account-auth-mode sn-current-account);; auth-mode
"statuses" "friends" nil 'identica-friends-show-user-sentinel '("friend"))
(run-hooks 'identica-friends-show-friends-hooks)
)
(defun identica-show-groups ()
(interactive)
;; (setq identica-method-class "statuses")
;; (setq identica-method "friends")
;; (identica-http-get identica-method-class identica-method identica-show-friend-sentinel)
(setq identica-friends-buffer-type 'groups)
(identica-http-get (sn-account-server sn-current-account) ;; server
(sn-account-auth-mode sn-current-account);; auth-mode
"statusnet" "groups/list" nil 'identica-friends-show-user-sentinel '("group"))
;;(run-hooks 'identica-friends-show-groups-hooks)
)
; ____________________
;
; Auxiliary Functions
; ____________________
(defun identica-friends-find-username ()
"Find the username in the nearby at current position.
I suppose that the cursor is on the nickname and not anywhere."
(save-excursion
(if (search-forward-regexp "Nick: \\(.*\\)" nil t)
(match-string-no-properties 1)
nil
)
)
)
(defun identica-friends-buffer ()
"Show a new buffer with all the friends. "
(setq identica-friends-buffer (get-buffer-create identica-friends-buffer-name))
(switch-to-buffer identica-friends-buffer)
(identica-friends-mode)
)
(defun identica-friends-get-current-user ()
"Return the current user(friend or follower) that we are pointing now in the *identica-buffer*.
This will be returned as a list wich components are in these order:
(NICK NAME DESCRIPTION LOCATION)"
(setq usr '())
(save-excursion
;; Position at the beginning of the user.
(search-backward-regexp "^--------------------$" nil t)
(goto-char (match-beginning 0))
(setq usr (cons (identica-friends-get-location) usr))
(setq usr (cons (identica-friends-get-desc) usr))
(setq usr (cons (identica-friends-get-name) usr))
(setq usr (cons (identica-friends-get-nick) usr))
)
usr
)
(defun identica-friends-get-nick ()
"Get the *next* user(friend or follower) nick.
If there are no user, return nil."
(with-current-buffer identica-friends-buffer
(save-excursion
(search-forward-regexp "Nick: \\(.*\\)$" nil t)
(match-string-no-properties 1)
)
)
)
(defun identica-friends-get-name ()
"Get the *next* user(friend or follower) nick.
If there are no user, return nil."
(with-current-buffer identica-friends-buffer
(save-excursion
(search-forward-regexp "Name: \\(.*\\)$" nil t)
(match-string-no-properties 1)
)
)
)
(defun identica-friends-get-desc ()
"Get the current user(friend or follower) nick.
If there are no user, return nil."
(with-current-buffer identica-friends-buffer
(save-excursion
(search-forward-regexp "Description: \\(.*\\)$" nil t)
(match-string-no-properties 1)
)
)
)
(defun identica-friends-get-location ()
"Get the current user(friend or follower) nick.
If there are no user, return nil."
(with-current-buffer identica-friends-buffer
(save-excursion
(search-forward-regexp "Location: \\(.*\\)$" nil t)
(match-string-no-properties 1)
)
)
)
(defun identica-friends-show-user-sentinel
(&optional status method-class method parameters type-of-user)
"Sentinel executed after recieving all the information from identi.ca.
This sentinel needs to know if the TYPE-OF-USER(or type of list) is one of these:
- \"friend\"
- \"follower\"
- \"group\"
First, its parse the XML file recieved by identi.ca. While parsing, it show the user data into a buffer.
"
;; cnngimenez: This I used for debug HTTP
(identica-friends-copiar-http-buffer)
;; Search for the begining of the xml...
(goto-char (point-min))
(search-forward "<?xml")
(setq start-xml (match-beginning 0))
;; Parse xml into a list
(setq lst-xml (xml-parse-region start-xml (point-max)))
;; Change buffer...
(identica-friends-buffer)
;; Find elements on that list and write it
(identica-friends-parse-xml-user-lists type-of-user lst-xml)
(goto-char (point-min))
)
(defun identica-friends-parse-xml-user-lists (type-of-user xml-lst)
"Parse the xml-lst list and, after that, write every user into the current buffer.
The way it is parsed depends on the type-of-user we are talking about:
- \"friend\"
- \"follower\"
- \"group\"
"
;; Get first element
(setq xml-lst (car xml-lst))
;; ignore the word 'users' and the next element... remove enter.
(setq xml-lst (nthcdr 3 xml-lst))
;; Erase friends-buffer
(with-current-buffer identica-friends-buffer-name
(let ((inhibit-read-only t))
(delete-region (point-min) (point-max))
)
)
;; for each user in the xml list, parse it, and write it...
(dolist (usr xml-lst)
(unless (stringp usr)
(cond ((string= type-of-user "friend")
(identica-friends-write-user
(identica-friends-get-friend-data usr))) ;; Is a friend, parse xml as a friends.xml
((string= type-of-user "follower")
(identica-friends-write-user
(identica-friends-get-follower-data usr)));; is a follower, parse as followers.xml
((string= type-of-user "group")
(identica-friends-write-group
(identica-friends-get-group-data usr)))
)
)
)
)
(defun identica-friends-write-user (usr-data)
"Write an user taking the info from a list.
The list must be of the form given by the functions `identica-friends-get-friend-data'
or `identica-friends-get-follower-data':
(id . name . screen_name . location . description )
"
(let ((inhibit-read-only t))
(insert-and-inherit "\nNick: " (decode-coding-string (nth 2 usr-data) 'utf-8))
(insert-and-inherit "\nName: " (decode-coding-string (nth 1 usr-data) 'utf-8))
(insert-and-inherit "\nDescription: " (decode-coding-string (nth 4 usr-data) 'utf-8))
(insert-and-inherit "\nLocation: " (decode-coding-string (nth 3 usr-data) 'utf-8))
(insert-and-inherit "\n--------------------\n")
)
)
(defun identica-friends-write-group (group-data)
"Write a group taking the info from a list.
The list must be of the form given by the functions `identica-friends-get-group-data':
(id url nickname fullname membership blocked member_count logo homepage description location modified)"
(let ((inhibit-read-only t))
(insert-and-inherit "\nNick: " (decode-coding-string (nth 2 group-data) 'utf-8))
(insert-and-inherit "\nName: " (decode-coding-string (nth 3 group-data) 'utf-8))
(insert-and-inherit "\nURL: " (decode-coding-string (nth 1 group-data) 'utf-8))
(insert-and-inherit "\nDescription: " (decode-coding-string (nth 9 group-data) 'utf-8))
(insert-and-inherit "\nLocation: " (decode-coding-string (nth 10 group-data) 'utf-8))
(insert-and-inherit "\nHomepage: " (decode-coding-string (nth 8 group-data) 'utf-8))
(insert-and-inherit "\n--------------------\n")
)
)
;; *****
;; ** Comment about `identica-friends-get-follower-data' and `identica-friends-get-friend-data':
;;
;; These parsers must be changed to a most suitable way of finding the members.
;; Maybe using the "member" function or any simmilar makes a more reliable way of finding the attributes
;; than going to the nth element of the list.
;;
;; This is because if we change the structure of the XML, or just alternate some items(for example: instead
;; using the description before the location, in the future the description comes after the location) this
;; functions won't work properly. Also, they aren't readable and easy to change.
;;
;; *****
(defun identica-friends-get-follower-data (usr-lst)
"Parse the list and make a more easy-to-read list. The final list will have the following form suitable
for writing in a buffer with the function `identica-friends-write-user'.
(id . name . screen_name . location . description )."
(setq lst '())
;; Put the desription
(push
(nth 2 (nth 11 usr-lst))
lst
)
;; Put the location
(push
(nth 2 (nth 9 usr-lst))
lst
)
;; Put the screen-name
(push
(nth 2 (nth 7 usr-lst))
lst)
;; Put the name
(push
(nth 2 (nth 5 usr-lst))
lst)
;; Put the id
(push
(nth 2 (nth 3 usr-lst))
lst)
;; Replace nils into strings...
(replace-nils lst "")
)
(defun identica-friends-get-friend-data (usr-lst)
"Parse the list and make a list more easy to read. The list has the following form:
(id . name . screen_name . location . description ).
This form is suitable for the function `identica-friends-write-user'.
"
(setq lst '())
;; Put the desription
(push
(nth 2 (nth 11 usr-lst))
lst
)
;; Put the location
(push
(nth 2 (nth 9 usr-lst))
lst
)
;; Put the screen name
(push
(nth 2 (nth 7 usr-lst))
lst
)
;; Put the name
(push
(nth 2 (nth 5 usr-lst))
lst
)
;; Put the id
(push
(nth 2 (nth 3 usr-lst))
lst
)
;; Replace nils into strings...
(replace-nils lst "")
)
(defun identica-friends-get-group-data (usr-lst)
"Parse the list and make a more easy-to-read list. The final list will have the following form suitable
for writing in a buffer with the function `identica-friends-write-user'.
(id url nickname fullname membership blocked member_count logo homepage description location modified)."
(setq lst '())
;; Put the id
(push
(nth 2 (nth 3 usr-lst))
lst
)
;; Put the url
(push
(nth 2 (nth 5 usr-lst))
lst
)
;; Put the nickname
(push
(nth 2 (nth 7 usr-lst))
lst)
;; Put the fullname
(push
(nth 2 (nth 9 usr-lst))
lst)
;; Put the membership
(push
(nth 2 (nth 11 usr-lst))
lst)
;; Put the blocked
(push
(nth 2 (nth 13 usr-lst))
lst)
;; Put the member-count
(push
(nth 2 (nth 15 usr-lst))
lst)
;; Put the logo(original logo!)
(push
(nth 2 (nth 17 usr-lst))
lst)
;; Put the homepage
(push
(nth 2 (nth 25 usr-lst))
lst)
;; Put the description
(push
(nth 2 (nth 27 usr-lst))
lst)
;; Put the location
(push
(nth 2 (nth 29 usr-lst))
lst)
;; Put the modified
(push
(nth 2 (nth 33 usr-lst))
lst)
(setq lst (reverse lst))
;; Replace nils into strings...
(replace-nils lst "")
)
(defun identica-friends-find-next-user-position ()
"Find the position in the *identica-friend-buffer* of the next user. If there are no next user(we are at the end of the list)
return the first one.
This function return nil when there are any friend in the buffer."
(with-current-buffer identica-friends-buffer
;; We have to put one char forward so, we cannot detect the actual "Nick: "
(forward-char 1)
(if (search-forward-regexp "Nick: " nil t)
(match-beginning 0)
(progn
;; Not found! Maybe we are at the end?
;; Go to the beginning of the buffer and search again, if fails, this user has no friends!
(goto-char (point-min))
(if (search-forward-regexp "Nick: " nil t)
(match-beginning 0) ; Yes, he has friends... the pointer was at the end of buffer
'nil ; Wow... he has no friends!
)
)
)
)
)
(defun identica-friends-find-prev-user-position ()
"Find the position in the *identica-friend-buffer* of the previous user. If there are no previous user(we are at the begin of the list)
return the last one.
This function return nil when there are any friend in the buffer."
(with-current-buffer identica-friends-buffer
(if (search-backward-regexp "Nick: " nil t)
(match-beginning 0)
(progn
;; Not found! Maybe we are at the end?
;; Go to the beginning of the buffer and search again, if fails, this user has no friends!
(goto-char (point-max))
(if (search-backward-regexp "Nick: " nil t)
(match-beginning 0) ; Yes, he has friends... the pointer was at the end of buffer
'nil ; Wow... he has no friends!
)
)
)
)
)
; ____________________
;
; Commons Functions
; ____________________
;; Are there any function to replace anything from a list?
(defun replace-nils (lst elt)
"Replace nils with an element elt."
(unless (null lst)
(if (null (car lst))
(cons elt (replace-nils (cdr lst) elt))
(cons (car lst) (replace-nils (cdr lst) elt))
)
)
)
;
; For debugging purpose
;
(defvar identica-friends-http-debug "*identica-http*"
"Buffer to the http requests")
(defun identica-friends-copiar-http-buffer ()
"Copia el buffer http a otro nuevo para ver el resultado de la comunicación."
(with-current-buffer identica-http-buffer
(setq str (buffer-string))
)
(with-current-buffer (get-buffer-create identica-friends-http-debug)
(delete-region (point-min) (point-max))
(insert str)
)
)
(provide 'identica-friends)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; friends.el ends here

View File

@ -0,0 +1,27 @@
;;; identica-mode-autoloads.el --- automatically extracted autoloads
;;
;;; Code:
(add-to-list 'load-path (or (file-name-directory #$) (car load-path)))
;;;### (autoloads nil "identica-mode" "identica-mode.el" (22501 5552
;;;;;; 533207 195000))
;;; Generated autoloads from identica-mode.el
(autoload 'identica "identica-mode" "\
Start identica-mode.
\(fn)" t nil)
;;;***
;;;### (autoloads nil nil ("bbdb-identica.el" "identica-friends.el"
;;;;;; "identica-mode-pkg.el") (22501 5552 560240 68000))
;;;***
;; Local Variables:
;; version-control: never
;; no-byte-compile: t
;; no-update-autoloads: t
;; End:
;;; identica-mode-autoloads.el ends here

View File

@ -0,0 +1,5 @@
(define-package "identica-mode" "20130204.1453" "Major mode API client for status.net open microblogging" 'nil :url "http://blog.gabrielsaldana.org/identica-mode-for-emacs/" :keywords
'("identica" "web"))
;; Local Variables:
;; no-byte-compile: t
;; End:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,859 @@
This is identica-mode.info, produced by makeinfo version 5.2 from
identica-mode.texi.
Copyright (C) 2009 Chris Bryant (<chrisbryant@ucla.edu>). Permission is
granted to copy, distribute and/or modify this document under the terms
of the GNU Free Documentation License, Version 1.2 or any later version
published by the Free Software Foundation; with no Invariant Sections,
no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is
included in the section entitled "GNU Free Documentation License".
INFO-DIR-SECTION Emacs
START-INFO-DIR-ENTRY
* Identica mode: (identica-mode). Emacs mode for microblogging services.
END-INFO-DIR-ENTRY

File: identica-mode.info, Node: Top, Next: About Identica mode and obtaining it, Prev: (dir), Up: (dir)
identica-mode
*************
This manual is for identica-mode.el, version 0.9.
* Menu:
* About Identica mode and obtaining it::
* Installation and configuration::
* Using identica-mode.el::
* Credits and contributing::
* GNU Free Documentation License::

File: identica-mode.info, Node: About Identica mode and obtaining it, Next: Installation and configuration, Prev: Top, Up: Top
1 About Identica mode and obtaining it
**************************************
* Menu:
* About identica-mode.el and this manual::
* Getting a copy::

File: identica-mode.info, Node: About identica-mode.el and this manual, Next: Getting a copy, Prev: About Identica mode and obtaining it, Up: About Identica mode and obtaining it
1.1 About identica-mode.el and this manual
==========================================
This manual instructs in the use of identica-mode.el, a major mode for
GNU Emacs used to perform useful actions with StatusNet
(http://status.net) microblogging services, like identi.ca
(http://identi.ca).
identica-mode.el was developed by Gabriel Saldana
(mailto:gsaldana@gmail.com) and other contributors (*note Credits::).
It is originally based on Twittering mode version 0.6 by Y. Hayamizu and
Tsuyoshi CHO.

File: identica-mode.info, Node: Getting a copy, Prev: About identica-mode.el and this manual, Up: About Identica mode and obtaining it
1.2 Getting a copy
==================
Identica mode can be obtained from the Savannah
(https://savannah.gnu.org) software forge. The URLs for the Identica
mode project are:
* http://www.nongnu.org/identica-mode
(http://www.nongnu.org/identica-mode/) - Main website
* https://savannah.nongnu.org/projects/identica-mode
(https://savannah.nongnu.org/projects/identica-mode/) - Software
forge
You can obtain identica-mode.el directly from the git repository at
Savannah by executing a git clone command:
git clone git://git.savannah.nongnu.org/identica-mode.git
This action will fetch the latest identica-mode.el file as well as
the latest manual, located under the 'doc/' directory.

File: identica-mode.info, Node: Installation and configuration, Next: Using identica-mode.el, Prev: About Identica mode and obtaining it, Up: Top
2 Installation and configuration
********************************
* Menu:
* Installing identica-mode.el::
* Configuring GNU Emacs::

File: identica-mode.info, Node: Installing identica-mode.el, Next: Configuring GNU Emacs, Prev: Installation and configuration, Up: Installation and configuration
2.1 Installing identica-mode.el
===============================
Installation of indentica-mode.el is fairly straightforward. Like most
GNU Emacs customizations, it is recommended you place your
identica-mode.el file under your 'emacs.d' directory. The location of
this directory will vary between OSs, but it is generally under
'~/.emacs.d/' for UNIX style systems. Consult your GNU Emacs
(http://www.gnu.org/software/emacs/) documentation.
Alternatively, you can create your own directory for this GNU Emacs
mode file, and others, if you choose. Read on for information on how to
configure your '.emacs' file to find indentica-mode.el.

File: identica-mode.info, Node: Configuring GNU Emacs, Prev: Installing identica-mode.el, Up: Installation and configuration
2.2 Configuring GNU Emacs
=========================
* Menu:
* identica-mode requirements::
* Configuring .emacs::

File: identica-mode.info, Node: identica-mode requirements, Next: Configuring .emacs, Prev: Configuring GNU Emacs, Up: Configuring GNU Emacs
2.2.1 identica-mode requirements
--------------------------------
The following GNU Emacs libraries are required by identica-mode.el. A
standard GNU Emacs installation should provide these, but if yours does
not, fetch a copy of the GNU Emacs (http://www.gnu.org/software/emacs/)
source. The libraries are generally found under the
'emacs-<version>/lisp/' directory.
* cl
* xml
* parse-time
* longlines
In addition to the library requirements, the following software is
currently required:
* GNU Emacs 22 or later
* Curl
* Wget
* UNIX-like OS (GNU/Linux, BSD, etcetera)

File: identica-mode.info, Node: Configuring .emacs, Prev: identica-mode requirements, Up: Configuring GNU Emacs
2.2.2 Configuring .emacs
------------------------
Some or all or the following settings can be configured from within GNU
Emacs or written to your '.emacs' file. To configure within GNU Emacs,
execute 'M-x' and type 'customize-group'. When prompted for the group
to customize, enter 'identica-mode'. The settings are:
* Identica Idle Time
* Identica Timer Interval
* Identica Username
* Identica Password
* Laconica Server
* Identica Default Timeline
* Identica Display Success Messages
* Identica Update Status Edit Confirm Cancellation
* Identica Update Status Method
* Identica Http Get Timeout
* Identica Status Format
For general usage, the defaults for each of these settings (excluding
Username and Password) should be fine to get started for use with
identi.ca. If you wish to customize these settings, please see the
StatusNet wiki (http://status.net/wiki/) for documentation of usage.
Management of the customizations can also be performed from within your
'.emacs' file. Below is a sample, explicitly calling the
identica-mode.el file and with an added global keybinding to allow
posting from the minibuffer without having the identica buffer active:
;; Identica Mode
(load "/home/identicauser/.emacs.d/identica-mode.el")
(require 'identica-mode)
(setq identica-username "identicauser")
(setq identica-password "password")
(global-set-key "\C-cip" 'identica-update-status-interactive)

File: identica-mode.info, Node: Using identica-mode.el, Next: Credits and contributing, Prev: Installation and configuration, Up: Top
3 Using identica-mode.el
************************
* Menu:
* Basic usage::
* Tips and tricks::

File: identica-mode.info, Node: Basic usage, Next: Tips and tricks, Prev: Using identica-mode.el, Up: Using identica-mode.el
3.1 Basic usage
===============
* Menu:
* Introduction::
* Startup::
* Icons::
* Replies timeline::
* Public timeline::
* Personal timeline::
* Update status::
* Send notice::
* Shorten url::

File: identica-mode.info, Node: Introduction, Next: Startup, Prev: Basic usage, Up: Basic usage
3.1.1 Introduction
------------------
Identica mode currently works under GNU Emacs in both terminal and
graphical mode. Where there are special considerations for one or the
other mode, they will be clearly highlighted. The purpose of Identica
mode is to provide an easy method to send and view updates while working
within a GNU Emacs environment. Thus, the command set detailed below is
simple. If you are interested in more complex functionality, feel free
to send suggestions through the Savannah project website. Additionally,
keep up-to-date with the latest releases. Also, see *note Extending
identica-mode:: for tips on writing your own functions.

File: identica-mode.info, Node: Startup, Next: Icons, Prev: Introduction, Up: Basic usage
3.1.2 Startup
-------------
To get started using Identica mode, execute 'M-x' and type
'identica-mode'. This will initiate the identica-mode buffer,
*identica*, and display the default timeline. At any time you wish to
refresh the timeline, press the 'G' key.

File: identica-mode.info, Node: Icons, Next: Replies timeline, Prev: Startup, Up: Basic usage
3.1.3 Icons
-----------
If you are using GNU Emacs with a graphical interface, you can toggle
the view of user icons by pressing the 'I' key.

File: identica-mode.info, Node: Replies timeline, Next: Public timeline, Prev: Icons, Up: Basic usage
3.1.4 Replies timeline
----------------------
To view your Replies timeline execute:
C-c C-r

File: identica-mode.info, Node: Public timeline, Next: Personal timeline, Prev: Replies timeline, Up: Basic usage
3.1.5 Public timeline
---------------------
To view the Public timeline execute:
C-c C-g

File: identica-mode.info, Node: Personal timeline, Next: Update status, Prev: Public timeline, Up: Basic usage
3.1.6 Personal timeline
-----------------------
To view your Personal timeline execute:
C-c C-f

File: identica-mode.info, Node: Update status, Next: Send notice, Prev: Personal timeline, Up: Basic usage
3.1.7 Update status
-------------------
To update your Identica status execute:
C-c C-s
At the 'Status:' prompt, type the content of your status, up to 140
characters. When done, hit the 'Enter' key. The message 'Success:
Post' will apper in the minibuffer.

File: identica-mode.info, Node: Send notice, Next: Shorten url, Prev: Update status, Up: Basic usage
3.1.8 Send notice
-----------------
To send a notice directly to a user execute:
C-c C-d
At the 'To user:' prompt type the exact user name and press the
'Enter' key. At the 'Direct message:' prompt, type your message and
press the 'Enter' key.

File: identica-mode.info, Node: Shorten url, Prev: Send notice, Up: Basic usage
3.1.9 Shorten url
-----------------
You can shorten a url while typing your update notice on the minibuffer
by pressing the '<F4>' key while the cursor is in between or at the end
of the long url you just typed.

File: identica-mode.info, Node: Tips and tricks, Prev: Basic usage, Up: Using identica-mode.el
3.2 Tips and tricks
===================
* Menu:
* Run commands after recieving notices::
* Extending identica-mode::

File: identica-mode.info, Node: Run commands after recieving notices, Prev: Tips and tricks, Up: Tips and tricks
3.2.1 Run commands after recieving notices
------------------------------------------
You can now create "hooks" that will run after recieving new notices.
Just add a hook function to 'identica-new-dents-hook'.
To display a notification message on KDE 4 you can add the following
code on your .emacs file:
;; KDE 4 Notification of new dents with kdialog
(add-hook 'identica-new-dents-hook (lambda ()
(let ((n identica-new-dents-count))
(start-process "identica-notify" nil "kdialog"
"--title"
"Emacs Identica-mode New dents"
"--passivepopup"
(format "You have %d new dent%s"
n (if (> n 1) "s" ""))
"3"
))))

File: identica-mode.info, Node: Extending identica-mode, Prev: Tips and tricks, Up: Tips and tricks
3.2.2 Extending identica-mode
-----------------------------
Because identica-mode.el is written in Emacs Lisp, there are many
options to extend the mode to your liking. As this is the first release
of the Identica mode manual, this section will serve to simply encourage
you to experiment with the code, and to see *note Contributing:: for
ways to let us know how you've extended identica-mode.el - maybe we'll
add your extensions to the code, and this section, in further releases!

File: identica-mode.info, Node: Credits and contributing, Next: GNU Free Documentation License, Prev: Using identica-mode.el, Up: Top
4 Credits and contributing
**************************
* Menu:
* Credits::
* Contributing::

File: identica-mode.info, Node: Credits, Next: Contributing, Prev: Credits and contributing, Up: Credits and contributing
4.1 Credits
===========
The following individuals have contributed to the Identica mode project.
See the identica-mode.el file for more information.
* Christian Cheng
* Alberto Garcia
* Bradley M. Kuhn
* Jason McBrayer
* Carlos A. Perilla
* Alex Schröder
* Shyam Karanatt

File: identica-mode.info, Node: Contributing, Prev: Credits, Up: Credits and contributing
4.2 Contributing
================
If you have any ideas for features, patches or bug fixes, please add
them to the identica-mode bug tracking list
(https://savannah.nongnu.org/bugs/?group=identica-mode). If you are
submitting something specifically for *note Extending identica-mode::,
be sure to note this in your ticket.

File: identica-mode.info, Node: GNU Free Documentation License, Prev: Credits and contributing, Up: Top
GNU Free Documentation License
******************************
Version 1.2, November 2002
Copyright (C) 2000,2001,2002 Free Software Foundation, Inc.
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
0. PREAMBLE
The purpose of this License is to make a manual, textbook, or other
functional and useful document "free" in the sense of freedom: to
assure everyone the effective freedom to copy and redistribute it,
with or without modifying it, either commercially or
noncommercially. Secondarily, this License preserves for the
author and publisher a way to get credit for their work, while not
being considered responsible for modifications made by others.
This License is a kind of "copyleft", which means that derivative
works of the document must themselves be free in the same sense.
It complements the GNU General Public License, which is a copyleft
license designed for free software.
We have designed this License in order to use it for manuals for
free software, because free software needs free documentation: a
free program should come with manuals providing the same freedoms
that the software does. But this License is not limited to
software manuals; it can be used for any textual work, regardless
of subject matter or whether it is published as a printed book. We
recommend this License principally for works whose purpose is
instruction or reference.
1. APPLICABILITY AND DEFINITIONS
This License applies to any manual or other work, in any medium,
that contains a notice placed by the copyright holder saying it can
be distributed under the terms of this License. Such a notice
grants a world-wide, royalty-free license, unlimited in duration,
to use that work under the conditions stated herein. The
"Document", below, refers to any such manual or work. Any member
of the public is a licensee, and is addressed as "you". You accept
the license if you copy, modify or distribute the work in a way
requiring permission under copyright law.
A "Modified Version" of the Document means any work containing the
Document or a portion of it, either copied verbatim, or with
modifications and/or translated into another language.
A "Secondary Section" is a named appendix or a front-matter section
of the Document that deals exclusively with the relationship of the
publishers or authors of the Document to the Document's overall
subject (or to related matters) and contains nothing that could
fall directly within that overall subject. (Thus, if the Document
is in part a textbook of mathematics, a Secondary Section may not
explain any mathematics.) The relationship could be a matter of
historical connection with the subject or with related matters, or
of legal, commercial, philosophical, ethical or political position
regarding them.
The "Invariant Sections" are certain Secondary Sections whose
titles are designated, as being those of Invariant Sections, in the
notice that says that the Document is released under this License.
If a section does not fit the above definition of Secondary then it
is not allowed to be designated as Invariant. The Document may
contain zero Invariant Sections. If the Document does not identify
any Invariant Sections then there are none.
The "Cover Texts" are certain short passages of text that are
listed, as Front-Cover Texts or Back-Cover Texts, in the notice
that says that the Document is released under this License. A
Front-Cover Text may be at most 5 words, and a Back-Cover Text may
be at most 25 words.
A "Transparent" copy of the Document means a machine-readable copy,
represented in a format whose specification is available to the
general public, that is suitable for revising the document
straightforwardly with generic text editors or (for images composed
of pixels) generic paint programs or (for drawings) some widely
available drawing editor, and that is suitable for input to text
formatters or for automatic translation to a variety of formats
suitable for input to text formatters. A copy made in an otherwise
Transparent file format whose markup, or absence of markup, has
been arranged to thwart or discourage subsequent modification by
readers is not Transparent. An image format is not Transparent if
used for any substantial amount of text. A copy that is not
"Transparent" is called "Opaque".
Examples of suitable formats for Transparent copies include plain
ASCII without markup, Texinfo input format, LaTeX input format,
SGML or XML using a publicly available DTD, and standard-conforming
simple HTML, PostScript or PDF designed for human modification.
Examples of transparent image formats include PNG, XCF and JPG.
Opaque formats include proprietary formats that can be read and
edited only by proprietary word processors, SGML or XML for which
the DTD and/or processing tools are not generally available, and
the machine-generated HTML, PostScript or PDF produced by some word
processors for output purposes only.
The "Title Page" means, for a printed book, the title page itself,
plus such following pages as are needed to hold, legibly, the
material this License requires to appear in the title page. For
works in formats which do not have any title page as such, "Title
Page" means the text near the most prominent appearance of the
work's title, preceding the beginning of the body of the text.
A section "Entitled XYZ" means a named subunit of the Document
whose title either is precisely XYZ or contains XYZ in parentheses
following text that translates XYZ in another language. (Here XYZ
stands for a specific section name mentioned below, such as
"Acknowledgements", "Dedications", "Endorsements", or "History".)
To "Preserve the Title" of such a section when you modify the
Document means that it remains a section "Entitled XYZ" according
to this definition.
The Document may include Warranty Disclaimers next to the notice
which states that this License applies to the Document. These
Warranty Disclaimers are considered to be included by reference in
this License, but only as regards disclaiming warranties: any other
implication that these Warranty Disclaimers may have is void and
has no effect on the meaning of this License.
2. VERBATIM COPYING
You may copy and distribute the Document in any medium, either
commercially or noncommercially, provided that this License, the
copyright notices, and the license notice saying this License
applies to the Document are reproduced in all copies, and that you
add no other conditions whatsoever to those of this License. You
may not use technical measures to obstruct or control the reading
or further copying of the copies you make or distribute. However,
you may accept compensation in exchange for copies. If you
distribute a large enough number of copies you must also follow the
conditions in section 3.
You may also lend copies, under the same conditions stated above,
and you may publicly display copies.
3. COPYING IN QUANTITY
If you publish printed copies (or copies in media that commonly
have printed covers) of the Document, numbering more than 100, and
the Document's license notice requires Cover Texts, you must
enclose the copies in covers that carry, clearly and legibly, all
these Cover Texts: Front-Cover Texts on the front cover, and
Back-Cover Texts on the back cover. Both covers must also clearly
and legibly identify you as the publisher of these copies. The
front cover must present the full title with all words of the title
equally prominent and visible. You may add other material on the
covers in addition. Copying with changes limited to the covers, as
long as they preserve the title of the Document and satisfy these
conditions, can be treated as verbatim copying in other respects.
If the required texts for either cover are too voluminous to fit
legibly, you should put the first ones listed (as many as fit
reasonably) on the actual cover, and continue the rest onto
adjacent pages.
If you publish or distribute Opaque copies of the Document
numbering more than 100, you must either include a machine-readable
Transparent copy along with each Opaque copy, or state in or with
each Opaque copy a computer-network location from which the general
network-using public has access to download using public-standard
network protocols a complete Transparent copy of the Document, free
of added material. If you use the latter option, you must take
reasonably prudent steps, when you begin distribution of Opaque
copies in quantity, to ensure that this Transparent copy will
remain thus accessible at the stated location until at least one
year after the last time you distribute an Opaque copy (directly or
through your agents or retailers) of that edition to the public.
It is requested, but not required, that you contact the authors of
the Document well before redistributing any large number of copies,
to give them a chance to provide you with an updated version of the
Document.
4. MODIFICATIONS
You may copy and distribute a Modified Version of the Document
under the conditions of sections 2 and 3 above, provided that you
release the Modified Version under precisely this License, with the
Modified Version filling the role of the Document, thus licensing
distribution and modification of the Modified Version to whoever
possesses a copy of it. In addition, you must do these things in
the Modified Version:
A. Use in the Title Page (and on the covers, if any) a title
distinct from that of the Document, and from those of previous
versions (which should, if there were any, be listed in the
History section of the Document). You may use the same title
as a previous version if the original publisher of that
version gives permission.
B. List on the Title Page, as authors, one or more persons or
entities responsible for authorship of the modifications in
the Modified Version, together with at least five of the
principal authors of the Document (all of its principal
authors, if it has fewer than five), unless they release you
from this requirement.
C. State on the Title page the name of the publisher of the
Modified Version, as the publisher.
D. Preserve all the copyright notices of the Document.
E. Add an appropriate copyright notice for your modifications
adjacent to the other copyright notices.
F. Include, immediately after the copyright notices, a license
notice giving the public permission to use the Modified
Version under the terms of this License, in the form shown in
the Addendum below.
G. Preserve in that license notice the full lists of Invariant
Sections and required Cover Texts given in the Document's
license notice.
H. Include an unaltered copy of this License.
I. Preserve the section Entitled "History", Preserve its Title,
and add to it an item stating at least the title, year, new
authors, and publisher of the Modified Version as given on the
Title Page. If there is no section Entitled "History" in the
Document, create one stating the title, year, authors, and
publisher of the Document as given on its Title Page, then add
an item describing the Modified Version as stated in the
previous sentence.
J. Preserve the network location, if any, given in the Document
for public access to a Transparent copy of the Document, and
likewise the network locations given in the Document for
previous versions it was based on. These may be placed in the
"History" section. You may omit a network location for a work
that was published at least four years before the Document
itself, or if the original publisher of the version it refers
to gives permission.
K. For any section Entitled "Acknowledgements" or "Dedications",
Preserve the Title of the section, and preserve in the section
all the substance and tone of each of the contributor
acknowledgements and/or dedications given therein.
L. Preserve all the Invariant Sections of the Document, unaltered
in their text and in their titles. Section numbers or the
equivalent are not considered part of the section titles.
M. Delete any section Entitled "Endorsements". Such a section
may not be included in the Modified Version.
N. Do not retitle any existing section to be Entitled
"Endorsements" or to conflict in title with any Invariant
Section.
O. Preserve any Warranty Disclaimers.
If the Modified Version includes new front-matter sections or
appendices that qualify as Secondary Sections and contain no
material copied from the Document, you may at your option designate
some or all of these sections as invariant. To do this, add their
titles to the list of Invariant Sections in the Modified Version's
license notice. These titles must be distinct from any other
section titles.
You may add a section Entitled "Endorsements", provided it contains
nothing but endorsements of your Modified Version by various
parties--for example, statements of peer review or that the text
has been approved by an organization as the authoritative
definition of a standard.
You may add a passage of up to five words as a Front-Cover Text,
and a passage of up to 25 words as a Back-Cover Text, to the end of
the list of Cover Texts in the Modified Version. Only one passage
of Front-Cover Text and one of Back-Cover Text may be added by (or
through arrangements made by) any one entity. If the Document
already includes a cover text for the same cover, previously added
by you or by arrangement made by the same entity you are acting on
behalf of, you may not add another; but you may replace the old
one, on explicit permission from the previous publisher that added
the old one.
The author(s) and publisher(s) of the Document do not by this
License give permission to use their names for publicity for or to
assert or imply endorsement of any Modified Version.
5. COMBINING DOCUMENTS
You may combine the Document with other documents released under
this License, under the terms defined in section 4 above for
modified versions, provided that you include in the combination all
of the Invariant Sections of all of the original documents,
unmodified, and list them all as Invariant Sections of your
combined work in its license notice, and that you preserve all
their Warranty Disclaimers.
The combined work need only contain one copy of this License, and
multiple identical Invariant Sections may be replaced with a single
copy. If there are multiple Invariant Sections with the same name
but different contents, make the title of each such section unique
by adding at the end of it, in parentheses, the name of the
original author or publisher of that section if known, or else a
unique number. Make the same adjustment to the section titles in
the list of Invariant Sections in the license notice of the
combined work.
In the combination, you must combine any sections Entitled
"History" in the various original documents, forming one section
Entitled "History"; likewise combine any sections Entitled
"Acknowledgements", and any sections Entitled "Dedications". You
must delete all sections Entitled "Endorsements."
6. COLLECTIONS OF DOCUMENTS
You may make a collection consisting of the Document and other
documents released under this License, and replace the individual
copies of this License in the various documents with a single copy
that is included in the collection, provided that you follow the
rules of this License for verbatim copying of each of the documents
in all other respects.
You may extract a single document from such a collection, and
distribute it individually under this License, provided you insert
a copy of this License into the extracted document, and follow this
License in all other respects regarding verbatim copying of that
document.
7. AGGREGATION WITH INDEPENDENT WORKS
A compilation of the Document or its derivatives with other
separate and independent documents or works, in or on a volume of a
storage or distribution medium, is called an "aggregate" if the
copyright resulting from the compilation is not used to limit the
legal rights of the compilation's users beyond what the individual
works permit. When the Document is included in an aggregate, this
License does not apply to the other works in the aggregate which
are not themselves derivative works of the Document.
If the Cover Text requirement of section 3 is applicable to these
copies of the Document, then if the Document is less than one half
of the entire aggregate, the Document's Cover Texts may be placed
on covers that bracket the Document within the aggregate, or the
electronic equivalent of covers if the Document is in electronic
form. Otherwise they must appear on printed covers that bracket
the whole aggregate.
8. TRANSLATION
Translation is considered a kind of modification, so you may
distribute translations of the Document under the terms of section
4. Replacing Invariant Sections with translations requires special
permission from their copyright holders, but you may include
translations of some or all Invariant Sections in addition to the
original versions of these Invariant Sections. You may include a
translation of this License, and all the license notices in the
Document, and any Warranty Disclaimers, provided that you also
include the original English version of this License and the
original versions of those notices and disclaimers. In case of a
disagreement between the translation and the original version of
this License or a notice or disclaimer, the original version will
prevail.
If a section in the Document is Entitled "Acknowledgements",
"Dedications", or "History", the requirement (section 4) to
Preserve its Title (section 1) will typically require changing the
actual title.
9. TERMINATION
You may not copy, modify, sublicense, or distribute the Document
except as expressly provided for under this License. Any other
attempt to copy, modify, sublicense or distribute the Document is
void, and will automatically terminate your rights under this
License. However, parties who have received copies, or rights,
from you under this License will not have their licenses terminated
so long as such parties remain in full compliance.
10. FUTURE REVISIONS OF THIS LICENSE
The Free Software Foundation may publish new, revised versions of
the GNU Free Documentation License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns. See
<http://www.gnu.org/copyleft/>.
Each version of the License is given a distinguishing version
number. If the Document specifies that a particular numbered
version of this License "or any later version" applies to it, you
have the option of following the terms and conditions either of
that specified version or of any later version that has been
published (not as a draft) by the Free Software Foundation. If the
Document does not specify a version number of this License, you may
choose any version ever published (not as a draft) by the Free
Software Foundation.
ADDENDUM: How to use this License for your documents
====================================================
To use this License in a document you have written, include a copy of
the License in the document and put the following copyright and license
notices just after the title page:
Copyright (C) YEAR YOUR NAME.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.2
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
Texts. A copy of the license is included in the section entitled ``GNU
Free Documentation License''.
If you have Invariant Sections, Front-Cover Texts and Back-Cover
Texts, replace the "with...Texts." line with this:
with the Invariant Sections being LIST THEIR TITLES, with
the Front-Cover Texts being LIST, and with the Back-Cover Texts
being LIST.
If you have Invariant Sections without Cover Texts, or some other
combination of the three, merge those two alternatives to suit the
situation.
If your document contains nontrivial examples of program code, we
recommend releasing these examples in parallel under your choice of free
software license, such as the GNU General Public License, to permit
their use in free software.

Tag Table:
Node: Top652
Node: About Identica mode and obtaining it1020
Node: About identica-mode.el and this manual1305
Node: Getting a copy1996
Node: Installation and configuration2855
Node: Installing identica-mode.el3143
Node: Configuring GNU Emacs3960
Node: identica-mode requirements4208
Node: Configuring .emacs4960
Node: Using identica-mode.el6550
Node: Basic usage6788
Node: Introduction7115
Node: Startup7883
Node: Icons8244
Node: Replies timeline8489
Node: Public timeline8698
Node: Personal timeline8915
Node: Update status9136
Node: Send notice9521
Node: Shorten url9885
Node: Tips and tricks10185
Node: Run commands after recieving notices10406
Node: Extending identica-mode11273
Node: Credits and contributing11865
Node: Credits12100
Node: Contributing12526
Node: GNU Free Documentation License12948

End Tag Table

View File

@ -0,0 +1,93 @@
;;; ng2-html.el --- Major mode for editing Angular 2 templates
;; Copyright 2016 Adam Niederer
;; Author: Adam Niederer <adam.niederer@gmail.com>
;; URL: http://github.com/AdamNiederer/ng2-mode
;; Version: 0.1
;; Keywords: typescript angular angular2
;; Package-Requires: ()
;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary
;; The main features of this mode are syntax highlighting (enabled with
;; `font-lock-mode' or `global-font-lock-mode'), and html-mode
;; integration
;;
;; Exported names start with "ng2-html-"; private names start with
;; "ng2-html--".
;;; Code:
(defconst ng2-html-var-regex
"#\\(\\w+\\)")
(defconst ng2-html-interp-regex
"{{.*?}}")
(defconst ng2-html-directive-regex
"\*\\(.*?\\)[\"= ]")
(defconst ng2-html-binding-regex
"\\(\\[.*?\\]\\)=\\(\".*?\"\\)")
(defconst ng2-html-event-regex
"\\((.*?)\\)=\".*?\"")
(defconst ng2-html-pipe-regex
"{{.*?\\(|\\) *\\(.*?\\) *}}")
(defcustom ng2-html-tab-width 2
"Tab width for ng2-html-mode"
:group 'ng2
:type 'integer)
(defun ng2-html-goto-binding ()
"Opens the corresponding component TypeScript file, then places the cursor at the function corresponding to the binding"
(interactive)
(let ((fn-name (word-at-point)))
(ng2-open-counterpart)
(ng2-ts-goto-fn fn-name)))
(defvar ng2-html-font-lock-keywords
`((,ng2-html-var-regex (1 font-lock-variable-name-face))
(,ng2-html-interp-regex . (0 font-lock-variable-name-face t))
(,ng2-html-directive-regex . (1 font-lock-keyword-face t))
(,ng2-html-binding-regex . (1 font-lock-type-face t))
(,ng2-html-event-regex . (1 font-lock-type-face t))
(,ng2-html-pipe-regex . (1 font-lock-keyword-face t))
(,ng2-html-pipe-regex . (2 font-lock-function-name-face t))))
(defvar ng2-html-map
(let ((map (make-keymap)))
(define-key map (kbd "C-c b") 'ng2-html-goto-binding)
(define-key map (kbd "C-c c") 'ng2-open-counterpart)
map)
"Keymap for ng2-html-mode")
;;;###autoload
(define-derived-mode ng2-html-mode
html-mode "ng2-html"
"Major mode for Angular 2 templates"
(use-local-map ng2-html-map)
(setq tab-width ng2-html-tab-width)
(font-lock-add-keywords nil ng2-html-font-lock-keywords))
;;;###autoload
(add-to-list 'auto-mode-alist '("\\.component.html\\'" . ng2-html-mode))
(provide 'ng2-html)
;;; ng2-html.el ends here

View File

@ -0,0 +1,54 @@
;;; ng2-mode-autoloads.el --- automatically extracted autoloads
;;
;;; Code:
(add-to-list 'load-path (or (file-name-directory #$) (car load-path)))
;;;### (autoloads nil "ng2-html" "ng2-html.el" (22500 63829 326570
;;;;;; 417000))
;;; Generated autoloads from ng2-html.el
(autoload 'ng2-html-mode "ng2-html" "\
Major mode for Angular 2 templates
\(fn)" t nil)
(add-to-list 'auto-mode-alist '("\\.component.html\\'" . ng2-html-mode))
;;;***
;;;### (autoloads nil "ng2-mode" "ng2-mode.el" (22500 63829 338570
;;;;;; 480000))
;;; Generated autoloads from ng2-mode.el
(autoload 'ng2-mode "ng2-mode" "\
Activates the appropriate Angular 2-related mode for the buffer.
\(fn)" t nil)
;;;***
;;;### (autoloads nil "ng2-ts" "ng2-ts.el" (22500 63829 318570 374000))
;;; Generated autoloads from ng2-ts.el
(autoload 'ng2-ts-mode "ng2-ts" "\
Major mode for Angular 2 TypeScript
\(fn)" t nil)
(add-to-list 'auto-mode-alist '("\\.component.ts\\'" . ng2-ts-mode))
(add-to-list 'auto-mode-alist '("\\.service.ts\\'" . ng2-ts-mode))
;;;***
;;;### (autoloads nil nil ("ng2-mode-pkg.el") (22500 63829 371106
;;;;;; 271000))
;;;***
;; Local Variables:
;; version-control: never
;; no-byte-compile: t
;; no-update-autoloads: t
;; End:
;;; ng2-mode-autoloads.el ends here

View File

@ -0,0 +1,7 @@
(define-package "ng2-mode" "20160910.820" "Major modes for editing Angular 2"
'((typescript-mode "0.1"))
:url "http://github.com/AdamNiederer/ng2-mode" :keywords
'("typescript" "angular" "angular2" "template"))
;; Local Variables:
;; no-byte-compile: t
;; End:

View File

@ -0,0 +1,80 @@
;;; ng2-mode.el --- Major modes for editing Angular 2
;; Copyright 2016 Adam Niederer
;; Author: Adam Niederer <adam.niederer@gmail.com>
;; URL: http://github.com/AdamNiederer/ng2-mode
;; Version: 0.1
;; Keywords: typescript angular angular2 template
;; Package-Requires: ((typescript-mode "0.1"))
;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; The main features of the modes are syntax highlighting (enabled with
;; `font-lock-mode' or `global-font-lock-mode'), and easy switching
;; between templates and components.
;;
;; Exported names start with "ng2-"; private names start with
;; "ng2--".
;;; Code:
(require 'typescript-mode)
(require 'ng2-ts)
(require 'ng2-html)
(defgroup ng2 nil
"Major mode for AngularJS 2 files"
:prefix "ng2-"
:group 'languages
:link '(url-link :tag "Github" "https://github.com/AdamNiederer/ng2-mode")
:link '(emacs-commentary-link :tag "Commentary" "ng2-mode"))
(defun ng2--counterpart-name (name)
"Return the file name of this file's counterpart. If a file has no counterpart, returns the name of the file. Ex. kek.component.html <-> kek.component.ts"
(when (not (ng2--is-component name)) name)
(let ((ext (file-name-extension name))
(base (file-name-sans-extension name)))
(if (equal ext "ts")
(concat base ".html")
(concat base ".ts"))))
(defun ng2--sans-type (name)
"Return the file name, minus its extension an type. Ex. kek.component.ts -> kek"
(file-name-sans-extension (file-name-sans-extension name)))
(defun ng2--is-component (name)
(equal (file-name-extension (file-name-sans-extension name)) "component"))
(defun ng2-open-counterpart ()
"Opens the counterpart file to this one. If it's a component, open the corresponding template, and vice versa"
(interactive)
(find-file (ng2--counterpart-name (buffer-file-name))))
;;;###autoload
(defun ng2-mode ()
"Activates the appropriate Angular 2-related mode for the buffer."
(interactive)
(if (equal buffer-file-name nil)
(message "This doesn't appear to be an Angular2 component or service.")
(let ((file-ext (file-name-extension (buffer-file-name))))
(cond
((equal file-ext "html") (ng2-html-mode))
((equal file-ext "ts") (ng2-ts-mode))
(t (message "This doesn't appear to be an Angular2 component or service."))))))
(provide 'ng2-mode)
;;; ng2-mode.el ends here

View File

@ -0,0 +1,99 @@
;;; ng2-ts.el --- Major mode for editing Angular 2 TypeScript
;; Copyright 2016 Adam Niederer
;; Author: Adam Niederer <adam.niederer@gmail.com>
;; URL: http://github.com/AdamNiederer/ng2-mode
;; Version: 0.1
;; Keywords: typescript angular angular2
;; Package-Requires: ((typescript-mode "0.1"))
;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary
;; The main features of this mode are syntax highlighting (enabled with
;; `font-lock-mode' or `global-font-lock-mode'), and typescript-mode
;; integration
;;
;; Exported names start with "ng2-ts-"; private names start with
;; "ng2-ts--".
;;; Code:
(defconst ng2-ts-decorator-keywords
'("@Component"
"@Directive"
"@Pipe"
"@NgModule"))
(defconst ng2-ts-interp-regex
"${.*?}")
(defconst ng2-ts-var-regex
"[^?/.] \\(\\w+\\) *[=:]")
(defconst ng2-ts-fn-regex
"\\(\\w+\\)\(.*\).*{")
(defconst ng2-ts-class-regex
"class \\(\\w+\\)")
(defconst ng2-ts-lambda-regex
"\\(\\w+\\) *\\(=>\\)")
(defconst ng2-ts-generic-regex
"<\\(\\w+\\)\\(\\[\\]\\)?>")
(defcustom ng2-ts-tab-width 2
"Tab width for ng2-ts-mode"
:group 'ng2
:type 'integer)
(defun ng2-ts-goto-fn (fn-name)
"Places the point on the function called fn-name"
(beginning-of-buffer)
(search-forward-regexp (format "\\(\\%s\\)\(.*\).*{" fn-name)))
(defvar ng2-ts-map
(let ((map (make-keymap)))
(define-key map (kbd "C-c c") 'ng2-open-counterpart)
map)
"Keymap for ng2-ts-mode")
(defvar ng2-ts-font-lock-keywords
`((,ng2-ts-interp-regex . (0 font-lock-constant-face t))
(,ng2-ts-var-regex (1 font-lock-variable-name-face))
(,ng2-ts-class-regex (1 font-lock-type-face))
(,ng2-ts-fn-regex (1 font-lock-function-name-face))
(,ng2-ts-generic-regex (1 font-lock-type-face))
(,ng2-ts-lambda-regex (1 font-lock-variable-name-face))
(,ng2-ts-lambda-regex (2 font-lock-function-name-face))
(,(regexp-opt ng2-ts-decorator-keywords) . font-lock-builtin-face)))
;;;###autoload
(define-derived-mode ng2-ts-mode
typescript-mode "ng2-ts"
"Major mode for Angular 2 TypeScript"
(use-local-map ng2-ts-map)
(setq tab-width ng2-ts-tab-width)
(font-lock-add-keywords nil ng2-ts-font-lock-keywords))
;;;###autoload
(add-to-list 'auto-mode-alist '("\\.component.ts\\'" . ng2-ts-mode))
;;;###autoload
(add-to-list 'auto-mode-alist '("\\.service.ts\\'" . ng2-ts-mode))
(provide 'ng2-ts)
;;; ng2-ts.el ends here