├── LICENSE ├── README.md └── after └── syntax └── rust.vim /LICENSE: -------------------------------------------------------------------------------- 1 | ISC License 2 | 3 | Copyright (c) 2020–present Aramis Razzaghipour 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted, provided that the above 7 | copyright notice and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vim-rust-syntax-ext 2 | 3 | This is a Vim plugin that enhances Rust syntax highlighting – it does nothing else. This means that it is ideally used in conjunction with [the official plugin](https://github.com/rust-lang/rust.vim), so that you can get all the latest non-syntax-related features. 4 | 5 | ## Installation 6 | 7 | If you don’t have a plugin manager of choice I recommend [vim-plug](https://github.com/junegunn/vim-plug): 8 | 9 | ```viml 10 | Plug 'arzg/vim-rust-syntax-ext' 11 | ``` 12 | 13 | ## Why would I use this plugin when the existing Rust syntax highlighting is good enough? 14 | 15 | Here is a screenshot of some code using the official plugin, rust.vim: 16 | 17 | ![Some code using the official Rust plugin for Vim](https://raw.githubusercontent.com/arzg/resources/master/vim-rust-syntax-ext/rust.vim.png) 18 | 19 | And here is a screenshot using vim-rust-syntax-ext: 20 | 21 | ![The same code using vim-rust-syntax-ext](https://raw.githubusercontent.com/arzg/resources/master/vim-rust-syntax-ext/vim-rust-syntax-ext.png) 22 | 23 | ## Features (some of which rust.vim also has) 24 | 25 | *Sorry for the bad/incorrect/inconsistent code in the following screenshots. After a while you start to run out of fake code ideas …* 26 | 27 | *Note that features which may require colourscheme support to be differentiated from other highlight groups are marked with an asterisk.* 28 | 29 | vim-rust-syntax-ext highlights function definitions\*: 30 | 31 | ![](https://raw.githubusercontent.com/arzg/resources/master/vim-rust-syntax-ext/FunctionDefinitions.png) 32 | 33 | Variable definitions\* too, whether they use `let`, `let mut`, `const`, `static ref`, or are in a tuple destructure pattern: 34 | 35 | ![](https://raw.githubusercontent.com/arzg/resources/master/vim-rust-syntax-ext/IdentifierDefinitions.png) 36 | 37 | Struct/enum/union/type alias definitions are also highlighted: 38 | 39 | ![](https://raw.githubusercontent.com/arzg/resources/master/vim-rust-syntax-ext/TypeDefinitions.png) 40 | 41 | Now that we’re on the subject of types, look at how the type parameter definitions in this screenshot are highlighted the same way other type definitions are: 42 | 43 | ![](https://raw.githubusercontent.com/arzg/resources/master/vim-rust-syntax-ext/TypeParameters.png) 44 | 45 | One of vim-rust-syntax-ext’s most unique features is that it differentiates\* between things from your project, things from the standard library, and things from other modules. This feature was inspired by Xcode, which does this for Swift (but by using code analysis, not regular expressions!). *Note that the constants and function calls being highlighted the same is just a quirk of the colourscheme I’m using. The same goes for things from other modules and things from the standard library being highlighted the same – you could make them different if you wanted to do so.* 46 | 47 | ![](https://raw.githubusercontent.com/arzg/resources/master/vim-rust-syntax-ext/OriginOfThings.png) 48 | 49 | You might worry that this would break the highlighting of enum variants such as `LocalEnum::Variant`, because vim-rust-syntax-ext would think that `Variant` is a type from a separate module. This is not the case, however: 50 | 51 | ![](https://raw.githubusercontent.com/arzg/resources/master/vim-rust-syntax-ext/OriginOfThingsEnums.png) 52 | 53 | vim-rust-syntax-ext makes sure that items from the current crate are still highlighted as local items: 54 | 55 | ![](https://raw.githubusercontent.com/arzg/resources/master/vim-rust-syntax-ext/OriginOfThingsCrate.png) 56 | 57 | Another one of vim-rust-syntax-ext’s unique features is its careful highlighting of punctuation. With my colourscheme, both delimiters and operators are highlighted the same: 58 | 59 | ![](https://raw.githubusercontent.com/arzg/resources/master/vim-rust-syntax-ext/Punctuation.png) 60 | 61 | To help you tell the two apart I have linked `Operator` to `Statement` in the next screenshot, which is also a common practice of many Vim colourschemes. Note how the less than and greater than operators are highlighted as, well, operators, while when they are used to denote a type parameter they are highlighted as delimiters. 62 | 63 | ![](https://raw.githubusercontent.com/arzg/resources/master/vim-rust-syntax-ext/PunctuationOtherThemes.png) 64 | 65 | Lifetimes have been paid careful attention in vim-rust-syntax-ext. This screenshot shows that lifetimes are highlighted with a similar logic to variables:\* ‘special’ lifetimes like `'static` and `'_` are highlighted as library constants,\* lifetime definitions are highlighted like variable definitions\* (look at `enum Token<'a>`), and lifetime usages are highlighted the same way user variable usages are highlighted.\* 66 | 67 | ![](https://raw.githubusercontent.com/arzg/resources/master/vim-rust-syntax-ext/Lifetimes.png) 68 | 69 | Field accesses are highlighted as `Identifer`s: 70 | 71 | ![](https://raw.githubusercontent.com/arzg/resources/master/vim-rust-syntax-ext/FieldAccess.png) 72 | 73 | vim-rust-syntax-ext also highlights attributes: 74 | 75 | ![](https://raw.githubusercontent.com/arzg/resources/master/vim-rust-syntax-ext/Derive.png) 76 | 77 | ## Note for colourscheme authors 78 | 79 | I have made sure that it is as easy as possible to take advantage of vim-rust-syntax-ext’s highlighting as a colourscheme designer, by using `highlight default link` instead of `highlight link` so that you can override any links this plugin makes. Additionally, as much as possible, every single syntactical element has its own highlight group so that you can be as granular as you want with your adjustments. To give you an idea of what I mean, the `let` keyword (`rsLet`) and macros that come with the standard library (`rsLibraryMacro`) both get their own highlight groups. I didn’t want to make any assumptions, however, so I have linked all of vim-rust-syntax-ext’s highlight groups to the standard ones found in `:help group-name`. This means, for example, that `rsLibraryMacro` and `rsUserMacro` are not differentiated by default. 80 | 81 | Here are some of the more important links you may want to customise: 82 | 83 | - `rs{User,Crate,Foreign,Library}{Type,Func,Macro,Const}`: The `Library` set of highlight groups is for items from the standard library; the `Foreign` set of groups is for items from another module; `Crate`, which by default links to the `User` groups, is for items accessed by `crate::`; and `User` is essentially for everything else. By default the `Crate` highlight groups link to the `User` highlight groups. In case I haven’t explained well, some examples of these highlight groups include `rsUserType`, `rsLibraryFunc`, and so on. 84 | - `rsUserIdent`: There are no `Crate`, `Foreign`, etc identifiers because identifiers cannot be exported, meaning all identifers you will see are from the current project. 85 | - `rs{Type,Func,Ident,Lifetime}Def`: These highlight groups are used for definitions of various syntactical items. Note that `rsTypeDef` is linked by default to `Typedef`, which may not fit with your colourscheme. 86 | - `rs{User,Special}Lifetime`: With ‘special’ lifetimes I really mean `'static` and `'_` – all other lifetimes get `rsUserLifetime`. 87 | - `rsAttribute`: This is applied to `#[attributes]`, including `#[derive(...)]` for example. Arguably this should link to `Macro` (since attributes are usually defined with procedural macros), but I personally find it nicer when `rsAttribute` is highlighted as a keyword. 88 | 89 | ## Todo 90 | 91 | - `r# ... #` syntax 92 | - Format string parameters, e.g. `"{}"`, `"{:?}"`, `"{:#?}"` 93 | - Markdown in doc comments 94 | 95 | ## Colophon 96 | 97 | All screenshots use [xcodedark](https://github.com/arzg/vim-colors-xcode) (which takes advantage of the aforementioned highlight groups) with the SF Mono font in the Medium weight, with iTerm configured to use the Bold weight for bold text (rather than Heavy). 98 | -------------------------------------------------------------------------------- /after/syntax/rust.vim: -------------------------------------------------------------------------------- 1 | syntax clear 2 | let b:current_syntax = "rust" 3 | 4 | syntax region rsTypeParams matchgroup=rsDelimiter start='<' end='>' keepend contains=TOP 5 | 6 | " 7 | " Variables 8 | " 9 | 10 | syntax match rsUserIdent '\v[a-z][a-z0-9_]*' 11 | 12 | " 13 | " Module 14 | " 15 | 16 | syntax match rsModule '\v(::)@<=[a-z][a-z0-9_]*' 17 | syntax match rsModule '\v[a-z][a-z0-9_]*(::)@=' 18 | 19 | " 20 | " Conditionals 21 | " 22 | 23 | syntax keyword rsElse else 24 | syntax keyword rsIf if 25 | syntax keyword rsMatch match 26 | 27 | highlight default link rsElse rsConditional 28 | highlight default link rsIf rsConditional 29 | highlight default link rsMatch rsConditional 30 | 31 | " 32 | " Repeat 33 | " 34 | 35 | syntax keyword rsFor for 36 | syntax keyword rsLoop loop 37 | syntax keyword rsWhile while 38 | 39 | highlight default link rsFor rsRepeat 40 | highlight default link rsLoop rsRepeat 41 | highlight default link rsWhile rsRepeat 42 | 43 | " 44 | " Includes 45 | " 46 | 47 | syntax keyword rsUse use 48 | highlight default link rsUse rsInclude 49 | 50 | " 51 | " Other keywords 52 | " 53 | 54 | syntax keyword rsAs as 55 | syntax keyword rsAsync async 56 | syntax keyword rsAwait await 57 | syntax keyword rsBreak break 58 | syntax keyword rsConst const nextgroup=rsIdentDef,rsUnusedIdentDef skipwhite skipempty 59 | syntax keyword rsContinue continue 60 | syntax keyword rsCrate crate 61 | syntax keyword rsDyn dyn 62 | syntax keyword rsEnum enum nextgroup=rsTypeDef,rsUnusedTypeDef skipwhite skipempty 63 | syntax keyword rsExtern extern 64 | syntax keyword rsFn fn nextgroup=rsFuncDef,rsUnusedFuncDef skipwhite skipempty 65 | syntax keyword rsImpl impl nextgroup=rsTypeDefParams 66 | syntax keyword rsIn in 67 | syntax keyword rsLet let nextgroup=rsIdentDef,rsUnusedIdentDef,rsMut,rsRef,rsPattern skipwhite skipempty 68 | syntax keyword rsMod mod 69 | syntax keyword rsMove move 70 | syntax keyword rsMut mut nextgroup=rsIdentDef,rsUnusedIdentDef,rsLibraryType,rsSelfType,rsSelfValue,rsUserType skipwhite skipempty 71 | syntax keyword rsPub pub 72 | syntax keyword rsRef ref nextgroup=rsIdentDef,rsUnusedIdentDef,rsMut skipwhite skipempty 73 | syntax keyword rsReturn return 74 | syntax keyword rsSelfType Self 75 | syntax keyword rsSelfValue self 76 | syntax keyword rsStatic static nextgroup=rsIdentDef,rsUnusedIdentDef,rsRef skipwhite skipempty 77 | syntax keyword rsStruct struct nextgroup=rsTypeDef,rsUnusedTypeDef skipwhite skipempty 78 | syntax keyword rsSuper super 79 | syntax keyword rsTrait trait nextgroup=rsTypeDef,rsUnusedTypeDef skipwhite skipempty 80 | syntax keyword rsTypeAlias type nextgroup=rsTypeDef,rsUnusedTypeDef skipwhite skipempty 81 | syntax keyword rsUnderscore _ 82 | syntax keyword rsUnion union nextgroup=rsTypeDef,rsUnusedTypeDef skipwhite skipempty 83 | syntax keyword rsUnsafe unsafe 84 | syntax keyword rsWhere where 85 | 86 | highlight default link rsAs rsKeyword 87 | highlight default link rsAsync rsKeyword 88 | highlight default link rsAwait rsKeyword 89 | highlight default link rsBreak rsKeyword 90 | highlight default link rsConst rsKeyword 91 | highlight default link rsContinue rsKeyword 92 | highlight default link rsCrate rsKeyword 93 | highlight default link rsDyn rsKeyword 94 | highlight default link rsEnum rsKeyword 95 | highlight default link rsExtern rsKeyword 96 | highlight default link rsFn rsKeyword 97 | highlight default link rsImpl rsKeyword 98 | highlight default link rsIn rsKeyword 99 | highlight default link rsLet rsKeyword 100 | highlight default link rsMod rsKeyword 101 | highlight default link rsMove rsKeyword 102 | highlight default link rsMut rsKeyword 103 | highlight default link rsPub rsKeyword 104 | highlight default link rsRef rsKeyword 105 | highlight default link rsReturn rsKeyword 106 | highlight default link rsSelfType rsKeyword 107 | highlight default link rsSelfValue rsKeyword 108 | highlight default link rsStatic rsKeyword 109 | highlight default link rsStruct rsKeyword 110 | highlight default link rsSuper rsKeyword 111 | highlight default link rsTrait rsKeyword 112 | highlight default link rsTypeAlias rsKeyword 113 | highlight default link rsUnderscore rsKeyword 114 | highlight default link rsUnion rsKeyword 115 | highlight default link rsUnsafe rsKeyword 116 | highlight default link rsWhere rsKeyword 117 | 118 | " 119 | " Booleans 120 | " 121 | 122 | syntax keyword rsTrue true 123 | syntax keyword rsFalse false 124 | 125 | highlight default link rsTrue rsBoolean 126 | highlight default link rsFalse rsBoolean 127 | 128 | " 129 | " Strings 130 | " 131 | 132 | syntax region rsString 133 | \ matchgroup=rsQuote 134 | \ start='b\?"' 135 | \ skip='\\"' 136 | \ end='"' 137 | \ contains=@Spell 138 | 139 | " 140 | " Field access 141 | " 142 | 143 | syntax match rsFieldAccess '\v(\.)@<=[a-z][a-z0-9_]*>(\()@!' 144 | 145 | " 146 | " Helpers for matching foreign and crate-local items 147 | " 148 | 149 | " Foreign items are always preceded by zero or more type names separated by ‘::’ 150 | " (think nested enum variants) and at least one module path. This module path is 151 | " preceded by a word separator to prevent matching partially on type names (i.e. 152 | " skipping the instal capital letter). 153 | function! MatchForeign(regex, groupName, extraParams) 154 | execute 'syntax match ' . a:groupName . ' "\v(<[a-z][a-z0-9_]*::([A-Z][A-Za-z0-9]*::)*)@<=' . a:regex . '"' . a:extraParams 155 | endfunction 156 | 157 | " Crate-local items are also preceded by zero or more types names separated by 158 | " ‘::’, which is then preceded by zero or more module names separated by ‘::’, 159 | " which is finally preceded by ‘crate::’. 160 | function! MatchCrateLocal(regex, groupName, extraParams) 161 | execute 'syntax match ' . a:groupName . ' "\v(crate::([a-z][a-z0-9_]*::)*([A-Z][A-Za-z0-9]*::)*)@<=' . a:regex . '"' . a:extraParams 162 | endfunction 163 | 164 | " 165 | " Types 166 | " 167 | 168 | syntax match rsUserType '\v<[A-Z][A-Za-z0-9]*' nextgroup=rsTypeParams 169 | call MatchForeign('[A-Z][A-Za-z0-9]*', 'rsForeignType', ' nextgroup=rsTypeParams') 170 | call MatchCrateLocal('[A-Z][A-Za-z0-9]*', 'rsCrateType', ' nextgroup=rsTypeParams') 171 | 172 | " Standard library types 173 | 174 | let s:standardLibraryTypes = ["AccessError", "AcqRel", "Acquire", "Add", "AddAssign", "AddrInUse", "AddrNotAvailable", "AddrParseError", "AdminLocal", "Alignment", "Alloc", "AllocErr", "AllocError", "AlreadyExists", "Ancestors", "Any", "Arc", "Args", "ArgsOs", "Arguments", "AsMut", "AsRawFd", "AsRawHandle", "AsRawSocket", "AsRef", "AsciiExt", "AssertUnwindSafe", "AtomicBool", "AtomicI16", "AtomicI32", "AtomicI64", "AtomicI8", "AtomicIsize", "AtomicPtr", "AtomicU16", "AtomicU32", "AtomicU64", "AtomicU8", "AtomicUsize", "BTreeMap", "BTreeSet", "Backtrace", "BacktraceStatus", "Barrier", "BarrierWaitResult", "Binary", "BinaryHeap", "BitAnd", "BitAndAssign", "BitOr", "BitOrAssign", "BitXor", "BitXorAssign", "Borrow", "BorrowError", "BorrowMut", "BorrowMutError", "Borrowed", "Both", "Bound", "Box", "BrokenPipe", "BufRead", "BufReader", "BufWriter", "BuildHasher", "BuildHasherDefault", "Builder", "Bytes", "CStr", "CString", "CannotReallocInPlace", "CapacityOverflow", "Captured", "Cell", "Center", "Chain", "CharIndices", "CharPredicateSearcher", "CharSearcher", "CharSliceSearcher", "CharTryFromError", "Chars", "Child", "ChildStderr", "ChildStdin", "ChildStdout", "Chunks", "ChunksExact", "ChunksExactMut", "ChunksMut", "Clone", "Cloned", "CoerceUnsized", "Command", "CommandExt", "Complete", "Component", "Components", "Concat", "Condvar", "ConnectionAborted", "ConnectionRefused", "ConnectionReset", "Context", "Copied", "Copy", "Cow", "CurDir", "Current", "Cursor", "Cycle", "Debug", "DebugList", "DebugMap", "DebugSet", "DebugStruct", "DebugTuple", "DecodeUtf16", "DecodeUtf16Error", "Default", "DefaultHasher", "Deref", "DerefMut", "DeviceNS", "Difference", "DirBuilder", "DirBuilderExt", "DirEntry", "DirEntryExt", "Disabled", "Disconnected", "Discriminant", "Disk", "DispatchFromDyn", "Display", "Div", "DivAssign", "Done", "DoubleEndedIterator", "DoubleEndedSearcher", "Drain", "DrainFilter", "DrainSorted", "Drop", "Duration", "Empty", "EncodeUtf16", "EncodeWide", "End", "Entry", "Enumerate", "Eq", "Equal", "Err", "ErrorKind", "EscapeDebug", "EscapeDefault", "EscapeUnicode", "ExactSizeIterator", "Excess", "Excluded", "ExitCode", "ExitStatus", "ExitStatusExt", "Extend", "File", "FileExt", "FileType", "FileTypeExt", "Filter", "FilterMap", "FixedSizeArray", "FlatMap", "Flatten", "FloatToInt", "Fn", "FnMut", "FnOnce", "Formatter", "FpCategory", "From", "FromBytesWithNulError", "FromFn", "FromIterator", "FromRawFd", "FromRawHandle", "FromRawSocket", "FromStr", "FromUtf16Error", "FromUtf8Error", "Full", "Fuse", "FusedIterator", "Future", "Generator", "GeneratorState", "Global", "GlobalAlloc", "Greater", "HANDLE", "Hash", "HashMap", "HashSet", "Hasher", "Included", "Incoming", "Index", "IndexMut", "Infallible", "Infinite", "Initializer", "Inspect", "Instant", "IntErrorKind", "InterfaceLocal", "Interrupted", "Intersection", "Into", "IntoInnerError", "IntoIter", "IntoIterSorted", "IntoIterator", "IntoRawFd", "IntoRawHandle", "IntoRawSocket", "IntoStringError", "InvalidData", "InvalidDigit", "InvalidInput", "IoSlice", "IoSliceMut", "IpAddr", "Ipv4Addr", "Ipv6Addr", "Ipv6MulticastScope", "Iter", "IterMut", "Iterator", "Join", "JoinHandle", "JoinHandleExt", "JoinPathsError", "Keys", "Layout", "LayoutErr", "Left", "LengthAtMost32", "Less", "LineWriter", "Lines", "LinesAny", "LinkLocal", "LinkedList", "LocalKey", "Location", "LockResult", "LowerExp", "LowerHex", "ManuallyDrop", "Map", "Match", "MatchIndices", "Matches", "MaybeUninit", "Metadata", "MetadataExt", "Mul", "MulAssign", "Mutex", "MutexGuard", "Nan", "Neg", "NonNull", "NonZeroI128", "NonZeroI16", "NonZeroI32", "NonZeroI64", "NonZeroI8", "NonZeroIsize", "NonZeroU128", "NonZeroU16", "NonZeroU32", "NonZeroU64", "NonZeroU8", "NonZeroUsize", "None", "NoneError", "Normal", "Not", "NotConnected", "NotFound", "NotPresent", "NotUnicode", "NulError", "Occupied", "OccupiedEntry", "Octal", "Ok", "Once", "OnceState", "OnceWith", "OpenOptions", "OpenOptionsExt", "Option", "Ord", "Ordering", "OrganizationLocal", "OsStr", "OsStrExt", "OsString", "OsStringExt", "Other", "Output", "Overflow", "Owned", "PanicInfo", "ParentDir", "ParseBoolError", "ParseCharError", "ParseError", "ParseFloatError", "ParseIntError", "PartialEq", "PartialOrd", "Path", "PathBuf", "Pattern", "PeekMut", "Peekable", "Pending", "PermissionDenied", "Permissions", "PermissionsExt", "PhantomData", "PhantomPinned", "Pin", "Pointer", "PoisonError", "Poisoned", "Poll", "Prefix", "PrefixComponent", "Product", "RChunks", "RChunksExact", "RChunksExactMut", "RChunksMut", "RMatchIndices", "RMatches", "RSplit", "RSplitMut", "RSplitN", "RSplitNMut", "RSplitTerminator", "RandomState", "Range", "RangeBounds", "RangeFrom", "RangeFull", "RangeInclusive", "RangeMut", "RangeTo", "RangeToInclusive", "RawEntryBuilder", "RawEntryBuilderMut", "RawEntryMut", "RawFd", "RawHandle", "RawOccupiedEntryMut", "RawPthread", "RawSocket", "RawVacantEntryMut", "RawWaker", "RawWakerVTable", "Rc", "Read", "ReadDir", "Ready", "RealmLocal", "Receiver", "RecvError", "RecvTimeoutError", "Ref", "RefCell", "RefMut", "RefUnwindSafe", "Reject", "Relaxed", "Release", "Rem", "RemAssign", "Repeat", "RepeatWith", "Result", "Rev", "Reverse", "ReverseSearcher", "Right", "RootDir", "RwLock", "RwLockReadGuard", "RwLockWriteGuard", "SOCKET", "Scan", "SearchStep", "Searcher", "Seek", "SeekFrom", "Send", "SendError", "Sender", "SeqCst", "Shl", "ShlAssign", "Shr", "ShrAssign", "Shutdown", "Sink", "SipHasher", "SiteLocal", "Sized", "Skip", "SkipWhile", "SliceIndex", "SocketAddr", "SocketAddrV4", "SocketAddrV6", "Some", "Splice", "Split", "SplitAsciiWhitespace", "SplitMut", "SplitN", "SplitNMut", "SplitPaths", "SplitTerminator", "SplitWhitespace", "Start", "Stderr", "StderrLock", "Stdin", "StdinLock", "Stdio", "Stdout", "StdoutLock", "Step", "StepBy", "StrSearcher", "String", "StripPrefixError", "StructuralEq", "StructuralPartialEq", "Sub", "SubAssign", "Subnormal", "Successors", "Sum", "SymmetricDifference", "Sync", "SyncSender", "System", "SystemTime", "SystemTimeError", "Take", "TakeWhile", "TcpListener", "TcpStream", "Termination", "Thread", "ThreadId", "TimedOut", "Timeout", "ToLowercase", "ToOwned", "ToSocketAddrs", "ToString", "ToUppercase", "TraitObject", "TrustedLen", "Try", "TryFrom", "TryFromIntError", "TryFromSliceError", "TryInto", "TryIter", "TryLockError", "TryLockResult", "TryRecvError", "TryReserveError", "TrySendError", "TypeId", "UNC", "UdpSocket", "Unbounded", "Underflow", "UnexpectedEof", "UnicodeVersion", "Union", "UnixDatagram", "UnixListener", "UnixStream", "Unpin", "UnsafeCell", "Unsize", "Unsupported", "UnwindSafe", "UpperExp", "UpperHex", "Utf8Error", "V4", "V6", "VaList", "VaListImpl", "Vacant", "VacantEntry", "Values", "ValuesMut", "VarError", "Vars", "VarsOs", "Vec", "VecDeque", "Verbatim", "VerbatimDisk", "VerbatimUNC", "WaitTimeoutResult", "Waker", "Weak", "TokenStream", "Windows", "WouldBlock", "Wrapping", "Write", "WriteZero", "Yielded", "Zero", "Zip", "blkcnt_t", "blksize_t", "bool", "c_char", "c_double", "c_float", "c_int", "c_long", "c_longlong", "c_schar", "c_short", "c_uchar", "c_uint", "c_ulong", "c_ulonglong", "c_ushort", "char", "dev_t", "f32", "f64", "gid_t", "i128", "i16", "i32", "i64", "i8", "ino_t", "isize", "mode_t", "nlink_t", "off_t", "pid_t", "pthread_t", "str", "time_t", "u128", "u16", "u32", "u64", "u8", "uid_t", "usize"] 175 | 176 | for s:standardLibraryType in s:standardLibraryTypes 177 | execute 'syntax keyword rsLibraryType ' . s:standardLibraryType . ' nextgroup=rsTypeParams' 178 | endfor 179 | 180 | " 181 | " Constants 182 | " 183 | 184 | syntax match rsUserConst '\v<[A-Z][A-Z0-9_]+>' 185 | call MatchForeign('[A-Z][A-Z0-9_]+>', 'rsForeignConst', '') 186 | call MatchCrateLocal('[A-Z][A-Z0-9_]+>', 'rsCrateConst', '') 187 | 188 | " Standard library constants 189 | 190 | let s:standardLibraryConsts = ["ARCH", "ATOMIC_BOOL_INIT", "ATOMIC_I16_INIT", "ATOMIC_I32_INIT", "ATOMIC_I64_INIT", "ATOMIC_I8_INIT", "ATOMIC_ISIZE_INIT", "ATOMIC_U16_INIT", "ATOMIC_U32_INIT", "ATOMIC_U64_INIT", "ATOMIC_U8_INIT", "ATOMIC_USIZE_INIT", "DIGITS", "DLL_EXTENSION", "DLL_PREFIX", "DLL_SUFFIX", "EPSILON", "EXE_EXTENSION", "EXE_SUFFIX", "FAMILY", "FRAC_1_PI", "FRAC_1_SQRT_2", "FRAC_2_PI", "FRAC_2_SQRT_PI", "FRAC_PI_2", "FRAC_PI_3", "FRAC_PI_4", "FRAC_PI_6", "FRAC_PI_8", "INFINITY", "LN_10", "LN_2", "LOG10_2", "LOG10_E", "LOG2_10", "LOG2_E", "MAIN_SEPARATOR", "MANTISSA_DIGITS", "MAX", "MAX_10_EXP", "MAX_EXP", "MIN", "MIN_10_EXP", "MIN_EXP", "MIN_POSITIVE", "NAN", "NEG_INFINITY", "ONCE_INIT", "OS", "PI", "RADIX", "REPLACEMENT_CHARACTER", "SQRT_2", "TAU", "UNICODE_VERSION", "UNIX_EPOCH"] 191 | 192 | for s:standardLibraryConst in s:standardLibraryConsts 193 | execute 'syntax keyword rsLibraryConst ' . s:standardLibraryConst 194 | endfor 195 | 196 | " 197 | " Macros 198 | " 199 | 200 | syntax match rsUserMacro '\v<[a-z][a-z0-9_]*!' 201 | call MatchForeign('[a-z][a-z0-9_]*!', 'rsForeignMacro', '') 202 | call MatchCrateLocal('[a-z][a-z0-9_]*!', 'rsCrateMacro', '') 203 | 204 | " Standard library macros 205 | 206 | let s:standardLibraryMacros = ["asm", "assert", "assert_eq", "assert_ne", "cfg", "column", "compile_error", "concat", "concat_idents", "dbg", "debug_assert", "debug_assert_eq", "debug_assert_ne", "env", "eprint", "eprintln", "file", "format", "format_args", "format_args_nl", "global_asm", "include", "include_bytes", "include_str", "is_aarch64_feature_detected", "is_arm_feature_detected", "is_mips64_feature_detected", "is_mips_feature_detected", "is_powerpc64_feature_detected", "is_powerpc_feature_detected", "is_x86_feature_detected", "line", "log_syntax", "matches", "module_path", "option_env", "panic", "print", "println", "stringify", "thread_local", "todo", "trace_macros", "try", "unimplemented", "unreachable", "vec", "write", "writeln"] 207 | 208 | for s:standardLibraryMacro in s:standardLibraryMacros 209 | execute 'syntax match rsLibraryMacro "\v<' . s:standardLibraryMacro . '!"' 210 | endfor 211 | 212 | " 213 | " Functions 214 | " 215 | 216 | syntax match rsUserFunc '\v[a-z][a-z0-9_]*(\()@=' 217 | 218 | call MatchForeign('[a-z][a-z0-9_]*(\()@=', 'rsForeignFunc', '') 219 | call MatchCrateLocal('[a-z][a-z0-9_]*(\()@=', 'rsCrateFunc', '') 220 | 221 | syntax match rsUserMethod '\v(\.)@<=[a-z][a-z0-9_]*(\(|::)@=' 222 | highlight default link rsUserMethod rsUserFunc 223 | 224 | " Standard library functions 225 | 226 | let s:standardLibraryFuncs = ["abort", "add_with_overflow", "align_of", "align_of_val", "alloc", "alloc_zeroed", "args", "args_os", "arith_offset", "assume", "atomic_and", "atomic_and_acq", "atomic_and_acqrel", "atomic_and_rel", "atomic_and_relaxed", "atomic_cxchg", "atomic_cxchg_acq", "atomic_cxchg_acq_failrelaxed", "atomic_cxchg_acqrel", "atomic_cxchg_acqrel_failrelaxed", "atomic_cxchg_failacq", "atomic_cxchg_failrelaxed", "atomic_cxchg_rel", "atomic_cxchg_relaxed", "atomic_cxchgweak", "atomic_cxchgweak_acq", "atomic_cxchgweak_acq_failrelaxed", "atomic_cxchgweak_acqrel", "atomic_cxchgweak_acqrel_failrelaxed", "atomic_cxchgweak_failacq", "atomic_cxchgweak_failrelaxed", "atomic_cxchgweak_rel", "atomic_cxchgweak_relaxed", "atomic_fence", "atomic_fence_acq", "atomic_fence_acqrel", "atomic_fence_rel", "atomic_load", "atomic_load_acq", "atomic_load_relaxed", "atomic_load_unordered", "atomic_max", "atomic_max_acq", "atomic_max_acqrel", "atomic_max_rel", "atomic_max_relaxed", "atomic_min", "atomic_min_acq", "atomic_min_acqrel", "atomic_min_rel", "atomic_min_relaxed", "atomic_nand", "atomic_nand_acq", "atomic_nand_acqrel", "atomic_nand_rel", "atomic_nand_relaxed", "atomic_or", "atomic_or_acq", "atomic_or_acqrel", "atomic_or_rel", "atomic_or_relaxed", "atomic_singlethreadfence", "atomic_singlethreadfence_acq", "atomic_singlethreadfence_acqrel", "atomic_singlethreadfence_rel", "atomic_store", "atomic_store_rel", "atomic_store_relaxed", "atomic_store_unordered", "atomic_umax", "atomic_umax_acq", "atomic_umax_acqrel", "atomic_umax_rel", "atomic_umax_relaxed", "atomic_umin", "atomic_umin_acq", "atomic_umin_acqrel", "atomic_umin_rel", "atomic_umin_relaxed", "atomic_xadd", "atomic_xadd_acq", "atomic_xadd_acqrel", "atomic_xadd_rel", "atomic_xadd_relaxed", "atomic_xchg", "atomic_xchg_acq", "atomic_xchg_acqrel", "atomic_xchg_rel", "atomic_xchg_relaxed", "atomic_xor", "atomic_xor_acq", "atomic_xor_acqrel", "atomic_xor_rel", "atomic_xor_relaxed", "atomic_xsub", "atomic_xsub_acq", "atomic_xsub_acqrel", "atomic_xsub_rel", "atomic_xsub_relaxed", "bitreverse", "black_box", "breakpoint", "bswap", "caller_location", "canonicalize", "catch_unwind", "ceilf32", "ceilf64", "channel", "compiler_fence", "copy", "copy_nonoverlapping", "copysignf32", "copysignf64", "cosf32", "cosf64", "create_dir", "create_dir_all", "ctlz", "ctlz_nonzero", "ctpop", "cttz", "cttz_nonzero", "current", "current_dir", "current_exe", "dealloc", "decode_utf16", "discriminant", "discriminant_value", "drop", "drop_in_place", "empty", "eq", "escape_default", "exact_div", "exit", "exp2f32", "exp2f64", "expf32", "expf64", "fabsf32", "fabsf64", "fadd_fast", "fdiv_fast", "fence", "float_to_int_approx_unchecked", "floorf32", "floorf64", "fmaf32", "fmaf64", "fmul_fast", "forget", "forget_unsized", "format", "frem_fast", "from_boxed_utf8_unchecked", "from_digit", "from_fn", "from_mut", "from_raw_parts", "from_raw_parts_mut", "from_ref", "from_u32", "from_u32_unchecked", "from_utf8", "from_utf8_mut", "from_utf8_unchecked", "from_utf8_unchecked_mut", "fsub_fast", "handle_alloc_error", "hard_link", "hash", "home_dir", "id", "identity", "init", "is_separator", "join_paths", "likely", "log10f32", "log10f64", "log2f32", "log2f64", "logf32", "logf64", "max", "max_by", "max_by_key", "maxnumf32", "maxnumf64", "metadata", "min", "min_align_of", "min_align_of_val", "min_by", "min_by_key", "minnumf32", "minnumf64", "miri_start_panic", "move_val_init", "mul_with_overflow", "nearbyintf32", "nearbyintf64", "needs_drop", "nontemporal_store", "null", "null_mut", "offset", "once", "once_with", "panic_if_uninhabited", "panicking", "parent_id", "park", "park_timeout", "park_timeout_ms", "powf32", "powf64", "powif32", "powif64", "pref_align_of", "prefetch_read_data", "prefetch_read_instruction", "prefetch_write_data", "prefetch_write_instruction", "ptr_offset_from", "read", "read_dir", "read_link", "read_to_string", "read_unaligned", "read_volatile", "realloc", "remove_dir", "remove_dir_all", "remove_file", "remove_var", "rename", "repeat", "repeat_with", "replace", "resume_unwind", "rintf32", "rintf64", "rotate_left", "rotate_right", "roundf32", "roundf64", "rustc_peek", "saturating_add", "saturating_sub", "set_alloc_error_hook", "set_current_dir", "set_hook", "set_permissions", "set_var", "sinf32", "sinf64", "sink", "size_of", "size_of_val", "sleep", "sleep_ms", "slice_from_raw_parts", "slice_from_raw_parts_mut", "soft_link", "spawn", "spin_loop", "spin_loop_hint", "split_paths", "sqrtf32", "sqrtf64", "stderr", "stdin", "stdout", "sub_with_overflow", "successors", "swap", "swap_nonoverlapping", "symlink", "symlink_dir", "symlink_file", "symlink_metadata", "sync_channel", "take", "take_alloc_error_hook", "take_hook", "temp_dir", "transmute", "transmute_copy", "truncf32", "truncf64", "try", "type_id", "type_name", "type_name_of_val", "unaligned_volatile_load", "unaligned_volatile_store", "unchecked_add", "unchecked_div", "unchecked_mul", "unchecked_rem", "unchecked_shl", "unchecked_shr", "unchecked_sub", "uninit", "uninitialized", "unlikely", "unreachable", "unreachable_unchecked", "var", "var_os", "vars", "vars_os", "volatile_copy_memory", "volatile_copy_nonoverlapping_memory", "volatile_load", "volatile_set_memory", "volatile_store", "wrapping_add", "wrapping_mul", "wrapping_sub", "write", "write_bytes", "write_unaligned", "write_volatile", "yield_now", "zeroed"] 227 | 228 | for s:standardLibraryFunc in s:standardLibraryFuncs 229 | execute 'syntax match rsLibraryFunc "\v'. s:standardLibraryFunc . '(\()@="' 230 | endfor 231 | 232 | " 233 | " Lifetimes 234 | " 235 | 236 | syntax match rsUserLifetime "'[a-z][a-z0-9_]*" 237 | 238 | syntax match rsInferredLifetime "'_" 239 | syntax match rsStaticLifetime "'static" 240 | 241 | highlight default link rsInferredLifetime rsSpecialLifetime 242 | highlight default link rsStaticLifetime rsSpecialLifetime 243 | 244 | " 245 | " Type definitions 246 | " 247 | 248 | syntax match rsTypeDef '\v[A-Z][A-Za-z0-9]*' 249 | \ contained 250 | \ nextgroup=rsTypeDefParams 251 | 252 | syntax match rsUnusedTypeDef '\v_[A-Za-z0-9]+' 253 | \ contained 254 | \ nextgroup=rsTypeDefParams 255 | 256 | highlight default link rsUnusedTypeDef rsTypeDef 257 | 258 | " Type parameters 259 | syntax region rsTypeDefParams 260 | \ matchgroup=rsDelimiter 261 | \ start='<' 262 | \ end='>' 263 | \ keepend 264 | \ contains=TOP 265 | 266 | syntax match rsTypeParamDef '\v(:\s*)@' contained display 291 | syntax match rsIdentDef '\v<[A-Z][A-Z0-9_]*>' contained display 292 | 293 | syntax match rsUnusedIdentDef '\v<_[a-z0-9_]+>' contained display 294 | syntax match rsUnusedIdentDef '\v<_[A-Z0-9_]+>' contained display 295 | 296 | highlight default link rsUnusedIdentDef rsIdentDef 297 | 298 | syntax region rsPattern 299 | \ matchgroup=rsDelimiter 300 | \ start='(' 301 | \ end=')' 302 | \ contained 303 | \ contains=rsMut,rsRef,rsDelimiter,rsOperator,rsLibraryType,rsUserType,rsIdentDef,rsUnusedIdentDef,rsUnderscore 304 | 305 | " 306 | " Lifetime definitions 307 | " 308 | 309 | syntax match rsLifetimeDef "'[a-z][a-z0-9_]*" 310 | \ contained 311 | \ containedin=rsTypeDefParams 312 | 313 | " 314 | " Numbers 315 | " 316 | 317 | syntax match rsNumber '\v<[0-9_]+((u|i)(size|8|16|32|64|128))?' 318 | syntax match rsFloat '\v<[0-9_]+\.[0-9_]+(f(32|64))?' 319 | 320 | " 321 | " Attributes 322 | " 323 | 324 | syntax region rsAttribute 325 | \ matchgroup=rsDelimiter 326 | \ start='\v#!?\[' 327 | \ skip='\v\(.*\)' 328 | \ end='\]' 329 | 330 | syntax region rsAttributeParenWrapped 331 | \ start='(' 332 | \ end=')' 333 | \ containedin=rsAttribute 334 | \ contains=TOP 335 | \ keepend 336 | 337 | " 338 | " Macro identifiers 339 | " 340 | 341 | " Macros frequently interpolate identifiers with names like #foobar. 342 | syntax match rsUserIdent '\v#[a-z][a-z0-9_]*' 343 | 344 | " macro_rules! uses $foobar for parameters 345 | syntax match rsUserIdent '\v\$[a-z][a-z0-9_]*' 346 | 347 | " 348 | " Characters 349 | " 350 | 351 | syntax match rsCharacter "'.'" 352 | 353 | " 354 | " Delimiters 355 | " 356 | 357 | syntax match rsDelimiter '[(){}\[\]|\.,:;]\+' 358 | 359 | " 360 | " Operators 361 | " 362 | 363 | syntax match rsOperator '[!%&/\*+<=>?\^-]\+' 364 | 365 | " We highlight mutable references separately as an operator because otherwise 366 | " they would be recognised as the ‘mut’ keyword, thus whatever comes after the 367 | " ‘mut’ is highlighted as an identifier definition. 368 | syntax match rsOperator '&mut' 369 | 370 | " 371 | " Comments 372 | " 373 | 374 | syntax region rsComment start='//' end='$' contains=@Spell 375 | 376 | syntax region rsBlockComment start='/\*' end='\*/' contains=@Spell 377 | 378 | syntax region rsDocComment start='///' end='$' contains=@Spell 379 | syntax region rsDocComment start='//!' end='$' contains=@Spell 380 | 381 | syntax match rsCommentNote '\v[A-Z]+(:)@=' 382 | \ contained 383 | \ containedin=rsComment,rsDocComment 384 | 385 | " The matchgroup highlights the ‘```’ as part of the surrounding comment. 386 | syntax region rsDocTest 387 | \ matchgroup=rsDocComment 388 | \ start='```' 389 | \ end='```' 390 | \ contains=TOP 391 | \ containedin=rsDocComment 392 | 393 | " This is used to ‘match away’ the ‘///’ at the start of each line in a 394 | " doctest. It is only allowed to exist within doctests. 395 | syntax match rsDocCommentHeader '///' containedin=rsDocTest contained 396 | syntax match rsDocCommentHeader '//!' containedin=rsDocTest contained 397 | 398 | highlight default link rsBlockComment rsComment 399 | highlight default link rsDocCommentHeader rsDocComment 400 | 401 | " 402 | " Default linkages 403 | " 404 | 405 | highlight default link rsAttribute rsKeyword 406 | highlight default link rsBoolean Boolean 407 | highlight default link rsCharacter Character 408 | highlight default link rsComment Comment 409 | highlight default link rsCommentNote Todo 410 | highlight default link rsConditional Conditional 411 | highlight default link rsCrateConst rsUserConst 412 | highlight default link rsCrateFunc rsUserFunc 413 | highlight default link rsCrateMacro rsUserMacro 414 | highlight default link rsCrateType rsUserType 415 | highlight default link rsDelimiter Delimiter 416 | highlight default link rsDocComment SpecialComment 417 | highlight default link rsFieldAccess Identifier 418 | highlight default link rsFloat Float 419 | highlight default link rsForeignConst Constant 420 | highlight default link rsForeignFunc Function 421 | highlight default link rsForeignMacro Macro 422 | highlight default link rsForeignType Type 423 | highlight default link rsFuncDef Function 424 | highlight default link rsIdentDef Identifier 425 | highlight default link rsInclude Include 426 | highlight default link rsKeyword Keyword 427 | highlight default link rsLibraryConst Constant 428 | highlight default link rsLibraryFunc Function 429 | highlight default link rsLibraryMacro Macro 430 | highlight default link rsLibraryType Type 431 | highlight default link rsLifetimeDef Special 432 | highlight default link rsNumber Number 433 | highlight default link rsOperator Operator 434 | highlight default link rsQuote StringDelimiter 435 | highlight default link rsRepeat Repeat 436 | highlight default link rsSpecialLifetime Special 437 | highlight default link rsString String 438 | highlight default link rsTypeDef Typedef 439 | highlight default link rsUserConst Constant 440 | highlight default link rsUserFunc Function 441 | highlight default link rsUserIdent Identifier 442 | highlight default link rsUserLifetime Special 443 | highlight default link rsUserMacro Macro 444 | highlight default link rsUserType Type 445 | 446 | " Account for the vast majority of colourschemes not highlighting string 447 | " delimiters explicitly. 448 | highlight default link StringDelimiter String 449 | --------------------------------------------------------------------------------