Skip to content

Commit

Permalink
feat: Support append and replace commands
Browse files Browse the repository at this point in the history
  • Loading branch information
weirongxu committed Jul 2, 2020
1 parent 2510e61 commit f7d91c8
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 50 deletions.
8 changes: 8 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@
sin(PI / 2) =
```

## Commands

- `calc.appendWithCursor` Calculate and append in front of cursor
- `calc.append` Calculate and append
- `calc.replaceWithCursor` Calculate and replace in front of cursor
- `calc.replace` Calculate and replace
- `calc.calculate` see Vim API

## Keymaps

Create keymappings like:
Expand Down
24 changes: 10 additions & 14 deletions src/calc-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@ import {
Range,
Position,
CancellationToken,
TextEdit,
} from 'vscode-languageserver-protocol';

export class CalcProvider implements CompletionItemProvider {
public enableActive: boolean;

private srcId: number;
private matchIds: Set<number> = new Set();
private replacePosition?: Range;
Expand All @@ -28,7 +27,6 @@ export class CalcProvider implements CompletionItemProvider {
private onError: (error: Error) => any,
) {
this.srcId = workspace.createNameSpace('coc-calc');
this.enableActive = false;
this.enableDebug = this.config.get<boolean>('debug', false);
this.enableReplaceOriginalExpression = this.config.get<boolean>(
'replaceOriginalExpression',
Expand Down Expand Up @@ -57,7 +55,7 @@ export class CalcProvider implements CompletionItemProvider {
): {
skip: number;
result: string;
newText: string;
insertText: string;
expressionRange: Range;
expressionWithEqualSignRange: Range;
expressionEndRange: Range;
Expand All @@ -69,12 +67,12 @@ export class CalcProvider implements CompletionItemProvider {
const rightMatches = formulaRaw.match(/[\s=]+$/);
const rightEmpty = rightMatches ? rightMatches[0].length : 0;

const newText = exprLine.endsWith(' =') ? ' ' + result : result;
const insertText = exprLine.endsWith(' =') ? ' ' + result : result;

return {
skip,
result,
newText,
insertText,
expressionRange: Range.create(
position.line,
skip + leftEmpty,
Expand Down Expand Up @@ -105,7 +103,7 @@ export class CalcProvider implements CompletionItemProvider {
const exprLine = document.getText(
Range.create(Position.create(position.line, 0), position),
);
if (!this.enableActive && !exprLine.trimRight().endsWith('=')) {
if (!exprLine.trimRight().endsWith('=')) {
return [];
}
try {
Expand All @@ -114,7 +112,7 @@ export class CalcProvider implements CompletionItemProvider {
expressionRange,
expressionWithEqualSignRange,
expressionEndRange,
newText,
insertText,
} = this.calculateLine(position, exprLine);

this.clearHighlight().catch(this.onError);
Expand All @@ -125,13 +123,11 @@ export class CalcProvider implements CompletionItemProvider {

return [
{
label: newText,
label: insertText,
kind: CompletionItemKind.Constant,
documentation: '`' + exprLine.slice(skip).trimLeft() + newText + '`',
textEdit: {
range: expressionEndRange,
newText,
},
documentation:
'`' + exprLine.slice(skip).trimLeft() + insertText + '`',
textEdit: TextEdit.replace(expressionEndRange, insertText),
} as CompletionItem,
];
} catch (error) {
Expand Down
93 changes: 57 additions & 36 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { workspace, languages, ExtensionContext, commands } from 'coc.nvim';
import {
workspace,
languages,
ExtensionContext,
commands,
Document,
} from 'coc.nvim';
import { Position, TextEdit } from 'vscode-languageserver-protocol';
import { CalcProvider } from './calc-provider';
import { calculate } from 'editor-calc';
Expand Down Expand Up @@ -41,58 +47,73 @@ export const activate = async (context: ExtensionContext) => {
return null;
}
}),
// workspace.registerAutocmd({
// event: ['InsertLeave'],
// callback: () => {
// calcProvider.enableActive = false;
// }
// }),
// workspace.registerKeymap(['n'], 'calc-active-mode-i', async () => {
// await nvim.feedKeys('i', 'n', false);
// calcProvider.enableActive = true;
// // TODO enableActive
// }),
);

async function replaceResult(mode: 'append' | 'replace') {
const doc = await workspace.document;
const position = await workspace.getCursorPosition();
const line = doc.getline(position.line);
const equalPosition = line.indexOf('=', position.character - 1);
const character = equalPosition === -1 ? line.length : equalPosition + 1;
const exprLine = line.slice(0, character);
async function replaceResultWithPosition(
doc: Document,
position: Position,
expression: string,
mode: 'append' | 'replace',
) {
const {
newText,
insertText,
expressionWithEqualSignRange,
expressionEndRange,
} = calcProvider.calculateLine(
Position.create(position.line, character),
exprLine,
);
} = calcProvider.calculateLine(position, expression);
if (mode === 'append') {
const endWithEqual = exprLine.trimRight().endsWith('=');
doc
.applyEdits(nvim, [
TextEdit.replace(
expressionEndRange,
endWithEqual ? newText : ' = ' + newText,
),
])
.catch(onError);
const endWithEqual = expression.trimRight().endsWith('=');
await doc.applyEdits([
TextEdit.replace(
expressionEndRange,
endWithEqual ? insertText : ' = ' + insertText,
),
]);
} else if (mode === 'replace') {
doc
.applyEdits(nvim, [
TextEdit.replace(expressionWithEqualSignRange, newText),
])
.catch(onError);
await doc.applyEdits([
TextEdit.replace(expressionWithEqualSignRange, insertText),
]);
}
}

async function replaceResult(
mode: 'append' | 'replace',
withCursor: boolean,
) {
const doc = await workspace.document;
const cursor = await workspace.getCursorPosition();
const line = doc.getline(cursor.line);
const [position, expression] = ((): [Position, string] => {
if (withCursor) {
return [cursor, line.slice(0, cursor.character)];
} else {
return [Position.create(cursor.line, line.length), line];
}
})();
await replaceResultWithPosition(doc, position, expression, mode);
}

subscriptions.push(
commands.registerCommand('calc.appendWithCursor', async () => {
await replaceResult('append', true);
}),
commands.registerCommand('calc.append', async () => {
await replaceResult('append', false);
}),
commands.registerCommand('calc.replaceWithCursor', async () => {
await replaceResult('replace', true);
}),
commands.registerCommand('calc.replace', async () => {
await replaceResult('replace', false);
}),
workspace.registerKeymap(['n', 'i'], 'calc-result-append', async () => {
await replaceResult('append');
await commands.executeCommand('calc.append');
}),
workspace.registerKeymap(['n', 'i'], 'calc-result-replace', async () => {
await replaceResult('replace');
await commands.executeCommand('calc.replace');
}),
);
};

0 comments on commit f7d91c8

Please sign in to comment.