feat: detect battery mode

This commit is contained in:
Myriad-Dreamin 2025-11-16 07:36:15 +08:00
parent 55d53ecd71
commit 7b8c44ef4c
9 changed files with 412 additions and 7 deletions

77
Cargo.lock generated
View file

@ -221,6 +221,23 @@ version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "battery"
version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4b624268937c0e0a3edb7c27843f9e547c320d730c610d3b8e6e8e95b2026e4"
dependencies = [
"cfg-if",
"core-foundation 0.7.0",
"lazycell",
"libc",
"mach",
"nix",
"num-traits",
"uom",
"winapi",
]
[[package]]
name = "biblatex"
version = "0.11.0"
@ -699,16 +716,32 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "core-foundation"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171"
dependencies = [
"core-foundation-sys 0.7.0",
"libc",
]
[[package]]
name = "core-foundation"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6"
dependencies = [
"core-foundation-sys",
"core-foundation-sys 0.8.7",
"libc",
]
[[package]]
name = "core-foundation-sys"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac"
[[package]]
name = "core-foundation-sys"
version = "0.8.7"
@ -1828,7 +1861,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"core-foundation-sys 0.8.7",
"iana-time-zone-haiku",
"js-sys",
"log",
@ -2345,6 +2378,12 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "lazycell"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "lexopt"
version = "0.3.1"
@ -2449,6 +2488,15 @@ dependencies = [
"url",
]
[[package]]
name = "mach"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa"
dependencies = [
"libc",
]
[[package]]
name = "memchr"
version = "2.7.5"
@ -2535,6 +2583,18 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16cf681a23b4d0a43fc35024c176437f9dcd818db34e0f42ab456a0ee5ad497b"
[[package]]
name = "nix"
version = "0.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2ccba0cfe4fdf15982d1674c69b1fd80bad427d293849982668dfe454bd61f2"
dependencies = [
"bitflags 1.3.2",
"cc",
"cfg-if",
"libc",
]
[[package]]
name = "nohash-hasher"
version = "0.2.0"
@ -4775,9 +4835,10 @@ version = "0.14.0"
dependencies = [
"anyhow",
"base64",
"battery",
"bitvec",
"comemo",
"core-foundation",
"core-foundation 0.10.1",
"dashmap",
"ecow",
"fxhash",
@ -5767,6 +5828,16 @@ version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
[[package]]
name = "uom"
version = "0.30.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e76503e636584f1e10b9b3b9498538279561adcef5412927ba00c2b32c4ce5ed"
dependencies = [
"num-traits",
"typenum",
]
[[package]]
name = "url"
version = "2.5.2"

View file

@ -34,6 +34,7 @@ tokio = { version = "1.48.0", features = ["macros"] }
tokio-util = { version = "0.7.16", features = ["compat"] }
# System
battery = "0.7.8"
temp-env = "0.3.6"
open = { version = "5.3.2" }
parking_lot = "0.12.1"

View file

@ -33,6 +33,7 @@ time = { workspace = true, features = ["formatting"] }
lsp-types.workspace = true
tempfile = { workspace = true, optional = true }
same-file = { workspace = true, optional = true }
battery = { workspace = true, optional = true }
# feature = "web"
js-sys = { workspace = true, optional = true }
@ -78,7 +79,7 @@ rkyv-validation = ["rkyv/validation"]
__web = ["wasm-bindgen", "js-sys", "web-time"]
web = ["__web"]
system = ["tempfile", "same-file"]
system = ["tempfile", "same-file", "battery"]
bi-hash = []
[lints]

View file

@ -0,0 +1,30 @@
//! Battery-related utilities.
#[cfg(feature = "system")]
mod system {
/// Detects if the system is currently in power saving mode.
pub fn is_power_saving() -> bool {
::battery::Manager::new()
.ok()
.and_then(|manager| manager.batteries().ok())
.map(|mut batteries| {
batteries.any(|battery| match battery {
Ok(bat) => matches!(bat.state(), ::battery::State::Discharging),
Err(_) => false,
})
})
.unwrap_or(false)
}
}
#[cfg(feature = "system")]
pub use system::*;
#[cfg(not(feature = "system"))]
mod other {
/// Detects if the system is currently in power saving mode.
pub fn is_power_saving() -> bool {
false
}
}
#[cfg(not(feature = "system"))]
pub use other::*;

View file

@ -1,6 +1,7 @@
//! Additional functions wrapping Rust's standard library.
pub mod adt;
pub mod battery;
pub mod error;
pub mod fs;
pub mod hash;

View file

@ -378,12 +378,13 @@ impl Config {
}
};
self.syntax_only = match try_(|| update.get("syntaxOnly")?.as_str()) {
Some("enable" | "onPowerSaving") => true,
Some("onPowerSaving") => tinymist_std::battery::is_power_saving(),
Some("enable") => true,
Some("disable" | "auto") | None => false,
Some(value) => {
self.warnings.push(tinymist_l10n::t!(
"tinymist.config.badCompileStatus",
"compileStatus must be either `\"enable\"`, `\"disable\", `\"onPowerSaving\"`, or `\"auto\"`, got {value}",
"tinymist.config.badSyntaxOnly",
"syntaxOnly must be either `\"enable\"`, `\"disable\", `\"onPowerSaving\"`, or `\"auto\"`, got {value}",
value = value.debug_l10n(),
));

View file

@ -29,6 +29,10 @@ zh = "性能分析"
en = "compileStatus must be either `\"enable\"`, `\"disable\", `\"onPowerSaving\"`, or `\"auto\"`, got {value}"
zh = "compileStatus 必须是`\"enable\"`(打开)或 `\"disable\"`(关闭),得到 {value}"
[tinymist.config.badSyntaxOnly]
en = "syntaxOnly must be either `\"enable\"`, `\"disable\", `\"onPowerSaving\"`, or `\"auto\"`, got {value}"
zh = "syntaxOnly 必须是`\"enable\"`(打开)或 `\"disable\"`(关闭), `\"onPowerSaving\"`(省电模式下开启)或 `\"auto\"`(自动),得到 {value}"
[tinymist.config.badHoverPeriscope]
en = "failed to parse hoverPeriscope: {err}"
zh = "解析 hoverPeriscope 失败:{err}"

View file

@ -35,6 +35,17 @@ fn test_lsp() {
let hash = replay_log(&root.join("vscode"));
insta::assert_snapshot!(hash, @"siphash128_13:9a266bad2c9e8113b66eae3cfe83aab5");
}
{
gen_smoke(SmokeArgs {
root: root.join("vscode"),
init: "initialization/vscode-syntax-only-1.87.2".to_owned(),
log: "tests/fixtures/editions/base.log".to_owned(),
});
let hash = replay_log(&root.join("vscode"));
insta::assert_snapshot!(hash, @"siphash128_13:9a266bad2c9e8113b66eae3cfe83aab5");
}
}
fn handle_io<T>(res: io::Result<T>) -> T {

View file

@ -0,0 +1,285 @@
{
"processId": 126420,
"clientInfo": { "name": "Visual Studio Code", "version": "1.87.2" },
"locale": "en",
"capabilities": {
"workspace": {
"applyEdit": true,
"workspaceEdit": {
"documentChanges": true,
"resourceOperations": ["create", "rename", "delete"],
"failureHandling": "textOnlyTransactional",
"normalizesLineEndings": true,
"changeAnnotationSupport": { "groupsOnLabel": true }
},
"configuration": true,
"didChangeWatchedFiles": {
"dynamicRegistration": true,
"relativePatternSupport": true
},
"symbol": {
"dynamicRegistration": true,
"symbolKind": {
"valueSet": [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26
]
},
"tagSupport": { "valueSet": [1] },
"resolveSupport": { "properties": ["location.range"] }
},
"codeLens": { "refreshSupport": true },
"executeCommand": { "dynamicRegistration": true },
"didChangeConfiguration": { "dynamicRegistration": true },
"workspaceFolders": true,
"foldingRange": { "refreshSupport": true },
"semanticTokens": { "refreshSupport": true },
"fileOperations": {
"dynamicRegistration": true,
"didCreate": true,
"didRename": true,
"didDelete": true,
"willCreate": true,
"willRename": true,
"willDelete": true
},
"inlineValue": { "refreshSupport": true },
"inlayHint": { "refreshSupport": true },
"diagnostics": { "refreshSupport": true }
},
"textDocument": {
"publishDiagnostics": {
"relatedInformation": true,
"versionSupport": false,
"tagSupport": { "valueSet": [1, 2] },
"codeDescriptionSupport": true,
"dataSupport": true
},
"synchronization": {
"dynamicRegistration": true,
"willSave": true,
"willSaveWaitUntil": true,
"didSave": true
},
"completion": {
"dynamicRegistration": true,
"contextSupport": true,
"completionItem": {
"snippetSupport": true,
"commitCharactersSupport": true,
"documentationFormat": ["markdown", "plaintext"],
"deprecatedSupport": true,
"preselectSupport": true,
"tagSupport": { "valueSet": [1] },
"insertReplaceSupport": true,
"resolveSupport": {
"properties": ["documentation", "detail", "additionalTextEdits"]
},
"insertTextModeSupport": { "valueSet": [1, 2] },
"labelDetailsSupport": true
},
"insertTextMode": 2,
"completionItemKind": {
"valueSet": [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25
]
},
"completionList": {
"itemDefaults": [
"commitCharacters",
"editRange",
"insertTextFormat",
"insertTextMode",
"data"
]
}
},
"hover": {
"dynamicRegistration": true,
"contentFormat": ["markdown", "plaintext"]
},
"signatureHelp": {
"dynamicRegistration": true,
"signatureInformation": {
"documentationFormat": ["markdown", "plaintext"],
"parameterInformation": { "labelOffsetSupport": true },
"activeParameterSupport": true
},
"contextSupport": true
},
"definition": { "dynamicRegistration": true, "linkSupport": true },
"references": { "dynamicRegistration": true },
"documentHighlight": { "dynamicRegistration": true },
"documentSymbol": {
"dynamicRegistration": true,
"symbolKind": {
"valueSet": [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26
]
},
"hierarchicalDocumentSymbolSupport": true,
"tagSupport": { "valueSet": [1] },
"labelSupport": true
},
"codeAction": {
"dynamicRegistration": true,
"isPreferredSupport": true,
"disabledSupport": true,
"dataSupport": true,
"resolveSupport": { "properties": ["edit"] },
"codeActionLiteralSupport": {
"codeActionKind": {
"valueSet": [
"",
"quickfix",
"refactor",
"refactor.extract",
"refactor.inline",
"refactor.rewrite",
"source",
"source.organizeImports"
]
}
},
"honorsChangeAnnotations": true
},
"codeLens": { "dynamicRegistration": true },
"formatting": { "dynamicRegistration": true },
"rangeFormatting": {
"dynamicRegistration": true,
"rangesSupport": true
},
"onTypeFormatting": { "dynamicRegistration": true },
"rename": {
"dynamicRegistration": true,
"prepareSupport": true,
"prepareSupportDefaultBehavior": 1,
"honorsChangeAnnotations": true
},
"documentLink": { "dynamicRegistration": true, "tooltipSupport": true },
"typeDefinition": { "dynamicRegistration": true, "linkSupport": true },
"implementation": { "dynamicRegistration": true, "linkSupport": true },
"colorProvider": { "dynamicRegistration": true },
"foldingRange": {
"dynamicRegistration": true,
"rangeLimit": 5000,
"lineFoldingOnly": true,
"foldingRangeKind": { "valueSet": ["comment", "imports", "region"] },
"foldingRange": { "collapsedText": false }
},
"declaration": { "dynamicRegistration": true, "linkSupport": true },
"selectionRange": { "dynamicRegistration": true },
"callHierarchy": { "dynamicRegistration": true },
"semanticTokens": {
"dynamicRegistration": true,
"tokenTypes": [
"namespace",
"type",
"class",
"enum",
"interface",
"struct",
"typeParameter",
"parameter",
"variable",
"property",
"enumMember",
"event",
"function",
"method",
"macro",
"keyword",
"modifier",
"comment",
"string",
"number",
"regexp",
"operator",
"decorator"
],
"tokenModifiers": [
"declaration",
"definition",
"readonly",
"static",
"deprecated",
"abstract",
"async",
"modification",
"documentation",
"defaultLibrary"
],
"formats": ["relative"],
"requests": { "range": true, "full": { "delta": true } },
"multilineTokenSupport": false,
"overlappingTokenSupport": false,
"serverCancelSupport": true,
"augmentsSyntaxTokens": true
},
"linkedEditingRange": { "dynamicRegistration": true },
"typeHierarchy": { "dynamicRegistration": true },
"inlineValue": { "dynamicRegistration": true },
"inlayHint": {
"dynamicRegistration": true,
"resolveSupport": {
"properties": [
"tooltip",
"textEdits",
"label.tooltip",
"label.location",
"label.command"
]
}
},
"diagnostic": {
"dynamicRegistration": true,
"relatedDocumentSupport": false
}
},
"window": {
"showMessage": {
"messageActionItem": { "additionalPropertiesSupport": true }
},
"showDocument": { "support": true },
"workDoneProgress": true
},
"general": {
"staleRequestSupport": {
"cancel": true,
"retryOnContentModified": [
"textDocument/semanticTokens/full",
"textDocument/semanticTokens/range",
"textDocument/semanticTokens/full/delta"
]
},
"regularExpressions": { "engine": "ECMAScript", "version": "ES2020" },
"markdown": { "parser": "marked", "version": "1.1.0" },
"positionEncodings": ["utf-16"]
},
"notebookDocument": {
"synchronization": {
"dynamicRegistration": true,
"executionSummarySupport": true
}
}
},
"initializationOptions": {
"outputPath": "$root/target/$dir/$name",
"exportPdf": "onSave",
"semanticTokens": "enable",
"noSystemFonts": null,
"typstExtraArgs": [],
"trace": { "server": "off" },
"triggerSuggest": true,
"triggerParameterHints": true,
"triggerSuggestAndParameterHints": true,
"supportHtmlInMarkdown": true,
"supportExtendedCodeAction": true,
"syntaxOnly": "enable",
"customizedShowDocument": true,
"experimentalFormatterMode": "disable"
},
"trace": "off"
}