I would share commentaris about my tridactylrc here, which may be helpfull. I really think some of they are interesting. Anyone's commentary or improvement are welcome too.
The masked rc is publicly hosted on the following forgejo server: https://git.disroot.org/gholk/dot-file/src/branch/main/tridactylrc . The personal information is removed (some bindurl and seturl commands), and so do the commit log. Contact me if you really want to read them.
usage
The commentaries are link to the line number of the commit hash, since track the line numbers with evolution is hard.
Moreover, the commands (or configs) often require some other commands to work. Mostly I will not mention the required commands; you have to find them yourself or just source the whole rc.
uglify js
All javascript are uglify to one line (but not compressed),
to read or modify them, just prettify it.
(with uglifyjs -b, firefox's devtool or something else)
I just work in this way.
version control about tridactylrc
Tridactyl sometimes mess up the persistent config store in browser,
and it will be hard to maintain a clean rc file without the native messenger and the source command.
The mktridactylrc fix (alias mktp) command will output a sorted and tidy tridactylrc;
copy it with composite mktridactylrc_fix | yank .
It will skip the default binding and sort the rc,
so the line number of rc will be stable and we can track it with git.
The source --clipboard command can source tridactylrc from clipboard.
To use my rc, just copy the whole rc file and call the source --clipboard command.
note it will not sanitise. To sanitise and source, use the source clipboard sanitise command.
Reuse js code
There is a useful jse command, which define many useful functions, and we can reuse them because tridactyl will recursive expand the command alias and append the argument strings.
For example, if we define:
command jse js let $ = q => document.querySelector(q);
command js_body jse let body = $('body');
command body_green js_body body.style.backgroundColor = 'green'
The command body_green will expand to:
body_green
# -> js_body body.style.backgroundColor = 'green'
# -> jse let body = $('body'); body.style.backgroundColor = 'green'
# -> js let $ = q => document.querySelector(q); let body = $('body'); body.style.backgroundColor = 'green'
useful js commands
jse, jsep and jse@ are commands define $ $all $ex $d $w run.
jsep is same to js -p, and jse@ is same to js -d@ (you have to add the @ to close a delimiter command).
$ $all is similar to querySelector and querySelectorAll, $ex async execute a ex command, $d is document and $w is window.
run is use to execute a wrap async function, so you don't need to (async () => { /* async code here */ })(),
just run(async () => { /* async */ }).
ex input node define the node to the <input> of the ex cmdline and all the jse function,
and return the node in js context.
use the node.value to access ex cmdline's content.
video with define the video to a video element in the page and all the jse function,
and return the video in js context.
drop_with see UI to drop file.
hint_with see UI to select element TODO.
in js context
If you are already in js context and want to reuse the code,
use the $ex function defined in jse
and make sure the command's js codes will evaluate to the value you want.
The $ex command not only execute the ex command but also return a promise
which resolve to the command's return value.
If you define:
command body_exp js document.body
the await $ex('body_exp') or composite body_exp | js -p JS_ARG will evaluate to the document.body,
but we will not be able to do body_exp body.appendChild(sth).
to reuse code in both js context and command expansion context, I define command like this:
command js_body js let body = document.body; body;
These statement still evaluate (the eval function in js) to body, and we also have a body variable,
or just manually make the last statement be the value you want: await $ex('js_body let child = body.firstChild; child').
To get more than one value: let [$, $all] = await $ex('jse [$, $all]')
play with JS_ARG command
If a command is defined with js -p and do something with the special variable JS_ARG,
reusing it will be a little tricky.
In fact, the js -p will simply take the previous command's return value in the composite context,
or take the string after the last space, as the JS_ARG.
given a simple command show:
command show js -p var show = msg => fillcmdline('# ' + msg); show(JS_ARG);
call it:
show foo
# -> js -p var show = msg => fillcmdline('# ' + msg); show(JS_ARG); foo
# -> js var JS_ARG = 'foo'; var show = msg => fillcmdline('# ' + msg); show(JS_ARG);
To reuse the defined function in it, we have to pre-define some special value which make command do nothing.
special string
command show js -p var show = msg => fillcmdline('# ' + msg); if (JS_ARG != '//nop//') show(JS_ARG);
$ex('show foo') // fillcmdline # foo
var x = await $ex('show 1 // foo')
// -> js -p var show = msg => fillcmdline('# ' + msg); if (JS_ARG != 'nop') show(JS_ARG); 1 // foo
// -> js var JS_ARG = 'foo'; var show = msg => fillcmdline('# ' + msg); if (JS_ARG != 'nop') show(JS_ARG); 1 //
// x == 1, fillcmdline foo
var show = await $ex('show show //nop//')
// show == msg => fillcmdline('# ' + msg), JS_ARG == '//nop//'
show('some message') // you can use the show function here.
accept only non-string value
command show js -p var show = msg => fillcmdline('# ' + msg); if (typeof JS_ARG == 'object') show(JS_ARG.msg); ;
The last semicolon will become the JS_ARG if nothing pass as argument, and act as a empty statement if any js code passed as argument.
In this case, call show in cmdline will always do nothing. One can only trigger the side effect like:
composte js {msg: 'hey'} | showjse tri._wrap = {msg: 'hey'}; $ex('composite js tri._wrap | show').then(() => tri._wrap = null)
and get the defined function like:
var show = await $ex('show show // nop')
// -> js -p var show = msg => fillcmdline('# ' + msg); if (typeof JS_ARG == 'object') show(JS_ARG.msg); ; show // nop
// -> js var JS_ARG = 'nop'; var show = msg => fillcmdline('# ' + msg); if (typeof JS_ARG == 'object') show(JS_ARG.msg); ; show
show({msg: 'some message'})
UI to drop file
use the drop with command to open cmdline and accept droping file on it one time.
you have to set the onDrop callback on the drop with command.
Eg:
drop_with onDrop = dropEvent => fillcmdline('# the file you drop is ' + dropEvent.dataTransfer.files[0].name)
will open the ex cmdline, wait you drop the file on it, and show the filename you drop.
To read the file content, you need the FileReader or ArrayBuffer api;
see the source drop command.
source tridactylrc from droped file
the source drop command will wait you drop the rc file on cmdline and prepare a command to source it (you need to press enter after drop the file).
the rc will be prepand a sanitise tridactyllocal command so the config will be clean.
to source without sanitise, remove the 'santise tridactyllocal\n' + in the cmdline.
save and resume the content in ex commandline
Press <C-s> in ex mode will save the content in command line,
and next time you press : to open command line the save content will present.
switch between tabopen and open
Easy tricks to switch between tabopen and open is to create following alias
alias topen tabopen
alias otabopen open
alias o open
alias to tabopen
Then if one's excmd line has open some.url,
hit <A-a> t and it become topen some.url,
which is an alias of tabopen,
and so do the otabopen.
(if you have bind --mode=ex <A-a> text.beginning_of_line)
expand searchurls
The command jsurl-expand is useful to expand a searchurls or jsurls.
I have aliases xopen xtabopen xt for it,
so prefixing the command open tabopen t with x,
make it show the expanded url in command line instead of open it directly.
# set searchurls.github https://github.com/search?utf8=✓&q=
xtabopen github tridactyl
# -> tabopen https://github.com/search?utf8=✓&q=tridactyl
Though the command name is jsurl-expand,
it does expand searchurls too.
minor mode
something like minor mode:
// command mode-minor-set js ...
async function modeMinorSet(minor, lmap) {
const h = location.hash || '#'
history.pushState(0, '', `${h}&--gholk-minor=${minor}&`)
// 0 because object from web-extension context
// throw error in web page's js
// force tridactyl clean cache
await tri.excmds.set("keymap_cache_update", Date.now())
// generate keymap with new url
for (const m of lmap) tri.keyseq.keyMap(m)
window.addEventListener('popstate',
e => {e.stopImmediatePropagation()},
{capture: true, once: true}
)
history.back() // remove hash
}
bindurl &--gholk-minor=annotate& --mode=visual c some-command
mode-minor-set modeMinorSet('annotate', ['vmaps'])
Now we can use bindings in &--gholk-minor=annotate&