1
0

home/develop/emacs: add yasnippet snippets and make snippet dirs configurable

This commit makes two significant changes to the Emacs configuration:

1. Refactors emacs.nix to use proper NixOS module structure:
   - Converts from simple configuration to a module with options/config
   - Adds `tb.emacs.extraSnippetDirs` option to allow per-machine snippet
     directories (defaults to ~/.emacs.d/snippets/)
   - Moves yasnippet configuration from custom.el to nix-generated elisp,
     enabling dynamic snippet directory configuration via Nix

2. Adds a comprehensive collection of yasnippet snippets for multiple modes:
   - C++ mode: 50 snippets for common patterns (class, namespace, operators,
     copy/move semantics, debug helpers, documentation, threading primitives)
   - CC mode (shared C/C++): for, switch, main, include guards, etc.
   - CMake mode: if/else, foreach, function, macro, project boilerplate
   - LaTeX mode: document structure, beamer frames, figures, lists
   - Perl mode: package boilerplate, shebang
   - Python/Shell/Nix/Protobuf/Java/CSS/Dockerfile modes: horizontal rules
     and common patterns
   - Text mode: modeline snippets for locale settings

The snippets use yasnippet's inheritance system via .yas-parents files,
so c++-mode inherits from cc-mode and text-mode, reducing duplication.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-08 22:38:18 -08:00
parent 3d098013a9
commit af6c1ba4e9
111 changed files with 951 additions and 130 deletions

View File

@@ -0,0 +1,2 @@
cc-mode
text-mode

View File

@@ -0,0 +1,6 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: A
# key: A
# binding: direct-keybinding
# --
ASSERT_EQ($0)

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: ac
# key: ac
# --
* @param[in] alloc Memory allocator to use.

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: alloc
# key: alloc
# --
const xplat::polymorphic_allocator<> alloc;

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: ator
# key: ator
# --
const xplat::polymorphic_allocator<> alloc;

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: be
# key: be
# --
$1.begin(), $1.end()

View File

@@ -0,0 +1,8 @@
# -*- mode: snippet -*-
# contributor: York Zhao <gtdplatform@gmail.com>
# name: cerr
# key: cerr
# --
`(progn (save-excursion) (goto-char (point-min)) (unless (re-search-forward
"^using\\s-+namespace std;" nil 'no-errer) "std::"))
`cerr << $0 << '\n';

View File

@@ -0,0 +1,13 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: class
# key: class
# binding: direct-keybinding
# --
class ${1:Class}
{
public:
$1()
: { }
private:
};

View File

@@ -0,0 +1,10 @@
# -*- mode: snippet -*-
# name: cmd
# key: cmd
# --
static void ${1:cmd}(base::Cmd& cmd)
{
$0
}
CMD($1, "$1");

View File

@@ -0,0 +1,8 @@
# -*- mode: snippet -*-
# name: constructor
# key: ct
# --
${1:Class}::$1(${2:args}) ${3: : ${4:init}}
{
$0
}

View File

@@ -0,0 +1,6 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: copy
# key: copy
# binding: direct-keybinding
# --
* Copyright (C) `(format-time-string "%Y" (current-time))` Timo Bingmann <tb@panthema.net>

View File

@@ -0,0 +1,14 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: copymove
# key: copymove
# binding: direct-keybinding
# expand-env: ((yas-indent-line 'fixed))
# --
//! default copy-constructor
${1:class}(const $1 &) = default;
//! default assignment operator
$1 & operator = (const $1 &) = default;
//! move-constructor: default
$1($1 &&) = default;
//! move-assignment operator: default
$1 & operator = ($1 &&) = default;

View File

@@ -0,0 +1,8 @@
# -*- mode: snippet -*-
# contributor: York Zhao <gtdplatform@gmail.com>
# name: cout
# key: cout
# --
`(progn (save-excursion) (goto-char (point-min)) (unless (re-search-forward
"^using\\s-+namespace std;" nil 'no-errer) "std::"))
`cout << $0 << '\n';

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: cv
# key: cv
# --
std::cout << "$1 " << $1 << std::endl;

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: d
# key: d
# --
qDebug() <<

View File

@@ -0,0 +1,6 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: debug
# key: debug
# binding: direct-keybinding
# --
static constexpr bool debug = true;

View File

@@ -0,0 +1,6 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: debugf
# key: debugf
# binding: direct-keybinding
# --
static constexpr bool debug = false;

View File

@@ -0,0 +1,7 @@
# -*- mode: snippet -*-
# name: doc
# key: doc
# --
/**
* @brief $1
*/

View File

@@ -0,0 +1,12 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: dog
# key: dog
# binding: direct-keybinding
# expand-env: ((yas-indent-line 'fixed))
# --
//! \\name $1
//! \\{
$0
//! \\}

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: el
# key: el
# --
<< std::endl

View File

@@ -0,0 +1,14 @@
# -*- mode: snippet -*-
# name: functor
# key: functor
# --
class ${1:Functor}
{
public:
$1($2) { }
void operator () () const {
}
private:
};

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: hi
# key: hi
# --
/*`(make-string (- 78 (current-column)) ?-)`*/

