(options)
| 228 | |
| 229 | class VisualMode extends KeyHandlerMode { |
| 230 | init(options) { |
| 231 | let movement; |
| 232 | if (options == null) { |
| 233 | options = {}; |
| 234 | } |
| 235 | this.movement = new Movement(options.alterMethod != null ? options.alterMethod : "extend"); |
| 236 | this.selection = this.movement.selection; |
| 237 | |
| 238 | // Build the key mapping structure required by KeyHandlerMode. This only handles one- and |
| 239 | // two-key mappings. |
| 240 | const keyMapping = {}; |
| 241 | for (const keys of Object.keys(this.movements || {})) { |
| 242 | movement = this.movements[keys]; |
| 243 | if ("function" === typeof movement) { |
| 244 | movement = movement.bind(this); |
| 245 | } |
| 246 | if (keys.length === 1) { |
| 247 | keyMapping[keys] = { command: movement }; |
| 248 | } else { // keys.length == 2 |
| 249 | if (keyMapping[keys[0]] == null) { |
| 250 | keyMapping[keys[0]] = {}; |
| 251 | } |
| 252 | Object.assign(keyMapping[keys[0]], { [keys[1]]: { command: movement } }); |
| 253 | } |
| 254 | } |
| 255 | |
| 256 | // Aliases and complex bindings. |
| 257 | Object.assign(keyMapping, { |
| 258 | "B": keyMapping.b, |
| 259 | "W": keyMapping.w, |
| 260 | "<c-e>": { |
| 261 | command(count) { |
| 262 | return Scroller.scrollBy("y", count * Settings.get("scrollStepSize"), 1, false); |
| 263 | }, |
| 264 | }, |
| 265 | "<c-y>": { |
| 266 | command(count) { |
| 267 | return Scroller.scrollBy("y", -count * Settings.get("scrollStepSize"), 1, false); |
| 268 | }, |
| 269 | }, |
| 270 | }); |
| 271 | |
| 272 | super.init(Object.assign(options, { |
| 273 | name: options.name != null ? options.name : "visual", |
| 274 | indicator: options.indicator != null ? options.indicator : "Visual mode", |
| 275 | // Visual mode, visual-line mode and caret mode each displace each other. |
| 276 | singleton: "visual-mode-group", |
| 277 | exitOnEscape: true, |
| 278 | suppressAllKeyboardEvents: true, |
| 279 | keyMapping, |
| 280 | commandHandler: this.commandHandler.bind(this), |
| 281 | })); |
| 282 | |
| 283 | // If there was a range selection when the user lanuched visual mode, then we retain the |
| 284 | // selection on exit. |
| 285 | this.shouldRetainSelectionOnExit = this.options.userLaunchedMode && |
| 286 | (this.selection.type === "Range"); |
| 287 |
no test coverage detected