cursor-position-view.js 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. const {Disposable} = require('atom');
  2. module.exports =
  3. class CursorPositionView {
  4. constructor() {
  5. this.viewUpdatePending = false;
  6. this.element = document.createElement('status-bar-cursor');
  7. this.element.classList.add('cursor-position', 'inline-block');
  8. this.goToLineLink = document.createElement('a');
  9. this.goToLineLink.classList.add('inline-block');
  10. this.element.appendChild(this.goToLineLink);
  11. this.formatString = atom.config.get('status-bar.cursorPositionFormat') ?? '%L:%C';
  12. this.activeItemSubscription = atom.workspace.onDidChangeActiveTextEditor(activeEditor => this.subscribeToActiveTextEditor());
  13. this.subscribeToConfig();
  14. this.subscribeToActiveTextEditor();
  15. this.tooltip = atom.tooltips.add(this.element, {title: () => `Line ${this.row}, Column ${this.column}`});
  16. this.handleClick();
  17. }
  18. destroy() {
  19. this.activeItemSubscription.dispose();
  20. this.cursorSubscription?.dispose();
  21. this.tooltip.dispose();
  22. this.configSubscription?.dispose();
  23. this.clickSubscription.dispose();
  24. this.updateSubscription?.dispose();
  25. }
  26. subscribeToActiveTextEditor() {
  27. this.cursorSubscription?.dispose();
  28. const selectionsMarkerLayer = atom.workspace.getActiveTextEditor()?.selectionsMarkerLayer;
  29. this.cursorSubscription = selectionsMarkerLayer?.onDidUpdate(this.scheduleUpdate.bind(this));
  30. this.scheduleUpdate();
  31. }
  32. subscribeToConfig() {
  33. this.configSubscription?.dispose();
  34. this.configSubscription = atom.config.observe('status-bar.cursorPositionFormat', value => {
  35. this.formatString = value != null ? value : '%L:%C';
  36. this.scheduleUpdate();
  37. });
  38. }
  39. handleClick() {
  40. const clickHandler = () => atom.commands.dispatch(atom.views.getView(atom.workspace.getActiveTextEditor()), 'go-to-line:toggle');
  41. this.element.addEventListener('click', clickHandler);
  42. this.clickSubscription = new Disposable(() => this.element.removeEventListener('click', clickHandler));
  43. }
  44. scheduleUpdate() {
  45. if (this.viewUpdatePending) { return; }
  46. this.viewUpdatePending = true;
  47. this.updateSubscription = atom.views.updateDocument(() => {
  48. const position = atom.workspace.getActiveTextEditor()?.getCursorBufferPosition();
  49. this.viewUpdatePending = false;
  50. if (position) {
  51. this.row = position.row + 1;
  52. this.column = position.column + 1;
  53. this.goToLineLink.textContent = this.formatString.replace('%L', this.row).replace('%C', this.column);
  54. this.element.classList.remove('hide');
  55. } else {
  56. this.goToLineLink.textContent = '';
  57. this.element.classList.add('hide');
  58. }
  59. });
  60. }
  61. }