-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Command options (in help message) #4554
base: master
Are you sure you want to change the base?
Changes from 4 commits
4b3bdd5
51e8753
034630e
0f93cb5
63f266d
6fdbdd1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -64,8 +64,8 @@ const Commands = { | |
|
||
for (const line of configLines) { | ||
const tokens = line.split(/\s+/); | ||
const command = tokens[0].toLowerCase(); | ||
switch (command) { | ||
const action = tokens[0].toLowerCase(); | ||
switch (action) { | ||
case "map": | ||
if (tokens.length >= 3) { | ||
const [_, key, command, ...optionList] = tokens; | ||
|
@@ -118,7 +118,7 @@ const Commands = { | |
} | ||
break; | ||
default: | ||
logWarning(`"${command}" is not a valid config command in line:`, line); | ||
logWarning(`"${action}" is not a valid config command in line:`, line); | ||
} | ||
} | ||
|
||
|
@@ -260,21 +260,30 @@ const Commands = { | |
const commandToKey = {}; | ||
for (const key of Object.keys(this.keyToRegistryEntry || {})) { | ||
const registryEntry = this.keyToRegistryEntry[key]; | ||
(commandToKey[registryEntry.command] != null | ||
? commandToKey[registryEntry.command] | ||
: (commandToKey[registryEntry.command] = [])).push(key); | ||
const optionString = registryEntry.optionList?.length > 0 | ||
? registryEntry.optionList?.join(" ") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Joining the option list here is the simplest way to turn the options back into a string. It does mean that differently written commands with the same options will be marked different. IE: |
||
: ""; | ||
if (commandToKey[registryEntry.command] == null) { | ||
commandToKey[registryEntry.command] = {}; | ||
} | ||
(commandToKey[registryEntry.command][optionString] != null | ||
? commandToKey[registryEntry.command][optionString] | ||
: (commandToKey[registryEntry.command][optionString] = [])).push(key); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This section changes the
to a 2 level dictionary mapping from command to options set, like:
Commands with no options will have the empty string options set, like:
This allows us to split key mappings to their respective command/options combo, while still allowing us to directly check if we have any mappings to a command with |
||
} | ||
const commandGroups = {}; | ||
for (const group of Object.keys(this.commandGroups || {})) { | ||
const commands = this.commandGroups[group]; | ||
commandGroups[group] = []; | ||
for (const command of commands) { | ||
commandGroups[group].push({ | ||
command, | ||
description: this.availableCommands[command].description, | ||
keys: commandToKey[command] != null ? commandToKey[command] : [], | ||
advanced: this.advancedCommands.includes(command), | ||
}); | ||
for (const [options, keys] of Object.entries(commandToKey[command] ?? { "": [] })) { | ||
commandGroups[group].push({ | ||
command, | ||
description: this.availableCommands[command].description, | ||
keys: keys, | ||
advanced: this.advancedCommands.includes(command), | ||
options: options, | ||
}); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since we now have a 2-level dictionary, we now have a nested loop to loop through both commands and each variation of the command with different options. This also allows us to remove the keys check for null because we provide a default empty array in the loop. So, for each Note that now we are also passing the options with the command entry. |
||
} | ||
} | ||
chrome.storage.session.set({ helpPageData: commandGroups }); | ||
|
@@ -297,7 +306,6 @@ const Commands = { | |
"scrollToLeft", | ||
"scrollToRight", | ||
"reload", | ||
"hardReload", | ||
"copyCurrentUrl", | ||
"openCopiedUrlInCurrentTab", | ||
"openCopiedUrlInNewTab", | ||
|
@@ -386,7 +394,6 @@ const Commands = { | |
"enterVisualLineMode", | ||
"toggleViewSource", | ||
"passNextKey", | ||
"hardReload", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Previously (last PR), |
||
"setZoom", | ||
"zoomIn", | ||
"zoomOut", | ||
|
@@ -409,7 +416,7 @@ const defaultKeyMappings = { | |
"d": "scrollPageDown", | ||
"u": "scrollPageUp", | ||
"r": "reload", | ||
"R": "hardReload", | ||
"R": "reload hard", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We also change the |
||
"yy": "copyCurrentUrl", | ||
"p": "openCopiedUrlInCurrentTab", | ||
"P": "openCopiedUrlInNewTab", | ||
|
@@ -499,7 +506,6 @@ const commandDescriptions = { | |
scrollFullPageUp: ["Scroll a full page up"], | ||
|
||
reload: ["Reload the page", { background: true }], | ||
hardReload: ["Hard reload the page", { background: true }], | ||
toggleViewSource: ["View page source", { noRepeat: true }], | ||
|
||
copyCurrentUrl: ["Copy the current URL to the clipboard", { noRepeat: true }], | ||
|
@@ -562,9 +568,9 @@ const commandDescriptions = { | |
moveTabLeft: ["Move tab to the left", { background: true }], | ||
moveTabRight: ["Move tab to the right", { background: true }], | ||
|
||
setZoom: ["Set zoom level to a given value. E.g. map zz setZoom 1.5", { background: true }], | ||
zoomIn: ["Increase zoom", { background: true }], | ||
zoomOut: ["Decrease zoom", { background: true }], | ||
setZoom: ["Set zoom", { background: true }], | ||
zoomIn: ["Zoom in", { background: true }], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change the command descriptions for zoom in/out to make them match the command name and provide better intuition for the default mappings "zi" and "zo" since that name/description is where the mappings come from. |
||
zoomOut: ["Zoom out", { background: true }], | ||
zoomReset: ["Reset zoom", { background: true }], | ||
|
||
"Vomnibar.activate": ["Open URL, bookmark or history entry", { topFrame: true }], | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -124,7 +124,17 @@ const HelpDialog = { | |
}); | ||
} | ||
|
||
$$(descriptionElement, ".vimiumHelpDescription").textContent = command.description; | ||
const MAX_LENGTH = 50; | ||
const desiredOptionsLength = Math.max(0, MAX_LENGTH - command.description.length - 3); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Find the length that the options list should be to make the full description the right length. Don't ever let it be less than 0, and leave room for the ellipsis "...". Since this might not be clear, I will explain why I implement it this correct way. It bothers me how many people implement this wrong. Leaving room means that we fit as long lines as we can. For example, if we want a line fewer than 10 characters, not leaving room (not having the "truncated!" -> "truncat..." There is no reason to do this since the word could have fit on the line (word is 10 chars and we are fine with 10 chars). The other common wrong implementation is to truncate anything >= 10 and add the "..." giving: "truncated!" -> "truncated!..." This gives us a line that is longer than 10 chars! The correct implementation (like this where we leave space) means only lines that need to be truncated are, and we never make a line too long: "truncated!" -> "truncated!" (10 chars) I hope this explains what the |
||
const optionsTruncated = command.options.substring(0, desiredOptionsLength); | ||
let ellipis = ""; | ||
if ((command.description.length + command.options.length) > MAX_LENGTH) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we needed to truncate, add a set of ellipsis and set the title to the full options list so that we can see it on hover. |
||
ellipis = "..."; | ||
$$(descriptionElement, ".vimiumHelpDescription").title = command.options; | ||
} | ||
const optionsString = command.options ? ` (${optionsTruncated}${ellipis})` : ""; | ||
const fullDescription = `${command.description}${optionsString}`; | ||
$$(descriptionElement, ".vimiumHelpDescription").textContent = fullDescription; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note that this implementation works exactly as you described in your comment on #4518 where the options list is truncated, but not the ending ")" or the command description itself. I tried the other methods of truncation, and I like this one the most. I agree with your design, it works very well. |
||
|
||
keysElement = $$(keysElement, ".vimiumKeyBindings"); | ||
let lastElement = null; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change is for understandability. Before there were two variables named
command
within this block:map
,unmap
, etc.This caused understanding errors for me, so to avoid this for others in the future, I renamed the
map
vsunmap
to the more fitting nameaction
. Please suggest your name preference if different.