Skip to content

Commit

Permalink
Implement jumping to messages that need to be update / support messag…
Browse files Browse the repository at this point in the history
…es with plural forms / Refactoring (#31)
  • Loading branch information
toku-sa-n authored Jan 28, 2024
1 parent 3198aa7 commit 28d15ba
Show file tree
Hide file tree
Showing 14 changed files with 738 additions and 386 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ Source tmLanguage file: https://github.com/textmate/gettext.tmbundle/blob/master
* `vscgettext.moveToPreviousUntranslated`: Move focus to previous untranslated message (`alt+shift+n`)
* `vscgettext.moveToNextFuzzy`: Move focus to next fuzzy message (`alt+f`)
* `vscgettext.moveToPreviousFuzzy`: Move focus to previous fuzzy message (`alt+shift+f`)
* `vscgettext.moveToNextUntranslatedOrFuzzy`: Move focus to next untranslated or fuzzy message (`alt+u`)
* `vscgettext.moveToPreviousUntranslatedOrFuzzy`: Move focus to previous untranslated or fuzzy message (`alt+shift+u`)
12 changes: 12 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
"onCommand:vscgettext.moveToPreviousUntranslated",
"onCommand:vscgettext.moveToNextFuzzy",
"onCommand:vscgettext.moveToPreviousFuzzy",
"onCommand:vscgettext.moveToNextUntranslatedOrFuzzy",
"onCommand:vscgettext.moveToPreviousUntranslatedOrFuzzy",
"onLanguage:po",
"onLanguage:pot",
"onLanguage:potx"
Expand Down Expand Up @@ -74,6 +76,16 @@
"command": "vscgettext.moveToPreviousFuzzy",
"key": "alt+shift+f",
"when": "editorTextFocus && resourceLangId == po"
},
{
"command": "vscgettext.moveToNextUntranslatedOrFuzzy",
"key": "alt+u",
"when": "editorTextFocus && resourceLangId == po"
},
{
"command": "vscgettext.moveToPreviousUntranslatedOrFuzzy",
"key": "alt+shift+u",
"when": "editorTextFocus && resourceLangId == po"
}
]
},
Expand Down
40 changes: 40 additions & 0 deletions src/focusing.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import * as vscode from "vscode";
import { Message } from "./message_type";
import { moveCursorTo } from "./moving";

export function focusOnNextTarget(
editor: vscode.TextEditor,
nextTargetFunc: (
editor: vscode.TextDocument,
lineno: number,
backwards: boolean
) => Message,
backwards = false
) {
const position = editor.selection.active;
const message = nextTargetFunc(editor.document, position.line, backwards);
if (message !== null) {
focusOnMessage(editor, message);
}
}

function focusOnMessage(editor: vscode.TextEditor, message: Message) {
const [line, character] = msgstrPosition(message);
const position = moveCursorTo(editor, line, character);
editor.revealRange(
new vscode.Range(position, position),
vscode.TextEditorRevealType.InCenterIfOutsideViewport
);
}

function msgstrPosition(message: Message): [number, number] {
for (const [index, line] of message.msgstrPluralLine.entries()) {
if (!message.msgstrPlural[index] || message.isfuzzy) {
return index === 0
? [line, 11]
: [line, 11 + Math.floor(Math.log10(index))];
}
}

return [message.msgstrLine, 8];
}
35 changes: 35 additions & 0 deletions src/lib.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import * as vscode from "vscode";
import {
nextFuzzyMessage,
nextUntranslatedMessage,
nextUntranslatedOrFuzzyMessage,
} from "./message";
import { focusOnNextTarget } from "./focusing";

export function moveToNextUntranslatedMessage(editor: vscode.TextEditor) {
focusOnNextTarget(editor, nextUntranslatedMessage);
}

export function moveToPreviousUntranslatedMessage(editor: vscode.TextEditor) {
focusOnNextTarget(editor, nextUntranslatedMessage, true);
}

export function moveToNextFuzzyMessage(editor: vscode.TextEditor) {
focusOnNextTarget(editor, nextFuzzyMessage);
}

export function moveToPreviousFuzzyMessage(editor: vscode.TextEditor) {
focusOnNextTarget(editor, nextFuzzyMessage, true);
}

export function moveToNextUntranslatedOrFuzzyMessage(
editor: vscode.TextEditor
) {
focusOnNextTarget(editor, nextUntranslatedOrFuzzyMessage);
}

export function moveToPreviousUntranslatedOrFuzzyMessage(
editor: vscode.TextEditor
) {
focusOnNextTarget(editor, nextUntranslatedOrFuzzyMessage, true);
}
16 changes: 16 additions & 0 deletions src/lines.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import * as vscode from "vscode";

export function* documentLines(document: vscode.TextDocument, startline = 0) {
for (let lineno = startline; lineno < document.lineCount; lineno++) {
yield document.lineAt(lineno);
}
}

export function* backwardDocumentLines(
document: vscode.TextDocument,
startline = document.lineCount - 1
) {
for (let lineno = startline; lineno >= 0; lineno--) {
yield document.lineAt(lineno);
}
}
99 changes: 99 additions & 0 deletions src/message.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import * as vscode from "vscode";
import { MessageParser } from "./message_parser";
import { Message } from "./message_type";
import { documentLines, backwardDocumentLines } from "./lines";

export function nextUntranslatedMessage(
document: vscode.TextDocument,
lineno: number,
backwards = false
): Message {
return nextMessageWithCondition(document, lineno, isUntranslated, backwards);
}

export function nextFuzzyMessage(
document: vscode.TextDocument,
lineno: number,
backwards = false
): Message {
return nextMessageWithCondition(
document,
lineno,
(message: Message) => message.isfuzzy,
backwards
);
}

export function nextUntranslatedOrFuzzyMessage(
document: vscode.TextDocument,
lineno: number,
backwards = false
): Message {
return nextMessageWithCondition(
document,
lineno,
(message: Message) => isUntranslated(message) || message.isfuzzy,
backwards
);
}

function nextMessageWithCondition(
document: vscode.TextDocument,
lineno: number,
condition: Function,
backwards = false
): Message {
let message = parseMessage(document, lineno);
const getMessage = backwards ? previousMessage : nextMessage;
while (message !== null) {
message = getMessage(document, message);
if (message && condition(message)) {
return message;
}
}
return null;
}

function nextMessage(
document: vscode.TextDocument,
currentMessage: Message
): Message {
for (const line of documentLines(document, currentMessage.lastline + 1)) {
if (line.text && !line.text.trim().startsWith("#")) {
return parseMessage(document, line.lineNumber);
}
}
return null;
}

function previousMessage(
document: vscode.TextDocument,
currentMessage: Message
): Message {
for (const line of backwardDocumentLines(
document,
currentMessage.firstline - 1
)) {
if (line.text && !line.text.trim().startsWith("#")) {
return parseMessage(document, line.lineNumber);
}
}
return null;
}

function parseMessage(document: vscode.TextDocument, lineno: number): Message {
return new MessageParser(document, lineno).parse();
}

function isUntranslated(message: Message): boolean {
return !isTranslated(message);
}

function isTranslated(message: Message): boolean {
return (
(message.msgstr && message.msgstr !== "") ||
(message.msgstrPlural &&
message.msgstrPlural.length > 0 &&
message.msgstrPlural.every((msgstr) => msgstr !== ""))
);
}
Loading

0 comments on commit 28d15ba

Please sign in to comment.