A type of light spherical helmet.
If you want to contribute, read the dev notes to learn about the architecture. It is modular and extensible, so you can easily add useful bits without breaking the rest.
A type of light spherical helmet
License: GNU General Public License v3.0
A type of light spherical helmet.
If you want to contribute, read the dev notes to learn about the architecture. It is modular and extensible, so you can easily add useful bits without breaking the rest.
This can be useful to do narrowing through "category trees" where we wouldn't flatten the structure immediately. Each candidate would yield another collection which would be started in a separate (recursive?) sallet. There could be a way to go back and forth.
(This is probably the last dependency on helm I need to get rid of)
The helm implementation for reference is in this fork: https://github.com/Fuco1/helm/blob/master/helm-org.el
If I have three sources for one csallet and the first two are empty, I have to invoke "next candidate" three times instead of just once. This probably happens because I have to skip the header line "manually". This
We should always move at least one actual visible candidate.
Example use-case: filter out buffers, then run moccur/ag/grep on the results.
Because each sallet can have its own interface, we should prefer to launch a new "instance" (possibly keeping a stack of sources so we can revert ot the source one).
For example on gtags files
This package has minimal adoption so caring about the userbase is pointless. Let's not waste time and just bump the minimal Emacs version.
See for example csallet-candidate-up
where we do resolution of canvas-specific predicates.
I've played around with the licensee gem and noticed that it failed detecting sallet's license because there was no LICENSE file at all. Normally I'd just have committed and pushed one, but I've detected that ever since you've moved the repository to your own account, I no longer have commit rights :D
https://github.com/alphapapa/frecency.el
Maybe also consdier ditching flx
and use a graph-based search instead (flx is quite a hog in terms of performance).
There should be a binding to pop up the options bar (standard among sallets) where the user could switch CMD arguments to the process and immediately see the results update in the output.
Right now it sometimes crashes the popup if the IO source is slower than the renderer or the dynamic array expansion happens at the wrong time. We should return something like data Maybe
and test for both cases (or mabye nil
will do)
Currently it's not clear whether a list is a candidate + user data or just candidate (which is a list). Because some producers produce just candidates which are later enriched it is difficult to decide what to do.
We should split the data everywhere into two variables, one for just the candidate (immutable, never changed during the pipeline) and user data which can be modified by all the stages.
We can either open a separate buffer or have it somehow inline. This could include
imenu
show the function context@function
or #fulltext
show the contextSometimes there is ~
and sometimes there is /home/<user>
. We should always shorten to ~
but at the same time the matcher should operate on the full path so that a query //home
or <user>
would also select those files. Probably the ~
should be highlighted then to show that we are matching there.
This could be done by fontifying the whole path first and then doing string replace which should keep the properties of the replaced regions
(note to self: ISTR there is something like that already present somewhere, or maybe it is in my modeline shortening routine)
Really annoys me deeply!!!!
I.e. inserting a space should not re-run the commands because it would not change the output in any meaningful way.
We should have some property on each sallet, like requires-update
which should check if an update is required or not.
Some features we should include are
C-h f
which is broken in newer emacsen (the package autoloading, see help--symbol-completion-table
, but if possible we should probably implement it somehow)Error in post-command-hook ((closure ((state (sources [object sallet-source-buffer "sallet-source-buffer" nil sallet-buffer-matcher (lambda (x _) x) sallet-buffer-renderer switch-to-buffer ["github.md" "sallet.el" "eyebrowse.el" "*SPEEDBAR*" "*notes*" "*scratch*" "*Messages*" "*package-build-checkout*" "*Compile-Log*" "*helm-mode-eyebrowse-switch-to-window-config*" "*Help*" "*helm-mode-quelpa*" "*Helm Find Files*" "*magit-process*" "*magit: sallet*" "*helm-smex*" "*Sallet candidates*"] nil nil "Buffers"]) (current-buffer . #<buffer sallet.el>) (prompt . "ern: ") (selected-candidate . 0) (processes) (candidate-buffer . #<killed buffer>)) t) nil (sallet-minibuffer-post-command-hook state))): (error "Selecting deleted buffer")
This should open a sallet with the default directory as it was at the time of saving and also restore the query.
Right now it is really difficult to pick between different files with the same name in different directories. We should attempt to uniquify the set based on the provided file paths/default directories, such that the bookmark name is printed uniquified and the full path is provided with appropriate shortenings (see #35).
Sometimes when the first source doesn't render any candidate and the second source does the point will move there and never re-set back to top of the first source if more candidates come later.
This is rather annoying as the behaviour depends on how the concurrency is scheduled. We should always set the point to the first candidate if the user extends the query and does nothing afterwards, even as more candidates stream in.
It should support the #fulltext
pattern to search for text inside the files
Ideally with customizable context around the point, so we see where we're jumping
This is a prereq for #20.
There should be some api with addOption
taking short/long option and possible values. At the end, there should be a build
function to return the command line ready to be passed to start-process
.
incf
and decf
are used instead of either requiring cl or using the cl- things in cl-lib, so sallet-candidate-{up,down}
results in void-function
Debugger entered--Lisp error: (wrong-type-argument eieio-object-p sallet-source-ido-virtual-buffer)
signal(wrong-type-argument (eieio-object-p sallet-source-ido-virtual-buffer))
eieio-oref(sallet-source-ido-virtual-buffer generator)
sallet-source-get-generator(sallet-source-ido-virtual-buffer)
(functionp (sallet-source-get-generator source))
(cond ((functionp candidates) (setq candidates (funcall candidates))) ((or (listp candidates) (vectorp candidates) (let ((sv (condition-case nil (progn ...) (error nil)))) (if sv (progn (if (or ... ...) (progn ...))))))) ((functionp (sallet-source-get-generator source)) (setq candidates nil)) (t (error "Invalid source: no way to generate candidates")))
(let ((candidates (sallet-source-get-candidates instance))) (cond ((functionp candidates) (setq candidates (funcall candidates))) ((or (listp candidates) (vectorp candidates) (let ((sv (condition-case nil ... ...))) (if sv (progn (if ... ...)))))) ((functionp (sallet-source-get-generator source)) (setq candidates nil)) (t (error "Invalid source: no way to generate candidates"))) (if (and candidates (not (vectorp candidates))) (progn (setq candidates (vconcat candidates)))) (sallet-source-set-candidates instance candidates) (sallet-source-set-processed-candidates instance (number-sequence 0 (1- (length candidates)))))
(let ((instance (funcall source (symbol-name source)))) (let ((candidates (sallet-source-get-candidates instance))) (cond ((functionp candidates) (setq candidates (funcall candidates))) ((or (listp candidates) (vectorp candidates) (let ((sv ...)) (if sv (progn ...))))) ((functionp (sallet-source-get-generator source)) (setq candidates nil)) (t (error "Invalid source: no way to generate candidates"))) (if (and candidates (not (vectorp candidates))) (progn (setq candidates (vconcat candidates)))) (sallet-source-set-candidates instance candidates) (sallet-source-set-processed-candidates instance (number-sequence 0 (1- (length candidates))))) (let ((generator (sallet-source-get-generator instance))) (if (functionp generator) nil (sallet-source-set-generator instance (eval generator t)))) instance)
sallet-init-source(sallet-source-ido-virtual-buffer)
mapcar(sallet-init-source (sallet-source-buffer sallet-source-ido-virtual-buffer sallet-source-bookmarks-file-only))
-map(sallet-init-source (sallet-source-buffer sallet-source-ido-virtual-buffer sallet-source-bookmarks-file-only))
(cons (quote sources) (-map (quote sallet-init-source) sources))
(list (cons (quote sources) (-map (quote sallet-init-source) sources)) (cons (quote current-buffer) (current-buffer)) (cons (quote prompt) "") (cons (quote selected-candidate) 0) (cons (quote candidate-buffer) candidate-buffer))
(let ((state (list (cons (quote sources) (-map (quote sallet-init-source) sources)) (cons (quote current-buffer) (current-buffer)) (cons (quote prompt) "") (cons (quote selected-candidate) 0) (cons (quote candidate-buffer) candidate-buffer)))) (setq sallet-state state) state)
sallet-init-state((sallet-source-buffer sallet-source-ido-virtual-buffer sallet-source-bookmarks-file-only) #<buffer *Candidates*>)
(let* ((buffer (get-buffer-create "*Candidates*")) (state (sallet-init-state sources buffer))) (pop-to-buffer buffer) (setq cursor-type nil) (sallet-render-state state) (condition-case var (let (setup-hook) (setq setup-hook (function (lambda nil (remove-hook (quote minibuffer-setup-hook) setup-hook) (funcall (function ...))))) (unwind-protect (progn (add-hook (quote minibuffer-setup-hook) setup-hook) (read-from-minibuffer ">>> " nil (let (...) (set-keymap-parent map minibuffer-local-map) (define-key map ... ...) (define-key map ... ...) map)) (sallet-default-action)) (remove-hook (quote minibuffer-setup-hook) setup-hook))) (quit (kill-buffer-and-window)) (error (kill-buffer-and-window))))
sallet((sallet-source-buffer sallet-source-ido-virtual-buffer sallet-source-bookmarks-file-only))
sallet-buffer()
call-interactively(sallet-buffer record nil)
command-execute(sallet-buffer record)
(let ((prefix-arg current-prefix-arg)) (command-execute command (quote record)) (smex-rank command))
helm-smex-execute-command(sallet-buffer)
apply(helm-smex-execute-command sallet-buffer)
helm-funcall-with-source(((match helm-mp-exact-match helm-mp-3-match) (name . "M-x") (candidates . helm-smex-items) (coerce . intern) (action ("smex" helm-smex-execute-command)) (header-line . helm-persistent-help-string)) (helm-smex-execute-command) sallet-buffer)
helm-execute-selection-action-1()
helm-execute-selection-action()
#[0 "\311\211\211\211\305\206\n��#�#�$�%�&�'\312\313�(\"\314\315\316\317\320\321��!\322\"\323\324%DC\216\325\303\301\307\300$\210\326�#!\210\327\330\331\"\210\332\333!\210\314\334DC\216\335\302\301\304\303\306\307\310&�\210*\210�$?\205Y�\336 \332\337\340\341\342\"P!\210-\207" [helm-smex-source nil nil nil nil "*helm-smex*" nil nil nil nil mapcar #[257 "\211�JB\207" [] 3 "\n\n(fn V)"] funcall make-byte-code 0 "\300\301\211�:\203���@\262��\211A\262�\242\262�\211�L\210�A\262�\202��\266�\302\303!\207" vconcat vector [nil helm-log "restore variables"] 5 "\n\n(fn)" helm-initialize helm-display-buffer add-hook post-command-hook helm--maybe-update-keymap helm-log "show prompt" #[0 "\300 \207" [helm-cleanup] 1 "\n\n(fn)"] helm-read-pattern-maybe helm-execute-selection-action "[End session] " make-string 41 45 helm-buffer helm-quit helm-in-persistent-action helm-current-source helm-source-name helm-restored-variables] 9 "\n\n(fn)"]()
funcall(#[0 "\311\211\211\211\305\206\n��#�#�$�%�&�'\312\313�(\"\314\315\316\317\320\321��!\322\"\323\324%DC\216\325\303\301\307\300$\210\326�#!\210\327\330\331\"\210\332\333!\210\314\334DC\216\335\302\301\304\303\306\307\310&�\210*\210�$?\205Y�\336 \332\337\340\341\342\"P!\210-\207" [helm-smex-source nil nil nil nil "*helm-smex*" nil nil nil nil mapcar #[257 "\211�JB\207" [] 3 "\n\n(fn V)"] funcall make-byte-code 0 "\300\301\211�:\203���@\262��\211A\262�\242\262�\211�L\210�A\262�\202��\266�\302\303!\207" vconcat vector [nil helm-log "restore variables"] 5 "\n\n(fn)" helm-initialize helm-display-buffer add-hook post-command-hook helm--maybe-update-keymap helm-log "show prompt" #[0 "\300 \207" [helm-cleanup] 1 "\n\n(fn)"] helm-read-pattern-maybe helm-execute-selection-action "[End session] " make-string 41 45 helm-buffer helm-quit helm-in-persistent-action helm-current-source helm-source-name helm-restored-variables] 9 "\n\n(fn)"])
#[0 "\311\312\313\314\315\"P!\210\311\316\302\"\210\311\317\304\"\210\311\320\305\"\210\311\321\306\"\210\311\322\307\"\210\311\323\310\"\210�(\324���)\206W�\325\300!\326\324\326�:\203U��@\262���*>\211\262�?\211\262�\203U��A\262�\2027�\266\203�)��+��\203e�\327\330!\210\331\332\333\334\335\336����\"\337\"\340\341%DC\216\342\331\332\333\343\335\336\300\301\302\303\304\305\306\307\310& \344\"\345\341%D\346\331\347\342EDC\217+\207" [helm-smex-source nil nil nil nil "*helm-smex*" nil nil nil helm-log "[Start session] " make-string 41 43 "any-prompt = %S" "any-preselect = %S" "any-buffer = %S" "any-keymap = %S" "any-default = %S" "any-history = %S" t helm-normalize-sources nil cua-mode -1 funcall make-byte-code 0 "\305\306\307\"\210\310\311!\203��\312\313\314\"\210\312\315\316\"\210\202 �\317\313!\210\317\315!\210\320\321\322\211�\"\210\300�\322\211��\301\2035�\323\324!\210\325 \207" vconcat vector [helm-alive-p overriding-terminal-local-map helm-in-file-completion-p remove-hook post-command-hook helm--maybe-update-keymap fboundp advice-add advice-remove tramp-read-passwd helm--advice-tramp-read-passwd ange-ftp-get-passwd helm--advice-ange-ftp-get-passwd ad-deactivate helm-log "helm-alive-p = %S" nil cua-mode 1 helm-log-save-maybe] 5 "\n\n(fn)" err "\311\211\211\211\305\206\n��#�#�$�%�&�'\312\313�(\"\314\315\316\317\320\321��!\322\"\323\324%DC\216\325\303\301\307\300$\210\326�#!\210\327\330\331\"\210\332\333!\210\314\334DC\216\335\302\301\304\303\306\307\310&�\210*\210�$?\205Y�\336 \332\337\340\341\342\"P!\210-\207" [nil mapcar #[257 "\211�JB\207" [] 3 "\n\n(fn V)"] funcall make-byte-code 0 "\300\301\211�:\203���@\262��\211A\262�\242\262�\211�L\210�A\262�\202��\266�\302\303!\207" vconcat vector [nil helm-log "restore variables"] 5 "\n\n(fn)" helm-initialize helm-display-buffer add-hook post-command-hook helm--maybe-update-keymap helm-log "show prompt" #[0 "\300 \207" [helm-cleanup] 1 "\n\n(fn)"] helm-read-pattern-maybe helm-execute-selection-action "[End session] " make-string 41 45 helm-buffer helm-quit helm-in-persistent-action helm-current-source helm-source-name helm-restored-variables] 9 quit #[257 "\300 \210\301\302\303\304\305\"P!\210\306\207" [helm-restore-position-on-quit helm-log "[End session (quit)] " make-string 34 45 nil] 6 "\n\n(fn V)"] overriding-terminal-local-map helm-maybe-use-default-as-input helm-sources-using-default-as-input non-essential] 19 "\n\n(fn)"]()
funcall(#[0 "\311\312\313\314\315\"P!\210\311\316\302\"\210\311\317\304\"\210\311\320\305\"\210\311\321\306\"\210\311\322\307\"\210\311\323\310\"\210�(\324���)\206W�\325\300!\326\324\326�:\203U��@\262���*>\211\262�?\211\262�\203U��A\262�\2027�\266\203�)��+��\203e�\327\330!\210\331\332\333\334\335\336����\"\337\"\340\341%DC\216\342\331\332\333\343\335\336\300\301\302\303\304\305\306\307\310& \344\"\345\341%D\346\331\347\342EDC\217+\207" [helm-smex-source nil nil nil nil "*helm-smex*" nil nil nil helm-log "[Start session] " make-string 41 43 "any-prompt = %S" "any-preselect = %S" "any-buffer = %S" "any-keymap = %S" "any-default = %S" "any-history = %S" t helm-normalize-sources nil cua-mode -1 funcall make-byte-code 0 "\305\306\307\"\210\310\311!\203��\312\313\314\"\210\312\315\316\"\210\202 �\317\313!\210\317\315!\210\320\321\322\211�\"\210\300�\322\211��\301\2035�\323\324!\210\325 \207" vconcat vector [helm-alive-p overriding-terminal-local-map helm-in-file-completion-p remove-hook post-command-hook helm--maybe-update-keymap fboundp advice-add advice-remove tramp-read-passwd helm--advice-tramp-read-passwd ange-ftp-get-passwd helm--advice-ange-ftp-get-passwd ad-deactivate helm-log "helm-alive-p = %S" nil cua-mode 1 helm-log-save-maybe] 5 "\n\n(fn)" err "\311\211\211\211\305\206\n��#�#�$�%�&�'\312\313�(\"\314\315\316\317\320\321��!\322\"\323\324%DC\216\325\303\301\307\300$\210\326�#!\210\327\330\331\"\210\332\333!\210\314\334DC\216\335\302\301\304\303\306\307\310&�\210*\210�$?\205Y�\336 \332\337\340\341\342\"P!\210-\207" [nil mapcar #[257 "\211�JB\207" [] 3 "\n\n(fn V)"] funcall make-byte-code 0 "\300\301\211�:\203���@\262��\211A\262�\242\262�\211�L\210�A\262�\202��\266�\302\303!\207" vconcat vector [nil helm-log "restore variables"] 5 "\n\n(fn)" helm-initialize helm-display-buffer add-hook post-command-hook helm--maybe-update-keymap helm-log "show prompt" #[0 "\300 \207" [helm-cleanup] 1 "\n\n(fn)"] helm-read-pattern-maybe helm-execute-selection-action "[End session] " make-string 41 45 helm-buffer helm-quit helm-in-persistent-action helm-current-source helm-source-name helm-restored-variables] 9 quit #[257 "\300 \210\301\302\303\304\305\"P!\210\306\207" [helm-restore-position-on-quit helm-log "[End session (quit)] " make-string 34 45 nil] 6 "\n\n(fn V)"] overriding-terminal-local-map helm-maybe-use-default-as-input helm-sources-using-default-as-input non-essential] 19 "\n\n(fn)"])
helm-internal(helm-smex-source nil nil nil nil "*helm-smex*" nil nil nil)
apply(helm-internal (helm-smex-source nil nil nil nil "*helm-smex*" nil nil nil))
helm(helm-smex-source nil nil nil nil "*helm-smex*" nil nil nil)
apply(helm (helm-smex-source nil nil nil nil "*helm-smex*" nil nil nil))
helm(:sources helm-smex-source :buffer "*helm-smex*")
helm-smex()
call-interactively(helm-smex nil nil)
command-execute(helm-smex)
What worked so far was redefining it:
(defun sallet-buffer ()
(interactive)
(sallet (list sallet-source-buffer)))
I conclude that something is wrong with the other sources involved.
Hi,
I just stumbled across this a few days ago... and don't remember how. :) Anyway, I see that you're still working on it. I just wondered, what are your plans in the mid-long term? Thanks. :)
In the places you use s-truncate
it is probably better to use truncate-string-to-width
as it has a clue about the actual width of a string
Further, s-chop-suffix can be string-remove-suffix if you don't care about emacsen older than 24. It's in subr-x though
Instead of erasing the buffer go over the candidates and rewrite them, then remove the rest?
This might get difficult because of the overlays and the canvas structure.
I don't understand what a "light spherical helmet" is supposed to do. ;-)
Right now these use sallet-filter-flx-then-substring
by default and there is no way to modify later search to use flx. So just add a prefix like ~
to do flx search.
I get this when using M-x eval-buffer
on the source code.
Still using Emacs 24.4 on Archlinux. Are you possibly on HEAD?
A replacement for helm-show-kill-ring
(Make this configurable?)
The assumption is that I work on a "project" on the same host and so those files should be easily accessible.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.