View File

@@ -0,0 +1,6 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: i
# key: i
# binding: direct-keybinding
# --
`(if (char-equal ?) (preceding-char)) "," "")` m_${1:var}($1)

View File

@@ -0,0 +1,6 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: lock
# key: lock
# binding: direct-keybinding
# --
std::unique_lock<std::mutex> lock$1(mutex$1_);

View File

@@ -0,0 +1,7 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: mutexlock
# key: mutexlock
# binding: direct-keybinding
# --
static std::mutex mutex$1;
std::unique_lock<std::mutex> lock$1(mutex$1);

View File

@@ -0,0 +1,17 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: mysource
# key: mysource
# binding: direct-keybinding
# --
/*******************************************************************************
* $1/<file>
*
* $2
******************************************************************************/
namespace $1 {
} // namespace $1
/******************************************************************************/

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: nl
# key: nl
# --
// NOLINTNEXTLINE($1)

View File

@@ -0,0 +1,10 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: noncopy
# key: noncopy
# binding: direct-keybinding
# expand-env: ((yas-indent-line 'fixed))
# --
//! non-copyable: delete copy-constructor
${1:class}(const $1 &) = delete;
//! non-copyable: delete assignment operator
$1 & operator = (const $1 &) = delete;

View File

@@ -0,0 +1,14 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: noncopymove
# key: noncopymove
# binding: direct-keybinding
# expand-env: ((yas-indent-line 'fixed))
# --
//! non-copyable: delete copy-constructor
${1:class}(const $1 &) = delete;
//! non-copyable: delete assignment operator
$1 & operator = (const $1 &) = delete;
//! move-constructor: default
$1($1 &&) noexcept = default;
//! move-assignment operator: default
$1 & operator = ($1 &&) noexcept = default;

View File

@@ -0,0 +1,10 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: namespace
# key: ns
# binding: direct-keybinding
# --
namespace $1 {
$0
} // namespace $1

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: al
# key: al
# --
allocator_type alloc

View File

@@ -0,0 +1,8 @@
# -*- mode: snippet -*-
# name: operator>>
# key: op>>
# --
istream& operator>>(istream& s, const ${1:type}& ${2:c})
{
$0
}

View File

@@ -0,0 +1,8 @@
# -*- mode: snippet -*-
# name: operator<
# key: op<
# --
friend bool operator < (const ${1:type}& a, const $1& b)
{
return $0;
}

View File

@@ -0,0 +1,8 @@
# -*- mode: snippet -*-
# name: operator<<
# key: op<<
# --
friend std::ostream& operator << (std::ostream& os, const ${1:type}& ${2:x})
{
return os << $0;
}

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: os
# key: os
# --
os << " $1=" << x.$1;

View File

@@ -0,0 +1,6 @@
# -*- mode: snippet -*-
# name: oso
# key: oso
# --
if (${2:t}.${1:var})
os << " $1=" << $2.$1;

View File

@@ -0,0 +1,6 @@
# -*- mode: snippet -*-
# name: oss
# key: oss
# --
std::ostringstream oss;
oss << $0

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: pe
# key: pe
# --
v.$1 += p.$1;

View File

@@ -0,0 +1,8 @@
# -*- mode: snippet -*-
# name: perl
# key: perl
# --
/*[[[perl
$0
]]]*/
//[[[end]]]

View File

@@ -0,0 +1,10 @@
# -*- mode: snippet -*-
# name: q
# key: q
# --
db::Query q = cmd.db_.query << "SELECT $1"
<< into(...);
while (q.next())
{
}

View File

@@ -0,0 +1,6 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: stdrand
# key: stdrand
# binding: direct-keybinding
# --
std::default_random_engine ${1:name}(std::random_device { } ())

View File

@@ -0,0 +1,6 @@
# -*- mode: snippet; require-final-newline: nil -*-
# name: stdsleep
# key: stdsleep
# binding: direct-keybinding
# --
std::this_thread::sleep_for(std::chrono::seconds($1));

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: sv
# key: sv
# --
std::string_view

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: svlit
# key: svlit
# --
using namespace std::string_view_literals;

View File

@@ -0,0 +1,9 @@
# -*- mode: snippet -*-
# name: timestamp
# key: timestamp
# --
//! Time is measured using chrono::steady_clock
static double timestamp() {
return std::chrono::duration_cast<std::chrono::duration<double> >(
std::chrono::steady_clock::now().time_since_epoch()).count();
}

View File

@@ -0,0 +1,10 @@
# -*- mode: snippet -*-
# name: try
# key: try
# a bit too intrusive now still, not always I want to do this
# --
try {
$0
} catch (${1:std::exception& e}) {
}

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: using_ator
# key: using
# --
using allocator_type = xplat::polymorphic_allocator<>;

View File

@@ -0,0 +1,5 @@
# -*- mode: snippet -*-
# name: ls
# key: ls
# --
common::allocate_local_shared