unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* [Proposed Minor-mode] Speed of thought Lisp (was: Abbrevs for the most frequent elisp symbols)
@ 2015-01-24 16:38 Artur Malabarba
  2015-01-25 14:49 ` [Proposed Minor-mode] Speed of thought Lisp Stefan Monnier
  2015-01-27 12:28 ` Oleh Krehel
  0 siblings, 2 replies; 16+ messages in thread
From: Artur Malabarba @ 2015-01-24 16:38 UTC (permalink / raw)
  To: emacs-devel


[-- Attachment #1.1: Type: text/plain, Size: 2693 bytes --]

For a while now, I've been using a system that leads to very fluid elisp
coding. The focus is on writing lisp as fast as you can think of it,
without being slowed down by your typing speed.
Thus the name: Speed-of-thought Lisp.

I've packaged it into a minor mode, which I'm proposing for inclusion into
Emacs. I really can't overstate how much I've come to like this little
mode, so hopefully some here will find it useful too.

The mode is quite simple, and is composed of two parts:
Abbrevs

A large number of abbrevs, almost identical to what was discussed back in
December on a thread in help-emacs. These abbrevs expand function initials
to their name. The actual abbrevs are completely arbitrary (I added them as
I ran into them), so I'm perfectly open to changing them based on general
usage frequency.

A few examples (currently they are 96 in total):

   - “wcb” -> “with-current-buffer”
   - “i” -> “insert”
   - “r” -> “require '”
   - “a” -> “and”

However, these are defined in a way such that they ONLY expand in a place
where you would use a function, so hitting SPC after “(r” expands to
“(require '”, but hitting SPC after “(delete-region r” will NOT expand the
`r', because that's obviously not a function.

Furtheromre, “#'r” will expand to “#'require” (note how it ommits that
extra quote, since it would be useless here).
Commands

It also defines 4 commands, which really fit into this “follow the
thought-flow” way of writing. The bindings are as follows, I understand
these don't fully adhere to conventions, and I'd appreaciate suggestions on
better bindings.

   - M-RET :: Break line, and insert “()” with point in the middle.
   - C-RET :: Do `forward-up-list', then do M-RET.

Hitting RET followed by a `(' was one of the most common key sequences for
me while writing elisp, so giving it a quick-to-hit key was a significant
improvement.

   - C-c f :: Find function under point. If it is not defined, create a
   definition for it below the current function and leave point inside.
   - C-c v :: Same, but for variable.

With these commands, you just write your code as you think of it. Once you
hit a “stop-point” of sorts in your tought flow, you hit C-c f/v on any
undefined functions/variables, write their definitions, and hit C-u C-SPC
to go back to the main function.
Small Example

With the above (assuming you use something like paredit or
electric-pair-mode), if you write:

    ( w t b M-RET i SPC text

You get

    (with-temp-buffer
      (insert text))


Cheers to all, and please let me hear your thoughts!
Artur

[-- Attachment #1.2: Type: text/html, Size: 3125 bytes --]

[-- Attachment #2: sotlisp.el --]
[-- Type: text/x-emacs-lisp, Size: 16862 bytes --]

;;; sotlisp.el --- Write lisp at the speed of thought.  -*- lexical-binding: t; -*-

;; Copyright (C) 2014 Free Software Foundation, Inc.

;; Author: Artur Malabarba  <bruce.connor.am@gmail.com>
;; Keywords: convenience, lisp
;; Package-Requires: ((emacs "24.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:
;;
;; This defines a new global minor-mode `speed-of-thought-mode', which
;; activates locally on any supported buffer.  Currently, only
;; `emacs-lisp-mode' buffers are supported.
;;
;; The mode is quite simple, and is composed of two parts:
;;
;;; Abbrevs
;;
;; A large number of abbrevs which expand function
;; initials to their name.  A few examples:
;; 
;; - wcb -> with-current-buffer
;; - i -> insert
;; - r -> require '
;; - a -> and
;; 
;; However, these are defined in a way such that they ONLY expand in a
;; place where you would use a function, so hitting SPC after "(r"
;; expands to "(require '", but hitting SPC after "(delete-region r" will
;; NOT expand the `r', because that's obviously not a function.
;; Furtheromre, "#'r" will expand to "#'require" (note how it ommits that
;; extra quote, since it would be useless here).
;;
;;; Commands
;;
;; It also defines 4 commands, which really fit into this "follow the
;; thought-flow" way of writing.  The bindings are as follows, I
;; understand these don't fully adhere to conventions, and I'd
;; appreaciate suggestions on better bindings.
;; 
;; - M-RET :: Break line, and insert "()" with point in the middle.
;; - C-RET :: Do `forward-up-list', then do M-RET.
;; 
;; Hitting RET followed by a `(' was one of the most common key sequences
;; for me while writing elisp, so giving it a quick-to-hit key was a
;; significant improvement.
;; 
;; - C-c f :: Find function under point.  If it is not defined, create a
;; definition for it below the current function and leave point inside.
;; - C-c v :: Same, but for variable.
;; 
;; With these commands, you just write your code as you think of it.  Once
;; you hit a "stop-point" of sorts in your tought flow, you hit `C-c f/v`
;; on any undefined functions/variables, write their definitions, and hit
;; `C-u C-SPC` to go back to the main function.
;; 
;;; Small Example
;;
;; With the above (assuming you use something like paredit or
;; electric-pair-mode), if you write:
;;
;;   ( w t b M-RET i SPC text
;; 
;; You get
;; 
;;   (with-temp-buffer (insert text))

\f
;;; Code:
(eval-when-compile
  (require 'subr-x))

;;; Predicates
(defun sotlisp--auto-paired-p ()
  "Non-nil if this buffer auto-inserts parentheses."
  (or (bound-and-true-p electric-pair-mode)
      (bound-and-true-p paredit-mode)
      (bound-and-true-p smartparens-mode)))

(defun sotlisp--function-form-p ()
  "Non-nil if point is at the start of a sexp.
Specially, avoids matching inside argument lists."
  (and (eq (char-before) ?\()
       (not (looking-back "(\\(defun\\s-+.*\\|lambda\\s-+\\)("))
       (not (string-match (rx (syntax symbol)) (string last-command-event)))))

(defun sotlisp--function-quote-p ()
  "Non-nil if point is at a sharp-quote."
  (looking-back "#'"))

(defun sotlisp--function-p ()
  "Non-nil if point is at reasonable place for a function name.
Returns non-nil if, after moving backwards by a sexp, either
`sotlisp--function-form-p' or `sotlisp--function-quote-p' return
non-nil."
  (save-excursion
    (ignore-errors
      (skip-chars-backward (rx alnum))
      (or (sotlisp--function-form-p)
          (sotlisp--function-quote-p)))))

(defun sotlisp--whitespace-p ()
  "Non-nil if current `self-insert'ed char is whitespace."
  (ignore-errors
    (string-match (rx space) (string last-command-event))))

\f
;;; Expansion logic
(defvar sotlisp--needs-moving nil
  "Will `sotlisp--move-to-$' move point after insertion?")

(defun sotlisp--move-to-$ ()
  "Move backwards until `$' and delete it.
Point is left where the `$' char was.  Does nothing if variable
`sotlisp-mode' is nil."
  (when (bound-and-true-p speed-of-thought-mode)
    (when sotlisp--needs-moving
      (setq sotlisp--needs-moving nil)
      (skip-chars-backward "^\\$")
      (delete-char -1))))

(add-hook 'post-command-hook #'sotlisp--move-to-$ 'append)

(defun sotlisp--maybe-skip-closing-paren ()
  "Move past `)' if variable `electric-pair-mode' is enabled."
  (when (and (char-after ?\))
             (sotlisp--auto-paired-p))
    (forward-char 1)))

(defvar sotlisp--function-table (make-hash-table :test #'equal)
  "Table where function abbrev expansions are stored.")

(defun sotlisp--expand-function ()
  "Expand the function abbrev before point.
See `sotlisp-define-function-abbrev'."
  (let ((r (point)))
    (skip-chars-backward (rx alnum))
    (let* ((name (buffer-substring (point) r))
           (expansion (gethash name sotlisp--function-table)))
      (delete-region (point) r)
      (if (sotlisp--function-quote-p)
          ;; After #' use the simple expansion.
          (insert (sotlisp--simplify-function-expansion expansion))
        ;; Inside a form, use the full expansion.
        (insert expansion)
        (when (string-match "\\$" expansion)
          (setq sotlisp--needs-moving t))))
    ;; Inform `expand-abbrev' that `self-insert-command' should not
    ;; trigger, by returning non-nil on SPC.
    (when (sotlisp--whitespace-p)
      ;; And maybe move out of closing paren if expansion ends with $.
      (when (eq (char-before) ?$)
        (delete-char -1)
        (setq sotlisp--needs-moving nil)
        (sotlisp--maybe-skip-closing-paren))
      t)))

(put 'sotlisp--expand-function 'no-self-insert t)

(defun sotlisp--simplify-function-expansion (expansion)
  "Take a substring of EXPANSION up to first space.
The space char is not included.  Any \"$\" are also removed."
  (replace-regexp-in-string
   "\\$" ""
   (substring expansion 0 (string-match " " expansion))))

\f
;;; Abbrev definitions
(defconst sotlisp--default-function-abbrevs
  '(
    ("a" . "and ")
    ("ah" . "add-hook '")
    ("atl" . "add-to-list '")
    ("bb" . "bury-buffer")
    ("bc" . "forward-char -1")
    ("bfn" . "buffer-file-name")
    ("bn" . "buffer-name")
    ("bl" . "buffer-list$")
    ("bod" . "beginning-of-defun")
    ("bp" . "boundp '")
    ("bs" . "buffer-string$")
    ("bss" . "buffer-substring ")
    ("bw" . "forward-word -1")
    ("c" . "concat ")
    ("ca" . "char-after$")
    ("cc" . "condition-case er\n$\n(error nil)")
    ("ci" . "call-interactively ")
    ("cip" . "called-interactively-p 'any")
    ("csv" . "customize-save-variable '")
    ("d" . "delete-char 1")
    ("df" . "delete-file ")
    ("dl" . "dolist (it $)")
    ("dk" . "define-key ")
    ("dmp" . "derived-mode-p '")
    ("dr" . "delete-region ")
    ("e" . "error \"$\"")
    ("efn" . "expand-file-name ")
    ("f" . "format \"$\"")
    ("fb" . "fboundp '")
    ("fbp" . "fboundp '")
    ("fc" . "forward-char 1")
    ("ff" . "find-file ")
    ("fl" . "forward-line 1")
    ("fp" . "functionp ")
    ("frp" . "file-readable-p ")
    ("fs" . "forward-sexp 1")
    ("fw" . "forward-word 1")
    ("g" . "goto-char ")
    ("gc" . "goto-char ")
    ("gsk" . "global-set-key ")
    ("i" . "insert ")
    ("ie" . "ignore-errors ")
    ("k" . "kbd \"$\"")
    ("kb" . "kill-buffer")
    ("l" . "lambda ($)")
    ("la" . "looking-at \"$\"")
    ("lap" . "looking-at-p \"$\"")
    ("lb" . "looking-back \"$\"")
    ("let" . "let (($))")
    ("lp" . "listp ")
    ("m" . "message \"$%s\"")
    ("mb" . "match-beginning 0")
    ("me" . "match-end 0")
    ("ms" . "match-string 0")
    ("msnp" . "match-string-no-properties 0")
    ("n" . "not ")
    ("nl" . "forward-line 1")
    ("np" . "numberp ")
    ("ow" . "other-window 1")
    ("p" . "point$")
    ("pa" . "point-max$")
    ("pi" . "point-min$")
    ("r" . "require '")
    ("rh" . "remove-hook '")
    ("rm" . "replace-match \"$\"")
    ("rq" . "regexp-quote \"$\"")
    ("rris" . "replace-regexp-in-string ")
    ("rrs" . "replace-regexp-in-string ")
    ("rs" . "while (search-forward $ nil t)\n(replace-match \"\") nil t)")
    ("s" . "setq ")
    ("s=" . "string= ")
    ("sb" . "search-backward \"$\"")
    ("sbr" . "search-backward-regexp \"$\"")
    ("scb" . "skip-chars-backward \"$\r\n[:blank:]\"")
    ("scf" . "skip-chars-forward \"$\r\n[:blank:]\"")
    ("se" . "save-excursion")
    ("sf" . "search-forward \"$\"")
    ("sfr" . "search-forward-regexp \"$\"")
    ("sm" . "string-match \"$\"")
    ("smd" . "save-match-data")
    ("sn" . "symbol-name ")
    ("sp" . "stringp ")
    ("sr" . "save-restriction")
    ("ss" . "substring ")
    ("stb" . "switch-to-buffer ")
    ("sw" . "select-window ")
    ("tap" . "thing-at-point 'symbol")
    ("u" . "unless ")
    ("up" . "unwind-protect ")
    ("w" . "when ")
    ("wcb" . "with-current-buffer ")
    ("wf" . "write-file ")
    ("wh" . "while ")
    ("wl" . "window-list nil 'nominibuffer")
    ("wtb" . "with-temp-buffer")
    ("wtf" . "with-temp-file")
    )
  "Alist of (ABBREV . EXPANSION) used by `sotlisp'.")

(defun sotlisp-define-function-abbrev (name expansion)
  "Define a function abbrev expanding NAME to EXPANSION.
This abbrev will only be expanded in places where a function name is
sensible.  Roughly, this is right after a `(' or a `#''.

If EXPANSION is any string, it doesn't have to be the just the
name of a function.  In particular:
  - if it contains a `$', this char will not be inserted and
    point will be moved to its position after expansion.
  - if it contains a space, only a substring of it up to the
first space is inserted when expanding after a `#'' (this is done
by defining two different abbrevs).

For instance, if one defines
   (sotlisp-define-function-abbrev \"d\" \"delete-char 1\")

then triggering `expand-abbrev' after \"d\" expands in the
following way:
   (d    => (delete-char 1
   #'d   => #'delete-char"
  (define-abbrev emacs-lisp-mode-abbrev-table
    name t #'sotlisp--expand-function
    ;; Don't override user abbrevs
    :system t
    ;; Only expand in function places.
    :enable-function #'sotlisp--function-p)
  (puthash name expansion sotlisp--function-table))

(defun sotlisp-erase-all-abbrevs ()
  "Undefine all abbrevs defined by `sotlisp'."
  (interactive)
  (maphash (lambda (x _) (define-abbrev emacs-lisp-mode-abbrev-table x nil))
           sotlisp--function-table))

(defun sotlisp-define-all-abbrevs ()
  "Define all abbrevs in `sotlisp--default-function-abbrevs'."
  (interactive)
  (mapc (lambda (x) (sotlisp-define-function-abbrev (car x) (cdr x)))
    sotlisp--default-function-abbrevs))

\f
;;; The minor-mode
;;;###autoload
(define-minor-mode speed-of-thought-mode nil nil nil nil
  :global t
  (if speed-of-thought-mode
      (progn
        (add-hook 'emacs-lisp-mode-hook #'speed-of-thought--lisp-mode)
        (sotlisp-define-all-abbrevs)
        (mapc (lambda (b)
                (with-current-buffer b
                  (when (derived-mode-p 'emacs-lisp-mode)
                    (speed-of-thought--lisp-mode 1))))
          (buffer-list)))
    (remove-hook 'emacs-lisp-mode-hook #'speed-of-thought--lisp-mode)
    (sotlisp-erase-all-abbrevs)
    (mapc (lambda (b)
            (with-current-buffer b
              (when (derived-mode-p 'emacs-lisp-mode)
                (speed-of-thought--lisp-mode -1))))
      (buffer-list))))

(define-minor-mode speed-of-thought--lisp-mode nil nil " SoT"
  '(([M-return] . sotlisp-newline-and-parentheses)
    ([C-return] . sotlisp-downlist-newline-and-parentheses)
    ("\C-cf"    . sotlisp-find-or-define-function)
    ("\C-cv"    . sotlisp-find-or-define-variable)))

\f
;;; Commands
(defun sotlisp-newline-and-parentheses ()
  "`newline-and-indent' then insert a pair of parentheses."
  (interactive)
  (point)
  (ignore-errors
    (expand-abbrev))
  (newline-and-indent)
  (insert "()")
  (forward-char -1))

(defun sotlisp-downlist-newline-and-parentheses ()
  "`up-list', `newline-and-indent', then insert a parentheses pair."
  (interactive)
  (ignore-errors
    (expand-abbrev))
  (up-list)
  (newline-and-indent)
  (insert "()")
  (forward-char -1))

(defun sotlisp--find-in-buffer (r s)
  "Find the string (concat R (regexp-quote S)) somewhere in this buffer."
  (let ((l (save-excursion
             (goto-char (point-min))
             (save-match-data
               (when (search-forward-regexp (concat r (regexp-quote s) "\\_>")
                                            nil :noerror)
                 (match-beginning 0))))))
    (when l
      (push-mark)
      (goto-char l)
      l)))

(defun sotlisp-find-or-define-function (&optional prefix)
  "If symbol under point is a defined function, go to it, otherwise define it.
Essentially `find-function' on steroids.

If you write in your code the name of a function you haven't
defined yet, just place point on its name and hit \\[sotlisp-find-or-define-function]
and a defun will be inserted with point inside it.  After that,
you can just hit `pop-mark' to go back to where you were.
With a PREFIX argument, creates a `defmacro' instead.

If the function under point is already defined this just calls
`find-function', with one exception:
    if there's a defun (or equivalent) for this function in the
    current buffer, we go to that even if it's not where the
    global definition comes from (this is useful if you're
    writing an Emacs package that also happens to be installed
    through package.el).

With a prefix argument, defines a `defmacro' instead of a `defun'."
  (interactive "P")
  (let ((name (sotlisp--function-at-point)))
    (unless (and name (sotlisp--find-in-buffer "(def\\(un\\|macro\\|alias\\) " name))
      (let ((name-s (intern-soft name)))
        (if (fboundp name-s)
            (find-function name-s)
          (push-mark)
          (end-of-defun)
          (insert "\n(def" (if prefix "macro" "un")
                  " " name " (")
          (save-excursion (insert ")\n  \"\"\n  )\n")))))))

(defun sotlisp--function-at-point ()
  "Return name of `function-called-at-point'."
  (if (save-excursion
        (ignore-errors (forward-sexp -1)
                       (looking-at-p "#'")))
      (thing-at-point 'symbol)
    (if-let ((fcap (function-called-at-point)))
        (symbol-name fcap)
      (thing-at-point 'symbol))))

(defun sotlisp-find-or-define-variable (&optional prefix)
  "If symbol under point is a defined variable, go to it, otherwise define it.
Essentially `find-variable' on steroids.

If you write in your code the name of a variable you haven't
defined yet, place point on its name and hit \\[sotlisp-find-or-define-variable]
and a `defcustom' will be created with point inside.  After that,
you can just `pop-mark' to go back to where you were.  With a
PREFIX argument, creates a `defvar' instead.

If the variable under point is already defined this just calls
`find-variable', with one exception:
    if there's a defvar (or equivalent) for this variable in the
    current buffer, we go to that even if it's not where the
    global definition comes from (this is useful if you're
    writing an Emacs package that also happens to be installed
    through package.el).

With a prefix argument, defines a `defvar' instead of a `defcustom'."
  (interactive "P")
  (let ((name (symbol-name (variable-at-point t))))
    (unless (sotlisp--find-in-buffer "(def\\(custom\\|const\\|var\\) " name)
      (unless (and (symbolp (variable-at-point))
                   (ignore-errors (find-variable (variable-at-point)) t))
        (push-mark)
        (let ((name (thing-at-point 'symbol)))
          (beginning-of-defun)
          (when (looking-back "^;;;###autoload\\s-*\n")
            (forward-line -1))
          (insert "(def" (if prefix "var" "custom")
                  " " name " t")
          (save-excursion
            (insert "\n  \"\"\n  :type 'boolean)\n\n")))))))

(provide 'sotlisp)
;;; sotlisp.el ends here


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Proposed Minor-mode] Speed of thought Lisp
  2015-01-24 16:38 [Proposed Minor-mode] Speed of thought Lisp (was: Abbrevs for the most frequent elisp symbols) Artur Malabarba
@ 2015-01-25 14:49 ` Stefan Monnier
  2015-01-26 19:37   ` Artur Malabarba
  2015-01-27 12:28 ` Oleh Krehel
  1 sibling, 1 reply; 16+ messages in thread
From: Stefan Monnier @ 2015-01-25 14:49 UTC (permalink / raw)
  To: Artur Malabarba; +Cc: emacs-devel

>    - C-c f :: Find function under point. If it is not defined, create a
>    definition for it below the current function and leave point inside.
>    - C-c v :: Same, but for variable.

For variables (and macros and defsubst), it's important that the
declaration be *before* rather than "below".  For plain functions I also
like to define them before I use them, tho it's not indispensable.

> Cheers to all, and please let me hear your thoughts!

Sounds neat.  Even neater would be to make the list dynamic.
As suggested on g.e.h, it could do a "completion with `initials' style",
selecting the first completion, with sorting based on frequency hints.


        Stefan



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Proposed Minor-mode] Speed of thought Lisp
  2015-01-25 14:49 ` [Proposed Minor-mode] Speed of thought Lisp Stefan Monnier
@ 2015-01-26 19:37   ` Artur Malabarba
  2015-01-26 21:01     ` Dmitry Gutov
  2015-01-27  3:36     ` Stefan Monnier
  0 siblings, 2 replies; 16+ messages in thread
From: Artur Malabarba @ 2015-01-26 19:37 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

2015-01-25 12:49 GMT-02:00 Stefan Monnier >>    - C-c f :: Find
function under point. If it is not defined, create a
>>    definition for it below the current function and leave point inside.
>>    - C-c v :: Same, but for variable.
>
> For variables (and macros and defsubst), it's important that the
> declaration be before rather than "below".  For plain functions I also
> like to define them before I use them, tho it's not indispensable.

Good point, I'll change that.

>> Cheers to all, and please let me hear your thoughts!
>
> Sounds neat.  Even neater would be to make the list dynamic.
> As suggested on g.e.h, it could do a "completion with `initials' style",
> selecting the first completion, with sorting based on frequency hints.

I'm happy to change and extend the abbrevs to something based on usage
frequency of current Emacs core, but implementing a completion system
would just feel like reinventing abbrevs. Also, these expansions work
best as a complement to tab-completion, not as
yet-another-tab-completion. While tab-completion handles user-defined
symbols which are project-dependent and can change at any time, these
abbrevs offer a fixed set of symbols that are always useful and easy
to remember.

Unless you meant to sort based on the user's current usage frequency
(something dynamic), but that would be a whole other beast to tackle
and I wouldn't even be sure where to start :-).



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Proposed Minor-mode] Speed of thought Lisp
  2015-01-26 19:37   ` Artur Malabarba
@ 2015-01-26 21:01     ` Dmitry Gutov
  2015-01-26 23:46       ` Rasmus
  2015-01-27  3:36     ` Stefan Monnier
  1 sibling, 1 reply; 16+ messages in thread
From: Dmitry Gutov @ 2015-01-26 21:01 UTC (permalink / raw)
  To: bruce.connor.am, Stefan Monnier; +Cc: emacs-devel

On 01/26/2015 09:37 PM, Artur Malabarba wrote:
> Unless you meant to sort based on the user's current usage frequency
> (something dynamic), but that would be a whole other beast to tackle
> and I wouldn't even be sure where to start :-).

FWIW, my first reaction was also thinking of the `initials' style. And 
if you use company-mode for completion, company-statistics [0] can track 
the usage frequency.

[0] https://github.com/company-mode/company-statistics



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Proposed Minor-mode] Speed of thought Lisp
  2015-01-26 21:01     ` Dmitry Gutov
@ 2015-01-26 23:46       ` Rasmus
  2015-01-27  2:17         ` Dmitry Gutov
  0 siblings, 1 reply; 16+ messages in thread
From: Rasmus @ 2015-01-26 23:46 UTC (permalink / raw)
  To: emacs-devel

Dmitry Gutov <dgutov@yandex.ru> writes:

> On 01/26/2015 09:37 PM, Artur Malabarba wrote:
>> Unless you meant to sort based on the user's current usage frequency
>> (something dynamic), but that would be a whole other beast to tackle
>> and I wouldn't even be sure where to start :-).
>
> FWIW, my first reaction was also thinking of the `initials' style. And
> if you use company-mode for completion, company-statistics [0] can
> track the usage frequency.
>
> [0] https://github.com/company-mode/company-statistics

Looks interesting.  The docs says it should be in Gnu ELPA, but I don't
see it (also not as part of company). . .

—Rasmus

-- 
There are known knowns; there are things we know that we know




^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Proposed Minor-mode] Speed of thought Lisp
  2015-01-26 23:46       ` Rasmus
@ 2015-01-27  2:17         ` Dmitry Gutov
  0 siblings, 0 replies; 16+ messages in thread
From: Dmitry Gutov @ 2015-01-27  2:17 UTC (permalink / raw)
  To: Rasmus, emacs-devel

On 01/27/2015 01:46 AM, Rasmus wrote:

>> [0] https://github.com/company-mode/company-statistics
>
> Looks interesting.  The docs says it should be in Gnu ELPA, but I don't
> see it (also not as part of company). . .

Hmm, it appears I've dropped the ball on that conversation. Thanks for 
the reminder.



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Proposed Minor-mode] Speed of thought Lisp
  2015-01-26 19:37   ` Artur Malabarba
  2015-01-26 21:01     ` Dmitry Gutov
@ 2015-01-27  3:36     ` Stefan Monnier
  1 sibling, 0 replies; 16+ messages in thread
From: Stefan Monnier @ 2015-01-27  3:36 UTC (permalink / raw)
  To: Artur Malabarba; +Cc: emacs-devel

BTW, regardless of the discussion about "making it dynamic", I'd welcome
this in GNU ELPA, of course,


        Stefan



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Proposed Minor-mode] Speed of thought Lisp
  2015-01-24 16:38 [Proposed Minor-mode] Speed of thought Lisp (was: Abbrevs for the most frequent elisp symbols) Artur Malabarba
  2015-01-25 14:49 ` [Proposed Minor-mode] Speed of thought Lisp Stefan Monnier
@ 2015-01-27 12:28 ` Oleh Krehel
  2015-01-27 13:57   ` Artur Malabarba
  1 sibling, 1 reply; 16+ messages in thread
From: Oleh Krehel @ 2015-01-27 12:28 UTC (permalink / raw)
  To: bruce.connor.am; +Cc: emacs-devel


I really like `sotlisp--default-function-abbrevs', and I'd love if it
could be a standardized as much as possible, so that it would change
very rarely once it's in GNU ELPA. Very few changes would be an immense
advantage for building muscle memory.

It would be great to separate the abbrevs from the rest of the commands,
and make a minor mode that upgrades `abbrev-mode' for Elisp.  Then
sotlisp.el could just `require' this new minor mode.

Oleh



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Proposed Minor-mode] Speed of thought Lisp
  2015-01-27 12:28 ` Oleh Krehel
@ 2015-01-27 13:57   ` Artur Malabarba
  2015-01-27 14:15     ` Oleh Krehel
  0 siblings, 1 reply; 16+ messages in thread
From: Artur Malabarba @ 2015-01-27 13:57 UTC (permalink / raw)
  To: Oleh Krehel; +Cc: emacs-devel

2015-01-27 1:36 GMT-02:00 Stefan Monnier <monnier@iro.umontreal.ca>:
> BTW, regardless of the discussion about "making it dynamic", I'd welcome
> this in GNU ELPA, of course,

2015-01-27 10:28 GMT-02:00 Oleh Krehel <ohwoeowho@gmail.com>:
> I really like `sotlisp--default-function-abbrevs', and I'd love if it
> could be a standardized as much as possible, so that it would change
> very rarely once it's in GNU ELPA. Very few changes would be an immense
> advantage for building muscle memory.

Yes, I'll push this to Elpa as soon as I can build a thorough set of
abbrevs based on actual usage frequency. If anyone happens to have any
sort of script related to counting that, it would be a great help. :-)



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Proposed Minor-mode] Speed of thought Lisp
  2015-01-27 13:57   ` Artur Malabarba
@ 2015-01-27 14:15     ` Oleh Krehel
  2015-01-27 15:25       ` Stefan Monnier
  0 siblings, 1 reply; 16+ messages in thread
From: Oleh Krehel @ 2015-01-27 14:15 UTC (permalink / raw)
  To: bruce.connor.am; +Cc: emacs-devel

On Tue, Jan 27, 2015 at 2:57 PM, Artur Malabarba
<bruce.connor.am@gmail.com> wrote:
> 2015-01-27 1:36 GMT-02:00 Stefan Monnier <monnier@iro.umontreal.ca>:
>> BTW, regardless of the discussion about "making it dynamic", I'd welcome
>> this in GNU ELPA, of course,
>
> 2015-01-27 10:28 GMT-02:00 Oleh Krehel <ohwoeowho@gmail.com>:
>> I really like `sotlisp--default-function-abbrevs', and I'd love if it
>> could be a standardized as much as possible, so that it would change
>> very rarely once it's in GNU ELPA. Very few changes would be an immense
>> advantage for building muscle memory.
>
> Yes, I'll push this to Elpa as soon as I can build a thorough set of
> abbrevs based on actual usage frequency. If anyone happens to have any
> sort of script related to counting that, it would be a great help. :-)

I think it would be efficient if you posted the package to your Github
and let it ferment there for a month or two. Maybe you'll get a
community-driven list of abbrevs going. I'd certainly try to help.
And once it stabilizes, you could put it into GNU ELPA as sort of a
"stable" version.

Because, if you update the muscle-memory stuff after the release,
it would probably upset the users. Just imagine `org-mode` rebinding
<S-iso-lefttab> midway.

Oleh



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Proposed Minor-mode] Speed of thought Lisp
  2015-01-27 14:15     ` Oleh Krehel
@ 2015-01-27 15:25       ` Stefan Monnier
  2015-01-27 15:40         ` Oleh Krehel
  0 siblings, 1 reply; 16+ messages in thread
From: Stefan Monnier @ 2015-01-27 15:25 UTC (permalink / raw)
  To: Oleh Krehel; +Cc: bruce.connor.am, emacs-devel

> community-driven list of abbrevs going. I'd certainly try to help.
> And once it stabilizes, you could put it into GNU ELPA as sort of a
> "stable" version.

GNU ELPA is not a retirement home.  Things can ferment there just as
well as anywhere else.


        Stefan



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Proposed Minor-mode] Speed of thought Lisp
  2015-01-27 15:25       ` Stefan Monnier
@ 2015-01-27 15:40         ` Oleh Krehel
  2015-01-27 16:40           ` Rasmus
  0 siblings, 1 reply; 16+ messages in thread
From: Oleh Krehel @ 2015-01-27 15:40 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: bruce.connor.am, emacs-devel

On Tue, Jan 27, 2015 at 4:25 PM, Stefan Monnier
<monnier@iro.umontreal.ca> wrote:
>> community-driven list of abbrevs going. I'd certainly try to help.
>> And once it stabilizes, you could put it into GNU ELPA as sort of a
>> "stable" version.
>
> GNU ELPA is not a retirement home.  Things can ferment there just as
> well as anywhere else.

Sorry for offending :). My impression was the GNU ELPA is a rolling
release.  I see now that it's possible to download older releases from
https://elpa.gnu.org/packages/.  It just makes sense to have something
to revert to, especially for packages that focus on key bindings.



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Proposed Minor-mode] Speed of thought Lisp
  2015-01-27 15:40         ` Oleh Krehel
@ 2015-01-27 16:40           ` Rasmus
  2015-01-27 18:19             ` Oleh Krehel
  0 siblings, 1 reply; 16+ messages in thread
From: Rasmus @ 2015-01-27 16:40 UTC (permalink / raw)
  To: emacs-devel

Oleh Krehel <ohwoeowho@gmail.com> writes:

>  My impression was the GNU ELPA is a rolling release.

The Magic Pixies make a new release when you change the version-header.
It is their custom.

—Rasmus

-- 
El Rey ha muerto. ¡Larga vida al Rey!




^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Proposed Minor-mode] Speed of thought Lisp
  2015-01-27 16:40           ` Rasmus
@ 2015-01-27 18:19             ` Oleh Krehel
  2015-01-27 18:23               ` Dmitry Gutov
  0 siblings, 1 reply; 16+ messages in thread
From: Oleh Krehel @ 2015-01-27 18:19 UTC (permalink / raw)
  To: Rasmus; +Cc: emacs-devel

On Tue, Jan 27, 2015 at 5:40 PM, Rasmus <rasmus@gmx.us> wrote:
> Oleh Krehel <ohwoeowho@gmail.com> writes:
>
>>  My impression was the GNU ELPA is a rolling release.
>
> The Magic Pixies make a new release when you change the version-header.
> It is their custom.

Yea, I realize that:)

Is there a way to get any version other than the last one from the
`package-list-packages' interface?



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Proposed Minor-mode] Speed of thought Lisp
  2015-01-27 18:19             ` Oleh Krehel
@ 2015-01-27 18:23               ` Dmitry Gutov
  2015-01-27 18:29                 ` Oleh Krehel
  0 siblings, 1 reply; 16+ messages in thread
From: Dmitry Gutov @ 2015-01-27 18:23 UTC (permalink / raw)
  To: Oleh Krehel, Rasmus; +Cc: emacs-devel

On 01/27/2015 08:19 PM, Oleh Krehel wrote:
> Is there a way to get any version other than the last one from the
> `package-list-packages' interface?

Not really: package.el has no support for this feature.

Not only it would have to allow the user to pick, the package archives 
would have to include the different versions they have in the output, 
which seems like a breaking change (unless they list the packages many 
times, each with a different version, which will linearly increase the 
download time).



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Proposed Minor-mode] Speed of thought Lisp
  2015-01-27 18:23               ` Dmitry Gutov
@ 2015-01-27 18:29                 ` Oleh Krehel
  0 siblings, 0 replies; 16+ messages in thread
From: Oleh Krehel @ 2015-01-27 18:29 UTC (permalink / raw)
  To: Dmitry Gutov; +Cc: Rasmus, emacs-devel

On Tue, Jan 27, 2015 at 7:23 PM, Dmitry Gutov <dgutov@yandex.ru> wrote:
> On 01/27/2015 08:19 PM, Oleh Krehel wrote:
>>
>> Is there a way to get any version other than the last one from the
>> `package-list-packages' interface?
>
>
> Not really: package.el has no support for this feature.
>
> Not only it would have to allow the user to pick, the package archives would
> have to include the different versions they have in the output, which seems
> like a breaking change (unless they list the packages many times, each with
> a different version, which will linearly increase the download time).

But see the bottom of e.g. https://elpa.gnu.org/packages/company.html,
the old versions are actually available for download.  And
`url-retrieve` - `package-install-from-buffer` combo would actually
work, there's just no interface for it yet.



^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2015-01-27 18:29 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-01-24 16:38 [Proposed Minor-mode] Speed of thought Lisp (was: Abbrevs for the most frequent elisp symbols) Artur Malabarba
2015-01-25 14:49 ` [Proposed Minor-mode] Speed of thought Lisp Stefan Monnier
2015-01-26 19:37   ` Artur Malabarba
2015-01-26 21:01     ` Dmitry Gutov
2015-01-26 23:46       ` Rasmus
2015-01-27  2:17         ` Dmitry Gutov
2015-01-27  3:36     ` Stefan Monnier
2015-01-27 12:28 ` Oleh Krehel
2015-01-27 13:57   ` Artur Malabarba
2015-01-27 14:15     ` Oleh Krehel
2015-01-27 15:25       ` Stefan Monnier
2015-01-27 15:40         ` Oleh Krehel
2015-01-27 16:40           ` Rasmus
2015-01-27 18:19             ` Oleh Krehel
2015-01-27 18:23               ` Dmitry Gutov
2015-01-27 18:29                 ` Oleh Krehel

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).