diff --git a/flow-libs/atom.js.flow b/flow-libs/atom.js.flow index 04dcfa7f..a3969aae 100644 --- a/flow-libs/atom.js.flow +++ b/flow-libs/atom.js.flow @@ -274,7 +274,7 @@ declare class atom$Decoration { } declare class atom$DisplayMarkerLayer { - id: number, + id: string, destroy(): void, clear(): void, isDestroyed(): boolean, @@ -663,6 +663,7 @@ declare class atom$Range { end: atom$Point, isEmpty(): boolean, isEqual(otherRange: atom$RangeLike): boolean, + isSingleLine(): boolean, intersectsWith(otherRange: atom$RangeLike, exclusive?: boolean): boolean, containsPoint(point: atom$PointLike, exclusive?: boolean): boolean, containsRange(other: atom$Range, exclusive?: boolean): boolean, @@ -686,6 +687,7 @@ type atom$StatusBarTile = { declare class atom$ScopeDescriptor { constructor(object: {scopes: Array}): void, + scopes: Array, getScopesArray(): Array, } @@ -957,7 +959,7 @@ declare class atom$TextEditor extends atom$Model { // Markers addMarkerLayer(): atom$DisplayMarkerLayer, getDefaultMarkerLayer(): atom$DisplayMarkerLayer, - getMarkerLayer(id: number): atom$DisplayMarkerLayer, + getMarkerLayer(id: string): atom$DisplayMarkerLayer, markBufferPosition(position: atom$PointLike, options?: MarkerOptions): atom$Marker, markBufferRange(range: atom$RangeLike, options?: MarkerOptions): atom$Marker, markScreenRange(range: atom$RangeLike, options?: MarkerOptions): atom$Marker, @@ -1768,6 +1770,7 @@ declare class atom$Project { } type TextBufferScanIterator = (arg: { + row: number, match: Array, matchText: string, range: atom$Range, diff --git a/lib/autocomplete/gocodeprovider-helper.js b/lib/autocomplete/gocodeprovider-helper.js index 152366a5..4d6e5499 100644 --- a/lib/autocomplete/gocodeprovider-helper.js +++ b/lib/autocomplete/gocodeprovider-helper.js @@ -1,11 +1,10 @@ // @flow import path from 'path' -import type { AtomPoint } from './provider' const vendorString = '/vendor/' -export function wantedPackage(buffer: any, pos: AtomPoint) { +export function wantedPackage(buffer: atom$TextBuffer, pos: atom$Point) { // get the pkg the user tries to autocomplete from the current line const lineTillPos = buffer.getTextInRange([[pos.row, 0], pos]) const matches = lineTillPos.match(/(\w+)\.$/) @@ -15,7 +14,11 @@ export function wantedPackage(buffer: any, pos: AtomPoint) { return matches[1] } -export function addImport(buffer: any, pkg: string, offset: number) { +export function addImport( + buffer: atom$TextBuffer, + pkg: string, + offset: number +) { // find the "package ..." statement let row = -1 buffer.scan(/^package /, result => { diff --git a/lib/autocomplete/gocodeprovider.js b/lib/autocomplete/gocodeprovider.js index e9f9edeb..214af3e6 100644 --- a/lib/autocomplete/gocodeprovider.js +++ b/lib/autocomplete/gocodeprovider.js @@ -142,7 +142,7 @@ class GocodeProvider implements AutocompleteProvider { characterIsSuppressed( char: string, - scopeDescriptor: { scopes: Array } + scopeDescriptor: atom$ScopeDescriptor ): boolean { if ( scopeDescriptor && @@ -188,7 +188,9 @@ class GocodeProvider implements AutocompleteProvider { } } - const sameFile = this.currentFile === editor.getPath() + const file = editor.getPath() || '' + + const sameFile = this.currentFile === file const sameLine = this.currentRow >= 0 && this.currentRow === bufferPosition.row const movingForward = @@ -216,7 +218,7 @@ class GocodeProvider implements AutocompleteProvider { }).map(s => Object.assign({}, s, { replacementPrefix: newPrefix }) ) - this.currentFile = editor.getPath() + this.currentFile = file this.currentRow = bufferPosition.row this.currentColumn = bufferPosition.column resolve(fil) @@ -262,7 +264,6 @@ class GocodeProvider implements AutocompleteProvider { resolve([]) return } - const file = buffer.getPath() const args = ['-f=json', 'autocomplete', file, offset.toString()] if (this.proposeBuiltins) args.unshift('-builtin') if (this.unimportedPackages) args.unshift('-unimported-packages') @@ -313,7 +314,7 @@ class GocodeProvider implements AutocompleteProvider { } this.currentSuggestions = suggestions - this.currentFile = editor.getPath() + this.currentFile = file this.currentRow = bufferPosition.row this.currentColumn = bufferPosition.column const newPrefix = editor.getTextInBufferRange([ @@ -386,8 +387,8 @@ class GocodeProvider implements AutocompleteProvider { mapMessages( res: RawGoCodeSuggestion, - editor: any, - position: any + editor: TextEditor, + position: atom$Point ): Array { const candidates: GoCodeSuggestion[] = res[1] if (!candidates || !candidates.length) { diff --git a/lib/autocomplete/provider.js b/lib/autocomplete/provider.js index e96f8a9a..adaabd65 100644 --- a/lib/autocomplete/provider.js +++ b/lib/autocomplete/provider.js @@ -34,15 +34,9 @@ export type Suggestion = { descriptionMoreURL?: string } -export type AtomPoint = { - row: number, - column: number, - copy: () => AtomPoint -} - export type SuggestionRequest = { - editor: any, - bufferPosition: AtomPoint, + editor: TextEditor, + bufferPosition: atom$Point, scopeDescriptor: string, prefix: string, activatedManually: boolean @@ -59,8 +53,8 @@ export interface AutocompleteProvider { +dipose?: () => void; +onDidInsertSuggestion?: ({ - editor: any, - triggerPosition: any, + editor: TextEditor, + triggerPosition: atom$Point, suggestion: Suggestion }) => void; diff --git a/lib/bootstrap.js b/lib/bootstrap.js index c71a8dff..21de50c0 100644 --- a/lib/bootstrap.js +++ b/lib/bootstrap.js @@ -59,7 +59,7 @@ class Bootstrap { subscribeToEvents() { const activationHook = (hookName, fn) => { - const hooks: any = (atom.packages: any).triggeredActivationHooks + const hooks = atom.packages.triggeredActivationHooks if (hooks && hooks.has(hookName)) { fn() return diff --git a/lib/build/builder.js b/lib/build/builder.js index 3d44fb53..b169f969 100644 --- a/lib/build/builder.js +++ b/lib/build/builder.js @@ -26,7 +26,7 @@ class Builder { goconfig: GoConfig, linter: () => LinterDelegate, output: OutputManager, - busySignal: () => any + busySignal: () => ?BusySignalService ) { this.goconfig = goconfig this.linter = linter @@ -64,7 +64,7 @@ class Builder { } } - async build(editor: any, path: string = editor.getPath()): Promise { + async build(editor: TextEditor, path: string): Promise { if (!atom.config.get('go-plus.config.compileOnSave')) { return } @@ -72,7 +72,7 @@ class Builder { throw new Error('invalid editor') } this.deleteMessages() - const options = this.goconfig.executor.getOptions('file') + const options = this.goconfig.executor.getOptions('file', editor) const cmd = await this.goconfig.locator.findTool('go') if (!cmd) { throw new Error('cannot find go tool') diff --git a/lib/config/executor.js b/lib/config/executor.js index 2ef6e633..6192b2bb 100644 --- a/lib/config/executor.js +++ b/lib/config/executor.js @@ -1,11 +1,11 @@ // @flow -import { BufferedProcess } from 'atom' +import { BufferedProcess, TextEditor } from 'atom' import { spawnSync } from 'child_process' import { getenvironment } from './environment' import fs from 'fs-extra' import path from 'path' -import { getEditor, projectPath } from '../utils' +import { projectPath } from '../utils' export type ExecutorOptions = { timeout?: number, @@ -196,7 +196,7 @@ class Executor { getOptions( kind: 'file' | 'project' = 'file', - editor: any = getEditor() + editor?: ?TextEditor ): ExecutorOptions { const result: ExecutorOptions = this.getDefaultOptions(kind, editor) return this.ensureOptions(result) @@ -225,7 +225,7 @@ class Executor { getDefaultOptions( key: 'file' | 'project' = 'file', - editor: any = getEditor() + editor?: ?TextEditor ): ExecutorOptions { let options = {} switch (key) { diff --git a/lib/config/service.js b/lib/config/service.js index e8fb21b5..5a6ec016 100644 --- a/lib/config/service.js +++ b/lib/config/service.js @@ -6,12 +6,15 @@ import { Locator } from './locator' import type { ExecutorOptions, ExecResult } from './executor' import type { FindResult, Runtime } from './locator' +interface PublicExecutor { + exec(string, Array, ExecutorOptions): Promise; + execSync(string, Array, ExecutorOptions): ExecResult; + getOptions('file', editor: TextEditor): ExecutorOptions; + getOptions('project', editor?: ?TextEditor): ExecutorOptions; +} + export type GoConfig = { - executor: { - exec: (string, Array, ExecutorOptions) => Promise, - execSync: (string, Array, ExecutorOptions) => ExecResult, - getOptions: ('file' | 'project', any) => ExecutorOptions - }, + executor: PublicExecutor, locator: { runtimes: () => Promise>, runtime: () => Promise, diff --git a/lib/doc/godoc.js b/lib/doc/godoc.js index 9ae0cfa2..213bb984 100644 --- a/lib/doc/godoc.js +++ b/lib/doc/godoc.js @@ -1,6 +1,6 @@ // @flow -import { CompositeDisposable, Point, Range } from 'atom' +import { CompositeDisposable, Range } from 'atom' import { GodocPanel } from './godoc-panel' import { utf8OffsetForBufferPosition } from '../utils' import { buildGuruArchive } from '../guru-utils' @@ -188,18 +188,6 @@ ${doc.doc}` }) } - editorByteOffset(editor: any): number { - const cursor = editor.getLastCursor() - const range = cursor.getCurrentWordBufferRange() - const middle = new Point( - range.start.row, - Math.floor((range.start.column + range.end.column) / 2) - ) - const charOffset = editor.buffer.characterIndexForPosition(middle) - const text = editor.getText().substring(0, charOffset) - return Buffer.byteLength(text, 'utf8') - } - getPanel() { return this.panelModel } diff --git a/lib/format/formatter.js b/lib/format/formatter.js index f7612005..003d1860 100644 --- a/lib/format/formatter.js +++ b/lib/format/formatter.js @@ -50,7 +50,7 @@ class Formatter { console.log('skipping format, could not find tool', tool) // eslint-disable-line no-console return null } - const options = this.goconfig.executor.getOptions('project') + const options = this.goconfig.executor.getOptions('project', editor) options.input = editor.getText() const args = [] if (tool === 'goimports') { diff --git a/lib/get/get-manager.js b/lib/get/get-manager.js index 12deb4b8..afca68a9 100644 --- a/lib/get/get-manager.js +++ b/lib/get/get-manager.js @@ -15,7 +15,7 @@ type GetResult = { args: Array } -type MultiGetResult = { +export type MultiGetResult = { success: boolean, result: ?GetResult, results: ?Array @@ -225,7 +225,7 @@ class GetManager { return { success: false, result: null, results: null } } - const executorOptions = this.goconfig.executor.getOptions('file') + const executorOptions = this.goconfig.executor.getOptions('project') const timeout = atom.config.get('go-plus.get.timeout') if (typeof timeout === 'number') { executorOptions.timeout = timeout diff --git a/lib/get/service.js b/lib/get/service.js index 569478f9..5b0eee4c 100644 --- a/lib/get/service.js +++ b/lib/get/service.js @@ -2,12 +2,13 @@ import { Disposable } from 'atom' import { GetManager } from './get-manager' +import type { MultiGetResult } from './get-manager' import type { GoConfig } from './../config/service' import type { InteractiveGetOptions } from './get-manager' export type GoGet = { - get: InteractiveGetOptions => Promise, + get: InteractiveGetOptions => Promise, register: (string, ?Function) => Disposable } diff --git a/lib/guru-utils.js b/lib/guru-utils.js index 5ad39e3f..bc5c25e6 100644 --- a/lib/guru-utils.js +++ b/lib/guru-utils.js @@ -1,7 +1,8 @@ // @flow +import type { TextEditor } from 'atom' + import { - getEditor, getCursorPosition, isValidEditor, utf8OffsetForBufferPosition @@ -17,7 +18,7 @@ const scopedModes = [ 'referrers' ] -function buildGuruArchive(editor: any = null) { +function buildGuruArchive(editor: ?TextEditor) { let archive = '' const editors = editor ? [editor] : atom.workspace.getTextEditors() for (const e of editors) { @@ -33,7 +34,7 @@ function buildGuruArchive(editor: any = null) { function computeArgs( mode: string, options: ?{ gopath: string }, - editor: any = getEditor(), + editor: TextEditor, pos: number = currentCursorOffset(editor) ): ?Array { if (!mode || !editor || (!pos && pos !== 0)) { @@ -41,6 +42,10 @@ function computeArgs( } const filePath = editor.getPath() + if (!filePath) { + return undefined + } + const args = ['-json'] if (scopedModes.includes(mode)) { const src = 'src/' @@ -59,15 +64,16 @@ function computeArgs( return args } -function currentCursorOffset(editor: any = getEditor()): number { - const pos = adjustPositionForGuru(getCursorPosition(), editor) +function currentCursorOffset(editor: TextEditor): number { + let pos = getCursorPosition(editor) + if (!pos) { + return 0 + } + pos = adjustPositionForGuru(pos, editor) return utf8OffsetForBufferPosition(pos, editor) } -function adjustPositionForGuru( - pos: any = getCursorPosition(), - editor: any = getEditor() -) { +function adjustPositionForGuru(pos: atom$Point, editor: TextEditor) { if (!pos) { return pos } @@ -78,9 +84,7 @@ function adjustPositionForGuru( // at the given position is considered a part of an identifier. // If not step back 1 char as it might contain a valid identifier. const char = editor.getTextInBufferRange([pos, pos.translate([0, 1])]) - const nonWordChars = editor.getNonWordCharacters( - editor.scopeDescriptorForBufferPosition(pos) - ) + const nonWordChars = editor.getNonWordCharacters(pos) if (nonWordChars.indexOf(char) >= 0 || /\s/.test(char)) { return pos.translate([0, -1]) } diff --git a/lib/implements/implements-view.js b/lib/implements/implements-view.js index 0e72b98d..c8855464 100644 --- a/lib/implements/implements-view.js +++ b/lib/implements/implements-view.js @@ -3,6 +3,7 @@ /* eslint-disable react/no-unknown-property */ /* eslint-disable react/jsx-key */ +import { Point } from 'atom' import etch from 'etch' import { EtchComponent } from './../etch-component' import { parseGoPosition, openFile } from './../utils' @@ -43,7 +44,7 @@ class ImplementsView extends EtchComponent { } const { file, line = 1, column = 1 } = pos - openFile(file, { row: line - 1, column: column - 1 }).catch(err => { + openFile(file, Point.fromObject([line - 1, column - 1])).catch(err => { console.log('could not access ' + file, err) // eslint-disable-line no-console }) } diff --git a/lib/implements/implements.js b/lib/implements/implements.js index 64e6779d..be362b8b 100644 --- a/lib/implements/implements.js +++ b/lib/implements/implements.js @@ -5,6 +5,7 @@ import { CompositeDisposable } from 'atom' import { getEditor } from './../utils' import { buildGuruArchive, computeArgs } from './../guru-utils' +import type { ImplementsView } from './implements-view' import type { GoConfig } from './../config/service' import type { PanelModel, Tab } from './../panel/tab' @@ -14,7 +15,7 @@ class Implements implements PanelModel { goconfig: GoConfig subscriptions: CompositeDisposable requestFocus: ?() => Promise - view: any + view: ImplementsView constructor(goconfig: GoConfig) { this.goconfig = goconfig @@ -47,7 +48,7 @@ class Implements implements PanelModel { if (!editor) { return } - const args = computeArgs('implements') + const args = computeArgs('implements', null, editor) if (args && args.length) { return this.runGuru(args) } diff --git a/lib/import/importer-view.js b/lib/import/importer-view.js index 1bbe547f..34141163 100644 --- a/lib/import/importer-view.js +++ b/lib/import/importer-view.js @@ -3,7 +3,7 @@ import SelectListView from 'atom-select-list' export class ImporterView { - modalPanel: any + modalPanel: ?atom$Panel selectListView: SelectListView previouslyFocusedElement: ?HTMLElement diff --git a/lib/lint/linter.js b/lib/lint/linter.js index 2e721ced..b879025c 100644 --- a/lib/lint/linter.js +++ b/lib/lint/linter.js @@ -110,7 +110,7 @@ class Linter { return } - const options = this.goconfig.executor.getOptions('file') + const options = this.goconfig.executor.getOptions('file', editor) let configuredArgs: string | string[] = (atom.config.get( 'go-plus.lint.args' diff --git a/lib/main.js b/lib/main.js index 1db52c96..39a18cd1 100644 --- a/lib/main.js +++ b/lib/main.js @@ -22,7 +22,9 @@ class Main { information = null implements = null importer = null - linter = null + linter: any = null + golinter = null + buildLinter: any = null loaded = null orchestrator = null outputManager = null @@ -36,8 +38,6 @@ class Main { autocompleteProvider = null definitionProvider = null packagemanager = null - buildLinter: any = null - gometalinterLinter: any = null activate() { this.subscriptions = new CompositeDisposable() @@ -338,7 +338,7 @@ class Main { const { Linter } = require('./lint/linter') this.golinter = new Linter( this.provideGoConfig(), - () => this.linter, + () => (this.linter: any), () => this.busySignal ) diff --git a/lib/navigator/navigator.js b/lib/navigator/navigator.js index 0140b6db..645f1857 100644 --- a/lib/navigator/navigator.js +++ b/lib/navigator/navigator.js @@ -71,13 +71,14 @@ class Navigator { } return this.gotoDefinitionForBufferPosition( - editor.getCursorBufferPosition() + editor.getCursorBufferPosition(), + editor ) } async definitionForBufferPosition( - pos: atom$PointLike, - editor: ?atom$TextEditor = getEditor() + pos: atom$Point, + editor: TextEditor ): Promise { const tool = atom.config.get('go-plus.navigator.mode') const r = @@ -94,8 +95,8 @@ class Navigator { } async gotoDefinitionForBufferPosition( - pos: atom$PointLike, - editor: any = getEditor() + pos: atom$Point, + editor: TextEditor ): Promise { if (!editor || !pos) { return false @@ -108,8 +109,8 @@ class Navigator { } async executeGuru( - pos: atom$PointLike, - editor: any + pos: atom$Point, + editor: TextEditor ): Promise { if (!editor || !pos) { return false @@ -119,9 +120,12 @@ class Navigator { return false } const filepath = editor.getPath() + if (!filepath) { + return false + } const archive = buildGuruArchive() - const options = this.goconfig.executor.getOptions('file') + const options = this.goconfig.executor.getOptions('file', editor) if (archive && archive !== '') { options.input = archive } @@ -137,16 +141,19 @@ class Navigator { async executeGodef( pos: atom$PointLike, - editor: any + editor: TextEditor ): Promise { const cmd = await this.goconfig.locator.findTool('godef') if (!cmd) { return false } - const offset = utf8OffsetForBufferPosition(pos, editor) const filepath = editor.getPath() + if (!filepath) { + return false + } + const offset = utf8OffsetForBufferPosition(pos, editor) const args = ['-f', filepath, '-o', offset.toString(), '-i'] - const options = this.goconfig.executor.getOptions('file') + const options = this.goconfig.executor.getOptions('file', editor) options.input = editor.getText() return this.goconfig.executor.exec(cmd, args, options) } @@ -228,11 +235,11 @@ class Navigator { } } - async visitFile(loc: DefLocation): Promise { + async visitFile(loc: DefLocation): Promise { return openFile(loc.filepath, loc.pos) } - async visitDirectory(loc: DefLocation): Promise { + async visitDirectory(loc: DefLocation): Promise { try { const file = await this.findFirstGoFile(loc.filepath) loc.filepath = file diff --git a/lib/output-manager.js b/lib/output-manager.js index 78c465cf..a67e9e2a 100644 --- a/lib/output-manager.js +++ b/lib/output-manager.js @@ -1,13 +1,14 @@ // @flow import type { PanelModel, Tab } from './panel/tab' +import type { OutputPanel } from './output-panel' class OutputManager implements PanelModel { key: string tab: Tab output: string props: Object - view: any + view: OutputPanel requestFocus: ?() => Promise constructor() { diff --git a/lib/output-panel.js b/lib/output-panel.js index 60e94959..66e20fc5 100644 --- a/lib/output-panel.js +++ b/lib/output-panel.js @@ -3,6 +3,7 @@ /* eslint-disable react/no-unknown-property */ /* eslint-disable react/no-string-refs */ +import { Point } from 'atom' import etch from 'etch' // eslint-disable-line no-unused-vars import path from 'path' import { EtchComponent } from './etch-component' @@ -93,7 +94,7 @@ export class OutputPanel extends EtchComponent { } const col = column && column > 0 ? column - 1 : 0 - openFile(filepath, { row: line - 1, column: col }).catch(err => { + openFile(filepath, Point.fromObject([line - 1, col])).catch(err => { console.log('could not access ' + file, err) // eslint-disable-line no-console }) } diff --git a/lib/package-manager.js b/lib/package-manager.js index 746041a6..997af63b 100644 --- a/lib/package-manager.js +++ b/lib/package-manager.js @@ -59,7 +59,7 @@ class PackageManager { subscriptions: CompositeDisposable toolChecker: ToolChecker - constructor(goconfig: GoConfig, goget: any) { + constructor(goconfig: GoConfig, goget: GoGet) { this.loaded = false this.goconfig = goconfig this.goget = goget diff --git a/lib/panel/panel-manager.js b/lib/panel/panel-manager.js index 53e722a8..7fdf4eef 100644 --- a/lib/panel/panel-manager.js +++ b/lib/panel/panel-manager.js @@ -8,19 +8,6 @@ import type { PanelModel } from './tab' import type { GoConfig } from './../config/service' import type { Renderable } from '../etch-component' -type StatusBarTile = { - getPriority: () => number, - getItem: () => any, - destroy: () => void -} - -type StatusBar = { - addLeftTile: ({ item: any, priority: number }) => void, - addRightTile: ({ item: any, priority: number }) => void, - getLeftTiles: Array, - getRightTiles: Array -} - class PanelManager { activeItem: string item: { @@ -34,12 +21,12 @@ class PanelManager { subscriptions: CompositeDisposable viewProviders: Map, model: PanelModel }> goPlusPanel: ?GoPlusPanel - statusBar: () => StatusBar | false + statusBar: () => atom$StatusBar | false goconfig: GoConfig goPlusStatusBar: ?GoPlusStatusBar - goPlusStatusBarTile: ?StatusBarTile + goPlusStatusBarTile: ?atom$StatusBarTile - constructor(statusBarFunc: () => StatusBar | false) { + constructor(statusBarFunc: () => atom$StatusBar | false) { this.statusBar = statusBarFunc this.activeItem = 'go' @@ -193,14 +180,15 @@ class PanelManager { return } - this.goPlusStatusBar = new GoPlusStatusBar({ + const goPlusStatusBar = new GoPlusStatusBar({ state: 'unknown', togglePanel: () => { this.togglePanel() } }) + this.goPlusStatusBar = goPlusStatusBar - this.subscriptions.add(this.goPlusStatusBar) + this.subscriptions.add(goPlusStatusBar) if (this.goPlusStatusBarTile) { this.goPlusStatusBarTile.destroy() @@ -209,7 +197,7 @@ class PanelManager { const sb = this.statusBar() if (sb) { this.goPlusStatusBarTile = sb.addRightTile({ - item: this.goPlusStatusBar, + item: goPlusStatusBar.element, priority: 1000 }) } diff --git a/lib/rename/gorename.js b/lib/rename/gorename.js index 9f0f6f09..07e80238 100644 --- a/lib/rename/gorename.js +++ b/lib/rename/gorename.js @@ -1,9 +1,9 @@ // @flow import path from 'path' -import { CompositeDisposable, Point } from 'atom' +import { CompositeDisposable } from 'atom' import { SimpleDialog } from './../simple-dialog' -import { isValidEditor } from '../utils' +import { isValidEditor, wordAndOffset } from '../utils' import type { GoConfig } from './../config/service' @@ -35,7 +35,7 @@ class Gorename { if (!cmd) { return } - const { word, offset } = this.wordAndOffset(editor) + const { word, offset } = wordAndOffset(editor) const cursor = editor.getCursorBufferPosition() const dialog = new SimpleDialog({ @@ -94,21 +94,6 @@ class Gorename { return Promise.all(promises) } - wordAndOffset(editor: any): { word: string, offset: number } { - const cursor = editor.getLastCursor() - const range = cursor.getCurrentWordBufferRange() - const middle = new Point( - range.start.row, - Math.floor((range.start.column + range.end.column) / 2) - ) - const charOffset = editor.buffer.characterIndexForPosition(middle) - const text = editor.getText().substring(0, charOffset) - return { - word: editor.getTextInBufferRange(range), - offset: Buffer.byteLength(text, 'utf8') - } - } - async runGorename( file: string, offset: number, diff --git a/lib/simple-dialog.js b/lib/simple-dialog.js index 9fb23759..25055421 100644 --- a/lib/simple-dialog.js +++ b/lib/simple-dialog.js @@ -15,7 +15,7 @@ type Props = { export class SimpleDialog extends EtchComponent { props: Props subscriptions: CompositeDisposable - panel: any + panel: ?atom$Panel previouslyFocusedElement: ?HTMLElement constructor(props: Props) { diff --git a/lib/tags/gomodifytags.js b/lib/tags/gomodifytags.js index 6fe84c60..595aafc4 100644 --- a/lib/tags/gomodifytags.js +++ b/lib/tags/gomodifytags.js @@ -1,7 +1,7 @@ // @flow -import { CompositeDisposable, Point } from 'atom' -import { isValidEditor } from '../utils' +import { CompositeDisposable } from 'atom' +import { isValidEditor, wordAndOffset } from '../utils' import { buildGuruArchive } from '../guru-utils' import { TagsDialog } from './tags-dialog' @@ -14,9 +14,9 @@ export type Tag = { option?: string } -type GoModifyTagsOptions = { +export type GoModifyTagsOptions = { tags: Array, - transform: any, + transform: 'snakecase' | 'camelcase', // | 'lispcase', sortTags: boolean } @@ -69,7 +69,7 @@ class GoModifyTags { } buildArgs( - editor: any, + editor: TextEditor, options: GoModifyTagsOptions, mode: Mode ): Array { @@ -77,7 +77,7 @@ class GoModifyTags { // if there is a selection, use the -line flag, // otherwise just use the cursor offset (and apply modifications to entire struct) - const args = ['-file', editor.getPath()] + const args = ['-file', editor.getPath() || ''] const selection = editor.getSelectedBufferRange() if (selection && !selection.start.isEqual(selection.end)) { args.push('-line') @@ -88,7 +88,7 @@ class GoModifyTags { } } else { args.push('-offset') - args.push(this.editorByteOffset(editor).toString()) + args.push(wordAndOffset(editor).offset.toString()) } if (editor.isModified()) { @@ -147,12 +147,12 @@ class GoModifyTags { } async modifyTags( - editor: any, + editor: TextEditor, options: GoModifyTagsOptions, mode: Mode, cmd: string ) { - const executorOptions = this.goconfig.executor.getOptions('file') + const executorOptions = this.goconfig.executor.getOptions('file', editor) if (editor.isModified()) { executorOptions.input = buildGuruArchive(editor) @@ -161,7 +161,7 @@ class GoModifyTags { const args = this.buildArgs(editor, options, mode) const r = await this.goconfig.executor.exec(cmd, args, executorOptions) if (r.error) { - if (r.error && r.error.code === 'ENOENT') { + if (r.error.code === 'ENOENT') { atom.notifications.addError('Missing Tool', { detail: 'Missing the `gomodifytags` tool.', dismissable: true @@ -181,21 +181,9 @@ class GoModifyTags { }) return { success: false, result: r } } - editor.getBuffer().setTextViaDiff(r.stdout) + editor.getBuffer().setTextViaDiff(r.stdout.toString()) return { success: true, result: r } } - - editorByteOffset(editor: any): number { - const cursor = editor.getLastCursor() - const range = cursor.getCurrentWordBufferRange() - const middle = new Point( - range.start.row, - Math.floor((range.start.column + range.end.column) / 2) - ) - const charOffset = editor.buffer.characterIndexForPosition(middle) - const text = editor.getText().substring(0, charOffset) - return Buffer.byteLength(text, 'utf8') - } } export { GoModifyTags } diff --git a/lib/tags/tags-dialog.js b/lib/tags/tags-dialog.js index 711c6a2b..5428c9ed 100644 --- a/lib/tags/tags-dialog.js +++ b/lib/tags/tags-dialog.js @@ -6,13 +6,9 @@ import { CompositeDisposable, TextEditor } from 'atom' import etch from 'etch' import { EtchComponent } from './../etch-component' -import type { Tag } from './gomodifytags' +import type { GoModifyTagsOptions, Tag } from './gomodifytags' -export type AcceptedCallback = ({ - tags: Array, - transform: 'snakecase' | 'camelcase', // | 'lispcase' - sortTags: boolean -}) => any +export type AcceptedCallback = GoModifyTagsOptions => any export class TagsDialog extends EtchComponent { tags: Array @@ -20,7 +16,7 @@ export class TagsDialog extends EtchComponent { tagRegex: RegExp optionRegex: RegExp subscriptions: CompositeDisposable - panel: any + panel: ?atom$Panel element: HTMLElement onAccept: ?AcceptedCallback sortTags: boolean diff --git a/lib/test/tester.js b/lib/test/tester.js index 6103d88e..29925a97 100644 --- a/lib/test/tester.js +++ b/lib/test/tester.js @@ -79,10 +79,11 @@ class Tester { ) this.subscriptions.add( atom.commands.add('atom-workspace', 'golang:run-tests', () => { - if (!getEditor()) { + const editor = getEditor() + if (!editor) { return } - this.runTests() + this.runTests(editor) }) ) this.subscriptions.add( @@ -248,7 +249,7 @@ class Tester { } for (const layerid of layersid.split(',')) { - const layer = editor.getMarkerLayer(parseInt(layerid, 10)) + const layer = editor.getMarkerLayer(layerid) if (layer) { layer.destroy() } @@ -330,7 +331,7 @@ class Tester { return args } - async runTests(editor: ?TextEditor = getEditor()): Promise { + async runTests(editor: TextEditor): Promise { if (!isValidEditor(editor)) { throw new Error('invalid editor') } @@ -361,7 +362,7 @@ class Tester { throw new Error('cannot find cover executable') } - const executorOptions = this.goconfig.executor.getOptions('file') + const executorOptions = this.goconfig.executor.getOptions('file', editor) const t = atom.config.get('go-plus.test.timeout') const timeout = typeof t === 'number' ? t : 60000 executorOptions.timeout = timeout diff --git a/lib/utils.js b/lib/utils.js index eb314ecb..cec4cf7f 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -1,7 +1,7 @@ // @flow import fs from 'fs' -import { TextEditor } from 'atom' +import { TextEditor, Point } from 'atom' const isValidEditor = (e: ?TextEditor): boolean %checks => { return !!e && hasGoGrammar(e.getGrammar()) @@ -43,7 +43,7 @@ const getWordPosition = ( return [start, end] } -const getCursorPosition = (editor: any = getEditor()) => { +const getCursorPosition = (editor: TextEditor) => { if (!editor) { return undefined } @@ -54,12 +54,12 @@ const getCursorPosition = (editor: any = getEditor()) => { return cursor.getBufferPosition() } -const currentCursorOffset = (editor: any = getEditor()) => { +const currentCursorOffset = (editor: TextEditor) => { if (!editor) { return undefined } - const pos = getCursorPosition() + const pos = getCursorPosition(editor) if (!pos) { return undefined } @@ -69,7 +69,7 @@ const currentCursorOffset = (editor: any = getEditor()) => { const utf8OffsetForBufferPosition = ( pos: atom$PointLike, - editor: any = getEditor() + editor: TextEditor ): number => { if (!editor || !editor.getBuffer() || !pos) { return -1 @@ -79,13 +79,33 @@ const utf8OffsetForBufferPosition = ( return Buffer.byteLength(text, 'utf8') } +const wordAndOffset = ( + editor: TextEditor +): { word: string, offset: number } => { + const cursor = editor.getLastCursor() + const range = cursor.getCurrentWordBufferRange() + const middle = new Point( + range.start.row, + Math.floor((range.start.column + range.end.column) / 2) + ) + const charOffset = editor.getBuffer().characterIndexForPosition(middle) + const text = editor.getText().substring(0, charOffset) + return { + word: editor.getTextInBufferRange(range), + offset: Buffer.byteLength(text, 'utf8') + } +} + /** * Opens the `file` and centers the editor around the `pos` * @param {string} file Path to the file to open. * @param {object} [pos] An optional object containing `row` and `column` to scroll to. * @return {Promise} Returns a promise which resolves with the opened editor */ -const openFile = async (file: string, pos: any): Promise => { +const openFile = async ( + file: string, + pos?: ?atom$Point +): Promise => { await new Promise((resolve, reject) => { fs.access(file, fs.constants.F_OK | fs.constants.R_OK, err => { if (err) { @@ -164,6 +184,7 @@ export { openFile, getWordPosition, utf8OffsetForBufferPosition, + wordAndOffset, currentCursorOffset, getCursorPosition, parseGoPosition, diff --git a/package-lock.json b/package-lock.json index 934ea624..039a8213 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1091,9 +1091,9 @@ } }, "flow-bin": { - "version": "0.85.0", - "resolved": "https://registry.npmjs.org/flow-bin/-/flow-bin-0.85.0.tgz", - "integrity": "sha512-ougBA2q6Rn9sZrjZQ9r5pTFxCotlGouySpD2yRIuq5AYwwfIT8HHhVMeSwrN5qJayjHINLJyrnsSkkPCZyfMrQ==", + "version": "0.90.0", + "resolved": "https://registry.npmjs.org/flow-bin/-/flow-bin-0.90.0.tgz", + "integrity": "sha512-/syDchjhLLL7nELK1ggyWJifGXuMCTz74kvkjR1t9DcmasMrilLl9qAAotsACcNb98etEEJpsCrvP7WL64kadw==", "dev": true }, "fs-extra": { diff --git a/package.json b/package.json index 3d4d0b6b..7ac1380a 100644 --- a/package.json +++ b/package.json @@ -98,7 +98,7 @@ "eslint-plugin-prettier": "^3.0.0", "eslint-plugin-promise": "^4.0.1", "eslint-plugin-react": "^7.11.1", - "flow-bin": "^0.85.0", + "flow-bin": "^0.90.0", "prettier": "1.14.3" }, "providedServices": { diff --git a/spec/rename/gorename-spec.js b/spec/rename/gorename-spec.js index d433dcb2..2b456246 100644 --- a/spec/rename/gorename-spec.js +++ b/spec/rename/gorename-spec.js @@ -3,6 +3,7 @@ import path from 'path' import fs from 'fs-extra' +import { wordAndOffset } from './../../lib/utils' import { lifecycle } from './../spec-helpers' import { it, fit, ffit, beforeEach, runs } from '../async-spec-helpers' // eslint-disable-line @@ -38,7 +39,7 @@ describe('gorename', () => { it('renames a single token', async () => { editor.setCursorBufferPosition([4, 5]) - const info = gorename.wordAndOffset(editor) + const info = wordAndOffset(editor) expect(info.word).toBe('foo') expect(info.offset).toBe(33) diff --git a/spec/test/tester-spec.js b/spec/test/tester-spec.js index 862c0870..66351ff7 100644 --- a/spec/test/tester-spec.js +++ b/spec/test/tester-spec.js @@ -123,7 +123,7 @@ describe('tester', () => { it('runs tests', async () => { spyOn(tester, 'runTests').andCallThrough() - await tester.handleSaveEvent() + await tester.handleSaveEvent(editor) expect(tester.runTests).toHaveBeenCalled() }) @@ -147,7 +147,7 @@ describe('tester', () => { it('does not run tests automatically on save', async () => { spyOn(tester, 'runTests') - await tester.handleSaveEvent() + await tester.handleSaveEvent(editor) expect(tester.runTests).not.toHaveBeenCalled() })